All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.apache.accumulo.manager.upgrade.PreUpgradeValidation Maven / Gradle / Ivy

/*
 * 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
 *
 *   https://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.accumulo.manager.upgrade;

import java.util.List;
import java.util.Objects;
import java.util.Set;
import java.util.concurrent.atomic.AtomicBoolean;

import org.apache.accumulo.core.fate.zookeeper.ZooReaderWriter;
import org.apache.accumulo.manager.EventCoordinator;
import org.apache.accumulo.server.AccumuloDataVersion;
import org.apache.accumulo.server.ServerContext;
import org.apache.zookeeper.KeeperException;
import org.apache.zookeeper.ZKUtil;
import org.apache.zookeeper.ZooDefs;
import org.apache.zookeeper.ZooKeeper;
import org.apache.zookeeper.data.ACL;
import org.apache.zookeeper.data.Stat;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;

/**
 * Provide checks before upgraders run that can perform checks that the environment from previous
 * versions match expectations. Checks include:
 * 
    *
  • ACL validation of ZooKeeper nodes
  • *
*/ public class PreUpgradeValidation { private final static Logger log = LoggerFactory.getLogger(PreUpgradeValidation.class); public void validate(final ServerContext context, final EventCoordinator eventCoordinator) { int cv = AccumuloDataVersion.getCurrentVersion(context); if (cv == AccumuloDataVersion.get()) { log.debug("already at current data version: {}, skipping validation", cv); return; } validateACLs(context); } private void validateACLs(ServerContext context) { final AtomicBoolean aclErrorOccurred = new AtomicBoolean(false); final ZooReaderWriter zrw = context.getZooReaderWriter(); final ZooKeeper zk = zrw.getZooKeeper(); final String rootPath = context.getZooKeeperRoot(); final Set users = Set.of("accumulo", "anyone"); log.info("Starting validation on ZooKeeper ACLs"); try { ZKUtil.visitSubTreeDFS(zk, rootPath, false, (rc, path, ctx, name) -> { try { final List acls = zk.getACL(path, new Stat()); if (!hasAllPermissions(users, acls)) { log.error( "ZNode at {} does not have an ACL that allows accumulo to write to it. ZNode ACL will need to be modified. Current ACLs: {}", path, acls); aclErrorOccurred.set(true); } } catch (KeeperException | InterruptedException e) { log.error("Error getting ACL for path: {}", path, e); aclErrorOccurred.set(true); } }); if (aclErrorOccurred.get()) { throw new RuntimeException( "Upgrade precondition failed! ACLs will need to be modified for some ZooKeeper nodes. " + "Check the log for specific failed paths, check ZooKeeper troubleshooting in user documentation " + "for instructions on how to fix."); } } catch (KeeperException | InterruptedException e) { throw new RuntimeException("Upgrade Failed! Error validating nodes under " + rootPath, e); } log.info("Successfully completed validation on ZooKeeper ACLs"); } private static boolean hasAllPermissions(final Set users, final List acls) { return acls.stream() .anyMatch(a -> users.contains(extractAuthName(a)) && a.getPerms() == ZooDefs.Perms.ALL); } private static String extractAuthName(ACL acl) { Objects.requireNonNull(acl, "provided ACL cannot be null"); try { return acl.getId().getId().trim().split(":")[0]; } catch (Exception ex) { log.debug("Invalid ACL passed, cannot parse id from '{}'", acl); return ""; } } @SuppressFBWarnings(value = "DM_EXIT", justification = "Want to immediately stop all threads on upgrade error") private void fail(Exception e) { log.error("FATAL: Error performing pre-upgrade checks", e); System.exit(1); } }




© 2015 - 2025 Weber Informatics LLC | Privacy Policy