accumulo-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From joshelser <...@git.apache.org>
Subject [GitHub] accumulo-examples pull request #2: ACCUMULO-1641 Removed use of non public A...
Date Tue, 13 Dec 2016 16:16:21 GMT
Github user joshelser commented on a diff in the pull request:

    https://github.com/apache/accumulo-examples/pull/2#discussion_r92203893
  
    --- Diff: src/main/java/org/apache/accumulo/examples/cli/ClientOpts.java ---
    @@ -0,0 +1,143 @@
    +/*
    + * 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.accumulo.examples.cli;
    +
    +import java.io.File;
    +import java.io.IOException;
    +import java.io.UncheckedIOException;
    +import java.time.Duration;
    +
    +import org.apache.accumulo.core.client.AccumuloException;
    +import org.apache.accumulo.core.client.AccumuloSecurityException;
    +import org.apache.accumulo.core.client.ClientConfiguration;
    +import org.apache.accumulo.core.client.Connector;
    +import org.apache.accumulo.core.client.ZooKeeperInstance;
    +import org.apache.accumulo.core.client.security.tokens.AuthenticationToken;
    +import org.apache.accumulo.core.client.security.tokens.KerberosToken;
    +import org.apache.accumulo.core.client.security.tokens.PasswordToken;
    +import org.apache.accumulo.core.security.Authorizations;
    +import org.apache.accumulo.core.security.ColumnVisibility;
    +import org.apache.commons.configuration.Configuration;
    +import org.apache.commons.configuration.ConfigurationException;
    +import org.apache.commons.configuration.PropertiesConfiguration;
    +
    +import com.beust.jcommander.IStringConverter;
    +import com.beust.jcommander.Parameter;
    +
    +public class ClientOpts extends Help {
    +
    +  public static class AuthConverter implements IStringConverter<Authorizations>
{
    +    @Override
    +    public Authorizations convert(String value) {
    +      return new Authorizations(value.split(","));
    +    }
    +  }
    +
    +  public static class VisibilityConverter implements IStringConverter<ColumnVisibility>
{
    +    @Override
    +    public ColumnVisibility convert(String value) {
    +      return new ColumnVisibility(value);
    +    }
    +  }
    +
    +  public static class TimeConverter implements IStringConverter<Long> {
    +    @Override
    +    public Long convert(String value) {
    +      if(value.matches("[0-9]+"))
    +        value = "PT"+value+"S"; //if only numbers then assume seconds
    +      return Duration.parse(value).toMillis();
    +    }
    +  }
    +
    +  public static class MemoryConverter implements IStringConverter<Long> {
    +    @Override
    +    public Long convert(String str) {
    +      try {
    +        char lastChar = str.charAt(str.length() - 1);
    +        int multiplier = 0;
    +        switch (Character.toUpperCase(lastChar)) {
    +          case 'G':
    +            multiplier += 10;
    +          case 'M':
    +            multiplier += 10;
    +          case 'K':
    +            multiplier += 10;
    +          case 'B':
    +            break;
    +          default:
    +            return Long.parseLong(str);
    +        }
    +        return Long.parseLong(str.substring(0, str.length() - 1)) << multiplier;
    +      } catch (Exception ex) {
    +        throw new IllegalArgumentException("The value '" + str + "' is not a valid memory
setting. A valid value would a number "
    +            + "possibily followed by an optional 'G', 'M', 'K', or 'B'.");
    +      }
    +    }
    +  }
    +
    +  public static class PropertiesConverter implements IStringConverter<Configuration>
{
    +    @Override
    +    public Configuration convert(String filename) {
    +      try {
    +        return new PropertiesConfiguration(filename);
    +      } catch (ConfigurationException e) {
    +        throw new RuntimeException(e);
    +      }
    +    }
    +  }
    +
    +  @Parameter(names = {"-c", "--conf"}, required = true, converter = PropertiesConverter.class,
    +      description = "Config file for connecting to Accumulo.  See README.md for details.")
    +  private Configuration config = null;
    +
    +  @Parameter(names = {"-auths", "--auths"}, converter = AuthConverter.class, description
= "the authorizations to use when reading or writing")
    +  public Authorizations auths = Authorizations.EMPTY;
    +
    +  public Connector getConnector() {
    +    try {
    +      ZooKeeperInstance zki = new ZooKeeperInstance(config);
    +      return zki.getConnector(getPrincipal(), getToken());
    +    } catch (AccumuloException | AccumuloSecurityException e) {
    +      throw new RuntimeException(e);
    +    }
    +  }
    +
    +  public ClientConfiguration getClientConfiguration() {
    +    return new ClientConfiguration(config);
    +  }
    +
    +  public String getPrincipal() {
    +    return config.getString("accumulo.examples.principal", "root");
    +  }
    +
    +  public AuthenticationToken getToken() {
    +    if (config.containsKey("instance.rpc.sasl.enabled")) {
    +      try {
    +        if (config.containsKey("accumulo.examples.keytab")) {
    +          String keytab = config.getString("accumulo.examples.keytab");
    +          return new KerberosToken(getPrincipal(), new File(keytab));
    +        } else {
    +          return new KerberosToken(getPrincipal());
    --- End diff --
    
    The `KerberosToken(String)` constructor expects that the user is already logged in via
the JAAS APIs or Hadoop's UserGroupInformation (which is sugar on top of JAAS APIs). As a
user, it would be common to use a ticket-cache instead of a keytab to run an example.
    
    UGI does have a method for acquiring an instance from a ticket-cache, `UserGroupInformation.getUGIFromTicketCache(String
ticketCache, String user)`; however, this only returns the UGI instance and does not update
the static state inside of UGI after this method is called (like `loginUserFromKeytab(..)`
does).
    
    I can see two ways forward:
    1. Try to use `UGI.loginUserFromSubject(Subject)` after performing the `UserGroupInformation.getUGIFromTicketCache(..)`
call. I think this would work, but I'm not 100% positive.
    2. Call `UserGroupInformation.getUGIFromTicketCache(..)` at the beginning of each example
and wrap all future execution of the example in a `doAs(..)` (instance method on the UGI object
returned by `getUGIFromTicketCache`). This is a bit more invasive, but logins are typically
one of the first things that could/should happen with Kerberos.


---
If your project is set up for it, you can reply to this email and have your
reply appear on GitHub as well. If your project does not have this feature
enabled and wishes so, or if the feature is enabled but not working, please
contact infrastructure at infrastructure@apache.org or file a JIRA ticket
with INFRA.
---

Mime
View raw message