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

org.apache.stratos.cli.StratosApplication Maven / Gradle / Ivy

The newest version!
/**
 * 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.stratos.cli; import org.apache.commons.cli.*; import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.text.StrTokenizer; import org.apache.commons.validator.routines.UrlValidator; import org.apache.log4j.Level; import org.apache.log4j.LogManager; import org.apache.stratos.cli.commands.*; import org.apache.stratos.cli.completer.CommandCompleter; import org.apache.stratos.cli.exception.CommandException; import org.apache.stratos.cli.utils.CliConstants; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import java.io.File; import java.io.PrintWriter; import java.util.Arrays; import java.util.Collection; import java.util.Map; import java.util.TreeMap; import static org.apache.stratos.cli.utils.CliConstants.STRATOS_DIR; import static org.apache.stratos.cli.utils.CliConstants.STRATOS_HISTORY_DIR; public class StratosApplication extends CommandLineApplication { private static final Logger logger = LoggerFactory.getLogger(StratosApplication.class); private final Map> commands; private final StratosCommandContext context; private final Options options; public StratosApplication(String[] args) { super(args); commands = new TreeMap>(); context = new StratosCommandContext(this); options = constructOptions(); createCommands(); } /** * Construct Options. * * @return Options expected from command-line. */ private Options constructOptions() { final Options options = new Options(); Option usernameOption = new Option(CliConstants.USERNAME_OPTION, CliConstants.USERNAME_LONG_OPTION, true, "Username"); usernameOption.setArgName("username"); options.addOption(usernameOption); Option passwordOption = new Option(CliConstants.PASSWORD_OPTION, CliConstants.PASSWORD_LONG_OPTION, true, "Password"); passwordOption.setArgName("password"); passwordOption.setOptionalArg(true); options.addOption(passwordOption); options.addOption(CliConstants.HELP_OPTION, CliConstants.HELP_LONG_OPTION, false, "Display this help"); options.addOption(CliConstants.TRACE_OPTION, false, "Enable trace logging"); options.addOption(CliConstants.DEBUG_OPTION, false, "Enable debug logging"); return options; } private void createCommands() { Command command = new HelpCommand(); commands.put(command.getName(), command); command = new ExitCommand(); commands.put(command.getName(), command); command = new ListCartridgesCommand(); commands.put(command.getName(), command); command = new AddTenantCommand(); commands.put(command.getName(), command); command = new AddUserCommand(); commands.put(command.getName(), command); command = new DeleteUserCommand(); commands.put(command.getName(), command); command = new ListUsers(); commands.put(command.getName(), command); command = new ListTenants(); commands.put(command.getName(), command); command = new DeactivateTenantCommand(); commands.put(command.getName(), command); command = new ActivateTenantCommand(); commands.put(command.getName(), command); command = new AddCartridgeCommand(); commands.put(command.getName(), command); command = new UpdateCartridgeCommand(); commands.put(command.getName(), command); command = new AddAutoscalingPolicyCommand(); commands.put(command.getName(), command); command = new CreateApplicationCommand(); commands.put(command.getName(), command); command = new ListApplicationsCommand(); commands.put(command.getName(), command); command = new RemoveCartridgeCommand(); commands.put(command.getName(), command); command = new ListAutoscalePolicyCommand(); commands.put(command.getName(), command); command = new DescribeCartridgeCommand(); commands.put(command.getName(), command); command = new DescribeDeploymentPolicyCommand(); commands.put(command.getName(), command); command = new DescribeAutoScalingPolicyCommand(); commands.put(command.getName(), command); command = new SynchronizeArtifactsCommand(); commands.put(command.getName(), command); command = new AddKubernetesClusterCommand(); commands.put(command.getName(), command); command = new ListKubernetesClustersCommand(); commands.put(command.getName(), command); command = new ListKubernetesHostsCommand(); commands.put(command.getName(), command); command = new AddKubernetesHostCommand(); commands.put(command.getName(), command); command = new RemoveKubernetesClusterCommand(); commands.put(command.getName(), command); command = new RemoveKubernetesHostCommand(); commands.put(command.getName(), command); command = new UpdateKubernetesMasterCommand(); commands.put(command.getName(), command); command = new UpdateKubernetesHostCommand(); commands.put(command.getName(), command); command = new AddCartridgeGroupCommand(); commands.put(command.getName(), command); command = new DescribeCartridgeGroupCommand(); commands.put(command.getName(), command); command = new ListCartridgeGroupsCommand(); commands.put(command.getName(), command); command = new RemoveCartridgeGroupCommand(); commands.put(command.getName(), command); command = new DeployApplicationCommand(); commands.put(command.getName(), command); command = new UndeployApplicationCommand(); commands.put(command.getName(), command); command = new DescribeApplicationCommand(); commands.put(command.getName(), command); command = new AddDomainMappingsCommand(); commands.put(command.getName(), command); command = new ListDomainMappingsCommand(); commands.put(command.getName(), command); command = new RemoveDomainMappingCommand(); commands.put(command.getName(), command); command = new DeleteAutoScalingPolicyCommand(); commands.put(command.getName(), command); command = new AddNetworkPartitionCommand(); commands.put(command.getName(), command); command = new RemoveNetworkPartitionCommand(); commands.put(command.getName(), command); command = new ListNetworkPartitionCommand(); commands.put(command.getName(), command); command = new UpdateNetworkPartitionCommand(); commands.put(command.getName(), command); command = new UpdateAutoscalingPolicyCommand(); commands.put(command.getName(), command); command = new AddApplicationSignupCommand(); commands.put(command.getName(), command); command = new DescribeTenantCommand(); commands.put(command.getName(), command); command = new DescribeApplicationSignupCommand(); commands.put(command.getName(), command); command = new DeleteApplicationSignupCommand(); commands.put(command.getName(), command); command = new AddDeploymentPolicyCommand(); commands.put(command.getName(), command); command = new UpdateDeploymentPolicyCommand(); commands.put(command.getName(), command); command = new RemoveDeploymentPolicyCommand(); commands.put(command.getName(), command); command = new DescribeNetworkPartitionCommand(); commands.put(command.getName(), command); command = new ListDeploymentPoliciesCommand(); commands.put(command.getName(), command); command = new DescribeDeploymentPolicyCommand(); commands.put(command.getName(), command); command = new DescribeKubernetesMasterCommand(); commands.put(command.getName(), command); command = new DescribeKubernetesClusterCommand(); commands.put(command.getName(), command); command = new DeleteApplicationCommand(); commands.put(command.getName(), command); command = new DescribeApplicationRuntimeCommand(); commands.put(command.getName(), command); command = new UpdateUserCommand(); commands.put(command.getName(), command); command = new UpdateTenantCommand(); commands.put(command.getName(), command); command = new DescribeApplicationSignupCommand(); commands.put(command.getName(), command); command = new DeleteApplicationSignupCommand(); commands.put(command.getName(), command); command = new AddApplicationPolicyCommand(); commands.put(command.getName(), command); command = new ListApplicationPoliciesCommand(); commands.put(command.getName(), command); command = new DescribeApplicationPolicyCommand(); commands.put(command.getName(), command); command = new RemoveApplicationPolicyCommand(); commands.put(command.getName(), command); command = new UpdateApplicationPolicyCommand(); commands.put(command.getName(), command); command = new UpdateApplicationCommand(); commands.put(command.getName(), command); if (logger.isDebugEnabled()) { logger.debug("Created {} commands for the application. {}", commands.size(), commands.keySet()); } } private void createAutocomplete() { reader.addCompleter(new CommandCompleter(commands)); } @Override protected String getPrompt() { return CliConstants.STRATOS_SHELL_PROMPT; } @Override protected File getHistoryFile(String username) { File stratosFile = new File(System.getProperty("user.home"), STRATOS_DIR); File historyFile = new File(stratosFile, STRATOS_HISTORY_DIR + "_" + username); return historyFile; } @Override public int run(String[] args) { boolean loaded = loadRequiredProperties(); if (!loaded) { return CliConstants.ERROR_CODE; } // To get the command action from arguments String[] remainingArgs = null; // Command action String action = null; // Command action options Option[] actionOptions = null; String usernameInput = null; String passwordInput = null; if (args != null && args.length > 0) { // Arguments are passed. if (logger.isDebugEnabled()) { logger.debug("Arguments:"); for (String arg : args) { logger.debug(arg); } } final CommandLineParser parser = new GnuParser(); CommandLine commandLine; try { // Must add all options. Otherwise actions cannot be performed directly by command line. // This is because the parser trips over unrecognised options. Options allCommandOptions = new Options(); for (Command command : commands.values()) { Options commandOptions = command.getOptions(); if (commandOptions != null) { Collection allOptions = commandOptions.getOptions(); for (Object o : allOptions) { allCommandOptions.addOption((Option) o); } } } // Add options in this application Collection allOptions = options.getOptions(); for (Object o : allOptions) { allCommandOptions.addOption((Option) o); } commandLine = parser.parse(options, args, true); remainingArgs = commandLine.getArgs(); actionOptions = commandLine.getOptions(); if (remainingArgs != null && remainingArgs.length > 0) { // Get command action action = remainingArgs[0]; } // Set logger levels from this point onwards setLoggerLevel(commandLine.hasOption(CliConstants.TRACE_OPTION), commandLine.hasOption(CliConstants.DEBUG_OPTION)); if (commandLine.hasOption(CliConstants.USERNAME_OPTION)) { if (logger.isTraceEnabled()) { logger.trace("Username option is passed"); } usernameInput = commandLine.getOptionValue(CliConstants.USERNAME_OPTION); } if (commandLine.hasOption(CliConstants.PASSWORD_OPTION)) { if (logger.isTraceEnabled()) { logger.trace("Password option is passed"); } passwordInput = commandLine.getOptionValue(CliConstants.PASSWORD_OPTION); } if (commandLine.hasOption(CliConstants.HELP_ACTION)) { printHelp(); return CliConstants.COMMAND_SUCCESSFULL; } } catch (ParseException e) { if (logger.isErrorEnabled()) { logger.error("Error parsing arguments when trying to login", e); } System.out.println(e.getMessage()); return CliConstants.COMMAND_FAILED; } } if (StringUtils.isNotBlank(action)) { // User is executing an action if (logger.isDebugEnabled()) { logger.debug("Action: {}", action); } Command command = commands.get(action); if (command == null) { printHelp(); return CliConstants.COMMAND_FAILED; } boolean loginRequired = !CliConstants.HELP_ACTION.equals(action); if (loginRequired && logger.isDebugEnabled()) { logger.debug("Trying to login..."); } if (loginRequired && !login(usernameInput, passwordInput, false)) { if (logger.isDebugEnabled()) { logger.debug("Exiting from CLI. Login required but login might have failed: {}", action); } // Exit return CliConstants.ERROR_CODE; } try { String[] actionArgs = Arrays.copyOfRange(remainingArgs, 1, remainingArgs.length); if (logger.isDebugEnabled()) { logger.debug("Executing Action: {} {}", action, Arrays.asList(actionArgs)); } int returnCode = command.execute(context, actionArgs, actionOptions); if (logger.isDebugEnabled()) { logger.debug("Exiting with error code {} after executing action {}", returnCode, action); } System.exit(returnCode); } catch (CommandException e) { if (logger.isErrorEnabled()) { logger.error("Error executing command: " + action, e); } return CliConstants.ERROR_CODE; } } else { if (login(usernameInput, passwordInput, true)) { System.out.println("Successfully authenticated"); } else { // Exit return CliConstants.ERROR_CODE; } promptLoop(); } return CliConstants.COMMAND_SUCCESSFULL; } private boolean login(String usernameInput, String passwordInput, boolean validateLogin) { // TODO Previous CLI version uses a keystore. Here we are not using it. // Check whether user has passed username and password if (StringUtils.isBlank(usernameInput) && StringUtils.isBlank(passwordInput)) { // User has not passed any arguments. // Try authenticating from the values found usernameInput = context.getString(CliConstants.STRATOS_USERNAME_ENV_PROPERTY); passwordInput = context.getString(CliConstants.STRATOS_PASSWORD_ENV_PROPERTY); if (logger.isDebugEnabled()) { if (StringUtils.isNotBlank(usernameInput) && StringUtils.isNotBlank(passwordInput)) { logger.debug("Found authentication details for {} from context", usernameInput); } } } // Get user input if not passed as args if (StringUtils.isBlank(usernameInput)) { usernameInput = getInput("Username"); } if (StringUtils.isBlank(passwordInput)) { passwordInput = getInput("Password", '*'); } boolean success = false; String stratosURL = null; stratosURL = context.getString(CliConstants.STRATOS_URL_ENV_PROPERTY); // This is to create the history file. // This section execute only when user didn't enter the username as command line arguments if (username == null) { reader = null; reader = createConsoleReaderWhithoutArgs(usernameInput); } createAutocomplete(); try { success = RestCommandLineService.getInstance().login(stratosURL, usernameInput, passwordInput, validateLogin); } catch (Exception e) { if (logger.isErrorEnabled()) { logger.error("Error when trying to login", e); } } if (success) { if (logger.isDebugEnabled()) { logger.debug("Successfully authenticated"); } } else { if (logger.isDebugEnabled()) { logger.debug("Authentication failed."); } } return success; } @Override protected int executeCommand(String line) { String[] tokens = new StrTokenizer(line).getTokenArray(); String action = tokens[0]; String[] actionArgs = Arrays.copyOfRange(tokens, 1, tokens.length); if (logger.isDebugEnabled()) { logger.debug("Executing command action: {}, Tokens: {}", action, tokens.length); } Command command = commands.get(action); if (command == null) { System.out.println(action + ": command not found."); return CliConstants.COMMAND_FAILED; } try { return command.execute(context, actionArgs, new Option[0]); } catch (CommandException e) { if (logger.isErrorEnabled()) { logger.error("Error executing command: " + action, e); } return CliConstants.ERROR_CODE; } } /** * @return {@code true} if required properties are loaded */ private boolean loadRequiredProperties() { if (logger.isDebugEnabled()) { logger.debug("Loading properties..."); } // Load properties String stratosURL = null; String username = null; String password = null; stratosURL = System.getenv(CliConstants.STRATOS_URL_ENV_PROPERTY); username = System.getenv(CliConstants.STRATOS_USERNAME_ENV_PROPERTY); password = System.getenv(CliConstants.STRATOS_PASSWORD_ENV_PROPERTY); if (StringUtils.isBlank(stratosURL)) { if (logger.isDebugEnabled()) { logger.debug("Required configuration not found."); } // Stratos Controller details are not set. System.out.format("Could not find required \"%s\" variable in your environment.%n", CliConstants.STRATOS_URL_ENV_PROPERTY); return false; } if (logger.isDebugEnabled()) { logger.debug("Required configuration found. Validating {}", stratosURL); } int slashCount = StringUtils.countMatches(stratosURL, "/"); int colonCount = StringUtils.countMatches(stratosURL, ":"); UrlValidator urlValidator = new UrlValidator(new String[]{"https"}, UrlValidator.ALLOW_LOCAL_URLS); // port must be provided, so colonCount must be 2 // context path must not be provided, so slashCount must not be >3 if (!urlValidator.isValid(stratosURL) || colonCount != 2 || slashCount > 3) { if (logger.isDebugEnabled()) { logger.debug("Stratos Controller URL {} is not valid", stratosURL); } System.out.format( "The \"%s\" variable in your environment is not a valid URL. You have provided \"%s\".%n" + "Please provide the Stratos Controller URL as follows%nhttps://:%n", CliConstants.STRATOS_URL_ENV_PROPERTY, stratosURL); return false; } if (logger.isDebugEnabled()) { logger.debug("Stratos Controller URL {} is valid.", stratosURL); logger.debug("Adding the values to context."); } context.put(CliConstants.STRATOS_URL_ENV_PROPERTY, stratosURL); context.put(CliConstants.STRATOS_USERNAME_ENV_PROPERTY, username); context.put(CliConstants.STRATOS_PASSWORD_ENV_PROPERTY, password); return true; } private void setLoggerLevel(boolean trace, boolean debug) { // We are using Log4j. So, get the logger and set log levels. org.apache.log4j.Logger logger = LogManager.getLogger(StratosApplication.class.getPackage().getName()); if (logger != null && trace) { logger.setLevel(Level.TRACE); LogManager.getRootLogger().setLevel(Level.TRACE); } else if (logger != null && debug) { logger.setLevel(Level.DEBUG); LogManager.getRootLogger().setLevel(Level.DEBUG); } } public void printHelp(final String action) { Command command = commands.get(action); if (command == null) { System.out.println(action + ": command not found. Help not available."); return; } System.out.println(command.getDescription()); Options options = command.getOptions(); if (options != null) { if (StringUtils.isNotBlank(command.getArgumentSyntax())) { printHelp(command.getName() + " " + command.getArgumentSyntax(), options); } else { printHelp(command.getName(), options); } } else { // No options. Just print the usage. printUsage(command); } } public void printHelp() { printHelp(CliConstants.STRATOS_APPLICATION_NAME, options); System.out.println("\n\nAvailable Commands: "); for (String action : commands.keySet()) { Command command = commands.get(action); if (command != null) { System.out.format("%-35s %s%n", command.getName(), command.getDescription()); } } System.out.println("\nFor help on a specific command type:\nhelp [command]"); } /** * Print "help" with usage */ private void printHelp(final String commandLineSyntax, final Options options) { final HelpFormatter helpFormatter = new HelpFormatter(); helpFormatter.printHelp(commandLineSyntax, options, true); } public void printUsage(final String action) { Command command = commands.get(action); if (command == null) { return; } printUsage(command); } private void printUsage(Command command) { Options options = command.getOptions(); if (options != null) { if (StringUtils.isNotBlank(command.getArgumentSyntax())) { printUsage(command.getName() + " " + command.getArgumentSyntax(), options); } else { printUsage(command.getName(), options); } } else { System.out.print("usage: "); if (StringUtils.isNotBlank(command.getArgumentSyntax())) { System.out.println(command.getName() + " " + command.getArgumentSyntax()); } else { System.out.println(command.getName()); } } } /** * Print "usage" */ private void printUsage(final String commandLineSyntax, final Options options) { final PrintWriter writer = new PrintWriter(System.out); final HelpFormatter usageFormatter = new HelpFormatter(); usageFormatter.printUsage(writer, 80, commandLineSyntax, options); writer.flush(); } }





© 2015 - 2025 Weber Informatics LLC | Privacy Policy