From c8e26fd0d126b02f24c6d77290414f8ea9818a9b Mon Sep 17 00:00:00 2001 From: Periklis Tsirakidis Date: Wed, 24 Mar 2021 18:07:27 +0100 Subject: [PATCH] Add OpenShift Logging sgconfig test suite This change set adds tests for the official OpenShift Logging opendistro configuration (). The test includes asserts that roles/rolemappings and configuration allow successful operations of the following: - Elasticsearch Operator on Cluster Level Operations - Elasticsearch Operator on Index Level Operations - Index Management Operations - Kibana Project User/Admin User/Server Access --- .../multitenancy/test/MultitenancyTests.java | 1 - .../openshift_logging/CollectorTests.java | 146 +++++ .../ElasticsearchOperatorTests.java | 574 ++++++++++++++++++ .../IndexManagementTests.java | 203 +++++++ .../openshift_logging/KibanaTests.java | 449 ++++++++++++++ .../openshift-logging/kirk-keystore.jks | Bin 0 -> 4525 bytes .../openshift-logging/node-0-keystore.jks | Bin 0 -> 4593 bytes .../openshift-logging/ocp_action_groups.yml | 143 +++++ .../openshift-logging/ocp_config.yml | 32 + .../openshift-logging/ocp_internal_users.yml | 12 + .../resources/openshift-logging/ocp_roles.yml | 165 +++++ .../openshift-logging/ocp_roles_mapping.yml | 48 ++ .../openshift-logging/ocp_tenants.yml | 3 + .../openshift-logging/spock-keystore.jks | Bin 0 -> 4528 bytes .../openshift-logging/truststore.jks | Bin 0 -> 1096 bytes 15 files changed, 1775 insertions(+), 1 deletion(-) create mode 100644 src/test/java/com/amazon/opendistroforelasticsearch/security/openshift_logging/CollectorTests.java create mode 100644 src/test/java/com/amazon/opendistroforelasticsearch/security/openshift_logging/ElasticsearchOperatorTests.java create mode 100644 src/test/java/com/amazon/opendistroforelasticsearch/security/openshift_logging/IndexManagementTests.java create mode 100644 src/test/java/com/amazon/opendistroforelasticsearch/security/openshift_logging/KibanaTests.java create mode 100644 src/test/resources/openshift-logging/kirk-keystore.jks create mode 100644 src/test/resources/openshift-logging/node-0-keystore.jks create mode 100644 src/test/resources/openshift-logging/ocp_action_groups.yml create mode 100644 src/test/resources/openshift-logging/ocp_config.yml create mode 100644 src/test/resources/openshift-logging/ocp_internal_users.yml create mode 100644 src/test/resources/openshift-logging/ocp_roles.yml create mode 100644 src/test/resources/openshift-logging/ocp_roles_mapping.yml create mode 100644 src/test/resources/openshift-logging/ocp_tenants.yml create mode 100644 src/test/resources/openshift-logging/spock-keystore.jks create mode 100644 src/test/resources/openshift-logging/truststore.jks diff --git a/src/test/java/com/amazon/opendistroforelasticsearch/security/multitenancy/test/MultitenancyTests.java b/src/test/java/com/amazon/opendistroforelasticsearch/security/multitenancy/test/MultitenancyTests.java index 3e94a2b31..b0aa9a128 100644 --- a/src/test/java/com/amazon/opendistroforelasticsearch/security/multitenancy/test/MultitenancyTests.java +++ b/src/test/java/com/amazon/opendistroforelasticsearch/security/multitenancy/test/MultitenancyTests.java @@ -383,5 +383,4 @@ public void testKibanaAlias65() throws Exception { System.out.println(res.getBody()); Assert.assertTrue(res.getBody().contains(".kibana_-900636979_kibanaro")); } - } diff --git a/src/test/java/com/amazon/opendistroforelasticsearch/security/openshift_logging/CollectorTests.java b/src/test/java/com/amazon/opendistroforelasticsearch/security/openshift_logging/CollectorTests.java new file mode 100644 index 000000000..2b408fcd1 --- /dev/null +++ b/src/test/java/com/amazon/opendistroforelasticsearch/security/openshift_logging/CollectorTests.java @@ -0,0 +1,146 @@ +package com.amazon.opendistroforelasticsearch.security.openshift_logging; + +import com.amazon.opendistroforelasticsearch.security.test.DynamicSecurityConfig; +import com.amazon.opendistroforelasticsearch.security.test.SingleClusterTest; +import com.amazon.opendistroforelasticsearch.security.test.helper.rest.RestHelper; +import org.apache.http.HttpStatus; +import org.apache.http.message.BasicHeader; +import org.elasticsearch.action.admin.indices.alias.Alias; +import org.elasticsearch.action.admin.indices.create.CreateIndexRequest; +import org.elasticsearch.action.index.IndexRequest; +import org.elasticsearch.action.support.WriteRequest; +import org.elasticsearch.client.transport.TransportClient; +import org.elasticsearch.common.settings.Settings; +import org.elasticsearch.common.xcontent.XContentType; +import org.junit.Assert; +import org.junit.Test; + +import java.util.HashMap; +import java.util.Map; + +public class CollectorTests extends SingleClusterTest { + + @Override + protected String getResourceFolder() { + return "openshift-logging"; + } + + @Test + public void testBulkIndexDocuments() throws Exception { + final Settings settings = Settings.builder() + .put("opendistro_security.restapi.roles_enabled", "kibana_server") + .build(); + + final DynamicSecurityConfig dsc = new DynamicSecurityConfig() + .setConfig("ocp_config.yml") + .setSecurityRoles("ocp_roles.yml") + .setSecurityRolesMapping("ocp_roles_mapping.yml") + .setSecurityInternalUsers("ocp_internal_users.yml") + .setSecurityActionGroups("ocp_action_groups.yml"); + + setup(Settings.EMPTY, dsc, settings); + try (TransportClient tc = getInternalTransportClient()) { + Map indexSettings = new HashMap(); + indexSettings.put("number_of_shards", 1); + indexSettings.put("number_of_replicas", 1); + + for (int i = 1; i < 21; i++) { + String leadingZeros = "00000"; + if (i >= 10) { + leadingZeros = "0000"; + } + + String appIndexName = "app-" + leadingZeros + i; + CreateIndexRequest cir = new CreateIndexRequest(appIndexName) + .alias(new Alias("app")) + .settings(indexSettings); + + if (i == 20) { + cir = cir.alias(new Alias("app-write")); + } + tc.admin().indices().create(cir).actionGet(); + + String doc = "{\"message\": \"This is just a test\", \"namespace\": \"test\", \"kubernetes\": {\"namespace_name\": \"test\"}}"; + tc.index(new IndexRequest(appIndexName) + .type("doc") + .setRefreshPolicy(WriteRequest.RefreshPolicy.IMMEDIATE) + .source(doc, XContentType.JSON)).actionGet(); + } + } + final RestHelper rh = nonSslRestHelper(); + RestHelper.HttpResponse res; + + res = rh.executePostRequest( + "_bulk", + "{ \"index\" : { \"_index\" : \"app-write\", \"_type\" : \"_doc\", \"_id\" : \"1\" } }\n" + + "{ \"index\" : { \"_index\" : \"app_write\", \"_type\" : \"_doc\", \"_id\" : \"2\" } }\n" + + "{ \"index\" : { \"_index\" : \"app-write\", \"_type\" : \"_doc\", \"_id\" : \"3\" } }\n" + + "{ \"index\" : { \"_index\" : \"app-write\", \"_type\" : \"_doc\", \"_id\" : \"4\" } }\n", + // Use x-forwarded* headers to allow extended-proxy authentication + new BasicHeader("x-forwarded-for", "127.0.0.1"), + new BasicHeader("x-forwarded-user", "CN=system.logging.fluentd,OU=Logging,O=OpenShift") + ); + + System.out.println(res.getBody()); + Assert.assertEquals(HttpStatus.SC_OK, res.getStatusCode()); + Assert.assertTrue(res.getBody().contains("\"errors\":false,\"items\":[{\"index\":{\"_index\":\"app-000020\",\"_type\":\"_doc\",\"_id\":\"1\",\"_version\":1,\"result\":\"created\",\"_shards\":{\"total\":2,\"successful\":2,\"failed\":0},\"_seq_no\":1,\"_primary_term\":1,\"status\":201}},{\"index\":{\"_index\":\"app-000020\",\"_type\":\"_doc\",\"_id\":\"3\",\"_version\":1,\"result\":\"created\",\"_shards\":{\"total\":2,\"successful\":2,\"failed\":0},\"_seq_no\":2,\"_primary_term\":1,\"status\":201}}]")); + } + + @Test + public void testCreateIndex() throws Exception { + final Settings settings = Settings.builder() + .put("opendistro_security.restapi.roles_enabled", "kibana_server") + .build(); + + final DynamicSecurityConfig dsc = new DynamicSecurityConfig() + .setConfig("ocp_config.yml") + .setSecurityRoles("ocp_roles.yml") + .setSecurityRolesMapping("ocp_roles_mapping.yml") + .setSecurityInternalUsers("ocp_internal_users.yml") + .setSecurityActionGroups("ocp_action_groups.yml"); + + setup(Settings.EMPTY, dsc, settings); + try (TransportClient tc = getInternalTransportClient()) { + Map indexSettings = new HashMap(); + indexSettings.put("number_of_shards", 1); + indexSettings.put("number_of_replicas", 1); + + for (int i = 1; i < 21; i++) { + String leadingZeros = "00000"; + if (i >= 10) { + leadingZeros = "0000"; + } + + String appIndexName = "app-" + leadingZeros + i; + CreateIndexRequest cir = new CreateIndexRequest(appIndexName) + .alias(new Alias("app")) + .settings(indexSettings); + + if (i == 20) { + cir = cir.alias(new Alias("app-write")); + } + tc.admin().indices().create(cir).actionGet(); + + String doc = "{\"message\": \"This is just a test\", \"namespace\": \"test\", \"kubernetes\": {\"namespace_name\": \"test\"}}"; + tc.index(new IndexRequest(appIndexName) + .type("doc") + .setRefreshPolicy(WriteRequest.RefreshPolicy.IMMEDIATE) + .source(doc, XContentType.JSON)).actionGet(); + } + } + final RestHelper rh = nonSslRestHelper(); + RestHelper.HttpResponse res; + + res = rh.executePutRequest( + "app-000021", + "", + // Use x-forwarded* headers to allow extended-proxy authentication + new BasicHeader("x-forwarded-for", "127.0.0.1"), + new BasicHeader("x-forwarded-user", "CN=system.logging.fluentd,OU=Logging,O=OpenShift") + ); + + System.out.println(res.getBody()); + Assert.assertEquals(HttpStatus.SC_OK, res.getStatusCode()); + Assert.assertTrue(res.getBody().contains("{\"acknowledged\":true,\"shards_acknowledged\":true,\"index\":\"app-000021\"}")); + } +} diff --git a/src/test/java/com/amazon/opendistroforelasticsearch/security/openshift_logging/ElasticsearchOperatorTests.java b/src/test/java/com/amazon/opendistroforelasticsearch/security/openshift_logging/ElasticsearchOperatorTests.java new file mode 100644 index 000000000..4406c0d74 --- /dev/null +++ b/src/test/java/com/amazon/opendistroforelasticsearch/security/openshift_logging/ElasticsearchOperatorTests.java @@ -0,0 +1,574 @@ +package com.amazon.opendistroforelasticsearch.security.openshift_logging; + +import com.amazon.opendistroforelasticsearch.security.test.DynamicSecurityConfig; +import com.amazon.opendistroforelasticsearch.security.test.SingleClusterTest; +import com.amazon.opendistroforelasticsearch.security.test.helper.rest.RestHelper; +import org.apache.http.HttpStatus; +import org.apache.http.message.BasicHeader; +import org.elasticsearch.action.admin.indices.alias.Alias; +import org.elasticsearch.action.admin.indices.create.CreateIndexRequest; +import org.elasticsearch.action.index.IndexRequest; +import org.elasticsearch.action.support.WriteRequest; +import org.elasticsearch.client.transport.TransportClient; +import org.elasticsearch.common.settings.Settings; +import org.elasticsearch.common.xcontent.XContentType; +import org.junit.Assert; +import org.junit.Test; + +import java.util.HashMap; +import java.util.Map; + +public class ElasticsearchOperatorTests extends SingleClusterTest { + + @Override + protected String getResourceFolder() { + return "openshift-logging"; + } + + /** + * Cluster Level Tests + **/ + + @Test + public void testDoSynchronizedFlush() throws Exception { + final Settings settings = Settings.builder() + .put("opendistro_security.restapi.roles_enabled", "kibana_server") + .build(); + + final DynamicSecurityConfig dsc = new DynamicSecurityConfig() + .setConfig("ocp_config.yml") + .setSecurityRoles("ocp_roles.yml") + .setSecurityRolesMapping("ocp_roles_mapping.yml") + .setSecurityInternalUsers("ocp_internal_users.yml") + .setSecurityActionGroups("ocp_action_groups.yml"); + + setup(Settings.EMPTY, dsc, settings); + + final RestHelper rh = nonSslRestHelper(); + RestHelper.HttpResponse res; + + res = rh.executeGetRequest( + "_flush/synced", + // Use x-forwarded* headers to allow extended-proxy authentication + new BasicHeader("x-forwarded-for", "127.0.0.1"), + new BasicHeader("x-forwarded-user", "system:serviceaccount:openshift-operators-redhat:elasticsearch-operator"), + new BasicHeader("x-forwarded-roles", "elasticsearch-operator,prometheus"), + new BasicHeader("x-ocp-ns", "openshift-logging") + ); + + System.out.println(res.getBody()); + Assert.assertEquals(HttpStatus.SC_OK, res.getStatusCode()); + } + + @Test + public void testGetClusterHealth() throws Exception { + final Settings settings = Settings.builder() + .put("opendistro_security.restapi.roles_enabled", "kibana_server") + .build(); + + final DynamicSecurityConfig dsc = new DynamicSecurityConfig() + .setConfig("ocp_config.yml") + .setSecurityRoles("ocp_roles.yml") + .setSecurityRolesMapping("ocp_roles_mapping.yml") + .setSecurityInternalUsers("ocp_internal_users.yml") + .setSecurityActionGroups("ocp_action_groups.yml"); + + setup(Settings.EMPTY, dsc, settings); + + final RestHelper rh = nonSslRestHelper(); + RestHelper.HttpResponse res; + + res = rh.executeGetRequest( + "_cluster/health", + // Use x-forwarded* headers to allow extended-proxy authentication + new BasicHeader("x-forwarded-for", "127.0.0.1"), + new BasicHeader("x-forwarded-user", "system:serviceaccount:openshift-operators-redhat:elasticsearch-operator"), + new BasicHeader("x-forwarded-roles", "elasticsearch-operator,prometheus"), + new BasicHeader("x-ocp-ns", "openshift-logging") + ); + + System.out.println(res.getBody()); + Assert.assertEquals(HttpStatus.SC_OK, res.getStatusCode()); + } + + @Test + public void testGetClusterSettings() throws Exception { + final Settings settings = Settings.builder() + .put("opendistro_security.restapi.roles_enabled", "kibana_server") + .build(); + + final DynamicSecurityConfig dsc = new DynamicSecurityConfig() + .setConfig("ocp_config.yml") + .setSecurityRoles("ocp_roles.yml") + .setSecurityRolesMapping("ocp_roles_mapping.yml") + .setSecurityInternalUsers("ocp_internal_users.yml") + .setSecurityActionGroups("ocp_action_groups.yml"); + + setup(Settings.EMPTY, dsc, settings); + + final RestHelper rh = nonSslRestHelper(); + RestHelper.HttpResponse res; + + res = rh.executeGetRequest( + "_cluster/settings", + // Use x-forwarded* headers to allow extended-proxy authentication + new BasicHeader("x-forwarded-for", "127.0.0.1"), + new BasicHeader("x-forwarded-user", "system:serviceaccount:openshift-operators-redhat:elasticsearch-operator"), + new BasicHeader("x-forwarded-roles", "elasticsearch-operator,prometheus"), + new BasicHeader("x-ocp-ns", "openshift-logging") + ); + + System.out.println(res.getBody()); + Assert.assertEquals(HttpStatus.SC_OK, res.getStatusCode()); + } + + @Test + public void testGetClusterStateNodes() throws Exception { + final Settings settings = Settings.builder() + .put("opendistro_security.restapi.roles_enabled", "kibana_server") + .build(); + + final DynamicSecurityConfig dsc = new DynamicSecurityConfig() + .setConfig("ocp_config.yml") + .setSecurityRoles("ocp_roles.yml") + .setSecurityRolesMapping("ocp_roles_mapping.yml") + .setSecurityInternalUsers("ocp_internal_users.yml") + .setSecurityActionGroups("ocp_action_groups.yml"); + + setup(Settings.EMPTY, dsc, settings); + + final RestHelper rh = nonSslRestHelper(); + RestHelper.HttpResponse res; + + res = rh.executeGetRequest( + "_cluster/state/nodes/_all", + // Use x-forwarded* headers to allow extended-proxy authentication + new BasicHeader("x-forwarded-for", "127.0.0.1"), + new BasicHeader("x-forwarded-user", "system:serviceaccount:openshift-operators-redhat:elasticsearch-operator"), + new BasicHeader("x-forwarded-roles", "elasticsearch-operator,prometheus"), + new BasicHeader("x-ocp-ns", "openshift-logging") + ); + + System.out.println(res.getBody()); + Assert.assertEquals(HttpStatus.SC_OK, res.getStatusCode()); + } + + @Test + public void testGetClusterStats() throws Exception { + final Settings settings = Settings.builder() + .put("opendistro_security.restapi.roles_enabled", "kibana_server") + .build(); + + final DynamicSecurityConfig dsc = new DynamicSecurityConfig() + .setConfig("ocp_config.yml") + .setSecurityRoles("ocp_roles.yml") + .setSecurityRolesMapping("ocp_roles_mapping.yml") + .setSecurityInternalUsers("ocp_internal_users.yml") + .setSecurityActionGroups("ocp_action_groups.yml"); + + setup(Settings.EMPTY, dsc, settings); + + final RestHelper rh = nonSslRestHelper(); + RestHelper.HttpResponse res; + + res = rh.executeGetRequest( + "_cluster/stats", + // Use x-forwarded* headers to allow extended-proxy authentication + new BasicHeader("x-forwarded-for", "127.0.0.1"), + new BasicHeader("x-forwarded-user", "system:serviceaccount:openshift-operators-redhat:elasticsearch-operator"), + new BasicHeader("x-forwarded-roles", "elasticsearch-operator,prometheus"), + new BasicHeader("x-ocp-ns", "openshift-logging") + ); + + System.out.println(res.getBody()); + Assert.assertEquals(HttpStatus.SC_OK, res.getStatusCode()); + } + + @Test + public void testGetNodesStatsFS() throws Exception { + final Settings settings = Settings.builder() + .put("opendistro_security.restapi.roles_enabled", "kibana_server") + .build(); + + final DynamicSecurityConfig dsc = new DynamicSecurityConfig() + .setConfig("ocp_config.yml") + .setSecurityRoles("ocp_roles.yml") + .setSecurityRolesMapping("ocp_roles_mapping.yml") + .setSecurityInternalUsers("ocp_internal_users.yml") + .setSecurityActionGroups("ocp_action_groups.yml"); + + setup(Settings.EMPTY, dsc, settings); + + final RestHelper rh = nonSslRestHelper(); + RestHelper.HttpResponse res; + + res = rh.executeGetRequest( + "_nodes/stats/fs", + // Use x-forwarded* headers to allow extended-proxy authentication + new BasicHeader("x-forwarded-for", "127.0.0.1"), + new BasicHeader("x-forwarded-user", "system:serviceaccount:openshift-operators-redhat:elasticsearch-operator"), + new BasicHeader("x-forwarded-roles", "elasticsearch-operator,prometheus"), + new BasicHeader("x-ocp-ns", "openshift-logging") + ); + + System.out.println(res.getBody()); + Assert.assertEquals(HttpStatus.SC_OK, res.getStatusCode()); + } + + /** + * Index Level Tests + **/ + + @Test + public void testGetSingleIndex() throws Exception { + final Settings settings = Settings.builder() + .put("opendistro_security.restapi.roles_enabled", "kibana_server") + .build(); + + final DynamicSecurityConfig dsc = new DynamicSecurityConfig() + .setConfig("ocp_config.yml") + .setSecurityRoles("ocp_roles.yml") + .setSecurityRolesMapping("ocp_roles_mapping.yml") + .setSecurityInternalUsers("ocp_internal_users.yml") + .setSecurityActionGroups("ocp_action_groups.yml"); + + setup(Settings.EMPTY, dsc, settings); + try (TransportClient tc = getInternalTransportClient()) { + Map indexSettings = new HashMap(); + indexSettings.put("number_of_shards", 1); + indexSettings.put("number_of_replicas", 1); + + for (int i = 1; i < 21; i++) { + String leadingZeros = "00000"; + if (i >= 10) { + leadingZeros = "0000"; + } + + String appIndexName = "app-" + leadingZeros + i; + CreateIndexRequest cir = new CreateIndexRequest(appIndexName) + .alias(new Alias("app")) + .settings(indexSettings); + + if (i == 20) { + cir = cir.alias(new Alias("app-write")); + } + tc.admin().indices().create(cir).actionGet(); + + String doc = "{\"message\": \"This is just a test\", \"namespace\": \"test\", \"kubernetes\": {\"namespace_name\": \"test\"}}"; + tc.index(new IndexRequest(appIndexName) + .type("doc") + .setRefreshPolicy(WriteRequest.RefreshPolicy.IMMEDIATE) + .source(doc, XContentType.JSON)).actionGet(); + } + } + final RestHelper rh = nonSslRestHelper(); + RestHelper.HttpResponse res; + + res = rh.executeGetRequest( + "app-000010", + // Use x-forwarded* headers to allow extended-proxy authentication + new BasicHeader("x-forwarded-for", "127.0.0.1"), + new BasicHeader("x-forwarded-user", "system:serviceaccount:openshift-operators-redhat:elasticsearch-operator"), + new BasicHeader("x-forwarded-roles", "elasticsearch-operator,prometheus"), + new BasicHeader("x-ocp-ns", "openshift-logging") + ); + + System.out.println(res.getBody()); + Assert.assertEquals(HttpStatus.SC_OK, res.getStatusCode()); + } + + @Test + public void testGetAllIndices() throws Exception { + final Settings settings = Settings.builder() + .put("opendistro_security.restapi.roles_enabled", "kibana_server") + .build(); + + final DynamicSecurityConfig dsc = new DynamicSecurityConfig() + .setConfig("ocp_config.yml") + .setSecurityRoles("ocp_roles.yml") + .setSecurityRolesMapping("ocp_roles_mapping.yml") + .setSecurityInternalUsers("ocp_internal_users.yml") + .setSecurityActionGroups("ocp_action_groups.yml"); + + setup(Settings.EMPTY, dsc, settings); + try (TransportClient tc = getInternalTransportClient()) { + Map indexSettings = new HashMap(); + indexSettings.put("number_of_shards", 1); + indexSettings.put("number_of_replicas", 1); + + for (int i = 1; i < 21; i++) { + String leadingZeros = "00000"; + if (i >= 10) { + leadingZeros = "0000"; + } + + String appIndexName = "app-" + leadingZeros + i; + CreateIndexRequest cir = new CreateIndexRequest(appIndexName) + .alias(new Alias("app")) + .settings(indexSettings); + + if (i == 20) { + cir = cir.alias(new Alias("app-write")); + } + tc.admin().indices().create(cir).actionGet(); + + String doc = "{\"message\": \"This is just a test\", \"namespace\": \"test\", \"kubernetes\": {\"namespace_name\": \"test\"}}"; + tc.index(new IndexRequest(appIndexName) + .type("doc") + .setRefreshPolicy(WriteRequest.RefreshPolicy.IMMEDIATE) + .source(doc, XContentType.JSON)).actionGet(); + } + } + final RestHelper rh = nonSslRestHelper(); + RestHelper.HttpResponse res; + + res = rh.executeGetRequest( + "_cat/indices/?format=json", + // Use x-forwarded* headers to allow extended-proxy authentication + new BasicHeader("x-forwarded-for", "127.0.0.1"), + new BasicHeader("x-forwarded-user", "system:serviceaccount:openshift-operators-redhat:elasticsearch-operator"), + new BasicHeader("x-forwarded-roles", "elasticsearch-operator,prometheus"), + new BasicHeader("x-ocp-ns", "openshift-logging") + ); + + System.out.println(res.getBody()); + Assert.assertEquals(HttpStatus.SC_OK, res.getStatusCode()); + } + + @Test + public void testGetAllIndicesForAlias() throws Exception { + final Settings settings = Settings.builder() + .put("opendistro_security.restapi.roles_enabled", "kibana_server") + .build(); + + final DynamicSecurityConfig dsc = new DynamicSecurityConfig() + .setConfig("ocp_config.yml") + .setSecurityRoles("ocp_roles.yml") + .setSecurityRolesMapping("ocp_roles_mapping.yml") + .setSecurityInternalUsers("ocp_internal_users.yml") + .setSecurityActionGroups("ocp_action_groups.yml"); + + setup(Settings.EMPTY, dsc, settings); + try (TransportClient tc = getInternalTransportClient()) { + Map indexSettings = new HashMap(); + indexSettings.put("number_of_shards", 1); + indexSettings.put("number_of_replicas", 1); + + for (int i = 1; i < 21; i++) { + String leadingZeros = "00000"; + if (i >= 10) { + leadingZeros = "0000"; + } + + String appIndexName = "app-" + leadingZeros + i; + CreateIndexRequest cir = new CreateIndexRequest(appIndexName) + .alias(new Alias("app")) + .settings(indexSettings); + + if (i == 20) { + cir = cir.alias(new Alias("app-write")); + } + tc.admin().indices().create(cir).actionGet(); + + String doc = "{\"message\": \"This is just a test\", \"namespace\": \"test\", \"kubernetes\": {\"namespace_name\": \"test\"}}"; + tc.index(new IndexRequest(appIndexName) + .type("doc") + .setRefreshPolicy(WriteRequest.RefreshPolicy.IMMEDIATE) + .source(doc, XContentType.JSON)).actionGet(); + } + } + final RestHelper rh = nonSslRestHelper(); + RestHelper.HttpResponse res; + + res = rh.executeGetRequest( + "_alias/app-write", + // Use x-forwarded* headers to allow extended-proxy authentication + new BasicHeader("x-forwarded-for", "127.0.0.1"), + new BasicHeader("x-forwarded-user", "system:serviceaccount:openshift-operators-redhat:elasticsearch-operator"), + new BasicHeader("x-forwarded-roles", "elasticsearch-operator,prometheus"), + new BasicHeader("x-ocp-ns", "openshift-logging") + ); + + System.out.println(res.getBody()); + Assert.assertEquals(HttpStatus.SC_OK, res.getStatusCode()); + Assert.assertTrue(res.getBody().contains("{\"app-000020\":{\"aliases\":{\"app-write\":{}}}}")); + } + + @Test + public void testIndexSettings() throws Exception { + final Settings settings = Settings.builder() + .put("opendistro_security.restapi.roles_enabled", "kibana_server") + .build(); + + final DynamicSecurityConfig dsc = new DynamicSecurityConfig() + .setConfig("ocp_config.yml") + .setSecurityRoles("ocp_roles.yml") + .setSecurityRolesMapping("ocp_roles_mapping.yml") + .setSecurityInternalUsers("ocp_internal_users.yml") + .setSecurityActionGroups("ocp_action_groups.yml"); + + setup(Settings.EMPTY, dsc, settings); + try (TransportClient tc = getInternalTransportClient()) { + Map indexSettings = new HashMap(); + indexSettings.put("number_of_shards", 1); + indexSettings.put("number_of_replicas", 1); + + for (int i = 1; i < 21; i++) { + String leadingZeros = "00000"; + if (i >= 10) { + leadingZeros = "0000"; + } + + String appIndexName = "app-" + leadingZeros + i; + CreateIndexRequest cir = new CreateIndexRequest(appIndexName) + .alias(new Alias("app")) + .settings(indexSettings); + + if (i == 20) { + cir = cir.alias(new Alias("app-write")); + } + tc.admin().indices().create(cir).actionGet(); + + String doc = "{\"message\": \"This is just a test\", \"namespace\": \"test\", \"kubernetes\": {\"namespace_name\": \"test\"}}"; + tc.index(new IndexRequest(appIndexName) + .type("doc") + .setRefreshPolicy(WriteRequest.RefreshPolicy.IMMEDIATE) + .source(doc, XContentType.JSON)).actionGet(); + } + } + final RestHelper rh = nonSslRestHelper(); + RestHelper.HttpResponse res; + + res = rh.executeGetRequest( + "app-000010/_settings", + // Use x-forwarded* headers to allow extended-proxy authentication + new BasicHeader("x-forwarded-for", "127.0.0.1"), + new BasicHeader("x-forwarded-user", "system:serviceaccount:openshift-operators-redhat:elasticsearch-operator"), + new BasicHeader("x-forwarded-roles", "elasticsearch-operator,prometheus"), + new BasicHeader("x-ocp-ns", "openshift-logging") + ); + + System.out.println(res.getBody()); + Assert.assertEquals(HttpStatus.SC_OK, res.getStatusCode()); + } + + @Test + public void testCreateIndex() throws Exception { + final Settings settings = Settings.builder() + .put("opendistro_security.restapi.roles_enabled", "kibana_server") + .build(); + + final DynamicSecurityConfig dsc = new DynamicSecurityConfig() + .setConfig("ocp_config.yml") + .setSecurityRoles("ocp_roles.yml") + .setSecurityRolesMapping("ocp_roles_mapping.yml") + .setSecurityInternalUsers("ocp_internal_users.yml") + .setSecurityActionGroups("ocp_action_groups.yml"); + + setup(Settings.EMPTY, dsc, settings); + try (TransportClient tc = getInternalTransportClient()) { + Map indexSettings = new HashMap(); + indexSettings.put("number_of_shards", 1); + indexSettings.put("number_of_replicas", 1); + + for (int i = 1; i < 21; i++) { + String leadingZeros = "00000"; + if (i >= 10) { + leadingZeros = "0000"; + } + + String appIndexName = "app-" + leadingZeros + i; + CreateIndexRequest cir = new CreateIndexRequest(appIndexName) + .alias(new Alias("app")) + .settings(indexSettings); + + if (i == 20) { + cir = cir.alias(new Alias("app-write")); + } + tc.admin().indices().create(cir).actionGet(); + + String doc = "{\"message\": \"This is just a test\", \"namespace\": \"test\", \"kubernetes\": {\"namespace_name\": \"test\"}}"; + tc.index(new IndexRequest(appIndexName) + .type("doc") + .setRefreshPolicy(WriteRequest.RefreshPolicy.IMMEDIATE) + .source(doc, XContentType.JSON)).actionGet(); + } + } + final RestHelper rh = nonSslRestHelper(); + RestHelper.HttpResponse res; + + res = rh.executePutRequest( + "app-000021", + "{\"aliases\":{\"app-write\":{\"is_write_index\":true}}}", + // Use x-forwarded* headers to allow extended-proxy authentication + new BasicHeader("x-forwarded-for", "127.0.0.1"), + new BasicHeader("x-forwarded-user", "system:serviceaccount:openshift-operators-redhat:elasticsearch-operator"), + new BasicHeader("x-forwarded-roles", "elasticsearch-operator,prometheus"), + new BasicHeader("x-ocp-ns", "openshift-logging") + ); + + System.out.println(res.getBody()); + Assert.assertEquals(HttpStatus.SC_OK, res.getStatusCode()); + Assert.assertTrue(res.getBody().contains("{\"acknowledged\":true,\"shards_acknowledged\":true,\"index\":\"app-000021\"}")); + } + + @Test + public void testUpdateIndexSettings() throws Exception { + final Settings settings = Settings.builder() + .put("opendistro_security.restapi.roles_enabled", "kibana_server") + .build(); + + final DynamicSecurityConfig dsc = new DynamicSecurityConfig() + .setConfig("ocp_config.yml") + .setSecurityRoles("ocp_roles.yml") + .setSecurityRolesMapping("ocp_roles_mapping.yml") + .setSecurityInternalUsers("ocp_internal_users.yml") + .setSecurityActionGroups("ocp_action_groups.yml"); + + setup(Settings.EMPTY, dsc, settings); + try (TransportClient tc = getInternalTransportClient()) { + Map indexSettings = new HashMap(); + indexSettings.put("number_of_shards", 1); + indexSettings.put("number_of_replicas", 1); + + for (int i = 1; i < 21; i++) { + String leadingZeros = "00000"; + if (i >= 10) { + leadingZeros = "0000"; + } + + String appIndexName = "app-" + leadingZeros + i; + CreateIndexRequest cir = new CreateIndexRequest(appIndexName) + .alias(new Alias("app")) + .settings(indexSettings); + + if (i == 20) { + cir = cir.alias(new Alias("app-write")); + } + tc.admin().indices().create(cir).actionGet(); + + String doc = "{\"message\": \"This is just a test\", \"namespace\": \"test\", \"kubernetes\": {\"namespace_name\": \"test\"}}"; + tc.index(new IndexRequest(appIndexName) + .type("doc") + .setRefreshPolicy(WriteRequest.RefreshPolicy.IMMEDIATE) + .source(doc, XContentType.JSON)).actionGet(); + } + } + final RestHelper rh = nonSslRestHelper(); + RestHelper.HttpResponse res; + + res = rh.executePutRequest( + "app-000002/_settings", + "{\"index\":{\"blocks\":{\"read_only_allow_delete\":true}}}", + // Use x-forwarded* headers to allow extended-proxy authentication + new BasicHeader("x-forwarded-for", "127.0.0.1"), + new BasicHeader("x-forwarded-user", "system:serviceaccount:openshift-operators-redhat:elasticsearch-operator"), + new BasicHeader("x-forwarded-roles", "elasticsearch-operator,prometheus"), + new BasicHeader("x-ocp-ns", "openshift-logging") + ); + + System.out.println(res.getBody()); + Assert.assertEquals(HttpStatus.SC_OK, res.getStatusCode()); + Assert.assertTrue(res.getBody().contains("{\"acknowledged\":true}")); + } +} diff --git a/src/test/java/com/amazon/opendistroforelasticsearch/security/openshift_logging/IndexManagementTests.java b/src/test/java/com/amazon/opendistroforelasticsearch/security/openshift_logging/IndexManagementTests.java new file mode 100644 index 000000000..128dbf477 --- /dev/null +++ b/src/test/java/com/amazon/opendistroforelasticsearch/security/openshift_logging/IndexManagementTests.java @@ -0,0 +1,203 @@ +package com.amazon.opendistroforelasticsearch.security.openshift_logging; + +import com.amazon.opendistroforelasticsearch.security.test.DynamicSecurityConfig; +import com.amazon.opendistroforelasticsearch.security.test.SingleClusterTest; +import com.amazon.opendistroforelasticsearch.security.test.helper.rest.RestHelper; +import org.apache.http.HttpStatus; +import org.apache.http.message.BasicHeader; +import org.elasticsearch.action.admin.indices.alias.Alias; +import org.elasticsearch.action.admin.indices.create.CreateIndexRequest; +import org.elasticsearch.action.index.IndexRequest; +import org.elasticsearch.action.support.WriteRequest; +import org.elasticsearch.client.transport.TransportClient; +import org.elasticsearch.common.settings.Settings; +import org.elasticsearch.common.xcontent.XContentType; +import org.junit.Assert; +import org.junit.Test; + +import java.util.HashMap; +import java.util.Map; + +public class IndexManagementTests extends SingleClusterTest { + + @Override + protected String getResourceFolder() { + return "openshift-logging"; + } + + @Test + public void testDeleteIndex() throws Exception { + final Settings settings = Settings.builder() + .put("opendistro_security.restapi.roles_enabled", "kibana_server") + .build(); + + final DynamicSecurityConfig dsc = new DynamicSecurityConfig() + .setConfig("ocp_config.yml") + .setSecurityRoles("ocp_roles.yml") + .setSecurityRolesMapping("ocp_roles_mapping.yml") + .setSecurityInternalUsers("ocp_internal_users.yml") + .setSecurityActionGroups("ocp_action_groups.yml"); + + setup(Settings.EMPTY, dsc, settings); + try (TransportClient tc = getInternalTransportClient()) { + Map indexSettings = new HashMap(); + indexSettings.put("number_of_shards", 1); + indexSettings.put("number_of_replicas", 1); + + for (int i = 1; i < 21; i++) { + String leadingZeros = "00000"; + if (i >= 10) { + leadingZeros = "0000"; + } + + String appIndexName = "app-" + leadingZeros + i; + CreateIndexRequest cir = new CreateIndexRequest(appIndexName) + .alias(new Alias("app")) + .settings(indexSettings); + + if (i == 20) { + cir = cir.alias(new Alias("app-write")); + } + tc.admin().indices().create(cir).actionGet(); + + String doc = "{\"message\": \"This is just a test\", \"namespace\": \"test\", \"kubernetes\": {\"namespace_name\": \"test\"}}"; + tc.index(new IndexRequest(appIndexName) + .type("doc") + .setRefreshPolicy(WriteRequest.RefreshPolicy.IMMEDIATE) + .source(doc, XContentType.JSON)).actionGet(); + } + } + final RestHelper rh = nonSslRestHelper(); + RestHelper.HttpResponse res; + + res = rh.executeDeleteRequest( + "app-000001", + // Use x-forwarded* headers to allow extended-proxy authentication + new BasicHeader("x-forwarded-for", "127.0.0.1"), + new BasicHeader("x-forwarded-user", "system:serviceaccount:openshift-logging:elasticsearch"), + new BasicHeader("x-forwarded-roles", "index-management") + ); + + System.out.println(res.getBody()); + Assert.assertEquals(HttpStatus.SC_OK, res.getStatusCode()); + Assert.assertTrue(res.getBody().contains("{\"acknowledged\":true}")); + } + + @Test + public void testDeleteByQuery() throws Exception { + final Settings settings = Settings.builder() + .put("opendistro_security.restapi.roles_enabled", "kibana_server") + .build(); + + final DynamicSecurityConfig dsc = new DynamicSecurityConfig() + .setConfig("ocp_config.yml") + .setSecurityRoles("ocp_roles.yml") + .setSecurityRolesMapping("ocp_roles_mapping.yml") + .setSecurityInternalUsers("ocp_internal_users.yml") + .setSecurityActionGroups("ocp_action_groups.yml"); + + setup(Settings.EMPTY, dsc, settings); + try (TransportClient tc = getInternalTransportClient()) { + Map indexSettings = new HashMap(); + indexSettings.put("number_of_shards", 1); + indexSettings.put("number_of_replicas", 1); + + for (int i = 1; i < 21; i++) { + String leadingZeros = "00000"; + if (i >= 10) { + leadingZeros = "0000"; + } + + String appIndexName = "app-" + leadingZeros + i; + CreateIndexRequest cir = new CreateIndexRequest(appIndexName) + .alias(new Alias("app")) + .settings(indexSettings); + + if (i == 20) { + cir = cir.alias(new Alias("app-write")); + } + tc.admin().indices().create(cir).actionGet(); + + String doc = "{\"message\": \"This is just a test\", \"namespace\": \"test\", \"kubernetes\": {\"namespace_name\": \"test\"}}"; + tc.index(new IndexRequest(appIndexName) + .type("doc") + .setRefreshPolicy(WriteRequest.RefreshPolicy.IMMEDIATE) + .source(doc, XContentType.JSON)).actionGet(); + } + } + final RestHelper rh = nonSslRestHelper(); + RestHelper.HttpResponse res; + + res = rh.executePostRequest( + "app-000001/_doc/_delete_by_query", + "{\"query\":{\"match\":{ \"message\": \"This is just a test\"}}}", + // Use x-forwarded* headers to allow extended-proxy authentication + new BasicHeader("x-forwarded-for", "127.0.0.1"), + new BasicHeader("x-forwarded-user", "system:serviceaccount:openshift-logging:elasticsearch"), + new BasicHeader("x-forwarded-roles", "index-management") + ); + + System.out.println(res.getBody()); + Assert.assertEquals(HttpStatus.SC_OK, res.getStatusCode()); + Assert.assertTrue(res.getBody().contains("{\"acknowledged\":true}")); + } + + @Test + public void testRollover() throws Exception { + final Settings settings = Settings.builder() + .put("opendistro_security.restapi.roles_enabled", "kibana_server") + .build(); + + final DynamicSecurityConfig dsc = new DynamicSecurityConfig() + .setConfig("ocp_config.yml") + .setSecurityRoles("ocp_roles.yml") + .setSecurityRolesMapping("ocp_roles_mapping.yml") + .setSecurityInternalUsers("ocp_internal_users.yml") + .setSecurityActionGroups("ocp_action_groups.yml"); + + setup(Settings.EMPTY, dsc, settings); + try (TransportClient tc = getInternalTransportClient()) { + Map indexSettings = new HashMap(); + indexSettings.put("number_of_shards", 1); + indexSettings.put("number_of_replicas", 1); + + for (int i = 1; i < 21; i++) { + String leadingZeros = "00000"; + if (i >= 10) { + leadingZeros = "0000"; + } + + String appIndexName = "app-" + leadingZeros + i; + CreateIndexRequest cir = new CreateIndexRequest(appIndexName) + .alias(new Alias("app")) + .settings(indexSettings); + + if (i == 20) { + cir = cir.alias(new Alias("app-write")); + } + tc.admin().indices().create(cir).actionGet(); + + String doc = "{\"message\": \"This is just a test\", \"namespace\": \"test\", \"kubernetes\": {\"namespace_name\": \"test\"}}"; + tc.index(new IndexRequest(appIndexName) + .type("doc") + .setRefreshPolicy(WriteRequest.RefreshPolicy.IMMEDIATE) + .source(doc, XContentType.JSON)).actionGet(); + } + } + final RestHelper rh = nonSslRestHelper(); + RestHelper.HttpResponse res; + + res = rh.executePostRequest( + "app-write/_rollover", + "", + // Use x-forwarded* headers to allow extended-proxy authentication + new BasicHeader("x-forwarded-for", "127.0.0.1"), + new BasicHeader("x-forwarded-user", "system:serviceaccount:openshift-logging:elasticsearch"), + new BasicHeader("x-forwarded-roles", "index-management") + ); + + System.out.println(res.getBody()); + Assert.assertEquals(HttpStatus.SC_OK, res.getStatusCode()); + Assert.assertTrue(res.getBody().contains("{\"acknowledged\":true,\"shards_acknowledged\":true,\"old_index\":\"app-000020\",\"new_index\":\"app-000021\",\"rolled_over\":true,\"dry_run\":false,\"conditions\":{}}")); + } +} diff --git a/src/test/java/com/amazon/opendistroforelasticsearch/security/openshift_logging/KibanaTests.java b/src/test/java/com/amazon/opendistroforelasticsearch/security/openshift_logging/KibanaTests.java new file mode 100644 index 000000000..ddaeded5a --- /dev/null +++ b/src/test/java/com/amazon/opendistroforelasticsearch/security/openshift_logging/KibanaTests.java @@ -0,0 +1,449 @@ +package com.amazon.opendistroforelasticsearch.security.openshift_logging; + +import com.amazon.opendistroforelasticsearch.security.test.DynamicSecurityConfig; +import com.amazon.opendistroforelasticsearch.security.test.SingleClusterTest; +import com.amazon.opendistroforelasticsearch.security.test.helper.rest.RestHelper; +import org.apache.http.HttpStatus; +import org.apache.http.message.BasicHeader; +import org.elasticsearch.action.admin.indices.alias.Alias; +import org.elasticsearch.action.admin.indices.create.CreateIndexRequest; +import org.elasticsearch.action.index.IndexRequest; +import org.elasticsearch.action.support.WriteRequest; +import org.elasticsearch.client.transport.TransportClient; +import org.elasticsearch.common.settings.Settings; +import org.elasticsearch.common.xcontent.XContentType; +import org.junit.Assert; +import org.junit.Test; + +import java.util.HashMap; +import java.util.Map; + +public class KibanaTests extends SingleClusterTest { + + @Override + protected String getResourceFolder() { + return "openshift-logging"; + } + + @Test + public void testProjectUser() throws Exception { + final Settings settings = Settings.builder() + .put("opendistro_security.restapi.roles_enabled", "kibana_server") + .build(); + + final DynamicSecurityConfig dsc = new DynamicSecurityConfig() + .setConfig("ocp_config.yml") + .setSecurityRoles("ocp_roles.yml") + .setSecurityRolesMapping("ocp_roles_mapping.yml") + .setSecurityInternalUsers("ocp_internal_users.yml") + .setSecurityActionGroups("ocp_action_groups.yml"); + + setup(Settings.EMPTY, dsc, settings); + + try (TransportClient tc = getInternalTransportClient()) { + Map indexSettings = new HashMap(); + indexSettings.put("number_of_shards", 1); + indexSettings.put("number_of_replicas", 1); + + tc.admin().indices().create(new CreateIndexRequest(".kibana_1") + .alias(new Alias(".kibana")) + .settings(indexSettings)) + .actionGet(); + + tc.admin().indices().create(new CreateIndexRequest(".kibana_-1159834508_testuser1_2") + .settings(indexSettings)) + .actionGet(); + + tc.admin().indices().create(new CreateIndexRequest(".kibana_-1159834508_testuser1_3") + .alias(new Alias(".kibana_-1159834508_testuser1")) + .settings(indexSettings)) + .actionGet(); + + String kibUserBodyJSON = "{\"buildNum\" : 20385,\"defaultIndex\" : \"9f63ccf0-8cb1-11eb-994c-7551a3e70b0d\"}"; + tc.index(new IndexRequest(".kibana_-1159834508_testuser1_2") + .type("doc") + .id("6.8.1") + .setRefreshPolicy(WriteRequest.RefreshPolicy.IMMEDIATE) + .source(kibUserBodyJSON, XContentType.JSON)).actionGet(); + tc.index(new IndexRequest(".kibana_-1159834508_testuser1_3") + .type("doc") + .id("6.8.1") + .setRefreshPolicy(WriteRequest.RefreshPolicy.IMMEDIATE) + .source(kibUserBodyJSON, XContentType.JSON)).actionGet(); + + for (int i = 1; i < 21; i++) { + String leadingZeros = "00000"; + if (i >= 10) { + leadingZeros = "0000"; + } + + String appIndexName = "app-" + leadingZeros + i; + CreateIndexRequest cir = new CreateIndexRequest(appIndexName) + .alias(new Alias("app")) + .settings(indexSettings); + + if (i == 20) { + cir = cir.alias(new Alias("app-write")); + } + tc.admin().indices().create(cir).actionGet(); + + String doc = "{\"message\": \"This is just a test\", \"namespace\": \"test\", \"kubernetes\": {\"namespace_name\": \"test\"}}"; + tc.index(new IndexRequest(appIndexName) + .type("doc") + .setRefreshPolicy(WriteRequest.RefreshPolicy.IMMEDIATE) + .source(doc, XContentType.JSON)).actionGet(); + } + + for (int i = 1; i < 21; i++) { + String leadingZeros = "00000"; + if (i >= 10) { + leadingZeros = "0000"; + } + + String appIndexName = "infra-" + leadingZeros + i; + CreateIndexRequest cir = new CreateIndexRequest(appIndexName) + .alias(new Alias("infra")) + .settings(indexSettings); + + if (i == 20) { + cir = cir.alias(new Alias("infra-write")); + } + tc.admin().indices().create(cir).actionGet(); + + String doc = "{\"message\": \"This is just a test\", \"namespace\": \"openshift-monitoring\", \"kubernetes\": {\"namespace_name\": \"openshift-monitoring\"}}"; + tc.index(new IndexRequest(appIndexName) + .type("doc") + .setRefreshPolicy(WriteRequest.RefreshPolicy.IMMEDIATE) + .source(doc, XContentType.JSON)).actionGet(); + } + } + + final RestHelper rh = nonSslRestHelper(); + RestHelper.HttpResponse res; + + res = rh.executeGetRequest( + "app-000001/_search", + + // Use x-forwarded* headers to allow extended-proxy authentication + new BasicHeader("x-forwarded-for", "127.0.0.1"), + new BasicHeader("x-forwarded-user", "testuser1"), + new BasicHeader("x-forwarded-roles", "project_user"), + new BasicHeader("x-ocp-ns", "test"), + + // Fake Cookie storage for selected tenant in Kibana + new BasicHeader("securitytenant", "__user__") + ); + + System.out.println(res.getBody()); + Assert.assertEquals(HttpStatus.SC_OK, res.getStatusCode()); + Assert.assertTrue(res.getBody().contains("This is just a test")); + + res = rh.executeGetRequest( + "infra-000001/_search", + + // Use x-forwarded* headers to allow extended-proxy authentication + new BasicHeader("x-forwarded-for", "127.0.0.1"), + new BasicHeader("x-forwarded-user", "testuser1"), + new BasicHeader("x-forwarded-roles", "project_user"), + new BasicHeader("x-ocp-ns", "test"), + + // Fake Cookie storage for selected tenant in Kibana + new BasicHeader("securitytenant", "__user__") + ); + + System.out.println(res.getBody()); + Assert.assertEquals(HttpStatus.SC_FORBIDDEN, res.getStatusCode()); + } + + @Test + public void testAdminUser() throws Exception { + final Settings settings = Settings.builder() + .put("opendistro_security.restapi.roles_enabled", "kibana_server") + .build(); + + final DynamicSecurityConfig dsc = new DynamicSecurityConfig() + .setConfig("ocp_config.yml") + .setSecurityRoles("ocp_roles.yml") + .setSecurityRolesMapping("ocp_roles_mapping.yml") + .setSecurityInternalUsers("ocp_internal_users.yml") + .setSecurityActionGroups("ocp_action_groups.yml"); + + setup(Settings.EMPTY, dsc, settings); + + try (TransportClient tc = getInternalTransportClient()) { + Map indexSettings = new HashMap(); + indexSettings.put("number_of_shards", 1); + indexSettings.put("number_of_replicas", 1); + + tc.admin().indices().create(new CreateIndexRequest(".kibana_1") + .alias(new Alias(".kibana")) + .settings(indexSettings)) + .actionGet(); + + tc.admin().indices().create(new CreateIndexRequest(".kibana_-1159834508_testuser1_2") + .settings(indexSettings)) + .actionGet(); + + tc.admin().indices().create(new CreateIndexRequest(".kibana_-1159834508_testuser1_3") + .alias(new Alias(".kibana_-1159834508_testuser1")) + .settings(indexSettings)) + .actionGet(); + + String kibUserBodyJSON = "{\"buildNum\" : 20385,\"defaultIndex\" : \"9f63ccf0-8cb1-11eb-994c-7551a3e70b0d\"}"; + tc.index(new IndexRequest(".kibana_-1159834508_testuser1_2") + .type("doc") + .id("6.8.1") + .setRefreshPolicy(WriteRequest.RefreshPolicy.IMMEDIATE) + .source(kibUserBodyJSON, XContentType.JSON)).actionGet(); + tc.index(new IndexRequest(".kibana_-1159834508_testuser1_3") + .type("doc") + .id("6.8.1") + .setRefreshPolicy(WriteRequest.RefreshPolicy.IMMEDIATE) + .source(kibUserBodyJSON, XContentType.JSON)).actionGet(); + + for (int i = 1; i < 21; i++) { + String leadingZeros = "00000"; + if (i >= 10) { + leadingZeros = "0000"; + } + + String appIndexName = "app-" + leadingZeros + i; + CreateIndexRequest cir = new CreateIndexRequest(appIndexName) + .alias(new Alias("app")) + .settings(indexSettings); + + if (i == 20) { + cir = cir.alias(new Alias("app-write")); + } + tc.admin().indices().create(cir).actionGet(); + + String doc = "{\"message\": \"This is just a test\", \"namespace\": \"test\", \"kubernetes\": {\"namespace_name\": \"test\"}}"; + tc.index(new IndexRequest(appIndexName) + .type("doc") + .setRefreshPolicy(WriteRequest.RefreshPolicy.IMMEDIATE) + .source(doc, XContentType.JSON)).actionGet(); + } + + for (int i = 1; i < 21; i++) { + String leadingZeros = "00000"; + if (i >= 10) { + leadingZeros = "0000"; + } + + String appIndexName = "infra-" + leadingZeros + i; + CreateIndexRequest cir = new CreateIndexRequest(appIndexName) + .alias(new Alias("infra")) + .settings(indexSettings); + + if (i == 20) { + cir = cir.alias(new Alias("infra-write")); + } + tc.admin().indices().create(cir).actionGet(); + + String doc = "{\"message\": \"This is just a test\", \"namespace\": \"openshift-monitoring\", \"kubernetes\": {\"namespace_name\": \"openshift-monitoring\"}}"; + tc.index(new IndexRequest(appIndexName) + .type("doc") + .setRefreshPolicy(WriteRequest.RefreshPolicy.IMMEDIATE) + .source(doc, XContentType.JSON)).actionGet(); + } + } + + final RestHelper rh = nonSslRestHelper(); + RestHelper.HttpResponse res; + + res = rh.executeGetRequest( + "app-000001/_search", + + // Use x-forwarded* headers to allow extended-proxy authentication + new BasicHeader("x-forwarded-for", "127.0.0.1"), + new BasicHeader("x-forwarded-user", "testuser1"), + new BasicHeader("x-forwarded-roles", "admin_reader"), + new BasicHeader("x-ocp-ns", "test"), + + // Fake Cookie storage for selected tenant in Kibana + new BasicHeader("securitytenant", "__user__") + ); + + System.out.println(res.getBody()); + Assert.assertEquals(HttpStatus.SC_OK, res.getStatusCode()); + Assert.assertTrue(res.getBody().contains("This is just a test")); + + res = rh.executeGetRequest( + "infra-000001/_search", + + // Use x-forwarded* headers to allow extended-proxy authentication + new BasicHeader("x-forwarded-for", "127.0.0.1"), + new BasicHeader("x-forwarded-user", "testuser1"), + new BasicHeader("x-forwarded-roles", "admin_reader"), + new BasicHeader("x-ocp-ns", "test"), + + // Fake Cookie storage for selected tenant in Kibana + new BasicHeader("securitytenant", "__user__") + ); + + System.out.println(res.getBody()); + Assert.assertEquals(HttpStatus.SC_OK, res.getStatusCode()); + } + + @Test + public void testKibanaUserTenantMigration() throws Exception { + final Settings settings = Settings.builder() + .put("opendistro_security.restapi.roles_enabled", "kibana_server") + .build(); + + final DynamicSecurityConfig dsc = new DynamicSecurityConfig() + .setConfig("ocp_config.yml") + .setSecurityRoles("ocp_roles.yml") + .setSecurityRolesMapping("ocp_roles_mapping.yml") + .setSecurityInternalUsers("ocp_internal_users.yml") + .setSecurityActionGroups("ocp_action_groups.yml"); + + setup(Settings.EMPTY, dsc, settings); + + try (TransportClient tc = getInternalTransportClient()) { + Map indexSettings = new HashMap(); + indexSettings.put("number_of_shards", 1); + indexSettings.put("number_of_replicas", 1); + + tc.admin().indices().create(new CreateIndexRequest(".kibana_1") + .alias(new Alias(".kibana")) + .settings(indexSettings)) + .actionGet(); + + tc.admin().indices().create(new CreateIndexRequest(".kibana_-1159834508_testuser1_2") + .settings(indexSettings)) + .actionGet(); + + tc.admin().indices().create(new CreateIndexRequest(".kibana_-1159834508_testuser1_3") + .alias(new Alias(".kibana_-1159834508_testuser1")) + .settings(indexSettings)) + .actionGet(); + + String kibUserBodyJSON = "{\"buildNum\" : 20385,\"defaultIndex\" : \"9f63ccf0-8cb1-11eb-994c-7551a3e70b0d\"}"; + tc.index(new IndexRequest(".kibana_-1159834508_testuser1_2") + .type("doc") + .id("6.8.1") + .setRefreshPolicy(WriteRequest.RefreshPolicy.IMMEDIATE) + .source(kibUserBodyJSON, XContentType.JSON)).actionGet(); + tc.index(new IndexRequest(".kibana_-1159834508_testuser1_3") + .type("doc") + .id("6.8.1") + .setRefreshPolicy(WriteRequest.RefreshPolicy.IMMEDIATE) + .source(kibUserBodyJSON, XContentType.JSON)).actionGet(); + + for (int i = 1; i < 21; i++) { + String leadingZeros = "00000"; + if (i >= 10) { + leadingZeros = "0000"; + } + + String appIndexName = "app-" + leadingZeros + i; + CreateIndexRequest cir = new CreateIndexRequest(appIndexName) + .alias(new Alias("app")) + .settings(indexSettings); + + if (i == 20) { + cir = cir.alias(new Alias("app-write")); + } + tc.admin().indices().create(cir).actionGet(); + + String doc = "{\"message\": \"This is just a test\", \"namespace\": \"test\", \"kubernetes\": {\"namespace_name\": \"test\"}}"; + tc.index(new IndexRequest(appIndexName) + .type("doc") + .setRefreshPolicy(WriteRequest.RefreshPolicy.IMMEDIATE) + .source(doc, XContentType.JSON)).actionGet(); + } + } + + final RestHelper rh = nonSslRestHelper(); + RestHelper.HttpResponse res; + + res = rh.executeDeleteRequest( + // Use .kibana for user testuser1, but this should be replaced by .kibana_-1159834508_testuser1 + // DELETE -> .kibana/doc/6.8.1 -> .kibana_-1159834508_testuser1/doc/6.8.1 -> .kibana_-1159834508_testuser1_3/doc/6.8.1 + ".kibana/doc/6.8.1", + + // Use x-forwarded* headers to allow extended-proxy authentication + new BasicHeader("x-forwarded-for", "127.0.0.1"), + new BasicHeader("x-forwarded-user", "testuser1"), + new BasicHeader("x-forwarded-roles", "project_user"), + new BasicHeader("x-ocp-ns", "test"), + + // Fake Cookie storage for selected tenant in Kibana + new BasicHeader("securitytenant", "__user__") + ); + + System.out.println(res.getBody()); + Assert.assertEquals(HttpStatus.SC_OK, res.getStatusCode()); + Assert.assertTrue(res.getBody().contains(".kibana_-1159834508_testuser1")); + } + + @Test + public void testKibanaServerAccess() throws Exception { + final Settings settings = Settings.builder() + .put("opendistro_security.restapi.roles_enabled", "kibana_server") + .build(); + + final DynamicSecurityConfig dsc = new DynamicSecurityConfig() + .setConfig("ocp_config.yml") + .setSecurityRoles("ocp_roles.yml") + .setSecurityRolesMapping("ocp_roles_mapping.yml") + .setSecurityInternalUsers("ocp_internal_users.yml") + .setSecurityActionGroups("ocp_action_groups.yml"); + + setup(Settings.EMPTY, dsc, settings); + + try (TransportClient tc = getInternalTransportClient()) { + Map indexSettings = new HashMap(); + indexSettings.put("number_of_shards", 1); + indexSettings.put("number_of_replicas", 1); + + tc.admin().indices().create(new CreateIndexRequest(".kibana_1") + .alias(new Alias(".kibana")) + .settings(indexSettings)) + .actionGet(); + + String kibUserBodyJSON = "{\"buildNum\" : 20385,\"defaultIndex\" : \"9f63ccf0-8cb1-11eb-994c-7551a3e70b0d\"}"; + tc.index(new IndexRequest(".kibana") + .type("doc") + .id("6.8.1") + .setRefreshPolicy(WriteRequest.RefreshPolicy.IMMEDIATE) + .source(kibUserBodyJSON, XContentType.JSON)).actionGet(); + + for (int i = 1; i < 21; i++) { + String leadingZeros = "00000"; + if (i >= 10) { + leadingZeros = "0000"; + } + + String appIndexName = "app-" + leadingZeros + i; + CreateIndexRequest cir = new CreateIndexRequest(appIndexName) + .alias(new Alias("app")) + .settings(indexSettings); + + if (i == 20) { + cir = cir.alias(new Alias("app-write")); + } + tc.admin().indices().create(cir).actionGet(); + + String doc = "{\"message\": \"This is just a test\", \"namespace\": \"test\", \"kubernetes\": {\"namespace_name\": \"test\"}}"; + tc.index(new IndexRequest(appIndexName) + .type("doc") + .setRefreshPolicy(WriteRequest.RefreshPolicy.IMMEDIATE) + .source(doc, XContentType.JSON)).actionGet(); + } + } + + final RestHelper rh = nonSslRestHelper(); + RestHelper.HttpResponse res; + + res = rh.executeDeleteRequest( + ".kibana/doc/6.8.1", + // Use x-forwarded* headers to allow extended-proxy authentication + new BasicHeader("x-forwarded-for", "127.0.0.1"), + new BasicHeader("x-forwarded-user", "CN=system.logging.kibana,OU=Logging,O=OpenShift") + ); + + Assert.assertEquals(HttpStatus.SC_OK, res.getStatusCode()); + } +} diff --git a/src/test/resources/openshift-logging/kirk-keystore.jks b/src/test/resources/openshift-logging/kirk-keystore.jks new file mode 100644 index 0000000000000000000000000000000000000000..dd7562ef81822291c9e48be60b6daef2883288a9 GIT binary patch literal 4525 zcmdVccT^MWwgB){LPGDoiG|JtLlcmi&;&(_6h#7rP(uq{DS;pYA_Afmm4HYQP!tF# zO+it?LY1P3NK;Ux3W)H6$9wKM=ic}3T5sJy?)_ud%--LgH8bDr`F*qXdFwL>1cER& z@XrnA;}zt?2;6|iLvA1t91KukKLBYi?ob|vHEVPXTvFy98Cf88WeS!f7A?SFPvZg)V z7v6j;sEtmwpQf&7q@7zop%6{r2s~o4`h$O*s-O*b>U-1znW*c#zSZBch%8xV*PK!@M#{2`WZYarXxm&{`QatOX?4u9M`&!g z&8@j*V|x00YnIuVYvX+t0oL3*%ZApt%D}TBgx;82*eFi6zP*KyC^rTTB}T2_jyE(_ z;f-sVA5zg)Q)lMvlIJLf*G91S{6-yTXOSiB%Pl6=)ezz52b@>D2PMdN`A#<=9WZ-| z7KW!1+>q&M9FI4m)Uo2)<*krrUc5S@Z)L7G7dgI!>|D_H@?HQ2<&8$8eAM5V`nS_j zNpG-+#Ccy*OAKTS(OGuQwm4>u0HI3?WwUI`J?nS!O@}YqX!P0n!lx^wZ-xy>9X%}X z%zmko=qLu(IqcUGH-zYG9NL}p(8Yv5_N2}HLil{#_GY+#+?8~+txTk4E?9{>Y6;8Q zEZMQQG+Zc7(ONjc_Z{R_?;uOgps(gW9B#f(6USN@W|Q~IWxj{osPJ=+k~BeQ@cQL| z$FtVYsZN!ibBkZ5nzYpH;ZHJ%>jHUIYX_z7yg_w(Pt?L{^X(1y1V;C7nhA@9^p>1jxzk4S}xL;ZtiB54PN2WN{SYvv3Rh9rlt7aOkInvb_wo?IeDCPpYvkB~u~s|dnp zzlO4kJt=!g)8MF%;L*>C7`w|&Q5;Zw^-N`BMf^2O*~k34r_QaBMiXr@B`1*OXV;sA z9gZ{qm~Tz#GUS?VMvHuD!B$x1U&)(!$F*Sp&b2~cEiXb}fOVHxav+Cc&lruM_R&V( z{43J!IB|M3ZPcwnQbKw_ebQNXOK%`r0lA@di3f&@c4}>O5mAX}`oa7CAntB*PQV6H z^L0WBm#47xTa;TPT3rIKe{dQg49MoR+S7kZUoEgm8$1*sT7hyWeFN zn%<%O^kC4vVk0^76VKU1bP6oo&2Wj(7bV7r$yWzRuT)$$b)}BoAG@t&D^9#0)4o5t z3!Xb!WQChtbPDCZqnv#{@Cy@D^Gw)@;l6aTSvhyQ&XWfqXs~EWy=uctyrPgS<;cB3 ziFkO@!mSh-w6rR5LZ+*OP##Ou?k-vUl=T*#5wv)XW2;UyNTZj8}9GudhAJ(K5qN?vK^qvH6t3LGn(B3(e+O(u*EW1 zgo5DqN~(Y+2m~`?c&GqQ{_o?!Vs@#_RA&(9SEpn!M%ab_5c z29yHk05S3?2n7rV(d*;#xkoZwk^xiERpN!)4V9H=l4Tn>l)s)UWPUlhW+IW-e}Nd?fsk@0y>16?UrrsO!Hfv0>DAFyj~ z4;Oe+Dtg6e1A$uu6@_fEHn~Tu=r`1LiAGjPWDh&kDWabnW};Hzp#zbs1*P^&lDQn3 zhr`|MiT6!+C&i|>I%eo`0eSDaQI)&vJ`Nd~4)V@wtQn-jj?ItB_B_)Xwk^s@lernM zO6lqvz0uD;>}Ldz03>%+rJfw%-gl1kJbl2iG7Yh2s)~NTOz*9{732Q!JpEGs6V6Or z?v@;35->T4fIz_@a8cZQAa0bgx9TTIG8{VR`$aOlLZ$GqH0yMO z@Y6xHgC39jse&KLbn`{{Q=Dt?sE>A+&5;&KL6?ewqvkimo8(4^)y-6@f|g&srG3>K zOR=S%Q-k-M?40&}c8i-mnBH1sjS;pxgNV#%ZPwef`YO#$*D?j$PZ$l zv{pW;Ex{36V{U;rt7KE%$r;XTZ-@9eYiWqK{GxeG!gsw=N<4qP;JB$*gcAmX#ZTkm zq-$D~{KvLfP0R=BdS#-bj(0KEcF*w_t(~hvN!;6+PE{lAeAu>?ljx1Nff@jeHBiRi z;8P7Z7*;-^Yp6&xT-dBKQxS9QF4n?^yDy1p2?1 z{23BJ<8P2)b|7Jd|FHo6E0OvuRKyY-<<1OEd3a0BM&Rq!?9JVYy#B1+Qd!I5#H&na zk30jH2V789$$yAG~m0RXuJD{3u#WSeCxe~2|f62_g>oeC8H2- ze_UH=t}fpaj}759iKB>E5tqFUk`YL%VC@Mru%ad`VPXugO{!w0WjwP{qm4bia|eAw z%*&+wPLE(jG-lJ5O7spY(>%Nwf zJoPod6ROYp-O|9-fNjCN;-j5sdwH&MMsRxO-8N?0U+SP@S1s;CxMp2EWy){1+$1-p z-DsI!@Z4bXQA?=y)QQ#3-$e2N-2dzmme zbbuEP3)|)lIMxspuEbuJf&jNE&eccAgGAH(;O4$ri-*b+2mD#*+5{X{T+%#m+hwnw zkf-(~ntl3qGJvy}XGYaA_O+L)P&_p4@%st9PcpPWv(828(5o1EE|+dIyIAoDXB5Rx z2VB*Q-H5fTW<9l){gQ8BNW*?6U`6S{ffb#a&3)ZV>)Im)?txTeS&1&gRUu8nNMOgv z+(FN+c$pG?jSUeB*?EX{HtNS#Gz{^Sc$kU#;o^jQwe_IHf@kKow7!c`4=eK)3_^Qx ze7?GX&f}#QwMYDVJliV?LGc3@|E>ar@q@9&P+{tq3gEv?*MFl5|8b7}D-UjPy+2V- zR(n5asG`m*?|e`x$VJQF^3>hqpOW4P>L+*@OdT!pG`Rd)sD7&MgFN|kU=M2@8(Y6w ztRiYPqHa?A_K*Cd0VS>?dqH_B%{`uuhc64=N%<(+p1=57=C#>Iv?CgYyQ>hI6)OpE zamrO&M9IHI$%MboyIg}=uimEGEuTd;oGskcyAn}lHDB0@@N+%$RGxMe6Cr4funqQ$ z(@D`B1+Ln_7dr$zQ;nCclkF8IVs{r0xqV`xp_b29-!1B1zY$=RRk4Wz8NU~@x|U=) z^7_KegkHLFMM4Z#0{ z2OPh900*E95B~5Q@=w3@{|^RoP6f5c3mqhA=})^K1scsL<<#R9%F6QEx{2Rb`ky~z zrY&|YhQ9HW!AbMWFK9)w`=or^w-wr%%ogmWARu$h2!fZ<*ZkVuCOohaSsN5nyOO&>*~TNv9yR<|${+cysDRR3}7H>+p?a9c8v%bU%E#C4CGWvaeW$ oIl4xa=rqgDw#QA?#n3);-E>Npf^^i;kSQ<9A)UYFuMDdGAEFEd8UO$Q literal 0 HcmV?d00001 diff --git a/src/test/resources/openshift-logging/node-0-keystore.jks b/src/test/resources/openshift-logging/node-0-keystore.jks new file mode 100644 index 0000000000000000000000000000000000000000..5693b7bf88ae5acc096a179fe2d4c9832dabd71a GIT binary patch literal 4593 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 literal 0 HcmV?d00001 diff --git a/src/test/resources/openshift-logging/ocp_action_groups.yml b/src/test/resources/openshift-logging/ocp_action_groups.yml new file mode 100644 index 000000000..04e49ed45 --- /dev/null +++ b/src/test/resources/openshift-logging/ocp_action_groups.yml @@ -0,0 +1,143 @@ +UNLIMITED: + - "*" + +###### INDEX LEVEL ###### + +INDICES_ALL: + - "indices:*" + +# for backward compatibility +ALL: + - INDICES_ALL + +MANAGE: + - "indices:monitor/*" + - "indices:admin/*" + +CREATE_INDEX: + - "indices:admin/create" + - "indices:admin/mapping/put" + +MANAGE_ALIASES: + - "indices:admin/aliases*" + +# for backward compatibility +MONITOR: + - INDICES_MONITOR + - cluster:monitor/main + +INDICES_MONITOR: + - "indices:monitor/*" + +DATA_ACCESS: + - "indices:data/*" + - CRUD + +WRITE: + - "indices:data/write*" + - "indices:admin/mapping/put" + +READ: + - "indices:data/read*" + - "indices:admin/mappings/fields/get*" + - "indices:admin/mappings/get" + - "indices:data/read/search" + +DELETE: + - "indices:data/write/delete*" + +CRUD: + - READ + - WRITE + +SEARCH: + - "indices:data/read/search*" + - "indices:data/read/msearch*" + - SUGGEST + +SUGGEST: + - "indices:data/read/suggest*" + +INDEX: + - "indices:data/write/index*" + - "indices:data/write/update*" + - "indices:admin/mapping/put" + - "indices:data/write/bulk*" + +GET: + - "indices:data/read/get*" + - "indices:data/read/mget*" + +INDEX_ANY_ADMIN: + - indices:admin/mappings/fields/get* + - indices:admin/mappings/get + - indices:admin/validate/query* + - indices:admin/get* + - "indices:data/read/field_stats" + - "indices:data/read/field_caps" + - READ + +INDEX_KIBANA: + - MANAGE + - INDEX + - READ + - DELETE +INDEX_ANY_KIBANA: + - INDEX_ANY_ADMIN + - MANAGE + - WRITE +INDEX_OPERATIONS: + - INDEX_ANY_ADMIN +INDEX_ANY_OPERATIONS: + - INDEX_ANY_ADMIN + - INDICES_MONITOR +INDEX_PROJECT: + - INDEX_ANY_ADMIN + - INDEX_ALL + +METRICS: + - CLUSTER_MONITOR + - SEARCH +USER_ALL_INDEX_OPS: + - "indices:data/read/field_caps" +USER_CLUSTER_OPERATIONS: + - CLUSTER_COMPOSITE_OPS_RO + - MONITOR + - CLUSTER_COMPOSITE_OPS + +###### CLUSTER LEVEL ###### + +# note indicies permissions here because they are +# 'cluster' level perms +CLUSTER_ALL: + - "cluster:*" + - CLUSTER_COMPOSITE_OPS + +CLUSTER_MONITOR: + - cluster:monitor/* +CLUSTER_MONITOR_KIBANA: + - cluster:monitor/nodes/info + - cluster:monitor/health + - CLUSTER_COMPOSITE_OPS +CLUSTER_OPERATIONS: + - CLUSTER_ALL + +CLUSTER_COMPOSITE_OPS_RO: + - "indices:data/read/coordinate-msearch*" + - "indices:data/read/field_caps" + - "indices:data/read/mget" + - "indices:data/read/search" + - "indices:data/read/msearch" + - "indices:data/read/mtv" + - "indices:data/read/scroll*" + - "indices:admin/aliases/exists*" + - "indices:admin/aliases/get*" + +CLUSTER_COMPOSITE_OPS: + - "indices:data/write/bulk" + - "indices:admin/aliases*" + - CLUSTER_COMPOSITE_OPS_RO + +MANAGE_SNAPSHOTS: + - "cluster:admin/snapshot/*" + - "cluster:admin/repository/*" diff --git a/src/test/resources/openshift-logging/ocp_config.yml b/src/test/resources/openshift-logging/ocp_config.yml new file mode 100644 index 000000000..074541349 --- /dev/null +++ b/src/test/resources/openshift-logging/ocp_config.yml @@ -0,0 +1,32 @@ +opendistro_security: + dynamic: + kibana: + server_username: 'CN=system.logging.kibana,OU=OpenShift,O=Logging' + do_not_fail_on_forbidden: true + http: + xff: + enabled: true + remoteIpHeader: 'x-forwarded-for' + internalProxies: '0:0:0:0:0:0:0:1|127\.0\.0\.1' + trustedProxies: '.*' + authc: + openshift_domain: + enabled: true + order: 0 + http_authenticator: + challenge: false + type: extended-proxy + config: + user_header: 'x-forwarded-user' + roles_header: 'x-forwarded-roles' + attr_header_prefix: 'x-ocp-' + authentication_backend: + type: noop + authentication_domain_basic_internal: + enabled: true + order: 1 + http_authenticator: + type: clientcert + challenge: false + authentication_backend: + type: noop \ No newline at end of file diff --git a/src/test/resources/openshift-logging/ocp_internal_users.yml b/src/test/resources/openshift-logging/ocp_internal_users.yml new file mode 100644 index 000000000..3ca3d3b60 --- /dev/null +++ b/src/test/resources/openshift-logging/ocp_internal_users.yml @@ -0,0 +1,12 @@ +spock: + hash: $2a$12$GI9JXffO3WUjTsU7Yy3E4.LBxC2ILo66Zg/rr79BpikSL2IIRezQa + #password is: spock + roles: + - vulcan + - starfleet +kirk: + hash: $2a$12$xZOcnwYPYQ3zIadnlQIJ0eNhX1ngwMkTN.oMwkKxoGvDVPn4/6XtO + #password is: kirk + roles: + - captains + - starfleet \ No newline at end of file diff --git a/src/test/resources/openshift-logging/ocp_roles.yml b/src/test/resources/openshift-logging/ocp_roles.yml new file mode 100644 index 000000000..26b10e747 --- /dev/null +++ b/src/test/resources/openshift-logging/ocp_roles.yml @@ -0,0 +1,165 @@ +# For the kibana server +kibana_server: + readonly: true + cluster: + - CLUSTER_MONITOR + - CLUSTER_COMPOSITE_OPS + - indices:admin/template* + - indices:data/read/scroll* + - indices:data/write/reindex + indices: + '?kibana': + '*': + - INDICES_ALL + '?kibana-6': + '*': + - INDICES_ALL + '?kibana_*': + '*': + - INDICES_ALL + '?reporting*': + '*': + - INDICES_ALL + '?monitoring*': + '*': + - INDICES_ALL + '?tasks': + '*': + - INDICES_ALL + '*': + '*': + - "indices:admin/aliases*" + '?opendistro': + '?security': + - indices:admin/get + +sg_role_prometheus: + cluster: + - METRICS + indices: + '*': + '*': + - indices:monitor* + - indices:data/read/search + +sg_role_fluentd: + cluster: + - indices:data/write/bulk + - CLUSTER_MONITOR + indices: + '*': + '*': + - CRUD + - CREATE_INDEX + +sg_role_rsyslog: + cluster: + - indices:data/write/bulk + - CLUSTER_MONITOR + indices: + '*': + '*': + - CRUD + - CREATE_INDEX + +sg_role_curator: + cluster: + - CLUSTER_MONITOR + - MANAGE + indices: + '*': + '*': + - READ + - MANAGE + - DELETE + - "indices:data/write/bulk*" + +sg_role_admin: + indices: + '*': + '*': + - ALL + cluster: + - CLUSTER_ALL + - ALL + +sg_role_jaeger: + cluster: + - indices:data/write/bulk + - SEARCH + - CLUSTER_MONITOR + - MANAGE + indices: + '*jaeger-span-*': + '*': + - CRUD + - CREATE_INDEX + - READ + - SEARCH + - MANAGE + '*jaeger-service-*': + '*': + - CRUD + - CREATE_INDEX + - READ + - SEARCH + - MANAGE + '*jaeger-span-archive': + '*': + - CRUD + - CREATE_INDEX + - READ + - SEARCH + - MANAGE + '*jaeger-span-archive-*': + '*': + - CRUD + - CREATE_INDEX + - READ + - SEARCH + - MANAGE + +sg_project_operations: + indices: + '?operations?*': + '*': + - READ + - indices:admin/validate/query* + - indices:admin/get* + '*?*?*': + '*': + - READ + - indices:admin/validate/query* + - indices:admin/get* + +# To support multi-tenancy. User's access to indices is restricted to indices belonging to the user's projects, enforced by DLS. +project_user: + readonly: true + cluster: + - CLUSTER_COMPOSITE_OPS_RO + - MONITOR + - indices:data/write/bulk #required for being able to let index mappings update... is this required still with multitenancy? + indices: + app: + '*': + - READ + _dls_: '{"bool":{"filter":{"terms":{"kubernetes.namespace_name":[${attr.proxy.ns}]}}}}' + '?kibana_*_${user_name}': + '*': + - CRUD + +admin_user: + readonly: true + cluster: + - CLUSTER_MONITOR + - CLUSTER_COMPOSITE_OPS_RO + - indices:data/write/bulk #required for being able to let index mappings update... is this required still with multitenancy? + indices: + '*': + '*': + - INDICES_ALL + '?kibana_*': + '*': + - CRUD + tenants: + admin: RW diff --git a/src/test/resources/openshift-logging/ocp_roles_mapping.yml b/src/test/resources/openshift-logging/ocp_roles_mapping.yml new file mode 100644 index 000000000..7675d2ffc --- /dev/null +++ b/src/test/resources/openshift-logging/ocp_roles_mapping.yml @@ -0,0 +1,48 @@ +kibana_server: + users: + - 'CN=system.logging.kibana,OU=OpenShift,O=Logging' + - 'CN=system.logging.kibana,OU=Logging,O=OpenShift' + +sg_role_fluentd: + users: + - 'CN=system.logging.fluentd,OU=OpenShift,O=Logging' + - 'CN=system.logging.fluentd,OU=Logging,O=OpenShift' + +sg_role_rsyslog: + users: + - 'CN=system.logging.rsyslog,OU=OpenShift,O=Logging' + - 'CN=system.logging.rsyslog,OU=Logging,O=OpenShift' + +sg_role_curator: + users: + - 'CN=system.logging.curator,OU=OpenShift,O=Logging' + - 'CN=system.logging.curator,OU=Logging,O=OpenShift' + backendroles: + - 'index-management' + +sg_role_admin: + users: + - 'CN=system.admin,OU=OpenShift,O=Logging' + - 'CN=system.admin,OU=Logging,O=OpenShift' + backendroles: + - 'elasticsearch-operator' + +sg_role_prometheus: + backendroles: + - 'prometheus' + +sg_role_jaeger: + users: + - 'CN=user.jaeger,OU=OpenShift,O=Logging' + - 'CN=user.jaeger,OU=Logging,O=OpenShift' + backendroles: + - 'jaeger' + +admin_user: + backendroles: + - 'admin_reader' + +project_user: + readonly: true + backendroles: + - 'project_user' diff --git a/src/test/resources/openshift-logging/ocp_tenants.yml b/src/test/resources/openshift-logging/ocp_tenants.yml new file mode 100644 index 000000000..e036519e6 --- /dev/null +++ b/src/test/resources/openshift-logging/ocp_tenants.yml @@ -0,0 +1,3 @@ +admin_tenant: + reserved: false + description: "Admin tenant to be shared by all admins" \ No newline at end of file diff --git a/src/test/resources/openshift-logging/spock-keystore.jks b/src/test/resources/openshift-logging/spock-keystore.jks new file mode 100644 index 0000000000000000000000000000000000000000..7ceed76f7c515338c4d6a8b14d284b2f94674c5d GIT binary patch literal 4528 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 literal 0 HcmV?d00001 diff --git a/src/test/resources/openshift-logging/truststore.jks b/src/test/resources/openshift-logging/truststore.jks new file mode 100644 index 0000000000000000000000000000000000000000..7a1b59a8d24993d19aeda0d1651ce9df702385ed GIT binary patch literal 1096 zcmezO_TO6u1_mY|W(3o`Mfv$9y2**U$r*{6c|g%*gFU(?46G4)rUsS_3@l6rP0arc znwXv~U}j=uVq#=8;AP{~YV&CO&dbQi&B|cV*l#FoAjrnWIZ3T^@+X}XMoBT|{q7A_tESBQv$bAGOZXI`?Np`w92NQ#?B0$oZW2S<-O|Fpv(2Ga@$jz4S(kZ6)aDZR%4iLwC_?zl>ZFLP2DeLj?DRVUE{jf zuevBhF1O7(Wm6gySocTIGW*1(eV$9B;`;0vTTFg#{NEb(rIT}K=b}Fjb1T;czF%~J zJvXWSr1ruflS&D9_R!+oM%!-7dj|7DSU(*X&**Xg65JJ`^Q1v#>CNO<+zYwBbZ*?d z_~OrH1uj$8{NZA7e<&F^zr*kL^@%T@I81O~v;2y}qg_#cdfAD~_uNU(_{eU)eyed@ zwDF7CzFS)sZke}dh5S?|W=00a#mNSV27JKuA$^-_(6PO5TDh68Aut( zf&}z_U`{Tr)P0b&I|nr_sKF41*b1rWflnou?Fl4P*XQB8W&mqSg(_*WGTVCEAIq&SU!A5i zKTa;{_@z8?`>odZ{nzR@E!O!J>0Z2Kf^W{+uM4@(oIUGM!g1io{qDaxEn(Yi-iNXr zGP$|ec0t*elL9jz?dy3`eVR$v+J9M>tv;{P_T0o(e%l`~mZ~o`;;7pqlOFw=k5@I> eG{HGy@~6JmhcBkqNFSY0=&xpc>Cc;)T}A+=vX}z^ literal 0 HcmV?d00001