blob: 9381c0319711780b349c09c127ab5f66eb376b98 [file] [log] [blame]
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.solr.cloud;
import java.io.File;
import java.io.IOException;
import java.lang.invoke.MethodHandles;
import java.nio.charset.Charset;
import java.util.Locale;
import javax.security.auth.login.Configuration;
import org.apache.hadoop.minikdc.MiniKdc;
import org.apache.lucene.util.Constants;
import org.apache.solr.SolrTestCaseJ4;
import org.apache.solr.common.cloud.DefaultZkACLProvider;
import org.apache.solr.common.cloud.SaslZkACLProvider;
import org.apache.solr.common.cloud.SolrZkClient;
import org.apache.solr.common.cloud.ZkACLProvider;
import org.apache.solr.util.BadZookeeperThreadsFilter;
import org.apache.zookeeper.CreateMode;
import org.junit.AfterClass;
import org.junit.BeforeClass;
import org.junit.Test;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.carrotsearch.randomizedtesting.annotations.ThreadLeakFilters;
@ThreadLeakFilters(defaultFilters = true, filters = {
BadZookeeperThreadsFilter.class // hdfs currently leaks thread(s)
})
public class SaslZkACLProviderTest extends SolrTestCaseJ4 {
private static final Logger log = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass());
private static final Charset DATA_ENCODING = Charset.forName("UTF-8");
protected Locale savedLocale = null;
protected ZkTestServer zkServer;
@BeforeClass
public static void beforeClass() {
assumeFalse("FIXME: This test fails on Java 9 (https://issues.apache.org/jira/browse/SOLR-8052)", Constants.JRE_IS_MINIMUM_JAVA9);
assumeFalse("FIXME: SOLR-7040: This test fails under IBM J9",
Constants.JAVA_VENDOR.startsWith("IBM"));
System.setProperty("solrcloud.skip.autorecovery", "true");
}
@AfterClass
public static void afterClass() throws InterruptedException {
System.clearProperty("solrcloud.skip.autorecovery");
}
@Override
public void setUp() throws Exception {
super.setUp();
savedLocale = KerberosTestUtil.overrideLocaleIfNotSpportedByMiniKdc();
log.info("####SETUP_START " + getTestName());
createTempDir();
String zkDir = createTempDir() + File.separator
+ "zookeeper/server1/data";
log.info("ZooKeeper dataDir:" + zkDir);
zkServer = new SaslZkTestServer(zkDir, createTempDir() + File.separator + "miniKdc");
zkServer.run();
System.setProperty("zkHost", zkServer.getZkAddress());
SolrZkClient zkClient = new SolrZkClientWithACLs(zkServer.getZkHost(), AbstractZkTestCase.TIMEOUT);
try {
zkClient.makePath("/solr", false, true);
} finally {
zkClient.close();
}
setupZNodes();
log.info("####SETUP_END " + getTestName());
}
protected void setupZNodes() throws Exception {
SolrZkClient zkClient = new SolrZkClientWithACLs(zkServer.getZkAddress(), AbstractZkTestCase.TIMEOUT);
try {
zkClient.create("/protectedCreateNode", "content".getBytes(DATA_ENCODING), CreateMode.PERSISTENT, false);
zkClient.makePath("/protectedMakePathNode", "content".getBytes(DATA_ENCODING), CreateMode.PERSISTENT, false);
} finally {
zkClient.close();
}
zkClient = new SolrZkClientNoACLs(zkServer.getZkAddress(), AbstractZkTestCase.TIMEOUT);
try {
zkClient.create("/unprotectedCreateNode", "content".getBytes(DATA_ENCODING), CreateMode.PERSISTENT, false);
zkClient.makePath("/unprotectedMakePathNode", "content".getBytes(DATA_ENCODING), CreateMode.PERSISTENT, false);
} finally {
zkClient.close();
}
}
@Override
public void tearDown() throws Exception {
zkServer.shutdown();
Locale.setDefault(savedLocale);
super.tearDown();
}
@Test
public void testSaslZkACLProvider() throws Exception {
// Test with Sasl enabled
SolrZkClient zkClient = new SolrZkClientWithACLs(zkServer.getZkAddress(), AbstractZkTestCase.TIMEOUT);
try {
VMParamsZkACLAndCredentialsProvidersTest.doTest(zkClient, true, true, true, true, true);
} finally {
zkClient.close();
}
// Test without Sasl enabled
setupZNodes();
System.setProperty("zookeeper.sasl.client", "false");
zkClient = new SolrZkClientNoACLs(zkServer.getZkAddress(), AbstractZkTestCase.TIMEOUT);
try {
VMParamsZkACLAndCredentialsProvidersTest.doTest(zkClient, true, true, false, false, false);
} finally {
zkClient.close();
System.clearProperty("zookeeper.sasl.client");
}
}
/**
* A SolrZKClient that adds Sasl ACLs
*/
private static class SolrZkClientWithACLs extends SolrZkClient {
public SolrZkClientWithACLs(String zkServerAddress, int zkClientTimeout) {
super(zkServerAddress, zkClientTimeout);
}
@Override
public ZkACLProvider createZkACLProvider() {
return new SaslZkACLProvider();
}
}
/**
* A SolrZKClient that doesn't add ACLs
*/
private static class SolrZkClientNoACLs extends SolrZkClient {
public SolrZkClientNoACLs(String zkServerAddress, int zkClientTimeout) {
super(zkServerAddress, zkClientTimeout);
}
@Override
public ZkACLProvider createZkACLProvider() {
return new DefaultZkACLProvider();
}
}
/**
* A ZkTestServer with Sasl support
*/
public static class SaslZkTestServer extends ZkTestServer {
private String kdcDir;
private MiniKdc kdc;
private Configuration conf;
public SaslZkTestServer(String zkDir, String kdcDir) {
super(zkDir);
this.kdcDir = kdcDir;
}
public SaslZkTestServer(String zkDir, int port, String kdcDir) {
super(zkDir, port);
this.kdcDir = kdcDir;
conf = Configuration.getConfiguration();
}
@Override
public void run() throws InterruptedException {
try {
kdc = KerberosTestUtil.getKdc(new File(kdcDir));
// Don't require that credentials match the entire principal string, e.g.
// can match "solr" rather than "solr/host@DOMAIN"
System.setProperty("zookeeper.kerberos.removeRealmFromPrincipal", "true");
System.setProperty("zookeeper.kerberos.removeHostFromPrincipal", "true");
File keytabFile = new File(kdcDir, "keytabs");
String zkClientPrincipal = "solr";
String zkServerPrincipal = "zookeeper/127.0.0.1";
kdc.start();
// Create ZK client and server principals and load them into the Configuration
kdc.createPrincipal(keytabFile, zkClientPrincipal, zkServerPrincipal);
KerberosTestUtil.JaasConfiguration jaas = new KerberosTestUtil.JaasConfiguration(
zkClientPrincipal, keytabFile, zkServerPrincipal, keytabFile);
Configuration.setConfiguration(jaas);
} catch (Exception ex) {
throw new RuntimeException(ex);
}
super.run();
}
@Override
public void shutdown() throws IOException, InterruptedException {
super.shutdown();
System.clearProperty("zookeeper.authProvider.1");
System.clearProperty("zookeeper.kerberos.removeRealmFromPrincipal");
System.clearProperty("zookeeper.kerberos.removeHostFromPrincipal");
Configuration.setConfiguration(conf);
kdc.stop();
}
}
}