/*
 * 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.knox.gateway.util;

import org.apache.commons.codec.binary.Base64;
import org.apache.commons.io.FileUtils;
import org.apache.commons.io.FilenameUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.conf.Configured;
import org.apache.hadoop.util.Tool;
import org.apache.hadoop.util.ToolRunner;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.knox.gateway.GatewayCommandLine;
import org.apache.knox.gateway.config.GatewayConfig;
import org.apache.knox.gateway.config.impl.GatewayConfigImpl;
import org.apache.knox.gateway.deploy.DeploymentFactory;
import org.apache.knox.gateway.services.CLIGatewayServices;
import org.apache.knox.gateway.services.GatewayServices;
import org.apache.knox.gateway.services.Service;
import org.apache.knox.gateway.services.ServiceLifecycleException;
import org.apache.knox.gateway.services.ServiceType;
import org.apache.knox.gateway.services.config.client.RemoteConfigurationRegistryClient;
import org.apache.knox.gateway.services.config.client.RemoteConfigurationRegistryClientService;
import org.apache.knox.gateway.services.security.AliasService;
import org.apache.knox.gateway.services.security.KeystoreService;
import org.apache.knox.gateway.services.security.KeystoreServiceException;
import org.apache.knox.gateway.services.security.MasterService;
import org.apache.knox.gateway.services.topology.TopologyService;
import org.apache.knox.gateway.topology.Provider;
import org.apache.knox.gateway.topology.Topology;
import org.apache.knox.gateway.topology.validation.TopologyValidator;
import org.apache.log4j.PropertyConfigurator;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.config.ConfigurationException;
import org.apache.shiro.config.Ini;
import org.apache.shiro.config.IniSecurityManagerFactory;
import org.apache.shiro.subject.Subject;
import org.apache.shiro.util.Factory;
import org.apache.shiro.util.ThreadContext;
import org.eclipse.persistence.oxm.MediaType;
import org.jboss.shrinkwrap.api.exporter.ExplodedExporter;
import org.jboss.shrinkwrap.api.spec.EnterpriseArchive;

import javax.net.ssl.SSLException;
import java.io.BufferedReader;
import java.io.Console;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.PrintStream;
import java.net.InetAddress;
import java.net.UnknownHostException;
import java.nio.charset.StandardCharsets;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.security.KeyStoreException;
import java.security.cert.Certificate;
import java.security.cert.X509Certificate;
import java.util.Arrays;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.Properties;
import java.util.Set;
import java.util.UUID;

public class KnoxCLI extends Configured implements Tool {

  private static final String USAGE_PREFIX = "KnoxCLI {cmd} [options]";
  private static final String COMMANDS =
      "   [--help]\n" +
      "   [" + VersionCommand.USAGE + "]\n" +
      "   [" + MasterCreateCommand.USAGE + "]\n" +
      "   [" + CertCreateCommand.USAGE + "]\n" +
      "   [" + CertExportCommand.USAGE + "]\n" +
      "   [" + AliasCreateCommand.USAGE + "]\n" +
      "   [" + AliasDeleteCommand.USAGE + "]\n" +
      "   [" + AliasListCommand.USAGE + "]\n" +
      "   [" + RedeployCommand.USAGE + "]\n" +
      "   [" + ListTopologiesCommand.USAGE + "]\n" +
      "   [" + ValidateTopologyCommand.USAGE + "]\n" +
      "   [" + LDAPAuthCommand.USAGE + "]\n" +
      "   [" + LDAPSysBindCommand.USAGE + "]\n" +
      "   [" + ServiceTestCommand.USAGE + "]\n" +
      "   [" + RemoteRegistryClientsListCommand.USAGE + "]\n" +
      "   [" + RemoteRegistryListProviderConfigsCommand.USAGE + "]\n" +
      "   [" + RemoteRegistryUploadProviderConfigCommand.USAGE + "]\n" +
      "   [" + RemoteRegistryListDescriptorsCommand.USAGE + "]\n" +
      "   [" + RemoteRegistryUploadDescriptorCommand.USAGE + "]\n" +
      "   [" + RemoteRegistryDeleteProviderConfigCommand.USAGE + "]\n" +
      "   [" + RemoteRegistryDeleteDescriptorCommand.USAGE + "]\n" +
      "   [" + RemoteRegistryGetACLCommand.USAGE + "]\n" +
      "   [" + TopologyConverter.USAGE + "]\n";

  /** allows stdout to be captured if necessary */
  public PrintStream out = System.out;
  /** allows stderr to be captured if necessary */
  public PrintStream err = System.err;

  private static GatewayServices services = new CLIGatewayServices();
  private Command command;
  private String value;
  private String cluster;
  private String path;
  private String generate = "false";
  private String hostname;
  private String port;
  private boolean force;
  private boolean debug;
  private String user;
  private String pass;
  private boolean groups;

  private String remoteRegistryClient;
  private String remoteRegistryEntryName;

  private String type;
  private String topologyName;
  private String providerName;
  private String descriptorName;
  private String outputDir;
  private String discoveryUrl;
  private String discoveryUser;
  private String discoveryPasswordAlias;
  private String discoveryType;

  // For testing only
  private String master;

  @Override
  public int run(String[] args) throws Exception {
    int exitCode = 0;
    try {
      exitCode = init(args);
      if (exitCode != 0) {
        return exitCode;
      }

      if (command != null && command.validate()) {
        initializeServices( command instanceof MasterCreateCommand );
        command.execute();
      } else if (!(command instanceof MasterCreateCommand)){
        out.println("ERROR: Invalid Command" + "\n" + "Unrecognized option:" +
            args[0] + "\n" +
            "A fatal exception has occurred. Program will exit.");
        exitCode = -2;
      }
    } catch (ServiceLifecycleException sle) {
      out.println("ERROR: Internal Error: Please refer to the knoxcli.log " +
          "file for details. " + sle.getMessage());
    } catch (Exception e) {
      e.printStackTrace( err );
      err.flush();
      return -3;
    }
    return exitCode;
  }

  public static synchronized GatewayServices getGatewayServices() {
    return services;
  }

  private void initializeServices(boolean persisting) throws ServiceLifecycleException {
    GatewayConfig config = getGatewayConfig();
    if (config.isHadoopKerberosSecured()) {
      configureKerberosSecurity(config);
    }
    Map<String,String> options = new HashMap<>();
    options.put(GatewayCommandLine.PERSIST_LONG, Boolean.toString(persisting));
    if (master != null) {
      options.put("master", master);
    }
    services.init(config, options);
  }

  /**
   * Parse the command line arguments and initialize the data.
   *
   * See the usage information for the commands itself for information on which parameters they take.
   *
   * @param args command line arguments
   * @return return exit code
   * @throws IOException exception on starting KnoxCLI
   */
  private int init(String[] args) throws IOException {
    if (args.length == 0) {
      printKnoxShellUsage();
      return -1;
    }
    for (int i = 0; i < args.length; i++) { // parse command line
      if (args[i].equals("create-master")) {
        command = new MasterCreateCommand();
        if ((args.length > i + 1) && args[i + 1].equals("--help")) {
          printKnoxShellUsage();
          return -1;
        }
      } else if (args[i].equals("delete-alias")) {
        String alias = null;
        if (args.length >= 2) {
          alias = args[++i];
        }
        command = new AliasDeleteCommand(alias);
        if (alias == null || "--help".equals(alias)) {
          printKnoxShellUsage();
          return -1;
        }
      } else if (args[i].equals("create-alias")) {
        String alias = null;
        if (args.length >= 2) {
          alias = args[++i];
        }
        command = new AliasCreateCommand(alias);
        if (alias == null || "--help".equals(alias)) {
          printKnoxShellUsage();
          return -1;
        }
      } else if (args[i].equals("create-cert")) {
        command = new CertCreateCommand();
        if ((args.length > i + 1) && args[i + 1].equals("--help")) {
          printKnoxShellUsage();
          return -1;
        }
      } else if (args[i].equals("export-cert")) {
        command = new CertExportCommand();
        if ((args.length > i + 1) && args[i + 1].equals("--help")) {
          printKnoxShellUsage();
          return -1;
        }
      }else if(args[i].equals("user-auth-test")) {
        if(i + 1 >= args.length) {
          printKnoxShellUsage();
          return -1;
        } else {
          command = new LDAPAuthCommand();
        }
      } else if(args[i].equals("system-user-auth-test")) {
        if (i + 1 >= args.length){
          printKnoxShellUsage();
          return -1;
        } else {
          command = new LDAPSysBindCommand();
        }
      } else if (args[i].equals("list-alias")) {
        command = new AliasListCommand();
      } else if (args[i].equals("--value")) {
        if( i+1 >= args.length || args[i+1].startsWith( "-" ) ) {
          printKnoxShellUsage();
          return -1;
        }
        this.value = args[++i];
        if ( command instanceof MasterCreateCommand ) {
          this.master = this.value;
        }
      } else if ( args[i].equals("version") ) {
        command = new VersionCommand();
      } else if ( args[i].equals("redeploy") ) {
        command = new RedeployCommand();
      } else if ( args[i].equals("validate-topology") ) {
        if(i + 1 >= args.length) {
          printKnoxShellUsage();
          return -1;
        } else {
          command = new ValidateTopologyCommand();
        }
      } else if( args[i].equals("list-topologies") ){
        command = new ListTopologiesCommand();
      }else if ( args[i].equals("--cluster") || args[i].equals("--topology") ) {
        if( i+1 >= args.length || args[i+1].startsWith( "-" ) ) {
          printKnoxShellUsage();
          return -1;
        }
        this.cluster = args[++i];
      } else if (args[i].equals("service-test")) {
        if( i + 1 >= args.length) {
          printKnoxShellUsage();
          return -1;
        } else {
          command = new ServiceTestCommand();
        }
      } else if (args[i].equals("--generate")) {
        if ( command instanceof MasterCreateCommand ) {
          this.master = UUID.randomUUID().toString();
        } else {
          this.generate = "true";
        }
      } else if(args[i].equals("--type")) {
        if( i+1 >= args.length || args[i+1].startsWith( "-" ) ) {
          printKnoxShellUsage();
          return -1;
        }
        this.type = args[++i];
      } else if(args[i].equals("--path")) {
        if( i+1 >= args.length || args[i+1].startsWith( "-" ) ) {
          printKnoxShellUsage();
          return -1;
        }
        this.path = args[++i];
      }else if (args[i].equals("--hostname")) {
        if( i+1 >= args.length || args[i+1].startsWith( "-" ) ) {
          printKnoxShellUsage();
          return -1;
        }
        this.hostname = args[++i];
      } else if (args[i].equals("--port")) {
        if( i+1 >= args.length || args[i+1].startsWith( "-" ) ) {
          printKnoxShellUsage();
          return -1;
        }
        this.port = args[++i];
      } else if (args[i].equals("--provider-name")) {
        if( i+1 >= args.length || args[i+1].startsWith( "-" ) ) {
          printKnoxShellUsage();
          return -1;
        }
        this.providerName = args[++i];
      } else if (args[i].equals("--topology-name")) {
        if( i+1 >= args.length || args[i+1].startsWith( "-" ) ) {
          printKnoxShellUsage();
          return -1;
        }
        this.topologyName = args[++i];
      } else if (args[i].equals("--descriptor-name")) {
        if( i+1 >= args.length || args[i+1].startsWith( "-" ) ) {
          printKnoxShellUsage();
          return -1;
        }
        this.descriptorName = args[++i];
      } else if (args[i].equals("--output-dir")) {
        if( i+1 >= args.length || args[i+1].startsWith( "-" ) ) {
          printKnoxShellUsage();
          return -1;
        }
        this.outputDir = args[++i];
      } else if (args[i].equals("--discovery-url")) {
        if( i+1 >= args.length || args[i+1].startsWith( "-" ) ) {
          printKnoxShellUsage();
          return -1;
        }
        this.discoveryUrl = args[++i];
      } else if (args[i].equals("--discovery-user")) {
        if( i+1 >= args.length || args[i+1].startsWith( "-" ) ) {
          printKnoxShellUsage();
          return -1;
        }
        this.discoveryUser = args[++i];
      } else if (args[i].equals("--discovery-pwd-alias")) {
        if( i+1 >= args.length || args[i+1].startsWith( "-" ) ) {
          printKnoxShellUsage();
          return -1;
        }
        this.discoveryPasswordAlias = args[++i];
      } else if (args[i].equals("--discovery-type")) {
        if( i+1 >= args.length || args[i+1].startsWith( "-" ) ) {
          printKnoxShellUsage();
          return -1;
        }
        this.discoveryType = args[++i];
      } else if (args[i].equals("--master")) {
        // For testing only
        if( i+1 >= args.length || args[i+1].startsWith( "-" ) ) {
          printKnoxShellUsage();
          return -1;
        }
        this.master = args[++i];
      } else if (args[i].equals("--force")) {
        this.force = true;
      } else if (args[i].equals("--help")) {
        printKnoxShellUsage();
        return -1;
      } else if(args[i].equals("--d")) {
        this.debug = true;
      } else if(args[i].equals("--u")) {
        if(i + 1 <= args.length) {
          this.user = args[++i];
        } else{
          printKnoxShellUsage();
          return -1;
        }
      } else if(args[i].equals("--p")) {
        if(i + 1 <= args.length) {
          this.pass = args[++i];
        } else{
          printKnoxShellUsage();
          return -1;
        }
      } else if (args[i].equals("--g")) {
        this.groups = true;
      } else if (args[i].equals("list-registry-clients")) {
        command = new RemoteRegistryClientsListCommand();
      } else if (args[i].equals("--registry-client")) {
        if (i + 1 >= args.length || args[i + 1].startsWith("-")) {
          printKnoxShellUsage();
          return -1;
        }
        this.remoteRegistryClient = args[++i];
      } else if (args[i].equalsIgnoreCase("list-provider-configs")) {
        command = new RemoteRegistryListProviderConfigsCommand();
      } else if (args[i].equalsIgnoreCase("list-descriptors")) {
        command = new RemoteRegistryListDescriptorsCommand();
      } else if (args[i].equalsIgnoreCase("upload-provider-config")) {
        String fileName;
        if (i <= (args.length - 1)) {
          fileName = args[++i];
          command = new RemoteRegistryUploadProviderConfigCommand(fileName);
        } else {
          printKnoxShellUsage();
          return -1;
        }
      } else if (args[i].equals("upload-descriptor")) {
        String fileName;
        if (i <= (args.length - 1)) {
          fileName = args[++i];
          command = new RemoteRegistryUploadDescriptorCommand(fileName);
        } else {
          printKnoxShellUsage();
          return -1;
        }
      } else if (args[i].equals("--entry-name")) {
        if (i <= (args.length - 1)) {
          remoteRegistryEntryName = args[++i];
        } else {
          printKnoxShellUsage();
          return -1;
        }
      } else if (args[i].equals("delete-descriptor")) {
        if (i <= (args.length - 1)) {
          String entry = args[++i];
          command = new RemoteRegistryDeleteDescriptorCommand(entry);
        } else {
          printKnoxShellUsage();
          return -1;
        }
      } else if (args[i].equals("delete-provider-config")) {
        if (i <= (args.length - 1)) {
          String entry = args[++i];
          command = new RemoteRegistryDeleteProviderConfigCommand(entry);
        } else {
          printKnoxShellUsage();
          return -1;
        }
      } else if (args[i].equalsIgnoreCase("get-registry-acl")) {
        if (i <= (args.length - 1)) {
          String entry = args[++i];
          command = new RemoteRegistryGetACLCommand(entry);
        } else {
          printKnoxShellUsage();
          return -1;
        }
      } else if (args[i].equalsIgnoreCase("convert-topology")) {
        if (args.length >= 5) {
          command = new TopologyConverter();
        }
        else {
          printKnoxShellUsage();
          return -1;
        }
      } else {
        printKnoxShellUsage();
        return -1;
      }
    }
    return 0;
  }

  private void printKnoxShellUsage() {
    out.println( USAGE_PREFIX + "\n" + COMMANDS );
    if ( command != null ) {
      out.println(command.getUsage());
    } else {
      char[] chars = new char[79];
      Arrays.fill( chars, '=' );
      String div = new String( chars );

      out.println( div );
      out.println( VersionCommand.USAGE + "\n\n" + VersionCommand.DESC );
      out.println();
      out.println( div );
      out.println( MasterCreateCommand.USAGE + "\n\n" + MasterCreateCommand.DESC );
      out.println();
      out.println( div );
      out.println( CertCreateCommand.USAGE + "\n\n" + CertCreateCommand.DESC );
      out.println();
      out.println( div );
      out.println( CertExportCommand.USAGE + "\n\n" + CertExportCommand.DESC );
      out.println();
      out.println( div );
      out.println( AliasCreateCommand.USAGE + "\n\n" + AliasCreateCommand.DESC );
      out.println();
      out.println( div );
      out.println( AliasDeleteCommand.USAGE + "\n\n" + AliasDeleteCommand.DESC );
      out.println();
      out.println( div );
      out.println( AliasListCommand.USAGE + "\n\n" + AliasListCommand.DESC );
      out.println();
      out.println( div );
      out.println( RedeployCommand.USAGE + "\n\n" + RedeployCommand.DESC );
      out.println();
      out.println( div );
      out.println(ValidateTopologyCommand.USAGE + "\n\n" + ValidateTopologyCommand.DESC);
      out.println();
      out.println( div );
      out.println(ListTopologiesCommand.USAGE + "\n\n" + ListTopologiesCommand.DESC);
      out.println();
      out.println( div );
      out.println(LDAPAuthCommand.USAGE + "\n\n" + LDAPAuthCommand.DESC);
      out.println();
      out.println( div );
      out.println(LDAPSysBindCommand.USAGE + "\n\n" + LDAPSysBindCommand.DESC);
      out.println();
      out.println( div );
      out.println(ServiceTestCommand.USAGE + "\n\n" + ServiceTestCommand.DESC);
      out.println();
      out.println( div );
      out.println(RemoteRegistryClientsListCommand.USAGE + "\n\n" + RemoteRegistryClientsListCommand.DESC);
      out.println();
      out.println( div );
      out.println(RemoteRegistryGetACLCommand.USAGE + "\n\n" + RemoteRegistryGetACLCommand.DESC);
      out.println();
      out.println( div );
      out.println(RemoteRegistryListProviderConfigsCommand.USAGE + "\n\n" + RemoteRegistryListProviderConfigsCommand.DESC);
      out.println();
      out.println( div );
      out.println(RemoteRegistryListDescriptorsCommand.USAGE + "\n\n" + RemoteRegistryListDescriptorsCommand.DESC);
      out.println();
      out.println( div );
      out.println(RemoteRegistryUploadProviderConfigCommand.USAGE + "\n\n" + RemoteRegistryUploadProviderConfigCommand.DESC);
      out.println();
      out.println( div );
      out.println(RemoteRegistryUploadDescriptorCommand.USAGE + "\n\n" + RemoteRegistryUploadDescriptorCommand.DESC);
      out.println();
      out.println( div );
      out.println(RemoteRegistryDeleteProviderConfigCommand.USAGE + "\n\n" + RemoteRegistryDeleteProviderConfigCommand.DESC);
      out.println();
      out.println( div );
      out.println(RemoteRegistryDeleteDescriptorCommand.USAGE + "\n\n" + RemoteRegistryDeleteDescriptorCommand.DESC);
      out.println();
      out.println( div );
      out.println(TopologyConverter.USAGE + "\n\n" + TopologyConverter.DESC);
      out.println();
      out.println( div );
    }
  }

  private abstract class Command {

    public boolean validate() {
      return true;
    }

    protected Service getService(String serviceName) {

      return null;
    }

    public abstract void execute() throws Exception;

    public abstract String getUsage();

    protected AliasService getAliasService() {
      return services.getService(ServiceType.ALIAS_SERVICE);
    }

    protected KeystoreService getKeystoreService() {
      return services.getService(ServiceType.KEYSTORE_SERVICE);
    }

    protected TopologyService getTopologyService()  {
      return services.getService(ServiceType.TOPOLOGY_SERVICE);
    }

    protected RemoteConfigurationRegistryClientService getRemoteConfigRegistryClientService() {
      return services.getService(ServiceType.REMOTE_REGISTRY_CLIENT_SERVICE);
    }

  }

 private class AliasListCommand extends Command {

  public static final String USAGE = "list-alias [--cluster clustername]";
  public static final String DESC = "The list-alias command lists all of the aliases\n" +
                                    "for the given hadoop --cluster. The default\n" +
                                    "--cluster being the gateway itself.";

   @Override
   public void execute() throws Exception {
     AliasService as = getAliasService();
      KeystoreService keystoreService = getKeystoreService();

     if (cluster == null) {
       cluster = "__gateway";
     }
      boolean credentialStoreForClusterAvailable =
          keystoreService.isCredentialStoreForClusterAvailable(cluster);
      if (credentialStoreForClusterAvailable) {
        out.println("Listing aliases for: " + cluster);
        List<String> aliases = as.getAliasesForCluster(cluster);
        for (String alias : aliases) {
          out.println(alias);
        }
        out.println("\n" + aliases.size() + " items.");
      } else {
        out.println("Invalid cluster name provided: " + cluster);
      }
   }

   @Override
   public String getUsage() {
     return USAGE + ":\n\n" + DESC;
   }
 }

  public class CertExportCommand extends Command {

    public static final String USAGE = "export-cert [--type PEM|JKS|JCEKS|PKCS12]";
    public static final String DESC = "The export-cert command exports the public certificate\n" +
                                      "from the a gateway.jks keystore with the alias of gateway-identity.\n" +
                                      "It will be exported to `{GATEWAY_HOME}/data/security/keystores/` with a name of `gateway-client-trust.<type>`" +
                                      "Using the --type option you can specify which keystore type you need (default: PEM)\n" +
                                      "NOTE: The password for the JKS, JCEKS and PKCS12 types is `changeit`.\n" +
                                      "It can be changed using: `keytool -storepasswd -storetype <type> -keystore gateway-client-trust.<type>`";

    private GatewayConfig getGatewayConfig() {
      GatewayConfig result;
      Configuration conf = getConf();
      if (conf instanceof GatewayConfig) {
        result = (GatewayConfig) conf;
      } else {
        result = new GatewayConfigImpl();
      }
      return result;
    }

    @Override
    public void execute() throws Exception {
      KeystoreService ks = getKeystoreService();

      if (ks != null) {
        try {
          if (!ks.isKeystoreForGatewayAvailable()) {
            out.println("No keystore has been created for the gateway. Please use the create-cert command or populate with a CA signed cert of your own.");
          }

          GatewayConfig config = getGatewayConfig();
          Certificate cert = ks.getKeystoreForGateway().getCertificate(config.getIdentityKeyAlias());
          String keyStoreDir = config.getGatewayKeystoreDir() + File.separator;
          File ksd = new File(keyStoreDir);
          if (!ksd.exists()) {
            if (!ksd.mkdirs()) {
              // certainly should not happen if the keystore is known to be available
              throw new ServiceLifecycleException("Unable to create keystores directory" + ksd.getAbsolutePath());
            }
          }

          if ("PEM".equalsIgnoreCase(type) || type == null) {
            X509CertificateUtil.writeCertificateToFile(cert, new File(keyStoreDir + "gateway-identity.pem"));
            out.println("Certificate gateway-identity has been successfully exported to: " + keyStoreDir + "gateway-identity.pem");
          } else if ("JKS".equalsIgnoreCase(type)) {
            X509CertificateUtil.writeCertificateToJks(cert, new File(keyStoreDir + "gateway-client-trust.jks"));
            out.println("Certificate gateway-identity has been successfully exported to: " + keyStoreDir + "gateway-client-trust.jks");
          } else if ("JCEKS".equalsIgnoreCase(type)) {
            X509CertificateUtil.writeCertificateToJceks(cert, new File(keyStoreDir + "gateway-client-trust.jceks"));
            out.println("Certificate gateway-identity has been successfully exported to: " + keyStoreDir + "gateway-client-trust.jceks");
          } else if ("PKCS12".equalsIgnoreCase(type)) {
            X509CertificateUtil.writeCertificateToPkcs12(cert, new File(keyStoreDir + "gateway-client-trust.pkcs12"));
            out.println("Certificate gateway-identity has been successfully exported to: " + keyStoreDir + "gateway-client-trust.pkcs12");
          } else {
            out.println("Invalid type for export file provided. Export has not been done. Please use: [PEM|JKS|JCEKS|PKCS12] default value is PEM.");
          }
        } catch (KeystoreServiceException e) {
          throw new ServiceLifecycleException("The identity keystore was not loaded properly - the provided password may not match the password for the keystore.", e);
        }
      }
    }

    @Override
    public String getUsage() {
      return USAGE + ":\n\n" + DESC;
    }
  }

 public class CertCreateCommand extends Command {

  public static final String USAGE = "create-cert [--force] [--hostname h]";
  public static final String DESC = "The create-cert command populates the configured identity\n" +
                                    "keystore with a self-signed certificate to be used as the\n" +
                                    "gateway identity. If a cert exists and it is determined to\n" +
                                    "not have been generated by Knox, --force must be specified\n" +
                                    "to overwrite it.  If a self-signed cert is created, a\n" +
                                    "password for the key will be generated and stored in the\n" +
                                    "__gateway-credentials.jceks credential store.";
  private static final String GATEWAY_CREDENTIAL_STORE_NAME = "__gateway";

   public CertCreateCommand() {
   }

   @Override
   public void execute() throws Exception {
     KeystoreService ks = getKeystoreService();

     AliasService as = getAliasService();

     if (ks != null) {
       try {
         if (!ks.isCredentialStoreForClusterAvailable(GATEWAY_CREDENTIAL_STORE_NAME)) {
//           log.creatingCredentialStoreForGateway();
           ks.createCredentialStoreForCluster(GATEWAY_CREDENTIAL_STORE_NAME);
         } else {
//           log.credentialStoreForGatewayFoundNotCreating();
         }
         // LET'S NOT GENERATE A DIFFERENT KEY PASSPHRASE BY DEFAULT ANYMORE
         // IF A DEPLOYMENT WANTS TO CHANGE THE KEY PASSPHRASE TO MAKE IT MORE SECURE THEN
         // THEY CAN ADD THE ALIAS EXPLICITLY WITH THE CLI
         //as.generateAliasForCluster(GATEWAY_CREDENTIAL_STORE_NAME, GATEWAY_IDENTITY_PASSPHRASE);
       } catch (KeystoreServiceException e) {
         throw new ServiceLifecycleException("Keystore was not loaded properly - the stored password may not match the password for the keystore.", e);
       }

       try {
         if (!ks.isKeystoreForGatewayAvailable()) {
//           log.creatingKeyStoreForGateway();
           ks.createKeystoreForGateway();
         }
         else {
//           log.keyStoreForGatewayFoundNotCreating();
         }


         GatewayConfig config = getGatewayConfig();

         if ( !isForceRequired(config, ks) || force) {
           char[] passphrase = as.getGatewayIdentityPassphrase();
           if (passphrase == null) {
             MasterService ms = services.getService(ServiceType.MASTER_SERVICE);
             passphrase = ms.getMasterSecret();
           }
           ks.addSelfSignedCertForGateway(config.getIdentityKeyAlias(), passphrase, hostname);
//         logAndValidateCertificate();
           out.println("Certificate " + config.getIdentityKeyAlias() + " has been successfully created.");
         } else {
           // require --force to replace...
           out.println("A non-self-signed certificate has already been installed in the configured keystore. " +
               "Please use --force if you wish to overwrite it with a generated self-signed certificate.");
         }
       } catch (KeystoreServiceException e) {
         throw new ServiceLifecycleException("The identity keystore was not loaded properly - the provided password may not match the password for the keystore.", e);
       }
     }
   }

   /**
    * Determines if <code>--force</code> should be used inorder to not accidentally overwrite a
    * real certificate.
    * <p>
    * <p>
    * All of the following must be met for <code>--force</code> to <b>NOT</b> be required:
    * <ul>
    * <li>The path to the keystore file is the default path: <code>[Gateway Keystore Directory]/gateway.jks</code></li>
    * <li>The alias name for the key is the default name: <code>gateway-identity</code></li>
    * <li>The relevant certificate does not exist or is self-signed</li>
    * <li>The relevant certificate has a subject name ending in "OU=Test,O=Hadoop,L=Test,ST=Test,C=US"</li>
    * </ul>
    *
    * @param config the Gateway configuration
    * @param ks     a {@link KeystoreService} implementation
    * @return <code>true</code> if <code>--force</code> is required; otherwise <code>false</code>
    */
   private boolean isForceRequired(GatewayConfig config, KeystoreService ks) {

     // Test the path of the keystore file
     Path defaultKeystorePath = Paths.get(config.getGatewayKeystoreDir(), GatewayConfig.DEFAULT_GATEWAY_KEYSTORE_NAME).toAbsolutePath();
     Path actualKeystorePath = Paths.get(config.getIdentityKeystorePath()).toAbsolutePath();
     if (!defaultKeystorePath.equals(actualKeystorePath)) {
       // The path is not the default path: --force is required
       return true;
     }

     // Test the alias name for the key
     if (!GatewayConfig.DEFAULT_IDENTITY_KEY_ALIAS.equals(config.getIdentityKeyAlias())) {
       // The alias name for the key is not the default name (gateway-identity): --force is required
       return true;
     }

     // Test the certificate
     try {
       Certificate certificate = ks.getCertificateForGateway();

       if (certificate instanceof X509Certificate) {
         if (!X509CertificateUtil.isSelfSignedCertificate(certificate)) {
           // The relevant certificate exists and is not self-signed: --force is required
           return true;
         } else if (!((X509Certificate) certificate).getSubjectDN().getName().matches(".*?,\\s*OU=Test,\\s*O=Hadoop,\\s*L=Test,\\s*ST=Test,\\s*C=US")) {
           // The subject name of certificate does not end with "OU=Test,O=Hadoop,L=Test,ST=Test,C=US": --force is required
           return true;
         }
       }
     } catch (KeyStoreException | KeystoreServiceException e) {
       // A certificate was (probably) not previously created...
     }

     // All indicators point to a previously created test certificate: --force is not required
     return false;
   }

   @Override
   public String getUsage() {
     return USAGE + ":\n\n" + DESC;
   }

 }

 public class AliasCreateCommand extends Command {

  public static final String USAGE = "create-alias aliasname [--cluster clustername] " +
                                     "[ (--value v) | (--generate) ]";
  public static final String DESC = "The create-alias command will create an alias\n"
                                       + "and secret pair within the credential store for the\n"
                                       + "indicated --cluster otherwise within the gateway\n"
                                       + "credential store. The actual secret may be specified via\n"
                                       + "the --value option or --generate (will create a random secret\n"
                                       + "for you) or user will be prompt to provide password.";

  private String name;

   public AliasCreateCommand(String alias) {
     name = alias;
   }

   @Override
   public void execute() throws Exception {
     AliasService as = getAliasService();
     if (cluster == null) {
       cluster = "__gateway";
     }
     if (value != null) {
       as.addAliasForCluster(cluster, name, value);
       out.println(name + " has been successfully created.");
     }
     else {
       if (Boolean.parseBoolean(generate)) {
         as.generateAliasForCluster(cluster, name);
         out.println(name + " has been successfully generated.");
       }
       else {
          value = new String(promptUserForPassword());
          as.addAliasForCluster(cluster, name, value);
          out.println(name + " has been successfully created.");
       }
     }
   }

   @Override
   public String getUsage() {
     return USAGE + ":\n\n" + DESC;
   }

    protected char[] promptUserForPassword() {
      char[] password = null;
      Console c = System.console();
      if (c == null) {
        System.err
            .println("No console to fetch password from user.Consider setting via --generate or --value.");
        System.exit(1);
      }

      boolean noMatch;
      do {
        char[] newPassword1 = c.readPassword("Enter password: ");
        char[] newPassword2 = c.readPassword("Enter password again: ");
        noMatch = !Arrays.equals(newPassword1, newPassword2);
        if (noMatch) {
          c.format("Passwords don't match. Try again.%n");
        } else {
          password = Arrays.copyOf(newPassword1, newPassword1.length);
        }
        Arrays.fill(newPassword1, ' ');
        Arrays.fill(newPassword2, ' ');
      } while (noMatch);
      return password;
    }

 }

 public class AliasDeleteCommand extends Command {
  public static final String USAGE = "delete-alias aliasname [--cluster clustername]";
  public static final String DESC = "The delete-alias command removes the\n" +
                                    "indicated alias from the --cluster specific\n" +
                                    "credential store or the gateway credential store.";

  private String name;

   public AliasDeleteCommand(String alias) {
     name = alias;
   }

   @Override
   public void execute() throws Exception {
     AliasService as = getAliasService();
      KeystoreService keystoreService = getKeystoreService();
     if (as != null) {
       if (cluster == null) {
         cluster = "__gateway";
       }
        boolean credentialStoreForClusterAvailable =
            keystoreService.isCredentialStoreForClusterAvailable(cluster);
        if (credentialStoreForClusterAvailable) {
          List<String> aliasesForCluster = as.getAliasesForCluster(cluster);
          if (null == aliasesForCluster || !aliasesForCluster.contains(name)) {
            out.println("Deletion of Alias: " + name + " from cluster: " + cluster + " Failed. "
                + "\n" + "No such alias exists in the cluster.");
          } else {
            as.removeAliasForCluster(cluster, name);
            out.println(name + " has been successfully deleted.");
          }
        } else {
          out.println("Invalid cluster name provided: " + cluster);
        }
     }
   }

   @Override
   public String getUsage() {
     return USAGE + ":\n\n" + DESC;
   }

 }

 public class MasterCreateCommand extends Command {
  public static final String USAGE = "create-master [--force] [--master mastersecret] [--generate]";
  public static final String DESC = "The create-master command persists the master secret in a file located at:\n" +
                                    "{GATEWAY_HOME}/data/security/master.\n" +
                                    "It will prompt the user for the secret to persist.\n" +
                                    "Use --force to overwrite the master secret.\n" +
                                    "Use --master to pass in a master secret to persist.\n" +
                                    "This can be used to persist the secret without any user interaction.\n" +
                                    "Be careful as the secret might appear in shell histories or process listings.\n" +
                                    "Instead of --master it is usually a better idea to use --generate instead!\n" +
                                    "Use --generate to have Knox automatically generate a random secret.\n" +
                                    "The generated secret will not be printed or otherwise exposed.\n" +
                                    "Do not specify both --master and --generate at the same time.\n";

   public MasterCreateCommand() {
   }

   private GatewayConfig getGatewayConfig() {
     GatewayConfig result;
     Configuration conf = getConf();
     if( conf instanceof GatewayConfig ) {
       result = (GatewayConfig)conf;
     } else {
       result = new GatewayConfigImpl();
     }
     return result;
   }

   @Override
   public boolean validate() {
     boolean valid = true;
     GatewayConfig config = getGatewayConfig();
     File dir = new File( config.getGatewaySecurityDir() );
     File file = new File( dir, "master" );
     if( file.exists() ) {
       if( force ) {
         if( !file.canWrite() ) {
           out.println(
               "This command requires write permissions on the master secret file: " +
                   file.getAbsolutePath() );
           valid = false;
         } else {
           valid = file.delete();
           if( !valid ) {
             out.println(
                 "Unable to delete the master secret file: " +
                     file.getAbsolutePath() );
           }
         }
       } else {
         out.println(
             "Master secret is already present on disk. " +
                 "Please be aware that overwriting it will require updating other security artifacts. " +
                 " Use --force to overwrite the existing master secret." );
         valid = false;
       }
     } else if( dir.exists() && !dir.canWrite() ) {
       out.println(
           "This command requires write permissions on the security directory: " +
               dir.getAbsolutePath() );
       valid = false;
     }
     return valid;
   }

   @Override
   public void execute() throws Exception {
     out.println("Master secret has been persisted to disk.");
   }

   @Override
   public String getUsage() {
     return USAGE + ":\n\n" + DESC;
   }
 }

  private class VersionCommand extends Command {

    public static final String USAGE = "version";
    public static final String DESC = "Displays Knox version information.";

    @Override
    public void execute() throws Exception {
      Properties buildProperties = loadBuildProperties();
      System.out.println(
          String.format(Locale.ROOT,
              "Apache Knox: %s (%s)",
              buildProperties.getProperty( "build.version", "unknown" ),
              buildProperties.getProperty( "build.hash", "unknown" ) ) );
    }

    @Override
    public String getUsage() {
      return USAGE + ":\n\n" + DESC;
    }

  }

  private class RedeployCommand extends Command {

    public static final String USAGE = "redeploy [--cluster clustername]";
    public static final String DESC =
        "Redeploys one or all of the gateway's clusters (a.k.a topologies).";

    @Override
    public void execute() throws Exception {
      TopologyService ts = getTopologyService();
      ts.reloadTopologies();
      if (cluster != null) {
        if (validateClusterName(cluster, ts)) {
          ts.redeployTopologies(cluster);
        }
        else {
          out.println("Invalid cluster name provided. Nothing to redeploy.");
        }
      }
    }

    /**
     * @param cluster Cluster name to validate against the TopologyService
     * @param ts ToplogyService to validate the given cluster name
     */
    private boolean validateClusterName(String cluster, TopologyService ts) {
      boolean valid = false;
      for (Topology t : ts.getTopologies() ) {
        if (t.getName().equals(cluster)) {
          valid = true;
          break;
        }
      }
      return valid;
    }

    @Override
    public String getUsage() {
      return USAGE + ":\n\n" + DESC;
    }

  }

  private class ValidateTopologyCommand extends Command {

    public static final String USAGE = "validate-topology [--cluster clustername] | [--path \"path/to/file\"]";
    public static final String DESC = "Ensures that a cluster's description (a.k.a topology) \n" +
        "follows the correct formatting rules.\n" +
        "use the list-topologies command to get a list of available cluster names";
    private String file = "";

    @Override
    public String getUsage() {
      return USAGE + ":\n\n" + DESC;
    }

    @Override
    public void execute() throws Exception {
      GatewayConfig gc = getGatewayConfig();
      String topDir = gc.getGatewayTopologyDir();

      if(path != null) {
        file = path;
      } else if(cluster == null) {
        // The following block of code retreieves the list of files in the topologies directory
        File tops = new File(topDir + "/topologies");
        if(tops.isDirectory()) {
          out.println("List of files available in the topologies directory");
          for (File f : tops.listFiles()) {
            if(f.getName().endsWith(".xml")) {
              String fName = f.getName().replace(".xml", "");
              out.println(fName);
            }
          }
          return;
        } else {
          out.println("Could not locate topologies directory");
          return;
        }

      } else {
        file = topDir + "/" + cluster + ".xml";
      }

      // The following block checks a topology against the XSD
      out.println();
      out.println("File to be validated: ");
      out.println(file);
      out.println("==========================================");

      if(new File(file).exists()) {
        TopologyValidator tv = new TopologyValidator(file);

        if(tv.validateTopology()) {
          out.println("Topology file validated successfully");
        } else {
          out.println(tv.getErrorString()) ;
          out.println("Topology validation unsuccessful");
        }
      } else {
        out.println("The topology file specified does not exist.");
      }
    }

  }

  private class ListTopologiesCommand extends Command {

    public static final String USAGE = "list-topologies";
    public static final String DESC = "Retrieves a list of the available topologies within the\n" +
        "default topologies directory. Will return topologies that may not be deployed due\n" +
        "errors in file formatting.";

    @Override
    public String getUsage() {
      return USAGE + ":\n\n" + DESC;
    }

    @Override
    public void execute() {

      String confDir = getGatewayConfig().getGatewayConfDir();
      File tops = new File(confDir + "/topologies");
      out.println("List of files available in the topologies directory");
      out.println(tops.toString());
      if(tops.isDirectory()) {
        for (File f : tops.listFiles()) {
          if(f.getName().endsWith(".xml")) {
            String fName = f.getName().replace(".xml", "");
            out.println(fName);
          }
        }
        return;
      } else {
        out.println("ERR: Topologies directory does not exist.");
        return;
      }

    }

  }

  private class LDAPCommand extends Command {

    public static final String USAGE = "ldap-command";
    public static final String DESC = "This is an internal command. It should not be used.";
    protected String username;
    protected char[] password;
    protected static final String debugMessage = "For more information use --d for debug output.";
    protected Topology topology;

    @Override
    public String getUsage() {
      return USAGE + ":\n\n" + DESC;
    }

    @Override
    public void execute() {
      out.println("This command does not have any functionality.");
    }


//    First define a few Exceptions
    protected class NoSuchTopologyException extends Exception {
      public NoSuchTopologyException() {}
      public NoSuchTopologyException(String message) { super(message); }
    }
    protected class MissingPasswordException extends Exception {
      public MissingPasswordException() {}
      public MissingPasswordException(String message) { super(message); }
    }

    protected class MissingUsernameException extends Exception {
      public MissingUsernameException() {}

      public MissingUsernameException(String message) { super(message); }
    }

    protected class BadSubjectException extends Exception {
      public BadSubjectException() {}
      public BadSubjectException(String message) { super(message); }
    }

    protected class NoSuchProviderException extends Exception {
      public NoSuchProviderException() {}
      public NoSuchProviderException(String name, String role, String topology) {
        super("Could not find provider with role: " + role + ", name: " + name + " inside of topology: " + topology);
      }
    }

    //    returns false if any errors are printed
    protected boolean hasShiroProviderErrors(Topology topology, boolean groupLookup) {
//      First let's define the variables that represent the ShiroProvider params
      String mainLdapRealm = "main.ldapRealm";
      String contextFactory = mainLdapRealm + ".contextFactory";
      String groupContextFactory = "main.ldapGroupContextFactory";
      String authorizationEnabled = mainLdapRealm + ".authorizationEnabled";
      String userSearchAttributeName = mainLdapRealm + ".userSearchAttributeName";
      String userObjectClass = mainLdapRealm + ".userObjectClass";
      String searchBase = mainLdapRealm + ".searchBase";
      String groupSearchBase = mainLdapRealm + ".groupSearchBase";
      String userSearchBase = mainLdapRealm + ".userSearchBase";
      String groupObjectClass = mainLdapRealm + ".groupObjectClass";
      String memberAttribute = mainLdapRealm + ".memberAttribute";
      String memberAttributeValueTemplate = mainLdapRealm + ".memberAttributeValueTemplate";
      String systemUsername = contextFactory + ".systemUsername";
      String systemPassword = contextFactory + ".systemPassword";
      String url = contextFactory + ".url";
      String userDnTemplate = mainLdapRealm + ".userDnTemplate";


      Provider shiro = topology.getProvider("authentication", "ShiroProvider");
      if(shiro != null) {
        Map<String, String> params = shiro.getParams();
        int errs = 0;
        if(groupLookup) {
          int errors = 0;
          errors += hasParam(params, groupContextFactory, true) ? 0 : 1;
          errors += hasParam(params, groupObjectClass, true) ? 0 : 1;
          errors += hasParam(params, memberAttributeValueTemplate, true) ? 0 : 1;
          errors += hasParam(params, memberAttribute, true) ? 0 : 1;
          errors += hasParam(params, authorizationEnabled, true) ? 0 : 1;
          errors += hasParam(params, systemUsername, true) ? 0 : 1;
          errors += hasParam(params, systemPassword, true) ? 0 : 1;
          errors += hasParam(params, userSearchBase, true) ? 0 : 1;
          errors += hasParam(params, groupSearchBase, true) ? 0 : 1;
          errs += errors;

        } else {

//        Realm + Url is always required.
          errs += hasParam(params, mainLdapRealm, true) ? 0 : 1;
          errs += hasParam(params, url, true) ? 0 : 1;

          if(hasParam(params, authorizationEnabled, false)) {
            int errors = 0;
            int searchBaseErrors = 0;
            errors += hasParam(params, systemUsername, true) ? 0 : 1;
            errors += hasParam(params, systemPassword, true) ? 0 : 1;
            searchBaseErrors += hasParam(params, searchBase, false) ? 0 : hasParam(params, userSearchBase, false) ? 0 : 1;
            if (searchBaseErrors > 0) {
              out.println("Warn: Both " + searchBase + " and " + userSearchBase + " are missing from the topology");
            }
            errors += searchBaseErrors;
            errs += errors;
          }

//        If any one of these is present they must all be present
          if( hasParam(params, userSearchAttributeName, false) ||
              hasParam(params, userObjectClass, false) ||
              hasParam(params, searchBase, false) ||
              hasParam(params, userSearchBase, false)) {

            int errors = 0;
            errors += hasParam(params, userSearchAttributeName, true) ? 0 : 1;
            errors += hasParam(params, userObjectClass, true) ? 0 : 1;
            errors += hasParam(params, searchBase, false) ? 0 : hasParam(params, userSearchBase, false) ? 0 : 1;
            errors += hasParam(params, systemUsername, true) ? 0 : 1;
            errors += hasParam(params, systemPassword, true) ? 0 : 1;

            if(errors > 0) {
              out.println(userSearchAttributeName + " or " + userObjectClass + " or " + searchBase + " or " + userSearchBase + " was found in the topology");
              out.println("If any one of the above params is present then " + userSearchAttributeName +
                  " and " + userObjectClass + " must both be present and either " + searchBase + " or " + userSearchBase + " must also be present.");
            }
            errs += errors;
          } else {
            errs += hasParam(params, userDnTemplate, true) ?  0 : 1;

          }
        }
        return (errs > 0);
      } else {
        out.println("Could not obtain ShiroProvider");
        return true;
      }
    }

    // Checks to see if the param name is present. If not, notify the user
    protected boolean hasParam(Map<String, String> params, String key, boolean notifyUser){
      if(params.get(key) == null){
        if(notifyUser) { out.println("Warn: " + key + " is not present in topology"); }
        return false;
      } else { return true; }
    }

    /**
     *
     * @param ini - the path to the shiro.ini file within a topology deployment.
     * @param token - token for username and password
     * @return - true/false whether a user was successfully able to authenticate or not.
     */
    protected boolean authenticateUser(Ini ini, UsernamePasswordToken token){
      boolean result = false;
      try {
        Subject subject = getSubject(ini);
        try{
          subject.login(token);
          if(subject.isAuthenticated()){
            result = true;
          }
        } catch (AuthenticationException e){
          out.println(e.toString());
          out.println(e.getCause().getMessage());
          if (debug) {
            e.printStackTrace(out);
          } else {
            out.println(debugMessage);
          }
        } finally {
          subject.logout();
        }
      } catch (BadSubjectException e) {
        out.println(e.toString());
        if (debug){
          e.printStackTrace();
        } else {
          out.println(debugMessage);
        }
      } catch (ConfigurationException e) {
        out.println(e.toString());
      } catch ( Exception e ) {
        out.println(e.getCause());
        out.println(e.toString());
      }
      return result;
    }

    protected boolean authenticateUser(String config, UsernamePasswordToken token) throws ConfigurationException {
      Ini ini = new Ini();
      ini.loadFromPath(config);
      return authenticateUser(ini, token);
    }

    /**
     *
     * @param t - topology configuration to use
     * @param config - the path to the shiro.ini file from the topology deployment.
     * @return - true/false whether LDAP successfully authenticated with system credentials.
     */
    protected boolean testSysBind(Topology t, String config) {
      boolean result = false;
      String username;
      char[] password;

      try {
//        Pull out contextFactory.url param for light shiro config
        Provider shiro = t.getProvider("authentication", "ShiroProvider");
        Map<String, String> params = shiro.getParams();
        String url = params.get("main.ldapRealm.contextFactory.url");

//        Build the Ini with minimum requirements
        Ini ini = new Ini();
        ini.addSection("main");
        ini.setSectionProperty("main", "ldapRealm", "org.apache.knox.gateway.shirorealm.KnoxLdapRealm");
        ini.setSectionProperty("main", "ldapContextFactory", "org.apache.knox.gateway.shirorealm.KnoxLdapContextFactory");
        ini.setSectionProperty("main", "ldapRealm.contextFactory.url", url);

        username = getSystemUsername(t);
        password = getSystemPassword(t);
        result = authenticateUser(ini, new UsernamePasswordToken(username, password));
      } catch (MissingUsernameException | NoSuchProviderException | MissingPasswordException | NullPointerException e) {
        out.println(e.toString());
      }
      return result;
    }

    /**
     *
     * @param t - topology configuration to use
     * @return - the principal of the systemUsername specified in topology. null if non-existent
     */
    private String getSystemUsername(Topology t) throws MissingUsernameException, NoSuchProviderException {
      final String SYSTEM_USERNAME = "main.ldapRealm.contextFactory.systemUsername";
      String user;
      Provider shiroProvider = t.getProvider("authentication", "ShiroProvider");
      if(shiroProvider != null){
        Map<String, String> params = shiroProvider.getParams();
        user = params.get(SYSTEM_USERNAME);
      } else {
        throw new NoSuchProviderException("ShiroProvider", "authentication", t.getName());
      }
      return user;
    }

    /**
     *
     * @param t - topology configuration to use
     * @return - the systemPassword specified in topology. null if non-existent
     */
    private char[] getSystemPassword(Topology t) throws NoSuchProviderException, MissingPasswordException{
      final String SYSTEM_PASSWORD = "main.ldapRealm.contextFactory.systemPassword";
      String pass;
      Provider shiro = t.getProvider("authentication", "ShiroProvider");
      if(shiro != null){
        Map<String, String> params = shiro.getParams();
        pass = params.get(SYSTEM_PASSWORD);
      } else {
        throw new NoSuchProviderException("ShiroProvider", "authentication", t.getName());
      }

      if(pass != null) {
        return pass.toCharArray();
      } else {
        throw new MissingPasswordException("ShiroProvider did not contain param: " + SYSTEM_PASSWORD);
      }
    }

    /**
     *
     * @param config - the shiro.ini config file created in topology deployment.
     * @return returns the Subject given by the shiro config's settings.
     */
    protected Subject getSubject(Ini config) throws BadSubjectException {
      try {
        ThreadContext.unbindSubject();
        @SuppressWarnings("deprecation")
        Factory factory = new IniSecurityManagerFactory(config);
        org.apache.shiro.mgt.SecurityManager securityManager = (org.apache.shiro.mgt.SecurityManager) factory.getInstance();
        SecurityUtils.setSecurityManager(securityManager);
        Subject subject = SecurityUtils.getSubject();
        if( subject != null) {
          return subject;
        } else {
          out.println("Error Creating Subject from config at: " + config);
        }
      } catch (Exception e){
        out.println(e.toString());
      }
      throw new BadSubjectException("Subject could not be created with Shiro Config at " + config);
    }

    protected Subject getSubject(String config) throws ConfigurationException {
      Ini ini = new Ini();
      ini.loadFromPath(config);
      try {
        return getSubject(ini);
      } catch (BadSubjectException e) {
        throw new ConfigurationException("Could not get Subject with Ini at " + config);
      }
    }

    /**
     * prompts the user for credentials in the command line if necessary
     * populates the username and password members.
     */
    protected void promptCredentials() {
      if(this.username == null){
        Console c = System.console();
        if( c != null) {
          this.username = c.readLine("Username: ");
        } else {
          try(InputStreamReader inputStreamReader = new InputStreamReader(System.in, StandardCharsets.UTF_8);
              BufferedReader reader = new BufferedReader(inputStreamReader)) {
            out.println("Username: ");
            this.username = reader.readLine();
          } catch (IOException e){
            out.println(e.toString());
            this.username = "";
          }
        }
      }

      if(this.password == null){
        Console c = System.console();
        if( c != null) {
          this.password = c.readPassword("Password: ");
        }else{
          try(InputStreamReader inputStreamReader = new InputStreamReader(System.in, StandardCharsets.UTF_8);
              BufferedReader reader = new BufferedReader(inputStreamReader)) {
            out.println("Password: ");
            String pw = reader.readLine();
            if(pw != null){
              this.password = pw.toCharArray();
            } else {
              this.password = new char[0];
            }
          } catch (IOException e){
            out.println(e.toString());
            this.password = new char[0];
          }
        }
      }
    }

    /**
     *
     * @param topologyName - the name of the topology to retrieve
     * @return - Topology object with specified name. null if topology doesn't exist in TopologyService
     */
    protected Topology getTopology(String topologyName) throws NoSuchTopologyException {
      TopologyService ts = getTopologyService();
      ts.reloadTopologies();
      for (Topology t : ts.getTopologies()) {
        if(t.getName().equals(topologyName)) {
          return t;
        }
      }
      throw new  NoSuchTopologyException("Topology " + topologyName + " does not" +
          " exist in the topologies directory.");
    }

    /**
     *
     * @param t - Topology to use for config
     * @return - path of shiro.ini config file.
     */
    protected String getConfig(Topology t){
      File tmpDir = new File(System.getProperty("java.io.tmpdir"));
      DeploymentFactory.setGatewayServices(services);
      EnterpriseArchive archive = DeploymentFactory.createDeployment(getGatewayConfig(), t);
      File war = archive.as(ExplodedExporter.class).exportExploded(tmpDir, t.getName() + "_deploy.tmp");
      war.deleteOnExit();
      String config = war.getAbsolutePath() + "/%2F/WEB-INF/shiro.ini";
      try{
        FileUtils.forceDeleteOnExit(war);
      } catch (IOException e) {
        out.println(e.toString());
        war.deleteOnExit();
      }
      return config;
    }

    /**
     * populates username and password if they were passed as arguments, if not will prompt user for them.
     */
    void acquireCredentials(){
      if(user != null){
        this.username = user;
      }
      if(pass != null){
        this.password = pass.toCharArray();
      }
      promptCredentials();
    }

    /**
     *
     * @return - true or false if the topology was acquired from the topology service and populated in the topology
     * field.
     */
    protected boolean acquireTopology(){
      try {
        topology = getTopology(cluster);
      } catch (NoSuchTopologyException e) {
        out.println(e.toString());
        return false;
      }
      return true;
    }
  }

  private class LDAPAuthCommand extends LDAPCommand {

    public static final String USAGE = "user-auth-test [--cluster clustername] [--u username] [--p password] [--g]";
    public static final String DESC = "This command tests a cluster's configuration ability to\n " +
        "authenticate a user with a cluster's ShiroProvider settings.\n Use \"--g\" if you want to list the groups a" +
        " user is a member of. \nOptional: [--u username]: Provide a username argument to the command\n" +
        "Optional: [--p password]: Provide a password argument to the command.\n" +
        "If a username and password argument are not supplied, the terminal will prompt you for one.";

    private static final String  SUBJECT_USER_GROUPS = "subject.userGroups";
    private Set<String> groupSet = new HashSet<>();

    @Override
    public String getUsage() {
      return USAGE + ":\n\n" + DESC;
    }

    @Override
    public void execute() {
      if(!acquireTopology()){
        return;
      }
      acquireCredentials();

      if(topology.getProvider("authentication", "ShiroProvider") == null) {
        out.println("ERR: This tool currently only works with Shiro as the authentication provider.");
        out.println("Please update the topology to use \"ShiroProvider\" as the authentication provider.");
        return;
      }

      String config = getConfig(topology);

      if(new File(config).exists()) {
          if(authenticateUser(config, new UsernamePasswordToken(username, password))) {
            out.println("LDAP authentication successful!");
            if(groups) {
              if(testSysBind(topology, config)) {
                groupSet = getGroups(topology, new UsernamePasswordToken(username, password));
                if(groupSet == null || groupSet.isEmpty()) {
                  out.println(username + " does not belong to any groups");
                  if(groups) {
                    hasShiroProviderErrors(topology, true);
                    out.println("You were looking for this user's groups but this user does not belong to any.");
                    out.println("Your topology file may be incorrectly configured for group lookup.");
                  }
                } else {
                  for (Object o : groupSet.toArray()) {
                    out.println(username + " is a member of: " + o.toString());
                  }
                }
              }
            }
          } else {
            out.println("ERR: Unable to authenticate user: " + username);
          }
      } else {
        out.println("ERR: No shiro config file found.");
      }
    }

    private Set<String> getGroups(Topology t, UsernamePasswordToken token){
      Set<String> groups = null;
      try {
        Subject subject = getSubject(getConfig(t));
        if(!subject.isAuthenticated()) {
          subject.login(token);
        }
        subject.hasRole(""); //Populate subject groups
        groups = (Set) subject.getSession().getAttribute(SUBJECT_USER_GROUPS);
        subject.logout();
      } catch (AuthenticationException e) {
        out.println("Error retrieving groups");
        out.println(e.toString());
        if(debug) {
          e.printStackTrace();
        } else {
          out.println(debugMessage);
        }
      } catch (ConfigurationException e) {
        out.println(e.toString());
        if(debug){
          e.printStackTrace();
        }
      }
      return groups;
    }

  }

  public class LDAPSysBindCommand extends LDAPCommand {

    public static final String USAGE = "system-user-auth-test [--cluster clustername] [--d]";
    public static final String DESC = "This command tests a cluster configuration's ability to\n " +
        "authenticate a user with a cluster's ShiroProvider settings.";

    @Override
    public String getUsage() {
      return USAGE + ":\n\n" + DESC;
    }

    @Override
    public void execute() {

      if(!acquireTopology()) {
        return;
      }

      if(hasShiroProviderErrors(topology, false)) {
        out.println("Topology warnings present. SystemUser may not bind.");
      }

      if(testSysBind(topology, getConfig(topology))) {
        out.println("System LDAP Bind successful.");
      } else {
        out.println("Unable to successfully bind to LDAP server with topology credentials. Are your parameters correct?");
      }
    }
  }

  private GatewayConfig getGatewayConfig() {
    GatewayConfig result;
    Configuration conf = getConf();
    if(conf instanceof GatewayConfig) {
      result = (GatewayConfig) conf;
    } else {
      result = new GatewayConfigImpl();
    }
    return result;
  }

  public class ServiceTestCommand extends Command {
    public static final String USAGE = "service-test [--u username] [--p password] [--cluster clustername] [--hostname name] " +
        "[--port port]";
    public static final String DESC =
                        "This command requires a running instance of Knox to be present on the same machine.\n" +
                        "It will execute a test to make sure all services are accessible through the gateway URLs.\n" +
                        "Errors are reported and suggestions to resolve any problems are returned. JSON formatted.\n";

    private boolean ssl = true;
    private int attempts;

    @Override
    public String getUsage() { return USAGE + ":\n\n" + DESC; }

    @Override
    public void execute() {
      attempts++;
      CloseableHttpClient client;
      String http = "http://";
      String https = "https://";
      GatewayConfig conf = getGatewayConfig();
      String gatewayPort;
      String host;

      if(cluster == null) {
        printKnoxShellUsage();
        out.println("A --cluster argument is required.");
        return;
      }

      if(hostname != null) {
        host = hostname;
      } else {
        try {
          host = InetAddress.getLocalHost().getHostName();
        } catch (UnknownHostException e) {
          out.println(e.toString());
          out.println("Defaulting address to localhost. Use --hostname option to specify a different hostname");
          host = "localhost";
        }
      }

      if (port != null) {
        gatewayPort = port;
      } else if (conf.getGatewayPort() > -1) {
        gatewayPort = Integer.toString(conf.getGatewayPort());
      } else {
        out.println("Could not get port. Please supply it using the --port option");
        return;
      }


      String path = "/" + conf.getGatewayPath();
      String topology = "/" + cluster;
      String httpServiceTestURL = http + host + ":" + gatewayPort + path + topology + "/service-test";
      String httpsServiceTestURL = https + host + ":" + gatewayPort + path + topology + "/service-test";

      String authString = "";
//    Create Authorization String
      if( user != null && pass != null) {
        authString = "Basic " + Base64.encodeBase64String((user + ":" + pass).getBytes(StandardCharsets.UTF_8));
      } else {
        out.println("Username and/or password not supplied. Expect HTTP 401 Unauthorized responses.");
      }

//    Initialize the HTTP client
      client = HttpClients.createDefault();

      HttpGet request;
      if(ssl) {
        request = new HttpGet(httpsServiceTestURL);
      } else {
        request = new HttpGet(httpServiceTestURL);
      }

      request.setHeader("Authorization", authString);
      request.setHeader("Accept", MediaType.APPLICATION_JSON.getMediaType());
      try {
        out.println(request.toString());
        try(CloseableHttpResponse response = client.execute(request)) {

          switch (response.getStatusLine().getStatusCode()) {

          case 200:
            response.getEntity().writeTo(out);
            break;
          case 404:
            out.println("Could not find service-test resource");
            out.println("Make sure you have configured the SERVICE-TEST service in your topology.");
            break;
          case 500:
            out.println("HTTP 500 Server error");
            break;

          default:
            out.println("Unexpected HTTP response code.");
            out.println(response.getStatusLine().toString());
            response.getEntity().writeTo(out);
            break;
          }
        }
        request.releaseConnection();
      } catch (ClientProtocolException e) {
        out.println(e.toString());
        if (debug) {
          e.printStackTrace(out);
        }
      } catch (SSLException e) {
        out.println(e.toString());
        retryRequest();
      } catch (IOException e) {
        out.println(e.toString());
        retryRequest();
        if(debug) {
          e.printStackTrace(out);
        }
      } finally {
        try {
          client.close();
        } catch (IOException e) {
          out.println(e.toString());
        }
      }
    }

    public void retryRequest(){
      if(attempts < 2) {
        if(ssl) {
          ssl = false;
          out.println("Attempting request without SSL.");
        } else {
          ssl = true;
          out.println("Attempting request with SSL ");
        }
        execute();
      } else {
        out.println("Unable to successfully make request. Try using the API with cURL.");
      }
    }

  }

  public class RemoteRegistryClientsListCommand extends Command {

    static final String USAGE = "list-registry-clients";
    static final String DESC = "Lists all of the remote configuration registry clients defined in gateway-site.xml.\n";

    @Override
    public void execute() throws Exception {
      GatewayConfig config = getGatewayConfig();
      List<String> remoteConfigRegistryClientNames = config.getRemoteRegistryConfigurationNames();
      if (!remoteConfigRegistryClientNames.isEmpty()) {
        out.println("Listing remote configuration registry clients:");
        for (String name : remoteConfigRegistryClientNames) {
          out.println(name);
        }
      }
    }

    @Override
    public String getUsage() {
      return USAGE + ":\n\n" + DESC;
    }
 }

  private abstract class RemoteRegistryCommand extends Command {
    static final String ROOT_ENTRY = "/knox";
    static final String CONFIG_ENTRY = ROOT_ENTRY + "/config";
    static final String PROVIDER_CONFIG_ENTRY = CONFIG_ENTRY + "/shared-providers";
    static final String DESCRIPTORS_ENTRY = CONFIG_ENTRY + "/descriptors";

    protected RemoteConfigurationRegistryClient getClient() {
      RemoteConfigurationRegistryClient client = null;
      if (remoteRegistryClient != null) {
        RemoteConfigurationRegistryClientService cs = getRemoteConfigRegistryClientService();
        client = cs.get(remoteRegistryClient);
        if (client == null) {
          out.println("No remote configuration registry identified by '" + remoteRegistryClient + "' could be found.");
        }
      } else {
        out.println("Missing required argument : --registry-client\n");
      }
      return client;
    }
  }


  public class RemoteRegistryListProviderConfigsCommand extends RemoteRegistryCommand {
    static final String USAGE = "list-provider-configs --registry-client name";
    static final String DESC = "Lists the provider configurations present in the specified remote registry\n";

    @Override
    public void execute() {
      RemoteConfigurationRegistryClient client = getClient();
      if (client != null) {
        out.println("Provider Configurations (@" + client.getAddress() + ")");
        List<String> entries = client.listChildEntries(PROVIDER_CONFIG_ENTRY);
        if (entries != null) {
          for (String entry : entries) {
            out.println(entry);
          }
        }
        out.println();
      }
    }

    @Override
    public String getUsage() {
      return USAGE + ":\n\n" + DESC;
    }
  }


  public class RemoteRegistryListDescriptorsCommand extends RemoteRegistryCommand {
    static final String USAGE = "list-descriptors --registry-client name";
    static final String DESC = "Lists the descriptors present in the specified remote registry\n";

    @Override
    public void execute() {
      RemoteConfigurationRegistryClient client = getClient();
      if (client != null) {
        out.println("Descriptors (@" + client.getAddress() + ")");
        List<String> entries = client.listChildEntries(DESCRIPTORS_ENTRY);
        if (entries != null) {
          for (String entry : entries) {
            out.println(entry);
          }
        }
        out.println();
      }
    }

    @Override
    public String getUsage() {
      return USAGE + ":\n\n" + DESC;
    }
  }


  /**
   * Base class for remote config registry upload commands
   */
  public abstract class RemoteRegistryUploadCommand extends RemoteRegistryCommand {
    private File sourceFile;
    protected String filename;

    protected RemoteRegistryUploadCommand(String sourceFileName) {
      this.filename = sourceFileName;
    }

    private void upload(RemoteConfigurationRegistryClient client, String entryPath, File source) throws Exception {
      String content = FileUtils.readFileToString(source, StandardCharsets.UTF_8);
      if (client.entryExists(entryPath)) {
        // If it exists, then we're going to set the data
        client.setEntryData(entryPath, content);
      } else {
        // If it does not exist, then create it and set the data
        client.createEntry(entryPath, content);
      }
    }

    File getSourceFile() {
      if (sourceFile == null) {
        sourceFile = new File(filename);
      }
      return sourceFile;
    }

    String getEntryName(String prefixPath) {
      String entryName = remoteRegistryEntryName;
      if (entryName == null) {
        File sourceFile = getSourceFile();
        if (sourceFile.exists()) {
          String path = sourceFile.getAbsolutePath();
          entryName = path.substring(path.lastIndexOf(File.separator) + 1);
        } else {
          out.println("Could not locate source file: " + filename);
        }
      }
      return prefixPath + "/" + entryName;
    }

    protected void execute(String entryName, File sourceFile) throws Exception {
      RemoteConfigurationRegistryClient client = getClient();
      if (client != null) {
        if (entryName != null) {
          upload(client, entryName, sourceFile);
        }
      }
    }
  }

  public class RemoteRegistryUploadProviderConfigCommand extends RemoteRegistryUploadCommand {

    static final String USAGE = "upload-provider-config providerConfigFile --registry-client name [--entry-name entryName]";
    static final String DESC = "Uploads a provider configuration to the specified remote registry client, optionally " +
                               "renaming the entry.\nIf the entry name is not specified, the name of the uploaded " +
                               "file is used.\n";

    RemoteRegistryUploadProviderConfigCommand(String fileName) {
      super(fileName);
    }

    @Override
    public void execute() throws Exception {
      super.execute(getEntryName(PROVIDER_CONFIG_ENTRY), getSourceFile());
    }

    @Override
    public String getUsage() {
      return USAGE + ":\n\n" + DESC;
    }
  }


  public class RemoteRegistryUploadDescriptorCommand extends RemoteRegistryUploadCommand {

    static final String USAGE = "upload-descriptor descriptorFile --registry-client name [--entry-name entryName]";
    static final String DESC = "Uploads a simple descriptor using the specified remote registry client, optionally " +
                               "renaming the entry.\nIf the entry name is not specified, the name of the uploaded " +
                               "file is used.\n";

    RemoteRegistryUploadDescriptorCommand(String fileName) {
      super(fileName);
    }

    @Override
    public void execute() throws Exception {
      super.execute(getEntryName(DESCRIPTORS_ENTRY), getSourceFile());
    }

    @Override
    public String getUsage() {
      return USAGE + ":\n\n" + DESC;
    }
  }


  public class RemoteRegistryGetACLCommand extends RemoteRegistryCommand {

    static final String USAGE = "get-registry-acl entry --registry-client name";
    static final String DESC = "Presents the ACL settings for the specified remote registry entry.\n";

    private String entry;

    RemoteRegistryGetACLCommand(String entry) {
      this.entry = entry;
    }

    @Override
    public void execute() throws Exception {
      RemoteConfigurationRegistryClient client = getClient();
      if (client != null) {
        if (entry != null) {
          List<RemoteConfigurationRegistryClient.EntryACL> acls = client.getACL(entry);
          for (RemoteConfigurationRegistryClient.EntryACL acl : acls) {
            out.println(acl.getType() + ":" + acl.getId() + ":" + acl.getPermissions());
          }
        }
      }
    }

    @Override
    public String getUsage() {
      return USAGE + ":\n\n" + DESC;
    }
  }


  /**
   * Base class for remote config registry delete commands
   */
  public abstract class RemoteRegistryDeleteCommand extends RemoteRegistryCommand {
    protected String entryName;

    protected RemoteRegistryDeleteCommand(String entryName) {
      this.entryName = entryName;
    }

    private void delete(RemoteConfigurationRegistryClient client, String entryPath) throws Exception {
      if (client.entryExists(entryPath)) {
        // If it exists, then delete it
        client.deleteEntry(entryPath);
      }
    }

    protected void execute(String entryName) throws Exception {
      RemoteConfigurationRegistryClient client = getClient();
      if (client != null) {
        if (entryName != null) {
          delete(client, entryName);
        }
      }
    }
  }


  public class RemoteRegistryDeleteProviderConfigCommand extends RemoteRegistryDeleteCommand {
    static final String USAGE = "delete-provider-config providerConfig --registry-client name";
    static final String DESC = "Deletes a shared provider configuration from the specified remote registry.\n";

    public RemoteRegistryDeleteProviderConfigCommand(String entryName) {
      super(entryName);
    }

    @Override
    public void execute() throws Exception {
      execute(PROVIDER_CONFIG_ENTRY + "/" + entryName);
    }

    @Override
    public String getUsage() {
      return USAGE + ":\n\n" + DESC;
    }
  }


  public class RemoteRegistryDeleteDescriptorCommand extends RemoteRegistryDeleteCommand {
    static final String USAGE = "delete-descriptor descriptor --registry-client name";
    static final String DESC = "Deletes a simple descriptor from the specified remote registry.\n";

    public RemoteRegistryDeleteDescriptorCommand(String entryName) {
      super(entryName);
    }

    @Override
    public void execute() throws Exception {
      execute(DESCRIPTORS_ENTRY + "/" + entryName);
    }

    @Override
    public String getUsage() {
      return USAGE + ":\n\n" + DESC;
    }
  }

  public class TopologyConverter extends Command {

    public static final String USAGE =
        "convert-topology --path \"path/to/topology.xml\" --provider-name my-provider.json [--descriptor-name my-descriptor.json] "
            + "[--topology-name topologyName] [--output-path \"path/to/configs/\"] [--force] [--cluster clusterName] [--discovery-url url] "
            + "[--discovery-user discoveryUser] [--discovery-pwd-alias discoveryPasswordAlias] [--discovery-type discoveryType]";
    public static final String DESC =
        "Convert Knox topology file to provider and descriptor config files \n"
            + "Options are as follows: \n"
            + "--path (required) path to topology xml file \n"
            + "--provider-name (required) name of the provider json config file (including .json extension) \n"
            + "--descriptor-name (optional) name of descriptor json config file (including .json extension) \n"
            + "--topology-name (optional) topology-name can be use instead of --path option, if used, KnoxCLI will attempt to find topology from deployed topologies.\n"
            + "\t if not provided topology name will be used as descriptor name \n"
            + "--output-path (optional) output directory to save provider and descriptor config files \n"
            + "\t if not provided config files will be saved in appropriate Knox config directory \n"
            + "--force (optional) force rewriting of existing files, if not used, command will fail when the configs files with same name already exist. \n"
            + "--cluster (optional) cluster name, required for service discovery \n"
            + "--discovery-url (optional) service discovery URL, required for service discovery \n"
            + "--discovery-user (optional) service discovery user, required for service discovery \n"
            + "--discovery-pwd-alias (optional) password alias for service discovery user, required for service discovery \n"
            + "--discovery-type (optional) service discovery type, required for service discovery \n";

    public TopologyConverter() {
      super();
    }

    @Override
    public void execute() throws Exception {
      if (StringUtils.isBlank(FilenameUtils.getExtension(providerName))
          || StringUtils.isBlank(FilenameUtils.getExtension(descriptorName))) {
        throw new IllegalArgumentException(
            " JSON extension is required for provider and descriptor file names");
      }

      final TopologyToDescriptor converter = new TopologyToDescriptor();

      converter.setForce(force);
      if (!StringUtils.isBlank(topologyName)) {
        converter.setTopologyPath(
            getGatewayConfig().getGatewayTopologyDir() + File.separator
                + topologyName);
      } else if (!StringUtils.isBlank(path)) {
        converter.setTopologyPath(path);
      } else {
        throw new IllegalArgumentException(
            "Please specify either --path or --topology-name option");
      }
      if (!StringUtils.isBlank(providerName)) {
        converter.setProviderName(providerName);
      }
      if (!StringUtils.isBlank(descriptorName)) {
        converter.setDescriptorName(descriptorName);
      }
      /* if output location is provided then use it */
      if (!StringUtils.isBlank(outputDir)) {
        converter.setProviderConfigDir(outputDir);
        converter.setDescriptorConfigDir(outputDir);
      } else {
        converter.setProviderConfigDir(
            getGatewayConfig().getGatewayProvidersConfigDir());
        converter.setDescriptorConfigDir(
            getGatewayConfig().getGatewayDescriptorsDir());
      }
      /* set discovery params */
      if (!StringUtils.isBlank(cluster)) {
        converter.setCluster(cluster);
      }
      if (!StringUtils.isBlank(discoveryUrl)) {
        converter.setDiscoveryUrl(discoveryUrl);
      }
      if (!StringUtils.isBlank(discoveryUser)) {
        converter.setDiscoveryUser(discoveryUser);
      }
      if (!StringUtils.isBlank(discoveryPasswordAlias)) {
        converter.setDiscoveryPasswordAlias(discoveryPasswordAlias);
      }
      if (!StringUtils.isBlank(discoveryType)) {
        converter.setDiscoveryType(discoveryType);
      }

      converter.validate();
      converter.convert();

      final String topoName = StringUtils.isBlank(topologyName) ?  FilenameUtils.getBaseName(path) : topologyName;
      out.println(
          "Provider " + providerName + " and descriptor " + descriptorName
              + " generated for topology " + topoName
              + "\n");
    }

    @Override
    public String getUsage() {
      return USAGE + ":\n\n" + DESC;
    }

  }

  private static Properties loadBuildProperties() {
    Properties properties = new Properties();
    try(InputStream inputStream = KnoxCLI.class.getClassLoader().getResourceAsStream( "build.properties" )) {
      properties.load(inputStream);
    } catch( IOException e ) {
      // Ignore.
    }
    return properties;
  }

  public static void main(String[] args) throws Exception {
    PropertyConfigurator.configure( System.getProperty( "log4j.configuration" ) );
    int res = ToolRunner.run(new GatewayConfigImpl(), new KnoxCLI(), args);
    System.exit(res);
  }

  private static void configureKerberosSecurity( GatewayConfig config ) {
    System.setProperty(GatewayConfig.HADOOP_KERBEROS_SECURED, "true");
    System.setProperty(GatewayConfig.KRB5_CONFIG, config.getKerberosConfig());
    System.setProperty(GatewayConfig.KRB5_DEBUG, Boolean.toString(config.isKerberosDebugEnabled()));
    System.setProperty(GatewayConfig.KRB5_LOGIN_CONFIG, config.getKerberosLoginConfig());
    System.setProperty(GatewayConfig.KRB5_USE_SUBJECT_CREDS_ONLY,  "false");
  }
}
