diff --git a/tests/templates/kuttl/ldap/00-patch-ns.yaml b/tests/templates/kuttl/ldap/00-patch-ns.yaml new file mode 100644 index 0000000..d4f91fa --- /dev/null +++ b/tests/templates/kuttl/ldap/00-patch-ns.yaml @@ -0,0 +1,15 @@ +# see https://github.com/stackabletech/issues/issues/566 +--- +apiVersion: kuttl.dev/v1beta1 +kind: TestStep +commands: + - script: | + kubectl patch namespace $NAMESPACE --patch=' + { + "metadata": { + "labels": { + "pod-security.kubernetes.io/enforce": "privileged" + } + } + }' + timeout: 120 diff --git a/tests/templates/kuttl/ldap/01-rbac.yaml b/tests/templates/kuttl/ldap/01-rbac.yaml new file mode 100644 index 0000000..64eced8 --- /dev/null +++ b/tests/templates/kuttl/ldap/01-rbac.yaml @@ -0,0 +1,31 @@ +--- +apiVersion: v1 +kind: ServiceAccount +metadata: + name: test-service-account +--- +kind: Role +apiVersion: rbac.authorization.k8s.io/v1 +metadata: + name: test-role +rules: + - apiGroups: + - security.openshift.io + resources: + - securitycontextconstraints + resourceNames: + - privileged + verbs: + - use +--- +kind: RoleBinding +apiVersion: rbac.authorization.k8s.io/v1 +metadata: + name: test-role-binding +subjects: + - kind: ServiceAccount + name: test-service-account +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: Role + name: test-role diff --git a/tests/templates/kuttl/ldap/10-assert.yaml b/tests/templates/kuttl/ldap/10-assert.yaml new file mode 100644 index 0000000..9bcbc0e --- /dev/null +++ b/tests/templates/kuttl/ldap/10-assert.yaml @@ -0,0 +1,12 @@ +--- +apiVersion: kuttl.dev/v1beta1 +kind: TestAssert +timeout: 300 +--- +apiVersion: apps/v1 +kind: StatefulSet +metadata: + name: openldap +status: + readyReplicas: 1 + replicas: 1 diff --git a/tests/templates/kuttl/ldap/10-install-openldap.yaml b/tests/templates/kuttl/ldap/10-install-openldap.yaml new file mode 100644 index 0000000..9114da5 --- /dev/null +++ b/tests/templates/kuttl/ldap/10-install-openldap.yaml @@ -0,0 +1,81 @@ +--- +apiVersion: apps/v1 +kind: StatefulSet +metadata: + name: openldap + labels: + app.kubernetes.io/name: openldap +spec: + selector: + matchLabels: + app.kubernetes.io/name: openldap + serviceName: openldap + replicas: 1 + template: + metadata: + labels: + app.kubernetes.io/name: openldap + spec: + containers: + - name: openldap + image: bitnamilegacy/openldap:2.5 + env: + - name: LDAP_ADMIN_USERNAME + value: admin + - name: LDAP_ADMIN_PASSWORD + value: admin + - name: LDAP_ENABLE_TLS + value: "yes" + - name: LDAP_TLS_CERT_FILE + value: /tls/tls.crt + - name: LDAP_TLS_KEY_FILE + value: /tls/tls.key + - name: LDAP_TLS_CA_FILE + value: /tls/ca.crt + ports: + - name: ldap + containerPort: 1389 + - name: tls-ldap + containerPort: 1636 + volumeMounts: + - name: tls + mountPath: /tls + startupProbe: + tcpSocket: + port: 1389 + readinessProbe: + tcpSocket: + port: 1389 + # See https://github.com/bitnami/containers/issues/40841#issuecomment-1649977191 + securityContext: + capabilities: + drop: + - ALL + add: + - NET_BIND_SERVICE + serviceAccountName: test-service-account + volumes: + - name: tls + csi: + driver: secrets.stackable.tech + volumeAttributes: + secrets.stackable.tech/class: tls + secrets.stackable.tech/scope: pod +--- +apiVersion: v1 +kind: Service +metadata: + name: openldap + labels: + app.kubernetes.io/name: openldap +spec: + type: ClusterIP + ports: + - name: ldap + port: 1389 + targetPort: ldap + - name: tls-ldap + port: 1636 + targetPort: tls-ldap + selector: + app.kubernetes.io/name: openldap diff --git a/tests/templates/kuttl/ldap/11-assert.yaml b/tests/templates/kuttl/ldap/11-assert.yaml new file mode 100644 index 0000000..387b79c --- /dev/null +++ b/tests/templates/kuttl/ldap/11-assert.yaml @@ -0,0 +1,11 @@ +--- +apiVersion: kuttl.dev/v1beta1 +kind: TestAssert +timeout: 600 +--- +apiVersion: batch/v1 +kind: Job +metadata: + name: create-ldap-user +status: + succeeded: 1 diff --git a/tests/templates/kuttl/ldap/11-create-ldap-user.yaml b/tests/templates/kuttl/ldap/11-create-ldap-user.yaml new file mode 100644 index 0000000..455e62d --- /dev/null +++ b/tests/templates/kuttl/ldap/11-create-ldap-user.yaml @@ -0,0 +1,105 @@ +--- +apiVersion: batch/v1 +kind: Job +metadata: + name: create-ldap-user +spec: + template: + spec: + containers: + - name: create-ldap-user + image: bitnamilegacy/openldap:2.5 + command: + - /bin/bash + - -euxo + - pipefail + - -c + args: + - | + ldapadd \ + -D cn=admin,dc=example,dc=org \ + -w admin \ + -f /stackable/ldap-users/integrationtest \ + || true + + ldappasswd \ + -D cn=admin,dc=example,dc=org \ + -w admin \ + -s integrationtest \ + cn=integrationtest,ou=users,dc=example,dc=org + + # Check that the user works + ldapsearch \ + -D cn=integrationtest,ou=users,dc=example,dc=org \ + -w integrationtest \ + -b ou=users,dc=example,dc=org + env: + - name: NAMESPACE + valueFrom: + fieldRef: + fieldPath: metadata.namespace + - name: LDAPURI + value: ldaps://openldap.$(NAMESPACE).svc.cluster.local:1636/ + - name: LDAPTLS_CACERT + value: /stackable/tls/ca.crt + volumeMounts: + - name: ldap-users + mountPath: /stackable/ldap-users + - name: tls + mountPath: /stackable/tls + securityContext: + allowPrivilegeEscalation: false + capabilities: + drop: + - ALL + runAsNonRoot: true + resources: + requests: + memory: 128Mi + cpu: 100m + limits: + memory: 128Mi + cpu: 400m + volumes: + - name: ldap-users + configMap: + name: ldap-users + - name: tls + ephemeral: + volumeClaimTemplate: + metadata: + annotations: + secrets.stackable.tech/class: tls + spec: + storageClassName: secrets.stackable.tech + accessModes: + - ReadWriteOnce + resources: + requests: + storage: "1" + serviceAccountName: test-service-account + restartPolicy: OnFailure +--- +apiVersion: v1 +kind: ConfigMap +metadata: + name: ldap-users +data: + integrationtest: | + dn: cn=integrationtest,ou=users,dc=example,dc=org + objectClass: inetOrgPerson + objectClass: posixAccount + objectClass: shadowAccount + cn: integrationtest + uid: integrationtest + givenName: Stackable + sn: Integration-Test + mail: integrationtest@stackable.de + uidNumber: 16842 + gidNumber: 100 + homeDirectory: /home/integrationtest + loginShell: /bin/bash + userPassword: {crypt}x + shadowLastChange: 0 + shadowMax: 0 + shadowWarning: 0 diff --git a/tests/templates/kuttl/ldap/20-create-opensearch-security-config.yaml b/tests/templates/kuttl/ldap/20-create-opensearch-security-config.yaml new file mode 100644 index 0000000..31930c0 --- /dev/null +++ b/tests/templates/kuttl/ldap/20-create-opensearch-security-config.yaml @@ -0,0 +1,7 @@ +--- +apiVersion: kuttl.dev/v1beta1 +kind: TestStep +commands: + - script: > + envsubst '$NAMESPACE' < 20_opensearch-security-config.yaml | + kubectl apply -n $NAMESPACE -f - diff --git a/tests/templates/kuttl/ldap/20_opensearch-security-config.yaml.j2 b/tests/templates/kuttl/ldap/20_opensearch-security-config.yaml.j2 new file mode 100644 index 0000000..d5130a6 --- /dev/null +++ b/tests/templates/kuttl/ldap/20_opensearch-security-config.yaml.j2 @@ -0,0 +1,106 @@ +--- +apiVersion: v1 +kind: Secret +metadata: + name: opensearch-security-config +stringData: + action_groups.yml: | + --- + _meta: + type: actiongroups + config_version: 2 + allowlist.yml: | + --- + _meta: + type: allowlist + config_version: 2 + + config: + enabled: false + audit.yml: | + --- + _meta: + type: audit + config_version: 2 + + config: + enabled: false + config.yml: | + --- + _meta: + type: config + config_version: 2 + + config: + dynamic: + authc: + ldap: + http_enabled: true + transport_enabled: true + order: 1 + http_authenticator: + type: basic + challenge: false + authentication_backend: + type: ldap + config: + enable_ssl: true + hosts: + - openldap.$NAMESPACE.svc.cluster.local:1636 + pemtrustedcas_filepath: {{ test_scenario['values']['opensearch_home'] }}/config/tls/ca.crt + userbase: ou=users,dc=example,dc=org + username_attribute: uid + usersearch: (cn={0}) + verify_hostnames: true + authz: {} + internal_users.yml: | + --- + # The hash value is a bcrypt hash and can be generated with plugin/tools/hash.sh + + _meta: + type: internalusers + config_version: 2 + + admin: + hash: $2y$10$xRtHZFJ9QhG9GcYhRpAGpufCZYsk//nxsuel5URh0GWEBgmiI4Q/e + reserved: true + backend_roles: + - admin + description: OpenSearch admin user + + kibanaserver: + hash: $2y$10$vPgQ/6ilKDM5utawBqxoR.7euhVQ0qeGl8mPTeKhmFT475WUDrfQS + reserved: true + description: OpenSearch Dashboards user + nodes_dn.yml: | + --- + _meta: + type: nodesdn + config_version: 2 + roles.yml: | + --- + _meta: + type: roles + config_version: 2 + roles_mapping.yml: | + --- + _meta: + type: rolesmapping + config_version: 2 + + all_access: + reserved: false + backend_roles: + - admin + users: + - integrationtest + + kibana_server: + reserved: true + users: + - kibanaserver + tenants.yml: | + --- + _meta: + type: tenants + config_version: 2 diff --git a/tests/templates/kuttl/ldap/21-assert.yaml.j2 b/tests/templates/kuttl/ldap/21-assert.yaml.j2 new file mode 100644 index 0000000..65425bd --- /dev/null +++ b/tests/templates/kuttl/ldap/21-assert.yaml.j2 @@ -0,0 +1,12 @@ +--- +apiVersion: kuttl.dev/v1beta1 +kind: TestAssert +timeout: 600 +--- +apiVersion: apps/v1 +kind: StatefulSet +metadata: + name: opensearch-nodes-default +status: + readyReplicas: 3 + replicas: 3 diff --git a/tests/templates/kuttl/ldap/21-install-opensearch.yaml.j2 b/tests/templates/kuttl/ldap/21-install-opensearch.yaml.j2 new file mode 100644 index 0000000..7a7ae18 --- /dev/null +++ b/tests/templates/kuttl/ldap/21-install-opensearch.yaml.j2 @@ -0,0 +1,66 @@ +--- +apiVersion: opensearch.stackable.tech/v1alpha1 +kind: OpenSearchCluster +metadata: + name: opensearch +spec: + image: +{% if test_scenario['values']['opensearch'].find(",") > 0 %} + custom: "{{ test_scenario['values']['opensearch'].split(',')[1] }}" + productVersion: "{{ test_scenario['values']['opensearch'].split(',')[0] }}" +{% else %} + productVersion: "{{ test_scenario['values']['opensearch'] }}" +{% endif %} + pullPolicy: IfNotPresent + nodes: + roleGroups: + default: + replicas: 3 + envOverrides: + DISABLE_INSTALL_DEMO_CONFIG: "true" + OPENSEARCH_HOME: {{ test_scenario['values']['opensearch_home'] }} + configOverrides: + opensearch.yml: + # Disable memory mapping in this test; If memory mapping were activated, the kernel setting + # vm.max_map_count would have to be increased to 262144 on the node. + node.store.allow_mmap: "false" + plugins.security.allow_default_init_securityindex: "true" + plugins.security.ssl.transport.enabled: "true" + plugins.security.ssl.transport.pemcert_filepath: {{ test_scenario['values']['opensearch_home'] }}/config/tls/tls.crt + plugins.security.ssl.transport.pemkey_filepath: {{ test_scenario['values']['opensearch_home'] }}/config/tls/tls.key + plugins.security.ssl.transport.pemtrustedcas_filepath: {{ test_scenario['values']['opensearch_home'] }}/config/tls/ca.crt + plugins.security.ssl.http.enabled: "true" + plugins.security.ssl.http.pemcert_filepath: {{ test_scenario['values']['opensearch_home'] }}/config/tls/tls.crt + plugins.security.ssl.http.pemkey_filepath: {{ test_scenario['values']['opensearch_home'] }}/config/tls/tls.key + plugins.security.ssl.http.pemtrustedcas_filepath: {{ test_scenario['values']['opensearch_home'] }}/config/tls/ca.crt + podOverrides: + spec: + containers: + - name: opensearch + volumeMounts: + - name: security-config + mountPath: {{ test_scenario['values']['opensearch_home'] }}/config/opensearch-security + readOnly: true + - name: tls + mountPath: {{ test_scenario['values']['opensearch_home'] }}/config/tls + readOnly: true + securityContext: + fsGroup: 1000 + volumes: + - name: security-config + secret: + secretName: opensearch-security-config + - name: tls + ephemeral: + volumeClaimTemplate: + metadata: + annotations: + secrets.stackable.tech/class: tls + secrets.stackable.tech/scope: node,pod,service=opensearch,service=opensearch-nodes-default-headless + spec: + storageClassName: secrets.stackable.tech + accessModes: + - ReadWriteOnce + resources: + requests: + storage: "1" diff --git a/tests/templates/kuttl/ldap/30-assert.yaml b/tests/templates/kuttl/ldap/30-assert.yaml new file mode 100644 index 0000000..bebbaa9 --- /dev/null +++ b/tests/templates/kuttl/ldap/30-assert.yaml @@ -0,0 +1,11 @@ +--- +apiVersion: kuttl.dev/v1beta1 +kind: TestAssert +timeout: 600 +--- +apiVersion: batch/v1 +kind: Job +metadata: + name: test-opensearch +status: + succeeded: 1 diff --git a/tests/templates/kuttl/ldap/30-test-opensearch.yaml b/tests/templates/kuttl/ldap/30-test-opensearch.yaml new file mode 100644 index 0000000..a428007 --- /dev/null +++ b/tests/templates/kuttl/ldap/30-test-opensearch.yaml @@ -0,0 +1,110 @@ +--- +apiVersion: batch/v1 +kind: Job +metadata: + name: test-opensearch +spec: + template: + spec: + containers: + - name: test-opensearch + image: oci.stackable.tech/sdp/testing-tools:0.2.0-stackable0.0.0-dev + command: + - /bin/bash + - -euxo + - pipefail + - -c + args: + - | + pip install opensearch-py==3.0.0 + python scripts/test.py + env: + # required for pip install + - name: HOME + value: /stackable + volumeMounts: + - name: script + mountPath: /stackable/scripts + - name: tls + mountPath: /stackable/tls + securityContext: + allowPrivilegeEscalation: false + capabilities: + drop: + - ALL + runAsNonRoot: true + resources: + requests: + memory: 128Mi + cpu: 100m + limits: + memory: 128Mi + cpu: 400m + volumes: + - name: script + configMap: + name: test-opensearch + - name: tls + ephemeral: + volumeClaimTemplate: + metadata: + annotations: + secrets.stackable.tech/class: tls + spec: + storageClassName: secrets.stackable.tech + accessModes: + - ReadWriteOnce + resources: + requests: + storage: "1" + serviceAccountName: test-service-account + securityContext: + fsGroup: 1000 + restartPolicy: OnFailure +--- +apiVersion: v1 +kind: ConfigMap +metadata: + name: test-opensearch +data: + test.py: | + from opensearchpy import OpenSearch + + host = 'opensearch' + port = 9200 + auth = ('integrationtest', 'integrationtest') + ca_certs_path = '/stackable/tls/ca.crt' + + client = OpenSearch( + hosts = [{'host': host, 'port': port}], + http_compress = True, + http_auth = auth, + use_ssl = True, + verify_certs = True, + ssl_assert_hostname = False, + ssl_show_warn = False, + ca_certs = ca_certs_path + ) + + # Create an index + index_name = 'test-index' + + response = client.indices.create(index=index_name) + + print(f'Creating index; {response=}') + + # Add a document to the index + response = client.index( + index = index_name, + body = { + 'name': 'Stackable' + }, + id = 1, + ) + + print(f'Adding document; {response=}') + + # Delete the index. + response = client.indices.delete(index=index_name) + + print(f'Deleting index; {response=}') diff --git a/tests/templates/kuttl/smoke/20-test-opensearch.yaml b/tests/templates/kuttl/smoke/20-test-opensearch.yaml index 25c927c..5ebbbda 100644 --- a/tests/templates/kuttl/smoke/20-test-opensearch.yaml +++ b/tests/templates/kuttl/smoke/20-test-opensearch.yaml @@ -16,7 +16,7 @@ spec: - -c args: - | - pip install opensearch-py + pip install opensearch-py==3.0.0 python scripts/test.py env: # required for pip install @@ -84,8 +84,6 @@ data: hosts = [{'host': host, 'port': port}], http_compress = True, # enables gzip compression for request bodies http_auth = auth, - # client_cert = client_cert_path, - # client_key = client_key_path, use_ssl = True, verify_certs = True, ssl_assert_hostname = False, diff --git a/tests/test-definition.yaml b/tests/test-definition.yaml index a48bbbf..efad126 100644 --- a/tests/test-definition.yaml +++ b/tests/test-definition.yaml @@ -30,6 +30,11 @@ tests: - opensearch - openshift - opensearch_home + - name: ldap + dimensions: + - opensearch + - openshift + - opensearch_home suites: - name: nightly patch: