/*-
* -\-\-
* Helios Services
* --
* Copyright (C) 2016 Spotify AB
* --
* Licensed 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 com.spotify.helios.servicescommon;
import static com.google.common.base.Throwables.propagate;
import static com.google.common.base.Throwables.propagateIfInstanceOf;
import static com.google.common.collect.Sets.newHashSet;
import static com.spotify.helios.servicescommon.ZooKeeperAclProviders.digest;
import static com.spotify.helios.servicescommon.ZooKeeperAclProviders.heliosAclProvider;
import com.google.common.collect.Lists;
import com.spotify.helios.servicescommon.coordination.CuratorClientFactoryImpl;
import com.spotify.helios.servicescommon.coordination.DefaultZooKeeperClient;
import com.spotify.helios.servicescommon.coordination.ZooKeeperClient;
import java.util.List;
import java.util.concurrent.TimeUnit;
import org.apache.curator.RetryPolicy;
import org.apache.curator.framework.AuthInfo;
import org.apache.curator.framework.CuratorFramework;
import org.apache.curator.framework.api.ACLProvider;
import org.apache.curator.retry.ExponentialBackoffRetry;
import org.apache.zookeeper.KeeperException;
import org.apache.zookeeper.data.ACL;
public class ZooKeeperAclInitializer {
public static void main(final String[] args) throws Exception {
if (args.length == 6) {
initializeAcl(args[0], args[1], args[2], args[3], args[4], args[5]);
} else {
System.out.println("usage: <ZK connect string> <ZK cluster ID> "
+ "<master user> <master password> <agent user> <agent password>");
System.exit(-1);
}
}
static void initializeAcl(final String zooKeeperConnectionString,
final String zooKeeperClusterId,
final String masterUser,
final String masterPassword,
final String agentUser,
final String agentPassword)
throws KeeperException {
final ACLProvider aclProvider = heliosAclProvider(
masterUser, digest(masterUser, masterPassword),
agentUser, digest(agentUser, agentPassword));
final List<AuthInfo> authorization = Lists.newArrayList(new AuthInfo(
"digest", String.format("%s:%s", masterUser, masterPassword).getBytes()));
final RetryPolicy zooKeeperRetryPolicy = new ExponentialBackoffRetry(1000, 3);
final CuratorFramework curator = new CuratorClientFactoryImpl().newClient(
zooKeeperConnectionString,
(int) TimeUnit.SECONDS.toMillis(60),
(int) TimeUnit.SECONDS.toMillis(15),
zooKeeperRetryPolicy,
aclProvider,
authorization);
final ZooKeeperClient client = new DefaultZooKeeperClient(curator, zooKeeperClusterId);
try {
client.start();
initializeAclRecursive(client, "/", aclProvider);
} finally {
client.close();
}
}
static void initializeAclRecursive(final ZooKeeperClient client, final String path,
final ACLProvider aclProvider)
throws KeeperException {
try {
final List<ACL> expected = aclProvider.getAclForPath(path);
final List<ACL> actual = client.getAcl(path);
if (newHashSet(expected).equals(newHashSet(actual))) {
// actual ACL matches expected
} else {
client.setAcl(path, expected);
}
for (final String child : client.getChildren(path)) {
initializeAclRecursive(client, path.replaceAll("/$", "") + "/" + child, aclProvider);
}
} catch (Exception e) {
propagateIfInstanceOf(e, KeeperException.class);
throw propagate(e);
}
}
}