You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ambari.apache.org by su...@apache.org on 2014/07/02 19:36:49 UTC
[1/4] AMBARI-6176. Integrate python shell into Ambari-shell
module(subin)
Repository: ambari
Updated Branches:
refs/heads/trunk 2ff28495a -> c8eceafc9
http://git-wip-us.apache.org/repos/asf/ambari/blob/c8eceafc/ambari-shell/src/main/java/org/apache/ambari/shell/commands/HostCommands.java
----------------------------------------------------------------------
diff --git a/ambari-shell/src/main/java/org/apache/ambari/shell/commands/HostCommands.java b/ambari-shell/src/main/java/org/apache/ambari/shell/commands/HostCommands.java
deleted file mode 100644
index dd3c775..0000000
--- a/ambari-shell/src/main/java/org/apache/ambari/shell/commands/HostCommands.java
+++ /dev/null
@@ -1,119 +0,0 @@
-/**
- * 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.ambari.shell.commands;
-
-import static org.apache.ambari.shell.support.TableRenderer.renderSingleMap;
-
-import org.apache.ambari.groovy.client.AmbariClient;
-import org.apache.ambari.shell.completion.Host;
-import org.apache.ambari.shell.model.AmbariContext;
-import org.apache.ambari.shell.model.FocusType;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.shell.core.CommandMarker;
-import org.springframework.shell.core.annotation.CliAvailabilityIndicator;
-import org.springframework.shell.core.annotation.CliCommand;
-import org.springframework.shell.core.annotation.CliOption;
-import org.springframework.stereotype.Component;
-
-/**
- * Host related commands used in the shell.
- *
- * @see org.apache.ambari.groovy.client.AmbariClient
- */
-@Component
-public class HostCommands implements CommandMarker {
-
- private AmbariClient client;
- private AmbariContext context;
-
- @Autowired
- public HostCommands(AmbariClient client, AmbariContext context) {
- this.client = client;
- this.context = context;
- }
-
- /**
- * Checks whether the host list command is available or not.
- *
- * @return true if available false otherwise
- */
- @CliAvailabilityIndicator("host list")
- public boolean isHostsCommandAvailable() {
- return true;
- }
-
- /**
- * Prints the available hosts of the Ambari Server.
- *
- * @return host list
- */
- @CliCommand(value = "host list", help = "Lists the available hosts")
- public String hosts() {
- return client.showHostList();
- }
-
- /**
- * Checks whether the host focus command is available or not.
- *
- * @return true if available false otherwise
- */
- @CliAvailabilityIndicator("host focus")
- public boolean isFocusHostCommandAvailable() {
- return context.isConnectedToCluster();
- }
-
- /**
- * Sets the focus to the specified host.
- *
- * @param host the host to set the focus to
- * @return status message
- */
- @CliCommand(value = "host focus", help = "Sets the useHost to the specified host")
- public String focusHost(
- @CliOption(key = "host", mandatory = true, help = "hostname") Host host) {
- String message;
- String hostName = host.getName();
- if (client.getHostNames().keySet().contains(hostName)) {
- context.setFocus(hostName, FocusType.HOST);
- message = "Focus set to: " + hostName;
- } else {
- message = hostName + " is not a valid host name";
- }
- return message;
- }
-
- /**
- * Checks whether the host components command is available or not.
- *
- * @return true if available false otherwise
- */
- @CliAvailabilityIndicator("host components")
- public boolean isHostComponentsCommandAvailable() {
- return context.isFocusOnHost();
- }
-
- /**
- * Prints the components which belongs to the host being focused on.
- *
- * @return list of host components
- */
- @CliCommand(value = "host components", help = "Lists the components assigned to the selected host")
- public String hostComponents() {
- return renderSingleMap(client.getHostComponentsMap(context.getFocusValue()), "COMPONENT", "STATE");
- }
-}
http://git-wip-us.apache.org/repos/asf/ambari/blob/c8eceafc/ambari-shell/src/main/java/org/apache/ambari/shell/completion/Blueprint.java
----------------------------------------------------------------------
diff --git a/ambari-shell/src/main/java/org/apache/ambari/shell/completion/Blueprint.java b/ambari-shell/src/main/java/org/apache/ambari/shell/completion/Blueprint.java
deleted file mode 100644
index 4eec7b1..0000000
--- a/ambari-shell/src/main/java/org/apache/ambari/shell/completion/Blueprint.java
+++ /dev/null
@@ -1,34 +0,0 @@
-/**
- * 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.ambari.shell.completion;
-
-/**
- * Wrapper class for TAB completion to blueprint names.
- */
-public class Blueprint {
-
- private final String name;
-
- public Blueprint(String name) {
- this.name = name;
- }
-
- public String getName() {
- return name;
- }
-}
http://git-wip-us.apache.org/repos/asf/ambari/blob/c8eceafc/ambari-shell/src/main/java/org/apache/ambari/shell/completion/Host.java
----------------------------------------------------------------------
diff --git a/ambari-shell/src/main/java/org/apache/ambari/shell/completion/Host.java b/ambari-shell/src/main/java/org/apache/ambari/shell/completion/Host.java
deleted file mode 100644
index f64e97b..0000000
--- a/ambari-shell/src/main/java/org/apache/ambari/shell/completion/Host.java
+++ /dev/null
@@ -1,34 +0,0 @@
-/**
- * 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.ambari.shell.completion;
-
-/**
- * Wrapper class for TAB completion to host names.
- */
-public class Host {
-
- private final String name;
-
- public Host(String name) {
- this.name = name;
- }
-
- public String getName() {
- return name;
- }
-}
http://git-wip-us.apache.org/repos/asf/ambari/blob/c8eceafc/ambari-shell/src/main/java/org/apache/ambari/shell/configuration/ConverterConfiguration.java
----------------------------------------------------------------------
diff --git a/ambari-shell/src/main/java/org/apache/ambari/shell/configuration/ConverterConfiguration.java b/ambari-shell/src/main/java/org/apache/ambari/shell/configuration/ConverterConfiguration.java
deleted file mode 100644
index 049c52f..0000000
--- a/ambari-shell/src/main/java/org/apache/ambari/shell/configuration/ConverterConfiguration.java
+++ /dev/null
@@ -1,142 +0,0 @@
-/**
- * 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.ambari.shell.configuration;
-
-import org.apache.ambari.groovy.client.AmbariClient;
-import org.apache.ambari.shell.converter.BlueprintConverter;
-import org.apache.ambari.shell.converter.HostConverter;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.context.annotation.Bean;
-import org.springframework.context.annotation.Configuration;
-import org.springframework.shell.converters.AvailableCommandsConverter;
-import org.springframework.shell.converters.BigDecimalConverter;
-import org.springframework.shell.converters.BigIntegerConverter;
-import org.springframework.shell.converters.BooleanConverter;
-import org.springframework.shell.converters.CharacterConverter;
-import org.springframework.shell.converters.DateConverter;
-import org.springframework.shell.converters.DoubleConverter;
-import org.springframework.shell.converters.EnumConverter;
-import org.springframework.shell.converters.FloatConverter;
-import org.springframework.shell.converters.IntegerConverter;
-import org.springframework.shell.converters.LocaleConverter;
-import org.springframework.shell.converters.LongConverter;
-import org.springframework.shell.converters.ShortConverter;
-import org.springframework.shell.converters.SimpleFileConverter;
-import org.springframework.shell.converters.StaticFieldConverterImpl;
-import org.springframework.shell.converters.StringConverter;
-import org.springframework.shell.core.Converter;
-
-/**
- * Configures the converters used by the shell.
- */
-@Configuration
-public class ConverterConfiguration {
-
- @Autowired
- private AmbariClient client;
-
- @Bean
- Converter simpleFileConverter() {
- return new SimpleFileConverter();
- }
-
- @Bean
- Converter stringConverter() {
- return new StringConverter();
- }
-
- @Bean
- Converter availableCommandsConverter() {
- return new AvailableCommandsConverter();
- }
-
- @Bean
- Converter bigDecimalConverter() {
- return new BigDecimalConverter();
- }
-
- @Bean
- Converter bigIntegerConverter() {
- return new BigIntegerConverter();
- }
-
- @Bean
- Converter booleanConverter() {
- return new BooleanConverter();
- }
-
- @Bean
- Converter characterConverter() {
- return new CharacterConverter();
- }
-
- @Bean
- Converter dateConverter() {
- return new DateConverter();
- }
-
- @Bean
- Converter doubleConverter() {
- return new DoubleConverter();
- }
-
- @Bean
- Converter enumConverter() {
- return new EnumConverter();
- }
-
- @Bean
- Converter floatConverter() {
- return new FloatConverter();
- }
-
- @Bean
- Converter integerConverter() {
- return new IntegerConverter();
- }
-
- @Bean
- Converter localeConverter() {
- return new LocaleConverter();
- }
-
- @Bean
- Converter longConverter() {
- return new LongConverter();
- }
-
- @Bean
- Converter shortConverter() {
- return new ShortConverter();
- }
-
- @Bean
- Converter staticFieldConverterImpl() {
- return new StaticFieldConverterImpl();
- }
-
- @Bean
- Converter blueprintConverter() {
- return new BlueprintConverter(client);
- }
-
- @Bean
- Converter hostConverter() {
- return new HostConverter(client);
- }
-}
http://git-wip-us.apache.org/repos/asf/ambari/blob/c8eceafc/ambari-shell/src/main/java/org/apache/ambari/shell/configuration/ShellConfiguration.java
----------------------------------------------------------------------
diff --git a/ambari-shell/src/main/java/org/apache/ambari/shell/configuration/ShellConfiguration.java b/ambari-shell/src/main/java/org/apache/ambari/shell/configuration/ShellConfiguration.java
deleted file mode 100644
index 4c493b0..0000000
--- a/ambari-shell/src/main/java/org/apache/ambari/shell/configuration/ShellConfiguration.java
+++ /dev/null
@@ -1,114 +0,0 @@
-/**
- * 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.ambari.shell.configuration;
-
-import org.apache.ambari.groovy.client.AmbariClient;
-import org.codehaus.jackson.map.ObjectMapper;
-import org.springframework.beans.factory.annotation.Value;
-import org.springframework.context.annotation.Bean;
-import org.springframework.context.annotation.Configuration;
-import org.springframework.context.support.PropertySourcesPlaceholderConfigurer;
-import org.springframework.scheduling.concurrent.ThreadPoolExecutorFactoryBean;
-import org.springframework.shell.CommandLine;
-import org.springframework.shell.SimpleShellCommandLineOptions;
-import org.springframework.shell.commands.ExitCommands;
-import org.springframework.shell.commands.HelpCommands;
-import org.springframework.shell.commands.ScriptCommands;
-import org.springframework.shell.commands.VersionCommands;
-import org.springframework.shell.core.CommandMarker;
-import org.springframework.shell.core.JLineShellComponent;
-import org.springframework.shell.plugin.HistoryFileNameProvider;
-import org.springframework.shell.plugin.support.DefaultHistoryFileNameProvider;
-
-/**
- * Spring bean definitions.
- */
-@Configuration
-public class ShellConfiguration {
-
- @Value("${ambari.host:localhost}")
- private String host;
-
- @Value("${ambari.port:8080}")
- private String port;
-
- @Value("${ambari.user:admin}")
- private String user;
-
- @Value("${ambari.password:admin}")
- private String password;
-
- @Value("${cmdfile:}")
- private String cmdFile;
-
- @Bean
- AmbariClient createAmbariClient() {
- return new AmbariClient(host, port, user, password);
- }
-
- @Bean
- static PropertySourcesPlaceholderConfigurer propertyPlaceholderConfigurer() {
- return new PropertySourcesPlaceholderConfigurer();
- }
-
- @Bean
- HistoryFileNameProvider defaultHistoryFileNameProvider() {
- return new DefaultHistoryFileNameProvider();
- }
-
- @Bean(name = "shell")
- JLineShellComponent shell() {
- return new JLineShellComponent();
- }
-
- @Bean
- CommandLine commandLine() throws Exception {
- String[] args = cmdFile.length() > 0 ? new String[]{"--cmdfile", cmdFile} : new String[0];
- return SimpleShellCommandLineOptions.parseCommandLine(args);
- }
-
- @Bean
- ThreadPoolExecutorFactoryBean getThreadPoolExecutorFactoryBean() {
- return new ThreadPoolExecutorFactoryBean();
- }
-
- @Bean
- ObjectMapper getObjectMapper() {
- return new ObjectMapper();
- }
-
- @Bean
- CommandMarker exitCommand() {
- return new ExitCommands();
- }
-
- @Bean
- CommandMarker versionCommands() {
- return new VersionCommands();
- }
-
- @Bean
- CommandMarker helpCommands() {
- return new HelpCommands();
- }
-
- @Bean
- CommandMarker scriptCommands() {
- return new ScriptCommands();
- }
-}
http://git-wip-us.apache.org/repos/asf/ambari/blob/c8eceafc/ambari-shell/src/main/java/org/apache/ambari/shell/converter/BlueprintConverter.java
----------------------------------------------------------------------
diff --git a/ambari-shell/src/main/java/org/apache/ambari/shell/converter/BlueprintConverter.java b/ambari-shell/src/main/java/org/apache/ambari/shell/converter/BlueprintConverter.java
deleted file mode 100644
index 7984e7f..0000000
--- a/ambari-shell/src/main/java/org/apache/ambari/shell/converter/BlueprintConverter.java
+++ /dev/null
@@ -1,58 +0,0 @@
-/**
- * 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.ambari.shell.converter;
-
-import java.util.List;
-import java.util.Set;
-
-import org.apache.ambari.groovy.client.AmbariClient;
-import org.apache.ambari.shell.completion.Blueprint;
-import org.springframework.shell.core.Completion;
-import org.springframework.shell.core.Converter;
-import org.springframework.shell.core.MethodTarget;
-
-/**
- * Converter used to complete blueprint names.
- */
-public class BlueprintConverter implements Converter<Blueprint> {
-
- private AmbariClient client;
-
- public BlueprintConverter(AmbariClient client) {
- this.client = client;
- }
-
- @Override
- public boolean supports(Class<?> type, String optionContext) {
- return Blueprint.class.isAssignableFrom(type);
- }
-
- @Override
- public Blueprint convertFromText(String value, Class<?> targetType, String optionContext) {
- return new Blueprint(value);
- }
-
- @Override
- public boolean getAllPossibleValues(List<Completion> completions, Class<?> targetType, String existingData, String optionContext, MethodTarget target) {
- Set<String> blueprints = client.getBlueprintsMap().keySet();
- for (String blueprint : blueprints) {
- completions.add(new Completion(blueprint));
- }
- return true;
- }
-}
http://git-wip-us.apache.org/repos/asf/ambari/blob/c8eceafc/ambari-shell/src/main/java/org/apache/ambari/shell/converter/HostConverter.java
----------------------------------------------------------------------
diff --git a/ambari-shell/src/main/java/org/apache/ambari/shell/converter/HostConverter.java b/ambari-shell/src/main/java/org/apache/ambari/shell/converter/HostConverter.java
deleted file mode 100644
index 39aa6e9..0000000
--- a/ambari-shell/src/main/java/org/apache/ambari/shell/converter/HostConverter.java
+++ /dev/null
@@ -1,58 +0,0 @@
-/**
- * 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.ambari.shell.converter;
-
-import java.util.List;
-import java.util.Set;
-
-import org.apache.ambari.groovy.client.AmbariClient;
-import org.apache.ambari.shell.completion.Host;
-import org.springframework.shell.core.Completion;
-import org.springframework.shell.core.Converter;
-import org.springframework.shell.core.MethodTarget;
-
-/**
- * Converter used to complete host names.
- */
-public class HostConverter implements Converter<Host> {
-
- private AmbariClient client;
-
- public HostConverter(AmbariClient client) {
- this.client = client;
- }
-
- @Override
- public boolean supports(Class<?> type, String optionContext) {
- return Host.class.isAssignableFrom(type);
- }
-
- @Override
- public Host convertFromText(String value, Class<?> targetType, String optionContext) {
- return new Host(value);
- }
-
- @Override
- public boolean getAllPossibleValues(List<Completion> completions, Class<?> targetType, String existingData, String optionContext, MethodTarget target) {
- Set<String> hosts = client.getHostNames().keySet();
- for (String host : hosts) {
- completions.add(new Completion(host));
- }
- return true;
- }
-}
http://git-wip-us.apache.org/repos/asf/ambari/blob/c8eceafc/ambari-shell/src/main/java/org/apache/ambari/shell/customization/AmbariBanner.java
----------------------------------------------------------------------
diff --git a/ambari-shell/src/main/java/org/apache/ambari/shell/customization/AmbariBanner.java b/ambari-shell/src/main/java/org/apache/ambari/shell/customization/AmbariBanner.java
deleted file mode 100644
index f97ef59..0000000
--- a/ambari-shell/src/main/java/org/apache/ambari/shell/customization/AmbariBanner.java
+++ /dev/null
@@ -1,50 +0,0 @@
-/**
- * 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.ambari.shell.customization;
-
-import org.springframework.shell.plugin.BannerProvider;
-import org.springframework.stereotype.Component;
-
-import com.github.lalyos.jfiglet.FigletFont;
-
-/**
- * Prints the banner when the user starts the shell.
- */
-@Component
-public class AmbariBanner implements BannerProvider {
-
- @Override
- public String getProviderName() {
- return "AmbariShell";
- }
-
- @Override
- public String getBanner() {
- return FigletFont.convertOneLine("AmbariShell");
- }
-
- @Override
- public String getVersion() {
- return getClass().getPackage().getImplementationVersion();
- }
-
- @Override
- public String getWelcomeMessage() {
- return "Welcome to Ambari Shell. For command and param completion press TAB, for assistance type 'hint'.";
- }
-}
http://git-wip-us.apache.org/repos/asf/ambari/blob/c8eceafc/ambari-shell/src/main/java/org/apache/ambari/shell/customization/AmbariHistory.java
----------------------------------------------------------------------
diff --git a/ambari-shell/src/main/java/org/apache/ambari/shell/customization/AmbariHistory.java b/ambari-shell/src/main/java/org/apache/ambari/shell/customization/AmbariHistory.java
deleted file mode 100644
index c23fc9a..0000000
--- a/ambari-shell/src/main/java/org/apache/ambari/shell/customization/AmbariHistory.java
+++ /dev/null
@@ -1,40 +0,0 @@
-/**
- * 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.ambari.shell.customization;
-
-import org.springframework.shell.plugin.HistoryFileNameProvider;
-import org.springframework.stereotype.Component;
-
-/**
- * Specifies the name of the Ambari command log. Later this log can be used
- * to re-execute the commands with either the --cmdfile option at startup
- * or with the script --file command.
- */
-@Component
-public class AmbariHistory implements HistoryFileNameProvider {
-
- @Override
- public String getHistoryFileName() {
- return "ambari-log.ash";
- }
-
- @Override
- public String getProviderName() {
- return "AmbariShell";
- }
-}
http://git-wip-us.apache.org/repos/asf/ambari/blob/c8eceafc/ambari-shell/src/main/java/org/apache/ambari/shell/customization/AmbariPrompt.java
----------------------------------------------------------------------
diff --git a/ambari-shell/src/main/java/org/apache/ambari/shell/customization/AmbariPrompt.java b/ambari-shell/src/main/java/org/apache/ambari/shell/customization/AmbariPrompt.java
deleted file mode 100644
index b91e76e..0000000
--- a/ambari-shell/src/main/java/org/apache/ambari/shell/customization/AmbariPrompt.java
+++ /dev/null
@@ -1,43 +0,0 @@
-/**
- * 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.ambari.shell.customization;
-
-import org.apache.ambari.shell.model.AmbariContext;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.shell.plugin.PromptProvider;
-import org.springframework.stereotype.Component;
-
-/**
- * Manages the text of the shell's prompt.
- */
-@Component
-public class AmbariPrompt implements PromptProvider {
-
- @Autowired
- private AmbariContext context;
-
- @Override
- public String getProviderName() {
- return AmbariPrompt.class.getSimpleName();
- }
-
- @Override
- public String getPrompt() {
- return context.getPrompt();
- }
-}
http://git-wip-us.apache.org/repos/asf/ambari/blob/c8eceafc/ambari-shell/src/main/java/org/apache/ambari/shell/flash/AbstractFlash.java
----------------------------------------------------------------------
diff --git a/ambari-shell/src/main/java/org/apache/ambari/shell/flash/AbstractFlash.java b/ambari-shell/src/main/java/org/apache/ambari/shell/flash/AbstractFlash.java
deleted file mode 100644
index 58abb75..0000000
--- a/ambari-shell/src/main/java/org/apache/ambari/shell/flash/AbstractFlash.java
+++ /dev/null
@@ -1,66 +0,0 @@
-/**
- * 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.ambari.shell.flash;
-
-import static java.lang.Thread.sleep;
-
-import java.util.logging.Level;
-
-import org.springframework.shell.core.JLineShellComponent;
-
-/**
- * Base class for showing flash messages.
- */
-public abstract class AbstractFlash implements Runnable {
-
- private static final int SLEEP_TIME = 1500;
- private volatile boolean stop;
- private FlashType flashType;
- private JLineShellComponent shell;
-
- protected AbstractFlash(JLineShellComponent shell, FlashType flashType) {
- this.shell = shell;
- this.flashType = flashType;
- }
-
- @Override
- public void run() {
- while (!stop) {
- String text = null;
- try {
- text = getText();
- if (text.isEmpty()) {
- stop = true;
- }
- sleep(SLEEP_TIME);
- } catch (Exception e) {
- // ignore
- } finally {
- shell.flash(Level.SEVERE, text == null ? "" : text, flashType.getName());
- }
- }
- }
-
- /**
- * Returns the actual text of the flash messages. To remove the flash
- * return an empty string.
- *
- * @return message
- */
- public abstract String getText();
-}
http://git-wip-us.apache.org/repos/asf/ambari/blob/c8eceafc/ambari-shell/src/main/java/org/apache/ambari/shell/flash/FlashService.java
----------------------------------------------------------------------
diff --git a/ambari-shell/src/main/java/org/apache/ambari/shell/flash/FlashService.java b/ambari-shell/src/main/java/org/apache/ambari/shell/flash/FlashService.java
deleted file mode 100644
index 78977a6..0000000
--- a/ambari-shell/src/main/java/org/apache/ambari/shell/flash/FlashService.java
+++ /dev/null
@@ -1,47 +0,0 @@
-/**
- * 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.ambari.shell.flash;
-
-import java.util.concurrent.ExecutorService;
-
-import org.apache.ambari.groovy.client.AmbariClient;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.shell.core.JLineShellComponent;
-import org.springframework.stereotype.Service;
-
-/**
- * Service for managing the flashes.
- */
-@Service
-public class FlashService {
-
- private AmbariClient client;
- private JLineShellComponent shell;
- private ExecutorService executorService;
-
- @Autowired
- public FlashService(AmbariClient client, JLineShellComponent shell, ExecutorService executorService) {
- this.client = client;
- this.shell = shell;
- this.executorService = executorService;
- }
-
- public void showInstallProgress(boolean exit) {
- executorService.submit(new InstallProgress(shell, client, exit));
- }
-}
http://git-wip-us.apache.org/repos/asf/ambari/blob/c8eceafc/ambari-shell/src/main/java/org/apache/ambari/shell/flash/FlashType.java
----------------------------------------------------------------------
diff --git a/ambari-shell/src/main/java/org/apache/ambari/shell/flash/FlashType.java b/ambari-shell/src/main/java/org/apache/ambari/shell/flash/FlashType.java
deleted file mode 100644
index 754a269..0000000
--- a/ambari-shell/src/main/java/org/apache/ambari/shell/flash/FlashType.java
+++ /dev/null
@@ -1,39 +0,0 @@
-/**
- * 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.ambari.shell.flash;
-
-/**
- * Holds the unique names of the flashes.
- */
-public enum FlashType {
-
- /**
- * Install progress percentage flash.
- */
- INSTALL("install");
-
- private String name;
-
- private FlashType(String name) {
- this.name = name;
- }
-
- public String getName() {
- return name;
- }
-}
http://git-wip-us.apache.org/repos/asf/ambari/blob/c8eceafc/ambari-shell/src/main/java/org/apache/ambari/shell/flash/InstallProgress.java
----------------------------------------------------------------------
diff --git a/ambari-shell/src/main/java/org/apache/ambari/shell/flash/InstallProgress.java b/ambari-shell/src/main/java/org/apache/ambari/shell/flash/InstallProgress.java
deleted file mode 100644
index 69164ea..0000000
--- a/ambari-shell/src/main/java/org/apache/ambari/shell/flash/InstallProgress.java
+++ /dev/null
@@ -1,79 +0,0 @@
-/**
- * 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.ambari.shell.flash;
-
-import static java.lang.Math.round;
-
-import java.math.BigDecimal;
-
-import org.apache.ambari.groovy.client.AmbariClient;
-import org.springframework.shell.core.JLineShellComponent;
-
-/**
- * Show the install progress in % value.
- */
-public class InstallProgress extends AbstractFlash {
-
- private static final int SUCCESS = 100;
- private static final int FAILED = -1;
- private final boolean exit;
- private AmbariClient client;
- private volatile boolean done;
-
- public InstallProgress(JLineShellComponent shell, AmbariClient client, boolean exit) {
- super(shell, FlashType.INSTALL);
- this.client = client;
- this.exit = exit;
- }
-
- @Override
- public String getText() {
- StringBuilder sb = new StringBuilder();
- if (!done) {
- BigDecimal progress = client.getInstallProgress();
- if (progress != null) {
- BigDecimal decimal = progress.setScale(2, BigDecimal.ROUND_HALF_UP);
- int intValue = decimal.intValue();
- if (intValue != SUCCESS && intValue != FAILED) {
- sb.append("Installation: ").append(decimal).append("% ");
- int rounded = round(progress.setScale(0, BigDecimal.ROUND_UP).intValue() / 10);
- for (int i = 0; i < 10; i++) {
- if (i < rounded) {
- sb.append("=");
- } else {
- sb.append("-");
- }
- }
- } else if (intValue == FAILED) {
- sb.append("Installation: FAILED");
- done = true;
- } else {
- sb.append("Installation: COMPLETE");
- done = true;
- }
- } else {
- sb.append("Installation: WAITING..");
- }
- } else {
- if (exit) {
- System.exit(0);
- }
- }
- return sb.toString();
- }
-}
http://git-wip-us.apache.org/repos/asf/ambari/blob/c8eceafc/ambari-shell/src/main/java/org/apache/ambari/shell/model/AmbariContext.java
----------------------------------------------------------------------
diff --git a/ambari-shell/src/main/java/org/apache/ambari/shell/model/AmbariContext.java b/ambari-shell/src/main/java/org/apache/ambari/shell/model/AmbariContext.java
deleted file mode 100644
index af45dd6..0000000
--- a/ambari-shell/src/main/java/org/apache/ambari/shell/model/AmbariContext.java
+++ /dev/null
@@ -1,159 +0,0 @@
-/**
- * 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.ambari.shell.model;
-
-import org.springframework.stereotype.Component;
-
-/**
- * Holds information about the connected Ambari Server.
- */
-@Component
-public class AmbariContext {
-
- private String cluster;
- private boolean blueprintsAvailable;
- private Focus focus;
- private Hints hint;
-
- public AmbariContext() {
- this.focus = getRootFocus();
- }
-
- /**
- * Sets the name of the cluster.
- *
- * @param cluster
- */
- public void setCluster(String cluster) {
- this.cluster = cluster;
- }
-
- /**
- * Sets the focus to the root.
- */
- public void resetFocus() {
- this.focus = getRootFocus();
- }
-
- /**
- * Sets the focus.
- *
- * @param id target of the focus, can be anything (blueprint id, host id..)
- * @param type type of the focus
- */
- public void setFocus(String id, FocusType type) {
- this.focus = new Focus(id, type);
- }
-
- /**
- * Returns the target of the focus.
- *
- * @return target
- */
- public String getFocusValue() {
- return focus.getValue();
- }
-
- /**
- * Checks whether blueprints are available or not.
- */
- public boolean areBlueprintsAvailable() {
- return blueprintsAvailable;
- }
-
- /**
- * Sets what should be the next hint message.
- *
- * @param hint the new message
- */
- public void setHint(Hints hint) {
- this.hint = hint;
- }
-
- /**
- * Returns the context sensitive prompt.
- *
- * @return text of the prompt
- */
- public String getPrompt() {
- return focus.isType(FocusType.ROOT) ?
- isConnectedToCluster() ? formatPrompt(focus.getPrefix(), cluster) : "ambari-shell>" :
- formatPrompt(focus.getPrefix(), focus.getValue());
- }
-
- public boolean isConnectedToCluster() {
- return cluster != null;
- }
-
- /**
- * Checks whether the focus is on the host or not.
- *
- * @return true if the focus is on a host false otherwise
- */
- public boolean isFocusOnHost() {
- return isFocusOn(FocusType.HOST);
- }
-
- /**
- * Checks whether the focus is on the cluster build or not.
- *
- * @return true if the focus is on a cluster build false otherwise
- */
- public boolean isFocusOnClusterBuild() {
- return isFocusOn(FocusType.CLUSTER_BUILD);
- }
-
- /**
- * Returns some context sensitive hint.
- *
- * @return hint
- */
- public String getHint() {
- return "Hint: " + hint.message();
- }
-
- /**
- * Returns the name of the cluster.
- *
- * @return cluster's name
- */
- public String getCluster() {
- return cluster;
- }
-
- /**
- * Sets whether there are blueprints available or not.
- *
- * @param blueprintsAvailable
- */
- public void setBlueprintsAvailable(boolean blueprintsAvailable) {
- this.blueprintsAvailable = blueprintsAvailable;
- }
-
- private boolean isFocusOn(FocusType type) {
- return focus.isType(type);
- }
-
- private Focus getRootFocus() {
- return new Focus("root", FocusType.ROOT);
- }
-
- private String formatPrompt(String prefix, String postfix) {
- return String.format("%s:%s>", prefix, postfix);
- }
-}
http://git-wip-us.apache.org/repos/asf/ambari/blob/c8eceafc/ambari-shell/src/main/java/org/apache/ambari/shell/model/Focus.java
----------------------------------------------------------------------
diff --git a/ambari-shell/src/main/java/org/apache/ambari/shell/model/Focus.java b/ambari-shell/src/main/java/org/apache/ambari/shell/model/Focus.java
deleted file mode 100644
index b637c87..0000000
--- a/ambari-shell/src/main/java/org/apache/ambari/shell/model/Focus.java
+++ /dev/null
@@ -1,53 +0,0 @@
-/**
- * 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.ambari.shell.model;
-
-/**
- * Holds information about the focus. Focus give you the ability to
- * provide context sensitive commands.
- *
- * @see org.apache.ambari.shell.model.FocusType
- */
-public class Focus {
-
- private final String value;
- private final FocusType type;
-
- public Focus(String value, FocusType type) {
- this.value = value;
- this.type = type;
- }
-
- public String getPrefix() {
- return type.prefix();
- }
-
- public String getValue() {
- return value;
- }
-
- /**
- * Checks if the current focus exists with the provided one.
- *
- * @param type type to check with the current
- * @return true if they match false otherwise
- */
- public boolean isType(FocusType type) {
- return this.type == type;
- }
-}
http://git-wip-us.apache.org/repos/asf/ambari/blob/c8eceafc/ambari-shell/src/main/java/org/apache/ambari/shell/model/FocusType.java
----------------------------------------------------------------------
diff --git a/ambari-shell/src/main/java/org/apache/ambari/shell/model/FocusType.java b/ambari-shell/src/main/java/org/apache/ambari/shell/model/FocusType.java
deleted file mode 100644
index 121f7b4..0000000
--- a/ambari-shell/src/main/java/org/apache/ambari/shell/model/FocusType.java
+++ /dev/null
@@ -1,55 +0,0 @@
-/**
- * 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.ambari.shell.model;
-
-/**
- * Types for different focuses. Its purpose to give the command availability
- * checkers a chance in decision making.
- */
-public enum FocusType {
-
- /**
- * The focus is on a selected host.
- */
- HOST("HOST"),
-
- /**
- * The focus is on the cluster building phase.
- */
- CLUSTER_BUILD("CLUSTER_BUILD"),
-
- /**
- * No focus at all.
- */
- ROOT("CLUSTER");
-
- private final String prefix;
-
- private FocusType(String prefix) {
- this.prefix = prefix;
- }
-
- /**
- * Prefix provided for the prompt.
- *
- * @return focus prefix
- */
- public String prefix() {
- return prefix;
- }
-}
http://git-wip-us.apache.org/repos/asf/ambari/blob/c8eceafc/ambari-shell/src/main/java/org/apache/ambari/shell/model/Hints.java
----------------------------------------------------------------------
diff --git a/ambari-shell/src/main/java/org/apache/ambari/shell/model/Hints.java b/ambari-shell/src/main/java/org/apache/ambari/shell/model/Hints.java
deleted file mode 100644
index 990c832..0000000
--- a/ambari-shell/src/main/java/org/apache/ambari/shell/model/Hints.java
+++ /dev/null
@@ -1,59 +0,0 @@
-/**
- * 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.ambari.shell.model;
-
-/**
- * Provides some guidance's to the user, what he/she can follow.
- */
-public enum Hints {
-
- /**
- * Hint for adding blueprints.
- */
- ADD_BLUEPRINT("Add a blueprint with the 'blueprint add' or add the default blueprints with the 'blueprint defaults' command."),
-
- /**
- * Hint for start building a cluster.
- */
- BUILD_CLUSTER("Start building a cluster with the 'cluster build' command using a previously added blueprint."),
-
- /**
- * Hint for start assigning hosts to host groups in cluster build phase.
- */
- ASSIGN_HOSTS("Assign hosts to different host groups with the 'cluster assign' command."),
-
- /**
- * Hint for create a cluster from the assigned hosts.
- */
- CREATE_CLUSTER("Create the cluster with the 'cluster create' command or use the 'cluster reset' command and start over."),
-
- /**
- * Hint for check the cluster creation result.
- */
- PROGRESS("See the install progress with the 'tasks' command.");
-
- private final String message;
-
- private Hints(String message) {
- this.message = message;
- }
-
- public String message() {
- return message;
- }
-}
http://git-wip-us.apache.org/repos/asf/ambari/blob/c8eceafc/ambari-shell/src/main/java/org/apache/ambari/shell/support/TableRenderer.java
----------------------------------------------------------------------
diff --git a/ambari-shell/src/main/java/org/apache/ambari/shell/support/TableRenderer.java b/ambari-shell/src/main/java/org/apache/ambari/shell/support/TableRenderer.java
deleted file mode 100644
index 3e5af1f..0000000
--- a/ambari-shell/src/main/java/org/apache/ambari/shell/support/TableRenderer.java
+++ /dev/null
@@ -1,121 +0,0 @@
-/**
- * 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.ambari.shell.support;
-
-import static java.util.Collections.singletonList;
-
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-
-import org.springframework.shell.support.table.Table;
-import org.springframework.shell.support.table.TableHeader;
-
-/**
- * Utility class used to render tables.
- */
-public final class TableRenderer {
-
- private TableRenderer() {
- throw new IllegalStateException();
- }
-
- /**
- * Renders a 2 columns wide table with the given headers and rows. If headers are provided it should match with the
- * number of columns.
- *
- * @param rows rows of the table
- * @param headers headers of the table
- * @return the formatted table
- */
- public static String renderSingleMap(Map<String, String> rows, String... headers) {
- return renderMultiValueMap(convert(rows), headers);
- }
-
- /**
- * Renders a 2 columns wide table with the given headers and rows. If headers are provided it should match with the
- * number of columns.
- *
- * @param rows rows of the table, each value will be added as a new row with the same key
- * @param headers headers of the table
- * @return formatted table
- */
- public static String renderMultiValueMap(Map<String, List<String>> rows, String... headers) {
- Table table = createTable(headers);
- if (rows != null) {
- for (String key : rows.keySet()) {
- List<String> values = rows.get(key);
- if (values != null) {
- for (String value : values) {
- table.addRow(key, value);
- }
- }
- }
- }
- return format(table);
- }
-
- /**
- * Renders a 3 columns wide table with the given headers and rows. If headers are provided it should match with the
- * number of columns.
- *
- * @param rows rows of the table, value map will be added as the last 2 columns to the table
- * @param headers headers of the table
- * @return formatted table
- */
- public static String renderMapValueMap(Map<String, Map<String, String>> rows, String... headers) {
- Table table = createTable(headers);
- if (rows != null) {
- for (String key1 : rows.keySet()) {
- Map<String, String> values = rows.get(key1);
- if (values != null) {
- for (String key2 : values.keySet()) {
- table.addRow(key1, key2, values.get(key2));
- }
- }
- }
- }
- return format(table);
- }
-
- private static Table createTable(String... headers) {
- Table table = new Table();
- if (headers != null) {
- int column = 1;
- for (String header : headers) {
- table.addHeader(column++, new TableHeader(header));
- }
- }
- return table;
- }
-
- private static Map<String, List<String>> convert(Map<String, String> map) {
- Map<String, List<String>> result = new HashMap<String, List<String>>(map.size());
- if (map != null) {
- for (String key : map.keySet()) {
- result.put(key, singletonList(map.get(key)));
- }
- }
- return result;
- }
-
- private static String format(Table table) {
- table.calculateColumnWidths();
- return table.toString();
- }
-}
http://git-wip-us.apache.org/repos/asf/ambari/blob/c8eceafc/ambari-shell/src/main/resources/elephant.txt
----------------------------------------------------------------------
diff --git a/ambari-shell/src/main/resources/elephant.txt b/ambari-shell/src/main/resources/elephant.txt
deleted file mode 100644
index f51e284..0000000
--- a/ambari-shell/src/main/resources/elephant.txt
+++ /dev/null
@@ -1,8 +0,0 @@
- .-.._
- __ /` '.
- .-' `/ ( a \
- / ( \,_ \
- /| '---` |\ =|
- ` \ /__.-/ / | |
- | / / \ \ \ \_\
- |__|_| |_|__\
http://git-wip-us.apache.org/repos/asf/ambari/blob/c8eceafc/ambari-shell/src/test/java/org/apache/ambari/shell/commands/BlueprintCommandsTest.java
----------------------------------------------------------------------
diff --git a/ambari-shell/src/test/java/org/apache/ambari/shell/commands/BlueprintCommandsTest.java b/ambari-shell/src/test/java/org/apache/ambari/shell/commands/BlueprintCommandsTest.java
deleted file mode 100644
index 3c9277c..0000000
--- a/ambari-shell/src/test/java/org/apache/ambari/shell/commands/BlueprintCommandsTest.java
+++ /dev/null
@@ -1,128 +0,0 @@
-/**
- * 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.ambari.shell.commands;
-
-import static org.junit.Assert.assertEquals;
-import static org.mockito.Mockito.doThrow;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.times;
-import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.when;
-
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.IOException;
-
-import org.apache.ambari.groovy.client.AmbariClient;
-import org.apache.ambari.shell.model.AmbariContext;
-import org.apache.ambari.shell.model.Hints;
-import org.apache.commons.io.IOUtils;
-import org.codehaus.jackson.JsonNode;
-import org.codehaus.jackson.map.ObjectMapper;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.mockito.InjectMocks;
-import org.mockito.Mock;
-import org.mockito.runners.MockitoJUnitRunner;
-
-import groovyx.net.http.HttpResponseException;
-
-@RunWith(MockitoJUnitRunner.class)
-public class BlueprintCommandsTest {
-
- @InjectMocks
- private BlueprintCommands blueprintCommands;
-
- @Mock
- private AmbariClient ambariClient;
- @Mock
- private HttpResponseException responseException;
- @Mock
- private AmbariContext context;
- @Mock
- private ObjectMapper objectMapper;
-
- @Test
- public void testAddBlueprintForFileReadPrecedence() throws IOException {
- File file = new File("src/test/resources/testBlueprint.json");
- String json = IOUtils.toString(new FileInputStream(file));
- JsonNode jsonNode = mock(JsonNode.class);
- when(objectMapper.readTree(json.getBytes())).thenReturn(jsonNode);
- when(jsonNode.get("Blueprints")).thenReturn(jsonNode);
- when(jsonNode.get("blueprint_name")).thenReturn(jsonNode);
- when(jsonNode.asText()).thenReturn("blueprintName");
-
- String result = blueprintCommands.addBlueprint("url", file);
-
- verify(ambariClient).addBlueprint(json);
- verify(context).setHint(Hints.BUILD_CLUSTER);
- verify(context).setBlueprintsAvailable(true);
- assertEquals("Blueprint: 'blueprintName' has been added", result);
- }
-
- @Test
- public void testAddBlueprintForException() throws IOException {
- File file = new File("src/test/resources/testBlueprint.json");
- String json = IOUtils.toString(new FileInputStream(file));
- doThrow(responseException).when(ambariClient).addBlueprint(json);
- when(responseException.getMessage()).thenReturn("error");
-
- String result = blueprintCommands.addBlueprint("url", file);
-
- verify(ambariClient).addBlueprint(json);
- verify(responseException).getMessage();
- assertEquals("Cannot add blueprint: error", result);
- }
-
- @Test
- public void testAddBlueprintForDefaults() throws HttpResponseException {
- String result = blueprintCommands.addBlueprint();
-
- verify(ambariClient).addDefaultBlueprints();
- assertEquals("Default blueprints added", result);
- }
-
- @Test
- public void testAddBlueprintForUnspecifiedValue() throws HttpResponseException {
- String response = blueprintCommands.addBlueprint(null, null);
-
- assertEquals("No blueprint specified", response);
- verify(ambariClient, times(0)).addBlueprint(null);
- }
-
- @Test
- public void testAddBlueprintDefaultsForException() throws HttpResponseException {
- doThrow(responseException).when(ambariClient).addDefaultBlueprints();
- when(responseException.getMessage()).thenReturn("error");
-
- String result = blueprintCommands.addBlueprint();
-
- verify(responseException).getMessage();
- assertEquals("Failed to add the default blueprints: error", result);
- }
-
- @Test
- public void testAddBlueprintDefaultsForConnectionRefused() throws HttpResponseException {
- doThrow(new RuntimeException("Connection refused")).when(ambariClient).addDefaultBlueprints();
- when(responseException.getMessage()).thenReturn("error");
-
- String result = blueprintCommands.addBlueprint();
-
- assertEquals("Failed to add the default blueprints: Connection refused", result);
- }
-}
http://git-wip-us.apache.org/repos/asf/ambari/blob/c8eceafc/ambari-shell/src/test/java/org/apache/ambari/shell/commands/ClusterCommandsTest.java
----------------------------------------------------------------------
diff --git a/ambari-shell/src/test/java/org/apache/ambari/shell/commands/ClusterCommandsTest.java b/ambari-shell/src/test/java/org/apache/ambari/shell/commands/ClusterCommandsTest.java
deleted file mode 100644
index 777d05d..0000000
--- a/ambari-shell/src/test/java/org/apache/ambari/shell/commands/ClusterCommandsTest.java
+++ /dev/null
@@ -1,279 +0,0 @@
-/**
- * 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.ambari.shell.commands;
-
-import static java.util.Arrays.asList;
-import static java.util.Collections.emptyList;
-import static java.util.Collections.singletonMap;
-import static org.apache.ambari.shell.support.TableRenderer.renderMultiValueMap;
-import static org.apache.ambari.shell.support.TableRenderer.renderSingleMap;
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertTrue;
-import static org.mockito.Mockito.doThrow;
-import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.when;
-
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-
-import org.apache.ambari.groovy.client.AmbariClient;
-import org.apache.ambari.shell.completion.Blueprint;
-import org.apache.ambari.shell.completion.Host;
-import org.apache.ambari.shell.flash.FlashService;
-import org.apache.ambari.shell.model.AmbariContext;
-import org.apache.ambari.shell.model.Hints;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.mockito.InjectMocks;
-import org.mockito.Mock;
-import org.mockito.runners.MockitoJUnitRunner;
-import org.springframework.test.util.ReflectionTestUtils;
-
-import groovyx.net.http.HttpResponseException;
-
-@RunWith(MockitoJUnitRunner.class)
-public class ClusterCommandsTest {
-
- @InjectMocks
- private ClusterCommands clusterCommands;
-
- @Mock
- private AmbariClient client;
- @Mock
- private AmbariContext context;
- @Mock
- private HttpResponseException responseException;
- @Mock
- private FlashService flashService;
-
- @Test
- public void testIsClusterBuildCommandAvailable() {
- when(context.isConnectedToCluster()).thenReturn(false);
- when(context.isFocusOnClusterBuild()).thenReturn(false);
- when(context.areBlueprintsAvailable()).thenReturn(true);
-
- boolean result = clusterCommands.isClusterBuildCommandAvailable();
-
- assertTrue(result);
- }
-
- @Test
- public void testIsClusterBuildCommandAvailableAndFocusOnBuild() {
- when(context.isConnectedToCluster()).thenReturn(false);
- when(context.isFocusOnClusterBuild()).thenReturn(true);
- when(context.areBlueprintsAvailable()).thenReturn(true);
-
- boolean result = clusterCommands.isClusterBuildCommandAvailable();
-
- assertFalse(result);
- }
-
- @Test
- public void testIsClusterBuildCommandAvailableAndNoBlueprints() {
- when(context.isConnectedToCluster()).thenReturn(false);
- when(context.isFocusOnClusterBuild()).thenReturn(false);
- when(context.areBlueprintsAvailable()).thenReturn(false);
-
- boolean result = clusterCommands.isClusterBuildCommandAvailable();
-
- assertFalse(result);
- }
-
- @Test
- public void testBuildClusterForNonExistingBlueprint() {
- when(client.doesBlueprintExist("id")).thenReturn(false);
-
- String result = clusterCommands.buildCluster(new Blueprint("id"));
-
- verify(client).doesBlueprintExist("id");
- assertEquals("Not a valid blueprint id", result);
- }
-
- @Test
- public void testBuildCluster() {
- Map<String, String> hostNames = singletonMap("host1", "HEALTHY");
- Map<String, List<String>> map = singletonMap("group1", asList("comp1", "comp2"));
- when(client.doesBlueprintExist("id")).thenReturn(true);
- when(client.getBlueprintMap("id")).thenReturn(map);
- when(context.getFocusValue()).thenReturn("id");
- when(client.getHostNames()).thenReturn(hostNames);
-
- String result = clusterCommands.buildCluster(new Blueprint("id"));
-
- verify(client).doesBlueprintExist("id");
- verify(client).getBlueprintMap("id");
- verify(client).getHostGroups("id");
- assertEquals(String.format("%s\n%s", renderSingleMap(hostNames, "HOSTNAME", "STATE"),
- renderMultiValueMap(map, "HOSTGROUP", "COMPONENT")), result);
- }
-
- @Test
- public void testAssignForInvalidHostGroup() {
- Map<String, List<String>> map = singletonMap("group1", asList("host", "host2"));
- ReflectionTestUtils.setField(clusterCommands, "hostGroups", map);
- when(client.getHostNames()).thenReturn(singletonMap("host3", "HEALTHY"));
-
- String result = clusterCommands.assign(new Host("host3"), "group0");
-
- assertEquals("group0 is not a valid host group", result);
- }
-
- @Test
- public void testAssignForValidHostGroup() {
- Map<String, List<String>> map = new HashMap<String, List<String>>();
- map.put("group1", new ArrayList<String>());
- ReflectionTestUtils.setField(clusterCommands, "hostGroups", map);
- when(client.getHostNames()).thenReturn(singletonMap("host3", "HEALTHY"));
-
- String result = clusterCommands.assign(new Host("host3"), "group1");
-
- assertEquals("host3 has been added to group1", result);
- }
-
- @Test
- public void testAssignForInvalidHost() {
- Map<String, List<String>> map = new HashMap<String, List<String>>();
- map.put("group1", new ArrayList<String>());
- ReflectionTestUtils.setField(clusterCommands, "hostGroups", map);
- when(client.getHostNames()).thenReturn(singletonMap("host2", "HEALTHY"));
-
- String result = clusterCommands.assign(new Host("host3"), "group1");
-
- assertEquals("host3 is not a valid hostname", result);
- }
-
- @Test
- public void testCreateClusterForException() throws HttpResponseException {
- String blueprint = "blueprint";
- Map<String, List<String>> map = singletonMap("group1", asList("host", "host2"));
- ReflectionTestUtils.setField(clusterCommands, "hostGroups", map);
- when(context.getFocusValue()).thenReturn(blueprint);
- doThrow(responseException).when(client).createCluster(blueprint, blueprint, map);
- doThrow(responseException).when(client).deleteCluster(blueprint);
-
- String result = clusterCommands.createCluster(false);
-
- verify(client).createCluster(blueprint, blueprint, map);
- verify(client).getHostGroups(blueprint);
- verify(client).deleteCluster(blueprint);
- assertTrue(result.contains("Failed"));
- }
-
- @Test
- public void testCreateCluster() throws HttpResponseException {
- String blueprint = "blueprint";
- Map<String, List<String>> map = singletonMap("group1", asList("host", "host2"));
- ReflectionTestUtils.setField(clusterCommands, "hostGroups", map);
- when(context.getFocusValue()).thenReturn(blueprint);
- when(client.getClusterName()).thenReturn("cluster");
-
- String result = clusterCommands.createCluster(false);
-
- verify(client).createCluster(blueprint, blueprint, map);
- verify(context).resetFocus();
- assertFalse(result.contains("Failed"));
- assertTrue(result.contains("Successfully"));
- }
-
- @Test
- public void testDeleteClusterForException() throws HttpResponseException {
- when(context.getCluster()).thenReturn("cluster");
- when(responseException.getMessage()).thenReturn("msg");
- doThrow(responseException).when(client).deleteCluster("cluster");
-
- String result = clusterCommands.deleteCluster();
-
- verify(client).deleteCluster("cluster");
- verify(context).getCluster();
- verify(responseException).getMessage();
- assertEquals("Could not delete the cluster: msg", result);
- }
-
- @Test
- public void testDeleteCluster() throws HttpResponseException {
- when(context.getCluster()).thenReturn("cluster");
- when(responseException.getMessage()).thenReturn("msg");
-
- String result = clusterCommands.deleteCluster();
-
- verify(client).deleteCluster("cluster");
- verify(context).getCluster();
- assertEquals("Successfully deleted the cluster", result);
- }
-
- @Test
- public void testIsClusterPreviewCommandAvailable() {
- when(context.isFocusOnClusterBuild()).thenReturn(true);
- ReflectionTestUtils.setField(clusterCommands, "hostGroups", singletonMap("group1", asList("host1")));
-
- boolean result = clusterCommands.isClusterPreviewCommandAvailable();
-
- assertTrue(result);
- }
-
- @Test
- public void testIsClusterPreviewCommandAvailableForNoAssignments() {
- when(context.isFocusOnClusterBuild()).thenReturn(true);
- ReflectionTestUtils.setField(clusterCommands, "hostGroups", singletonMap("group1", emptyList()));
-
- boolean result = clusterCommands.isClusterPreviewCommandAvailable();
-
- assertFalse(result);
- }
-
- @Test
- public void testIsClusterResetCommandAvailable() {
- when(context.isFocusOnClusterBuild()).thenReturn(true);
- ReflectionTestUtils.setField(clusterCommands, "hostGroups", singletonMap("group1", asList("host1")));
-
- boolean result = clusterCommands.isClusterResetCommandAvailable();
-
- assertTrue(result);
- }
-
- @Test
- public void testAutoAssignForEmptyResult() {
- Map<String, List<String>> hostGroups = singletonMap("group1", asList("host1"));
- ReflectionTestUtils.setField(clusterCommands, "hostGroups", hostGroups);
- when(context.getFocusValue()).thenReturn("blueprint");
- when(client.recommendAssignments("blueprint")).thenReturn(new HashMap<String, List<String>>());
-
- clusterCommands.autoAssign();
-
- Map<String, List<String>> result = (Map<String, List<String>>) ReflectionTestUtils.getField(clusterCommands, "hostGroups");
- assertEquals(hostGroups, result);
- }
-
- @Test
- public void testAutoAssign() {
- Map<String, List<String>> hostGroups = singletonMap("group1", asList("host1"));
- Map<String, List<String>> newAssignments = singletonMap("group1", asList("host1"));
- ReflectionTestUtils.setField(clusterCommands, "hostGroups", hostGroups);
- when(context.getFocusValue()).thenReturn("blueprint");
- when(client.recommendAssignments("blueprint")).thenReturn(newAssignments);
-
- clusterCommands.autoAssign();
-
- Map<String, List<String>> result = (Map<String, List<String>>) ReflectionTestUtils.getField(clusterCommands, "hostGroups");
- assertEquals(newAssignments, result);
- verify(context).setHint(Hints.CREATE_CLUSTER);
- }
-}
http://git-wip-us.apache.org/repos/asf/ambari/blob/c8eceafc/ambari-shell/src/test/java/org/apache/ambari/shell/commands/HostCommandsTest.java
----------------------------------------------------------------------
diff --git a/ambari-shell/src/test/java/org/apache/ambari/shell/commands/HostCommandsTest.java b/ambari-shell/src/test/java/org/apache/ambari/shell/commands/HostCommandsTest.java
deleted file mode 100644
index 6ca6d4d..0000000
--- a/ambari-shell/src/test/java/org/apache/ambari/shell/commands/HostCommandsTest.java
+++ /dev/null
@@ -1,66 +0,0 @@
-/**
- * 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.ambari.shell.commands;
-
-import static java.util.Collections.singletonMap;
-import static org.junit.Assert.assertEquals;
-import static org.mockito.Mockito.times;
-import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.when;
-
-import org.apache.ambari.groovy.client.AmbariClient;
-import org.apache.ambari.shell.completion.Host;
-import org.apache.ambari.shell.model.AmbariContext;
-import org.apache.ambari.shell.model.FocusType;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.mockito.InjectMocks;
-import org.mockito.Mock;
-import org.mockito.runners.MockitoJUnitRunner;
-
-@RunWith(MockitoJUnitRunner.class)
-public class HostCommandsTest {
-
- @InjectMocks
- private HostCommands hostCommands;
-
- @Mock
- private AmbariClient client;
- @Mock
- private AmbariContext context;
-
- @Test
- public void testFocusHostForValidHost() {
- when(client.getHostNames()).thenReturn(singletonMap("host1", "HEALTHY"));
-
- String result = hostCommands.focusHost(new Host("host1"));
-
- verify(context).setFocus("host1", FocusType.HOST);
- assertEquals("Focus set to: host1", result);
- }
-
- @Test
- public void testFocusHostForInvalidHost() {
- when(client.getHostNames()).thenReturn(singletonMap("host3", "HEALTHY"));
-
- String result = hostCommands.focusHost(new Host("host1"));
-
- verify(context, times(0)).setFocus("host1", FocusType.HOST);
- assertEquals("host1 is not a valid host name", result);
- }
-}
http://git-wip-us.apache.org/repos/asf/ambari/blob/c8eceafc/ambari-shell/src/test/java/org/apache/ambari/shell/customization/AmbariPromptTest.java
----------------------------------------------------------------------
diff --git a/ambari-shell/src/test/java/org/apache/ambari/shell/customization/AmbariPromptTest.java b/ambari-shell/src/test/java/org/apache/ambari/shell/customization/AmbariPromptTest.java
deleted file mode 100644
index ba90d00..0000000
--- a/ambari-shell/src/test/java/org/apache/ambari/shell/customization/AmbariPromptTest.java
+++ /dev/null
@@ -1,54 +0,0 @@
-/**
- * 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.ambari.shell.customization;
-
-import static org.junit.Assert.assertEquals;
-import static org.mockito.Mockito.when;
-
-import org.apache.ambari.shell.model.AmbariContext;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.mockito.InjectMocks;
-import org.mockito.Mock;
-import org.mockito.runners.MockitoJUnitRunner;
-
-@RunWith(MockitoJUnitRunner.class)
-public class AmbariPromptTest {
-
- @InjectMocks
- private AmbariPrompt prompt;
-
- @Mock
- private AmbariContext context;
-
- @Test
- public void testGetProviderName() {
- String result = prompt.getProviderName();
-
- assertEquals(AmbariPrompt.class.getSimpleName(), result);
- }
-
- @Test
- public void testGetPrompt(){
- when(context.getPrompt()).thenReturn("prompt");
-
- String result = prompt.getPrompt();
-
- assertEquals("prompt", result);
- }
-}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/ambari/blob/c8eceafc/ambari-shell/src/test/java/org/apache/ambari/shell/model/AmbariContextTest.java
----------------------------------------------------------------------
diff --git a/ambari-shell/src/test/java/org/apache/ambari/shell/model/AmbariContextTest.java b/ambari-shell/src/test/java/org/apache/ambari/shell/model/AmbariContextTest.java
deleted file mode 100644
index ca9e919..0000000
--- a/ambari-shell/src/test/java/org/apache/ambari/shell/model/AmbariContextTest.java
+++ /dev/null
@@ -1,66 +0,0 @@
-/**
- * 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.ambari.shell.model;
-
-import static org.junit.Assert.assertEquals;
-
-import org.apache.ambari.groovy.client.AmbariClient;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.mockito.InjectMocks;
-import org.mockito.Mock;
-import org.mockito.runners.MockitoJUnitRunner;
-import org.springframework.test.util.ReflectionTestUtils;
-
-@RunWith(MockitoJUnitRunner.class)
-public class AmbariContextTest {
-
- @InjectMocks
- private AmbariContext ambariContext;
-
- @Mock
- private AmbariClient ambariClient;
-
- @Test
- public void testGetPromptForRoot() {
- ReflectionTestUtils.setField(ambariContext, "cluster", "single-node");
-
- String result = ambariContext.getPrompt();
-
- assertEquals(FocusType.ROOT.prefix() + ":single-node>", result);
- }
-
- @Test
- public void testGetPromptForRootButNotConnected() {
- ReflectionTestUtils.setField(ambariContext, "cluster", null);
-
- String result = ambariContext.getPrompt();
-
- assertEquals("ambari-shell>", result);
- }
-
- @Test
- public void testGetPromptForFocus() {
- ReflectionTestUtils.setField(ambariContext, "cluster", "single-node");
- ReflectionTestUtils.setField(ambariContext, "focus", new Focus("target", FocusType.HOST));
-
- String result = ambariContext.getPrompt();
-
- assertEquals(String.format("%s:%s>", FocusType.HOST.prefix(), "target"), result);
- }
-}
http://git-wip-us.apache.org/repos/asf/ambari/blob/c8eceafc/ambari-shell/src/test/java/org/apache/ambari/shell/support/TableRendererTest.java
----------------------------------------------------------------------
diff --git a/ambari-shell/src/test/java/org/apache/ambari/shell/support/TableRendererTest.java b/ambari-shell/src/test/java/org/apache/ambari/shell/support/TableRendererTest.java
deleted file mode 100644
index e576390..0000000
--- a/ambari-shell/src/test/java/org/apache/ambari/shell/support/TableRendererTest.java
+++ /dev/null
@@ -1,54 +0,0 @@
-/**
- * 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.ambari.shell.support;
-
-import static org.junit.Assert.assertEquals;
-
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.IOException;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-
-import org.apache.commons.io.IOUtils;
-import org.junit.Test;
-
-public class TableRendererTest {
-
- @Test
- public void testRenderMultiValueMap() throws IOException {
- Map<String, List<String>> map = new HashMap<String, List<String>>();
- map.put("HDFS", Collections.singletonList("DATANODE"));
- map.put("MAPREDUCE2", Collections.singletonList("HISTORYSERVER"));
- map.put("ZOOKEEPER", Collections.singletonList("ZOOKEEPER_SERVER"));
- assertEquals(IOUtils.toString(new FileInputStream(new File("src/test/resources/2columns"))),
- TableRenderer.renderMultiValueMap(map, "SERVICE", "COMPONENT"));
- }
-
- @Test
- public void testRenderMapValueMap() throws IOException {
- Map<String, Map<String, String>> map = new HashMap<String, Map<String, String>>();
- map.put("HDFS", Collections.singletonMap("DATANODE", "STARTED"));
- map.put("MAPREDUCE2", Collections.singletonMap("HISTORYSERVER", "STARTED"));
- map.put("ZOOKEEPER", Collections.singletonMap("ZOOKEEPER_SERVER", "INSTALLED"));
- assertEquals(IOUtils.toString(new FileInputStream(new File("src/test/resources/3columns"))),
- TableRenderer.renderMapValueMap(map, "SERVICE", "COMPONENT", "STATE"));
- }
-}
http://git-wip-us.apache.org/repos/asf/ambari/blob/c8eceafc/ambari-shell/src/test/resources/2columns
----------------------------------------------------------------------
diff --git a/ambari-shell/src/test/resources/2columns b/ambari-shell/src/test/resources/2columns
deleted file mode 100644
index 190771b..0000000
--- a/ambari-shell/src/test/resources/2columns
+++ /dev/null
@@ -1,5 +0,0 @@
- SERVICE COMPONENT
- ---------- ----------------
- ZOOKEEPER ZOOKEEPER_SERVER
- MAPREDUCE2 HISTORYSERVER
- HDFS DATANODE
http://git-wip-us.apache.org/repos/asf/ambari/blob/c8eceafc/ambari-shell/src/test/resources/3columns
----------------------------------------------------------------------
diff --git a/ambari-shell/src/test/resources/3columns b/ambari-shell/src/test/resources/3columns
deleted file mode 100644
index 127a414..0000000
--- a/ambari-shell/src/test/resources/3columns
+++ /dev/null
@@ -1,5 +0,0 @@
- SERVICE COMPONENT STATE
- ---------- ---------------- ---------
- ZOOKEEPER ZOOKEEPER_SERVER INSTALLED
- MAPREDUCE2 HISTORYSERVER STARTED
- HDFS DATANODE STARTED
http://git-wip-us.apache.org/repos/asf/ambari/blob/c8eceafc/ambari-shell/src/test/resources/testBlueprint.json
----------------------------------------------------------------------
diff --git a/ambari-shell/src/test/resources/testBlueprint.json b/ambari-shell/src/test/resources/testBlueprint.json
deleted file mode 100644
index 971c46d..0000000
--- a/ambari-shell/src/test/resources/testBlueprint.json
+++ /dev/null
@@ -1,48 +0,0 @@
-{
- "host_groups" : [
- {
- "name" : "host_group_1",
- "components" : [
- {
- "name" : "NAMENODE"
- },
- {
- "name" : "SECONDARY_NAMENODE"
- },
- {
- "name" : "DATANODE"
- },
- {
- "name" : "HDFS_CLIENT"
- },
- {
- "name" : "RESOURCEMANAGER"
- },
- {
- "name" : "NODEMANAGER"
- },
- {
- "name" : "YARN_CLIENT"
- },
- {
- "name" : "HISTORYSERVER"
- },
- {
- "name" : "MAPREDUCE2_CLIENT"
- },
- {
- "name" : "ZOOKEEPER_SERVER"
- },
- {
- "name" : "ZOOKEEPER_CLIENT"
- }
- ],
- "cardinality" : "1"
- }
- ],
- "Blueprints" : {
- "blueprint_name" : "single-node-hdfs-yarn",
- "stack_name" : "HDP",
- "stack_version" : "2.0"
- }
-}
\ No newline at end of file
[4/4] git commit: AMBARI-6176. Integrate python shell into
Ambari-shell module(subin)
Posted by su...@apache.org.
AMBARI-6176. Integrate python shell into Ambari-shell module(subin)
Project: http://git-wip-us.apache.org/repos/asf/ambari/repo
Commit: http://git-wip-us.apache.org/repos/asf/ambari/commit/c8eceafc
Tree: http://git-wip-us.apache.org/repos/asf/ambari/tree/c8eceafc
Diff: http://git-wip-us.apache.org/repos/asf/ambari/diff/c8eceafc
Branch: refs/heads/trunk
Commit: c8eceafc9efc6fa305519f27c21ab51531c0d7cb
Parents: 2ff2849
Author: Subin <su...@apache.org>
Authored: Wed Jul 2 23:03:34 2014 +0530
Committer: Subin <su...@apache.org>
Committed: Wed Jul 2 23:04:34 2014 +0530
----------------------------------------------------------------------
.../src/main/python/ambari_client/ambari_api.py | 26 +-
.../python/ambari_client/core/http_client.py | 13 +-
.../python/ambari_client/model/blueprint.py | 53 +++
.../src/main/python/ambari_client/model/host.py | 7 +-
.../main/python/ambari_client/model/paths.py | 2 +
.../main/python/ambari_client/model/status.py | 42 +-
.../main/python/ambari_client/model/utils.py | 39 +-
ambari-shell/ambari-groovy-shell/pom.xml | 142 +++++++
.../org/apache/ambari/shell/AmbariShell.java | 111 +++++
.../ambari/shell/commands/BasicCommands.java | 207 ++++++++++
.../shell/commands/BlueprintCommands.java | 198 +++++++++
.../ambari/shell/commands/ClusterCommands.java | 294 +++++++++++++
.../ambari/shell/commands/ElephantCommand.java | 53 +++
.../ambari/shell/commands/HostCommands.java | 119 ++++++
.../ambari/shell/completion/Blueprint.java | 34 ++
.../apache/ambari/shell/completion/Host.java | 34 ++
.../configuration/ConverterConfiguration.java | 142 +++++++
.../shell/configuration/ShellConfiguration.java | 114 +++++
.../shell/converter/BlueprintConverter.java | 58 +++
.../ambari/shell/converter/HostConverter.java | 58 +++
.../shell/customization/AmbariBanner.java | 50 +++
.../shell/customization/AmbariHistory.java | 40 ++
.../shell/customization/AmbariPrompt.java | 43 ++
.../ambari/shell/flash/AbstractFlash.java | 66 +++
.../apache/ambari/shell/flash/FlashService.java | 47 +++
.../apache/ambari/shell/flash/FlashType.java | 39 ++
.../ambari/shell/flash/InstallProgress.java | 79 ++++
.../ambari/shell/model/AmbariContext.java | 159 +++++++
.../org/apache/ambari/shell/model/Focus.java | 53 +++
.../apache/ambari/shell/model/FocusType.java | 55 +++
.../org/apache/ambari/shell/model/Hints.java | 59 +++
.../ambari/shell/support/TableRenderer.java | 121 ++++++
.../src/main/resources/elephant.txt | 8 +
.../shell/commands/BlueprintCommandsTest.java | 128 ++++++
.../shell/commands/ClusterCommandsTest.java | 279 +++++++++++++
.../ambari/shell/commands/HostCommandsTest.java | 66 +++
.../shell/customization/AmbariPromptTest.java | 54 +++
.../ambari/shell/model/AmbariContextTest.java | 66 +++
.../ambari/shell/support/TableRendererTest.java | 54 +++
.../src/test/resources/2columns | 5 +
.../src/test/resources/3columns | 5 +
.../src/test/resources/testBlueprint.json | 48 +++
.../ambari-python-shell/conf/unix/ambari-shell | 62 +++
.../conf/unix/ambari-shell.ini | 19 +
ambari-shell/ambari-python-shell/pom.xml | 237 +++++++++++
.../src/main/package/deb/control/control | 22 +
.../src/main/package/deb/control/postinst | 15 +
.../src/main/package/deb/control/postrm | 15 +
.../src/main/package/deb/control/posttrm | 15 +
.../src/main/package/deb/control/preinst | 15 +
.../src/main/package/deb/control/prerm | 15 +
.../src/main/python/ambari_shell/__init__.py | 16 +
.../main/python/ambari_shell/ambari_shell.py | 412 +++++++++++++++++++
.../python/ambari_shell/plugins/__init__.py | 16 +
.../python/ambari_shell/plugins/blueprint.py | 21 +
.../ambari_shell/plugins/connect_cluster.py | 81 ++++
.../ambari_shell/plugins/create_cluster.py | 34 ++
.../main/python/ambari_shell/plugins/service.py | 125 ++++++
.../python/ambari_shell/plugins/shell_config.py | 77 ++++
.../main/python/ambari_shell/plugins/show.py | 155 +++++++
.../main/python/ambari_shell/utils/__init__.py | 16 +
.../python/ambari_shell/utils/displayutils.py | 128 ++++++
.../main/python/ambari_shell/utils/osutils.py | 69 ++++
.../python/ambari_shell/utils/pluginutils.py | 100 +++++
.../src/main/python/setup.py | 40 ++
.../src/packages/tarball/all.xml | 34 ++
ambari-shell/assemblies/client.xml | 20 +
ambari-shell/pom.xml | 128 ++----
.../org/apache/ambari/shell/AmbariShell.java | 111 -----
.../ambari/shell/commands/BasicCommands.java | 207 ----------
.../shell/commands/BlueprintCommands.java | 198 ---------
.../ambari/shell/commands/ClusterCommands.java | 294 -------------
.../ambari/shell/commands/ElephantCommand.java | 53 ---
.../ambari/shell/commands/HostCommands.java | 119 ------
.../ambari/shell/completion/Blueprint.java | 34 --
.../apache/ambari/shell/completion/Host.java | 34 --
.../configuration/ConverterConfiguration.java | 142 -------
.../shell/configuration/ShellConfiguration.java | 114 -----
.../shell/converter/BlueprintConverter.java | 58 ---
.../ambari/shell/converter/HostConverter.java | 58 ---
.../shell/customization/AmbariBanner.java | 50 ---
.../shell/customization/AmbariHistory.java | 40 --
.../shell/customization/AmbariPrompt.java | 43 --
.../ambari/shell/flash/AbstractFlash.java | 66 ---
.../apache/ambari/shell/flash/FlashService.java | 47 ---
.../apache/ambari/shell/flash/FlashType.java | 39 --
.../ambari/shell/flash/InstallProgress.java | 79 ----
.../ambari/shell/model/AmbariContext.java | 159 -------
.../org/apache/ambari/shell/model/Focus.java | 53 ---
.../apache/ambari/shell/model/FocusType.java | 55 ---
.../org/apache/ambari/shell/model/Hints.java | 59 ---
.../ambari/shell/support/TableRenderer.java | 121 ------
ambari-shell/src/main/resources/elephant.txt | 8 -
.../shell/commands/BlueprintCommandsTest.java | 128 ------
.../shell/commands/ClusterCommandsTest.java | 279 -------------
.../ambari/shell/commands/HostCommandsTest.java | 66 ---
.../shell/customization/AmbariPromptTest.java | 54 ---
.../ambari/shell/model/AmbariContextTest.java | 66 ---
.../ambari/shell/support/TableRendererTest.java | 54 ---
ambari-shell/src/test/resources/2columns | 5 -
ambari-shell/src/test/resources/3columns | 5 -
.../src/test/resources/testBlueprint.json | 48 ---
102 files changed, 5039 insertions(+), 3064 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/ambari/blob/c8eceafc/ambari-client/python-client/src/main/python/ambari_client/ambari_api.py
----------------------------------------------------------------------
diff --git a/ambari-client/python-client/src/main/python/ambari_client/ambari_api.py b/ambari-client/python-client/src/main/python/ambari_client/ambari_api.py
index 470db36..a79d907 100644
--- a/ambari-client/python-client/src/main/python/ambari_client/ambari_api.py
+++ b/ambari-client/python-client/src/main/python/ambari_client/ambari_api.py
@@ -18,7 +18,7 @@
import logging
from ambari_client.core.http_client import HttpClient
from ambari_client.core.rest_resource import RestResource
-from ambari_client.model import blueprint, stack, cluster, host
+from ambari_client.model import blueprint, stack, cluster, host, status
__docformat__ = "epytext"
@@ -66,6 +66,13 @@ class AmbariClient(RestResource):
if port is None:
port = 8080
+ if not http_header:
+ http_header = {'X-Requested-By': 'pythonclient'}
+ elif 'X-Requested-By' not in http_header.keys():
+ http_header.update({'X-Requested-By': 'pythonclient'})
+ else:
+ pass
+
host_url = "%s://%s:%s/api/v%s" % (protocol, host_name, port, version)
if client is None:
client = HttpClient(host_url, user_name, password)
@@ -224,6 +231,15 @@ class AmbariClient(RestResource):
"""
return cluster._task_status(self, cluster_name, requestid)
+ def get_requests(self, cluster_name, noOfrequest=3):
+ """
+ get components from stack
+ @param version: The HDP version.
+ @param service_name: service name
+ @return: A ConfigModel object
+ """
+ return status._get_N_requests(self, cluster_name, noOfrequest)
+
def get_blueprint(self, blueprint_name=None):
"""
get blueprint
@@ -232,6 +248,14 @@ class AmbariClient(RestResource):
"""
return blueprint.get_blueprint(self, blueprint_name)
+ def get_cluster_blueprint(self, cluster_name):
+ """
+ get blueprint
+ @param cluster_name:cluster_name name.
+ @return: A BlueprintModel object
+ """
+ return blueprint.get_cluster_blueprint(self, cluster_name)
+
def delete_blueprint(self, blueprint_name=None):
"""
get blueprint
http://git-wip-us.apache.org/repos/asf/ambari/blob/c8eceafc/ambari-client/python-client/src/main/python/ambari_client/core/http_client.py
----------------------------------------------------------------------
diff --git a/ambari-client/python-client/src/main/python/ambari_client/core/http_client.py b/ambari-client/python-client/src/main/python/ambari_client/core/http_client.py
index 299b279..72b3b5f 100644
--- a/ambari-client/python-client/src/main/python/ambari_client/core/http_client.py
+++ b/ambari-client/python-client/src/main/python/ambari_client/core/http_client.py
@@ -103,6 +103,13 @@ class HttpClient(object):
self.c.setopt(pycurl.WRITEFUNCTION, buf.write)
self.c.setopt(pycurl.SSL_VERIFYPEER, 0)
+ # make sure options are reset from previous requests or your GET might
+ # become a DELETE
+ self.c.setopt(pycurl.CUSTOMREQUEST, None)
+ self.c.setopt(pycurl.HTTPGET, 0)
+ self.c.setopt(pycurl.NOBODY, 0)
+ self.c.setopt(pycurl.POST, 0)
+
LOG.debug("invoke : url = " + str(url))
# set http_method
if http_method == "GET":
@@ -121,9 +128,9 @@ class HttpClient(object):
if http_method in ('POST', 'PUT'):
LOG.debug("data..........." + str(payload))
data = json.dumps(payload)
- #data= data.decode('unicode-escape')
- #LOG.debug( "after unicode decode")
- #LOG.debug( data)
+ # data= data.decode('unicode-escape')
+ # LOG.debug( "after unicode decode")
+ # LOG.debug( data)
data = self._to_bytestring(data)
LOG.debug("after _to_bytestring")
LOG.debug(data)
http://git-wip-us.apache.org/repos/asf/ambari/blob/c8eceafc/ambari-client/python-client/src/main/python/ambari_client/model/blueprint.py
----------------------------------------------------------------------
diff --git a/ambari-client/python-client/src/main/python/ambari_client/model/blueprint.py b/ambari-client/python-client/src/main/python/ambari_client/model/blueprint.py
index 8497dc6..e207a6b 100644
--- a/ambari-client/python-client/src/main/python/ambari_client/model/blueprint.py
+++ b/ambari-client/python-client/src/main/python/ambari_client/model/blueprint.py
@@ -15,6 +15,7 @@
# limitations under the License.
import logging
+import json
from ambari_client.model.base_model import BaseModel, ModelList
from ambari_client.model import paths, utils, status
@@ -46,6 +47,33 @@ def get_blueprint(resource_root, blueprint_name):
"Blueprints")
+def get_cluster_blueprint(resource_root, cluster_name):
+ """
+ Get all Blueprint
+ @param root_resource: The root Resource .
+ @param name: blueprint_name
+ @return: A list of BlueprintModel objects.
+ """
+ resp = resource_root.get(paths.BLUEPRINT_CLUSTER_PATH % cluster_name)
+ result = json.dumps(resp)
+ resp_dictt = json.loads(result)
+ objects = [
+ utils.ModelUtils.create_model(
+ BlueprintHostModel,
+ x,
+ resource_root,
+ "NO_KEY") for x in resp_dictt['host_groups']]
+ LOG.debug(objects)
+
+ bluep = utils.ModelUtils.create_model(
+ BlueprintModel,
+ resp,
+ resource_root,
+ "Blueprints")
+
+ return bluep, ModelList(objects)
+
+
def delete_blueprint(resource_root, blueprint_name):
"""
Delete a blueprint by name
@@ -93,6 +121,31 @@ class BlueprintModel(BaseModel):
return "<<BlueprintModel>> blueprint_name = %s " % (
self.blueprint_name)
+ def _get_cluster_name(self):
+ if self.clusterRef:
+ return self.clusterRef.cluster_name
+ return None
+
+
+class BlueprintHostModel(BaseModel):
+
+ """
+ The BlueprintHostModel class
+ """
+ RO_ATTR = ('blueprint_name',)
+ RW_ATTR = ('name', 'components', 'cardinality')
+ REF_ATTR = ()
+
+ def __init__(self, resource_root, name, components, cardinality):
+ utils.retain_self_helper(BaseModel, **locals())
+
+ def __str__(self):
+ return "<<BlueprintHostModel>> name = %s ,components =%s" % (
+ self.name, str(self.components))
+
+ def to_json(self):
+ pass
+
class BlueprintConfigModel(BaseModel):
http://git-wip-us.apache.org/repos/asf/ambari/blob/c8eceafc/ambari-client/python-client/src/main/python/ambari_client/model/host.py
----------------------------------------------------------------------
diff --git a/ambari-client/python-client/src/main/python/ambari_client/model/host.py b/ambari-client/python-client/src/main/python/ambari_client/model/host.py
index 05bdf6e..f6c39d6 100644
--- a/ambari-client/python-client/src/main/python/ambari_client/model/host.py
+++ b/ambari-client/python-client/src/main/python/ambari_client/model/host.py
@@ -219,8 +219,11 @@ def _bootstrap_hosts(root_resource, hosts_list, ssh_key, ssh_user):
@param hosts_list list of host_names.
@return: A StatusModel object.
"""
- payload_dic = {"verbose":True, "sshKey": ssh_key.encode(
- 'string_escape') , "hosts":str(hosts_list) , "user": ssh_user }
+ payload_dic = {
+ "verbose": True,
+ "sshKey": ssh_key,
+ "hosts": str(hosts_list),
+ "user": ssh_user}
resp = root_resource.post(
paths.BOOTSTRAP_PATH,
payload_dic,
http://git-wip-us.apache.org/repos/asf/ambari/blob/c8eceafc/ambari-client/python-client/src/main/python/ambari_client/model/paths.py
----------------------------------------------------------------------
diff --git a/ambari-client/python-client/src/main/python/ambari_client/model/paths.py b/ambari-client/python-client/src/main/python/ambari_client/model/paths.py
index 3643129..e111824 100644
--- a/ambari-client/python-client/src/main/python/ambari_client/model/paths.py
+++ b/ambari-client/python-client/src/main/python/ambari_client/model/paths.py
@@ -40,6 +40,7 @@ HOSTS_ASSIGN_ROLE = "/clusters/%s/hosts?Hosts/host_name=%s"
BOOTSTRAP_PATH = "/bootstrap"
REQUEST_STATUS_PATH = "/clusters/%s/requests/%s?fields=tasks/Tasks/status"
REQUEST_PATH = "clusters/%s/requests/%s"
+REQUEST_N_PATH = "clusters/%s/requests?to=end&page_size=%s&fields=Requests"
CONFIGURATION_PATH = "/clusters/%s/configurations?type=%s&tag=%s"
CONFIGURATION_ALL_PATH = "/clusters/%s/configurations?type=%s"
@@ -57,3 +58,4 @@ TASKS_PATH = "clusters/%s/requests/%s/tasks?fields=*"
BLUEPRINT_ALL_PATH = "blueprints?fields=*"
BLUEPRINT_PATH = "blueprints/%s"
+BLUEPRINT_CLUSTER_PATH = "clusters/%s?format=blueprint"
http://git-wip-us.apache.org/repos/asf/ambari/blob/c8eceafc/ambari-client/python-client/src/main/python/ambari_client/model/status.py
----------------------------------------------------------------------
diff --git a/ambari-client/python-client/src/main/python/ambari_client/model/status.py b/ambari-client/python-client/src/main/python/ambari_client/model/status.py
index 37ca8fd..8ef1140 100644
--- a/ambari-client/python-client/src/main/python/ambari_client/model/status.py
+++ b/ambari-client/python-client/src/main/python/ambari_client/model/status.py
@@ -15,7 +15,7 @@
# limitations under the License.
import logging
-from ambari_client.model.base_model import BaseModel
+from ambari_client.model.base_model import BaseModel, ModelList
from ambari_client.model import paths, utils
@@ -32,7 +32,7 @@ class StatusModel(BaseModel):
REF_ATTR = ('cluster_name',)
def __init__(self, resource_root, status, requestId=None, message=None):
- #BaseModel.__init__(self, **locals())
+ # BaseModel.__init__(self, **locals())
utils.retain_self_helper(BaseModel, **locals())
def __str__(self):
@@ -72,3 +72,41 @@ class StatusModel(BaseModel):
return self.status
else:
None
+
+
+def _get_N_requests(resource_root, cluster_name, noOfrequest):
+ """
+ Get all services in a cluster.
+ @param cluster_name :Cluster name.
+ @return: A ModelList object.
+ """
+ path = paths.REQUEST_N_PATH % (cluster_name, noOfrequest)
+ dic = resource_root.get(path)
+ return utils.ModelUtils.get_model_list(
+ ModelList,
+ RequestModel,
+ dic,
+ resource_root,
+ "Requests")
+
+
+class RequestModel(BaseModel):
+
+ """
+ The RequestModel class
+ """
+ RO_ATTR = ("request_context",)
+ RW_ATTR = ('id', 'request_status')
+ REF_ATTR = ('cluster_name',)
+
+ def __init__(self, resource_root, id, request_status=None):
+ # BaseModel.__init__(self, **locals())
+ utils.retain_self_helper(BaseModel, **locals())
+
+ def __str__(self):
+ return "<<RequestModel>> id = %s ; request_status = %s" % (
+ self.id, self.request_status)
+
+ def is_error(self):
+ return (
+ self.status != 200 and self.status != 201 and self.status != 202)
http://git-wip-us.apache.org/repos/asf/ambari/blob/c8eceafc/ambari-client/python-client/src/main/python/ambari_client/model/utils.py
----------------------------------------------------------------------
diff --git a/ambari-client/python-client/src/main/python/ambari_client/model/utils.py b/ambari-client/python-client/src/main/python/ambari_client/model/utils.py
index e1f1479..65dd153 100644
--- a/ambari-client/python-client/src/main/python/ambari_client/model/utils.py
+++ b/ambari-client/python-client/src/main/python/ambari_client/model/utils.py
@@ -162,12 +162,20 @@ class ModelUtils(object):
rw_dict = {}
LOG.debug("model_dict = " + str(model_dict))
+ # extract model /keyword
if isinstance(model_dict, dict) and RESOURCE_KEY_WORD in model_dict:
model_dict = model_dict[RESOURCE_KEY_WORD]
- LOG.debug(
- "model_dict has %s ;subset = %s" %
- (RESOURCE_KEY_WORD, str(
- model_dict.items())))
+ if not isinstance(model_dict, list):
+ LOG.debug(
+ "model_dict has %s ;subset = %s" %
+ (RESOURCE_KEY_WORD, str(
+ model_dict.items())))
+ else:
+ LOG.debug(
+ "model_dict is list and has %s ;subset = %s" %
+ (RESOURCE_KEY_WORD, str(
+ model_dict)))
+ # check for Requests
if isinstance(model_dict, dict) and "Requests" in model_dict:
model_dict = model_dict["Requests"]
LOG.debug(
@@ -175,12 +183,17 @@ class ModelUtils(object):
(str(
model_dict.items())))
- for k, v in model_dict.items():
- LOG.debug("key = %s ; value = %s " % (str(k), str(v)))
- if k in model_cls.RW_ATTR:
- LOG.debug(k + " is there in RW_ATTR")
- rw_dict[k] = v
- del model_dict[k]
+ # check for composition i.e list of Models
+ if isinstance(model_dict, list):
+ LOG.debug(
+ "model_dict is list")
+ else:
+ for k, v in model_dict.items():
+ LOG.debug("key = %s ; value = %s " % (str(k), str(v)))
+ if k in model_cls.RW_ATTR:
+ LOG.debug(k + " is there in RW_ATTR")
+ rw_dict[k] = v
+ del model_dict[k]
rw_dict = get_unicode_kw(rw_dict)
obj = model_cls(resource_root, **rw_dict)
@@ -238,7 +251,7 @@ def get_REF_object(ref_class_name):
def get_unicode(v):
- #import unicodedata
+ # import unicodedata
if v:
if isinstance(v, unicode):
v = unicodedata.normalize('NFKD', v).encode('ascii', 'ignore')
@@ -249,8 +262,8 @@ def get_unicode(v):
def retain_self_helper(memclass, self=None, **kwargs):
- # print locals()
- #from ambari_client.model.base_model import BaseModel
+ # print locals()
+ # from ambari_client.model.base_model import BaseModel
memclass.__init__(self, **kwargs)
http://git-wip-us.apache.org/repos/asf/ambari/blob/c8eceafc/ambari-shell/ambari-groovy-shell/pom.xml
----------------------------------------------------------------------
diff --git a/ambari-shell/ambari-groovy-shell/pom.xml b/ambari-shell/ambari-groovy-shell/pom.xml
new file mode 100644
index 0000000..a1acf8b
--- /dev/null
+++ b/ambari-shell/ambari-groovy-shell/pom.xml
@@ -0,0 +1,142 @@
+<?xml version="1.0"?>
+<!-- Licensed under the Apache License, Version 2.0 (the "License"); you
+ may not use this file except in compliance with the License. You may obtain
+ a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless
+ required by applicable law or agreed to in writing, software distributed
+ under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES
+ OR CONDITIONS OF ANY KIND, either express or implied. See the License for
+ the specific language governing permissions and limitations under the License.
+ See accompanying LICENSE file. -->
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+ <parent>
+ <groupId>org.apache.ambari</groupId>
+ <artifactId>ambari-shell</artifactId>
+ <version>1.3.0-SNAPSHOT</version>
+ <relativePath>../../ambari-shell</relativePath>
+ </parent>
+ <modelVersion>4.0.0</modelVersion>
+ <groupId>org.apache.ambari</groupId>
+ <artifactId>ambari-groovy-shell</artifactId>
+ <packaging>jar</packaging>
+ <name>Ambari Groovy Shell</name>
+ <version>1.3.0-SNAPSHOT</version>
+ <description>Ambari Groovy Shell</description>
+ <properties>
+ <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
+ <start-class>org.apache.ambari.shell.AmbariShell</start-class>
+ </properties>
+ <dependencies>
+ <dependency>
+ <groupId>junit</groupId>
+ <artifactId>junit</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.springframework.shell</groupId>
+ <artifactId>spring-shell</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.springframework.boot</groupId>
+ <artifactId>spring-boot-starter</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.springframework.boot</groupId>
+ <artifactId>spring-boot-starter-test</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>com.github.lalyos</groupId>
+ <artifactId>jfiglet</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>commons-io</groupId>
+ <artifactId>commons-io</artifactId>
+ <version>2.3</version>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.ambari</groupId>
+ <artifactId>groovy-client</artifactId>
+ <version>1.3.0-SNAPSHOT</version>
+ </dependency>
+ <dependency>
+ <groupId>org.mockito</groupId>
+ <artifactId>mockito-core</artifactId>
+ <version>1.9.5</version>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>jline</groupId>
+ <artifactId>jline</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.codehaus.jackson</groupId>
+ <artifactId>jackson-mapper-asl</artifactId>
+ </dependency>
+ </dependencies>
+ <build>
+ <plugins>
+ <plugin>
+ <artifactId>maven-compiler-plugin</artifactId>
+ <version>3.0</version>
+ </plugin>
+ <plugin>
+ <groupId>org.apache.rat</groupId>
+ <artifactId>apache-rat-plugin</artifactId>
+ <configuration>
+ <excludes>
+ <exclude>src/main/resources/elephant.txt</exclude>
+ <exclude>src/test/resources/2columns</exclude>
+ <exclude>src/test/resources/3columns</exclude>
+ <exclude>src/test/resources/testBlueprint.json</exclude>
+ </excludes>
+ </configuration>
+ <executions>
+ <execution>
+ <phase>test</phase>
+ <goals>
+ <goal>check</goal>
+ </goals>
+ </execution>
+ </executions>
+ </plugin>
+ <plugin>
+ <artifactId>maven-assembly-plugin</artifactId>
+ <configuration>
+ <skipAssembly>true</skipAssembly>
+ </configuration>
+ </plugin>
+ <plugin>
+ <groupId>org.springframework.boot</groupId>
+ <artifactId>spring-boot-maven-plugin</artifactId>
+ <version>1.0.2.RELEASE</version>
+ <executions>
+ <execution>
+ <goals>
+ <goal>repackage</goal>
+ </goals>
+ </execution>
+ </executions>
+ <configuration>
+ <mainClass>${start-class}</mainClass>
+ </configuration>
+ </plugin>
+ <plugin>
+ <groupId>org.vafer</groupId>
+ <artifactId>jdeb</artifactId>
+ <version>1.0.1</version>
+ <executions>
+ <execution>
+ <phase>none</phase>
+ <goals>
+ <goal>jdeb</goal>
+ </goals>
+ </execution>
+ </executions>
+ <configuration>
+ <controlDir>${basedir}/../../ambari-project/src/main/package/deb/control</controlDir>
+ <skip>true</skip>
+ <submodules>false</submodules>
+ </configuration>
+ </plugin>
+ </plugins>
+ </build>
+</project>
http://git-wip-us.apache.org/repos/asf/ambari/blob/c8eceafc/ambari-shell/ambari-groovy-shell/src/main/java/org/apache/ambari/shell/AmbariShell.java
----------------------------------------------------------------------
diff --git a/ambari-shell/ambari-groovy-shell/src/main/java/org/apache/ambari/shell/AmbariShell.java b/ambari-shell/ambari-groovy-shell/src/main/java/org/apache/ambari/shell/AmbariShell.java
new file mode 100644
index 0000000..e842620
--- /dev/null
+++ b/ambari-shell/ambari-groovy-shell/src/main/java/org/apache/ambari/shell/AmbariShell.java
@@ -0,0 +1,111 @@
+/**
+ * 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.ambari.shell;
+
+import org.apache.ambari.groovy.client.AmbariClient;
+import org.apache.ambari.shell.model.AmbariContext;
+import org.apache.ambari.shell.model.Hints;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.CommandLineRunner;
+import org.springframework.boot.builder.SpringApplicationBuilder;
+import org.springframework.context.annotation.ComponentScan;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.shell.CommandLine;
+import org.springframework.shell.core.JLineShellComponent;
+import org.springframework.shell.event.ShellStatus;
+import org.springframework.shell.event.ShellStatusListener;
+
+/**
+ * Shell bootstrap.
+ */
+@Configuration
+@ComponentScan(basePackageClasses = {AmbariShell.class})
+public class AmbariShell implements CommandLineRunner, ShellStatusListener {
+
+ @Autowired
+ private CommandLine commandLine;
+ @Autowired
+ private JLineShellComponent shell;
+ @Autowired
+ private AmbariContext context;
+ @Autowired
+ private AmbariClient client;
+
+ @Override
+ public void run(String... arg) throws Exception {
+ String[] shellCommandsToExecute = commandLine.getShellCommandsToExecute();
+ if (shellCommandsToExecute != null) {
+ for (String cmd : shellCommandsToExecute) {
+ if (!shell.executeScriptLine(cmd)) {
+ break;
+ }
+ }
+ System.exit(0);
+ } else {
+ shell.addShellStatusListener(this);
+ shell.start();
+ shell.promptLoop();
+ shell.waitForComplete();
+ }
+ }
+
+ @Override
+ public void onShellStatusChange(ShellStatus oldStatus, ShellStatus newStatus) {
+ if (newStatus.getStatus() == ShellStatus.Status.STARTED) {
+ try {
+ String cluster = client.getClusterName();
+ boolean available = client.isBlueprintAvailable();
+ if (cluster == null) {
+ if (available) {
+ context.setHint(Hints.BUILD_CLUSTER);
+ } else {
+ context.setHint(Hints.ADD_BLUEPRINT);
+ }
+ } else {
+ context.setHint(Hints.PROGRESS);
+ }
+ context.setCluster(cluster);
+ context.setBlueprintsAvailable(available);
+ } catch (Exception e) {
+ System.out.println(e.getMessage());
+ shell.executeCommand("quit");
+ }
+ }
+ }
+
+
+ public static void main(String[] args) {
+ if (args.length == 0) {
+ System.out.println(
+ "\nAmbari Shell: Interactive command line tool for managing Apache Ambari.\n\n" +
+ "Usage:\n" +
+ " java -jar ambari-shell.jar : Starts Ambari Shell in interactive mode.\n" +
+ " java -jar ambari-shell.jar --cmdfile=<FILE> : Ambari Shell executes commands read from the file.\n\n" +
+ "Options:\n" +
+ " --ambari.host=<HOSTNAME> Hostname of the Ambari Server [default: localhost].\n" +
+ " --ambari.port=<PORT> Port of the Ambari Server [default: 8080].\n" +
+ " --ambari.user=<USER> Username of the Ambari admin [default: admin].\n" +
+ " --ambari.password=<PASSWORD> Password of the Ambari admin [default: admin].\n\n" +
+ "Note:\n" +
+ " At least one option is mandatory."
+ );
+ System.exit(1);
+ }
+ new SpringApplicationBuilder(AmbariShell.class).showBanner(false).run(args);
+ }
+}
http://git-wip-us.apache.org/repos/asf/ambari/blob/c8eceafc/ambari-shell/ambari-groovy-shell/src/main/java/org/apache/ambari/shell/commands/BasicCommands.java
----------------------------------------------------------------------
diff --git a/ambari-shell/ambari-groovy-shell/src/main/java/org/apache/ambari/shell/commands/BasicCommands.java b/ambari-shell/ambari-groovy-shell/src/main/java/org/apache/ambari/shell/commands/BasicCommands.java
new file mode 100644
index 0000000..9babe12
--- /dev/null
+++ b/ambari-shell/ambari-groovy-shell/src/main/java/org/apache/ambari/shell/commands/BasicCommands.java
@@ -0,0 +1,207 @@
+/**
+ * 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.ambari.shell.commands;
+
+import static org.apache.ambari.shell.support.TableRenderer.renderMapValueMap;
+import static org.apache.ambari.shell.support.TableRenderer.renderSingleMap;
+
+import org.apache.ambari.groovy.client.AmbariClient;
+import org.apache.ambari.shell.model.AmbariContext;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.shell.core.CommandMarker;
+import org.springframework.shell.core.annotation.CliAvailabilityIndicator;
+import org.springframework.shell.core.annotation.CliCommand;
+import org.springframework.shell.core.annotation.CliOption;
+import org.springframework.stereotype.Component;
+
+/**
+ * Basic commands used in the shell. Delegating the commands
+ * to the Ambari Server via a Groovy based client.
+ *
+ * @see org.apache.ambari.groovy.client.AmbariClient
+ */
+@Component
+public class BasicCommands implements CommandMarker {
+
+ private AmbariClient client;
+ private AmbariContext context;
+
+ @Autowired
+ public BasicCommands(AmbariClient client, AmbariContext context) {
+ this.client = client;
+ this.context = context;
+ }
+
+ /**
+ * Checks whether the tasks command is available or not.
+ *
+ * @return true if its available false otherwise
+ */
+ @CliAvailabilityIndicator("tasks")
+ public boolean isTasksCommandAvailable() {
+ return context.isConnectedToCluster();
+ }
+
+ /**
+ * Prints the tasks of the Ambari Server.
+ *
+ * @param id id of the request
+ * @return task list
+ */
+ @CliCommand(value = "tasks", help = "Lists the Ambari tasks")
+ public String tasks(
+ @CliOption(key = "id", mandatory = false, help = "Id of the request; default is: 1", unspecifiedDefaultValue = "1") String id) {
+ return renderSingleMap(client.getTaskMap(id), "TASK", "STATUS");
+ }
+
+ /**
+ * Checks whether the service list command is available or not.
+ *
+ * @return true if available false otherwise
+ */
+ @CliAvailabilityIndicator("services list")
+ public boolean isServiceListCommandAvailable() {
+ return context.isConnectedToCluster();
+ }
+
+ /**
+ * Prints the available service list of the Ambari Server.
+ *
+ * @return service list
+ */
+ @CliCommand(value = "services list", help = "Lists the available services")
+ public String servicesList() {
+ return renderSingleMap(client.getServicesMap(), "SERVICE", "STATE");
+ }
+
+ /**
+ * Checks whether the service components command is available or not.
+ *
+ * @return true if available false otherwise
+ */
+ @CliAvailabilityIndicator("services components")
+ public boolean isServiceComponentsCommandAvailable() {
+ return context.isConnectedToCluster();
+ }
+
+ /**
+ * Prints the service components of the Ambari Server.
+ *
+ * @return service component list
+ */
+ @CliCommand(value = "services components", help = "Lists all services with their components")
+ public String serviceComponents() {
+ return renderMapValueMap(client.getServiceComponentsMap(), "SERVICE", "COMPONENT", "STATE");
+ }
+
+ /**
+ * Checks whether the debug on command is available or not.
+ *
+ * @return true if available false otherwise
+ */
+ @CliAvailabilityIndicator("debug on")
+ public boolean isDebugOnCommandAvailable() {
+ return !client.isDebugEnabled();
+ }
+
+ /**
+ * Turns the debug on. From now on users will see the URLs of the API calls.
+ *
+ * @return status message
+ */
+ @CliCommand(value = "debug on", help = "Shows the URL of the API calls")
+ public String debugOn() {
+ client.setDebugEnabled(true);
+ return "debug enabled";
+ }
+
+ /**
+ * Checks whether the debug off command is available or not.
+ *
+ * @return true if available false otherwise
+ */
+ @CliAvailabilityIndicator("debug off")
+ public boolean isDebugOffCommandAvailable() {
+ return client.isDebugEnabled();
+ }
+
+ /**
+ * Turns the debug off. URLs are not visible anymore.
+ *
+ * @return status message
+ */
+ @CliCommand(value = "debug off", help = "Stops showing the URL of the API calls")
+ public String debugOff() {
+ client.setDebugEnabled(false);
+ return "debug disabled";
+ }
+
+ /**
+ * Checks whether the hint command is available or not.
+ *
+ * @return true if available false otherwise
+ */
+ @CliAvailabilityIndicator("hint")
+ public boolean isHintCommandAvailable() {
+ return true;
+ }
+
+ /**
+ * Provides some hints what you can do in the current context.
+ *
+ * @return hint message
+ */
+ @CliCommand(value = "hint", help = "Shows some hints")
+ public String hint() {
+ return context.getHint();
+ }
+
+ @CliAvailabilityIndicator("services stop")
+ public boolean isServiceStopCommandAvailable() {
+ return context.isConnectedToCluster();
+ }
+
+ @CliCommand(value = "services stop", help = "Stops all the running services")
+ public String stopServices() {
+ String message;
+ try {
+ client.stopAllServices();
+ message = "Stopping all services..";
+ } catch (Exception e) {
+ message = "Cannot stop services";
+ }
+ return String.format("%s\n\n%s", message, servicesList());
+ }
+
+ @CliAvailabilityIndicator("services start")
+ public boolean isServiceStartCommandAvailable() {
+ return context.isConnectedToCluster();
+ }
+
+ @CliCommand(value = "services start", help = "Starts all the services")
+ public String startServices() {
+ String message;
+ try {
+ client.startAllServices();
+ message = "Starting all services..";
+ } catch (Exception e) {
+ message = "Cannot start services";
+ }
+ return String.format("%s\n\n%s", message, servicesList());
+ }
+}
http://git-wip-us.apache.org/repos/asf/ambari/blob/c8eceafc/ambari-shell/ambari-groovy-shell/src/main/java/org/apache/ambari/shell/commands/BlueprintCommands.java
----------------------------------------------------------------------
diff --git a/ambari-shell/ambari-groovy-shell/src/main/java/org/apache/ambari/shell/commands/BlueprintCommands.java b/ambari-shell/ambari-groovy-shell/src/main/java/org/apache/ambari/shell/commands/BlueprintCommands.java
new file mode 100644
index 0000000..73000d0
--- /dev/null
+++ b/ambari-shell/ambari-groovy-shell/src/main/java/org/apache/ambari/shell/commands/BlueprintCommands.java
@@ -0,0 +1,198 @@
+/**
+ * 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.ambari.shell.commands;
+
+import static org.apache.ambari.shell.support.TableRenderer.renderMultiValueMap;
+import static org.apache.ambari.shell.support.TableRenderer.renderSingleMap;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.net.URL;
+
+import org.apache.ambari.groovy.client.AmbariClient;
+import org.apache.ambari.shell.completion.Blueprint;
+import org.apache.ambari.shell.model.AmbariContext;
+import org.apache.ambari.shell.model.Hints;
+import org.apache.commons.io.IOUtils;
+import org.codehaus.jackson.map.ObjectMapper;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.shell.core.CommandMarker;
+import org.springframework.shell.core.annotation.CliAvailabilityIndicator;
+import org.springframework.shell.core.annotation.CliCommand;
+import org.springframework.shell.core.annotation.CliOption;
+import org.springframework.stereotype.Component;
+
+/**
+ * Blueprint related commands used in the shell.
+ *
+ * @see org.apache.ambari.groovy.client.AmbariClient
+ */
+@Component
+public class BlueprintCommands implements CommandMarker {
+
+ private AmbariClient client;
+ private AmbariContext context;
+ private ObjectMapper jsonMapper;
+
+ @Autowired
+ public BlueprintCommands(AmbariClient client, AmbariContext context, ObjectMapper jsonMapper) {
+ this.client = client;
+ this.context = context;
+ this.jsonMapper = jsonMapper;
+ }
+
+ /**
+ * Checks whether the blueprints command is available or not.
+ *
+ * @return true if available false otherwise
+ */
+ @CliAvailabilityIndicator("blueprint list")
+ public boolean isBlueprintListCommandAvailable() {
+ return context.areBlueprintsAvailable();
+ }
+
+ /**
+ * Prints all the blueprints.
+ *
+ * @return list of blueprints
+ */
+ @CliCommand(value = "blueprint list", help = "Lists all known blueprints")
+ public String listBlueprints() {
+ return renderSingleMap(client.getBlueprintsMap(), "BLUEPRINT", "STACK");
+ }
+
+ /**
+ * Checks whether the blueprint show command is available or not.
+ *
+ * @return true if available false otherwise
+ */
+ @CliAvailabilityIndicator(value = "blueprint show")
+ public boolean isBlueprintShowCommandAvailable() {
+ return context.areBlueprintsAvailable();
+ }
+
+ /**
+ * Shows the requested blueprint's details.
+ *
+ * @param id id of the blueprint
+ * @return blueprint as formatted table
+ */
+ @CliCommand(value = "blueprint show", help = "Shows the blueprint by its id")
+ public String showBlueprint(
+ @CliOption(key = "id", mandatory = true, help = "Id of the blueprint") Blueprint id) {
+ return renderMultiValueMap(client.getBlueprintMap(id.getName()), "HOSTGROUP", "COMPONENT");
+ }
+
+ /**
+ * Checks whether the blueprint add command is available or not.
+ *
+ * @return true if available false otherwise
+ */
+ @CliAvailabilityIndicator(value = "blueprint add")
+ public boolean isBlueprintAddCommandAvailable() {
+ return true;
+ }
+
+ /**
+ * Adds a blueprint to the Ambari server either through an URL or from a file.
+ * If both specified the file takes precedence.
+ *
+ * @param url -optional, URL containing the blueprint json
+ * @param file - optional, file containing the blueprint json
+ * @return status message
+ */
+ @CliCommand(value = "blueprint add", help = "Add a new blueprint with either --url or --file")
+ public String addBlueprint(
+ @CliOption(key = "url", mandatory = false, help = "URL of the blueprint to download from") String url,
+ @CliOption(key = "file", mandatory = false, help = "File which contains the blueprint") File file) {
+ String message;
+ try {
+ String json = file == null ? readContent(url) : readContent(file);
+ if (json != null) {
+ client.addBlueprint(json);
+ context.setHint(Hints.BUILD_CLUSTER);
+ context.setBlueprintsAvailable(true);
+ message = String.format("Blueprint: '%s' has been added", getBlueprintName(json));
+ } else {
+ message = "No blueprint specified";
+ }
+ } catch (Exception e) {
+ message = "Cannot add blueprint: " + e.getMessage();
+ }
+ return message;
+ }
+
+ /**
+ * Checks whether the blueprint defaults command is available or not.
+ *
+ * @return true if available false otherwise
+ */
+ @CliAvailabilityIndicator(value = "blueprint defaults")
+ public boolean isBlueprintDefaultsAddCommandAvailable() {
+ return !context.areBlueprintsAvailable();
+ }
+
+ /**
+ * Adds two default blueprints to the Ambari server.
+ *
+ * @return status message
+ */
+ @CliCommand(value = "blueprint defaults", help = "Adds the default blueprints to Ambari")
+ public String addBlueprint() {
+ String message = "Default blueprints added";
+ try {
+ client.addDefaultBlueprints();
+ context.setHint(Hints.BUILD_CLUSTER);
+ context.setBlueprintsAvailable(true);
+ } catch (Exception e) {
+ message = "Failed to add the default blueprints: " + e.getMessage();
+ }
+ return message;
+ }
+
+ private String readContent(File file) {
+ String content = null;
+ try {
+ content = IOUtils.toString(new FileInputStream(file));
+ } catch (IOException e) {
+ // not important
+ }
+ return content;
+ }
+
+ private String readContent(String url) {
+ String content = null;
+ try {
+ content = IOUtils.toString(new URL(url));
+ } catch (IOException e) {
+ // not important
+ }
+ return content;
+ }
+
+ private String getBlueprintName(String json) {
+ String result = "";
+ try {
+ result = jsonMapper.readTree(json.getBytes()).get("Blueprints").get("blueprint_name").asText();
+ } catch (IOException e) {
+ // not important
+ }
+ return result;
+ }
+}
http://git-wip-us.apache.org/repos/asf/ambari/blob/c8eceafc/ambari-shell/ambari-groovy-shell/src/main/java/org/apache/ambari/shell/commands/ClusterCommands.java
----------------------------------------------------------------------
diff --git a/ambari-shell/ambari-groovy-shell/src/main/java/org/apache/ambari/shell/commands/ClusterCommands.java b/ambari-shell/ambari-groovy-shell/src/main/java/org/apache/ambari/shell/commands/ClusterCommands.java
new file mode 100644
index 0000000..dafdb85
--- /dev/null
+++ b/ambari-shell/ambari-groovy-shell/src/main/java/org/apache/ambari/shell/commands/ClusterCommands.java
@@ -0,0 +1,294 @@
+/**
+ * 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.ambari.shell.commands;
+
+import static org.apache.ambari.shell.support.TableRenderer.renderMultiValueMap;
+import static org.apache.ambari.shell.support.TableRenderer.renderSingleMap;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import org.apache.ambari.groovy.client.AmbariClient;
+import org.apache.ambari.shell.completion.Blueprint;
+import org.apache.ambari.shell.completion.Host;
+import org.apache.ambari.shell.flash.FlashService;
+import org.apache.ambari.shell.model.AmbariContext;
+import org.apache.ambari.shell.model.FocusType;
+import org.apache.ambari.shell.model.Hints;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.shell.core.CommandMarker;
+import org.springframework.shell.core.annotation.CliAvailabilityIndicator;
+import org.springframework.shell.core.annotation.CliCommand;
+import org.springframework.shell.core.annotation.CliOption;
+import org.springframework.stereotype.Component;
+
+import groovyx.net.http.HttpResponseException;
+
+/**
+ * Cluster related commands used in the shell.
+ *
+ * @see org.apache.ambari.groovy.client.AmbariClient
+ */
+@Component
+public class ClusterCommands implements CommandMarker {
+
+ private AmbariClient client;
+ private AmbariContext context;
+ private FlashService flashService;
+ private Map<String, List<String>> hostGroups;
+
+ @Autowired
+ public ClusterCommands(AmbariClient client, AmbariContext context, FlashService flashService) {
+ this.client = client;
+ this.context = context;
+ this.flashService = flashService;
+ }
+
+ /**
+ * Checks whether the cluster build command is available or not.
+ *
+ * @return true if available false otherwise
+ */
+ @CliAvailabilityIndicator("cluster build")
+ public boolean isClusterBuildCommandAvailable() {
+ return !context.isConnectedToCluster() && !context.isFocusOnClusterBuild() && context.areBlueprintsAvailable();
+ }
+
+ /**
+ * Sets the focus on cluster building. Takes a blueprint id, if it does not exists it wont focus.
+ * After focus the users are able to assign hosts to host groups.
+ *
+ * @param id id of the blueprint
+ * @return prints the blueprint as formatted table if exists, otherwise error message
+ */
+ @CliCommand(value = "cluster build", help = "Starts to build a cluster")
+ public String buildCluster(
+ @CliOption(key = "blueprint", mandatory = true, help = "Id of the blueprint, use 'blueprints' command to see the list") Blueprint id) {
+ String message;
+ String blueprint = id.getName();
+ if (client.doesBlueprintExist(blueprint)) {
+ context.setFocus(blueprint, FocusType.CLUSTER_BUILD);
+ context.setHint(Hints.ASSIGN_HOSTS);
+ message = String.format("%s\n%s",
+ renderSingleMap(client.getHostNames(), "HOSTNAME", "STATE"),
+ renderMultiValueMap(client.getBlueprintMap(blueprint), "HOSTGROUP", "COMPONENT"));
+ createNewHostGroups();
+ } else {
+ message = "Not a valid blueprint id";
+ }
+ return message;
+ }
+
+ /**
+ * Checks whether the cluster assign command is available or not.
+ *
+ * @return true if available false otherwise
+ */
+ @CliAvailabilityIndicator("cluster assign")
+ public boolean isAssignCommandAvailable() {
+ return context.isFocusOnClusterBuild();
+ }
+
+ /**
+ * Assign hosts to host groups provided in the blueprint.
+ *
+ * @param host host to assign
+ * @param group which host group to
+ * @return status message
+ */
+ @CliCommand(value = "cluster assign", help = "Assign host to host group")
+ public String assign(
+ @CliOption(key = "host", mandatory = true, help = "Fully qualified host name") Host host,
+ @CliOption(key = "hostGroup", mandatory = true, help = "Host group which to assign the host") String group) {
+ String message;
+ String hostName = host.getName();
+ if (client.getHostNames().keySet().contains(hostName)) {
+ if (addHostToGroup(hostName, group)) {
+ context.setHint(Hints.CREATE_CLUSTER);
+ message = String.format("%s has been added to %s", hostName, group);
+ } else {
+ message = String.format("%s is not a valid host group", group);
+ }
+ } else {
+ message = String.format("%s is not a valid hostname", hostName);
+ }
+ return message;
+ }
+
+ /**
+ * Checks whether the cluster auto command is available or not.
+ *
+ * @return true if available false otherwise
+ */
+ @CliAvailabilityIndicator(value = "cluster autoAssign")
+ public boolean isClusterAutoAssignAvailable() {
+ return context.isFocusOnClusterBuild() && !isHostAssigned();
+ }
+
+ /**
+ * Tries to auto associate hosts to host groups.
+ *
+ * @return prints the auto assignments
+ */
+ @CliCommand(value = "cluster autoAssign", help = "Automatically assigns hosts to different host groups base on the provided strategy")
+ public String autoAssign() {
+ Map<String, List<String>> assignments = client.recommendAssignments(context.getFocusValue());
+ if (!assignments.isEmpty()) {
+ hostGroups = assignments;
+ context.setHint(Hints.CREATE_CLUSTER);
+ }
+ return showAssignments();
+ }
+
+ /**
+ * Checks whether the cluster preview command is available or not.
+ *
+ * @return true if available false otherwise
+ */
+ @CliAvailabilityIndicator("cluster preview")
+ public boolean isClusterPreviewCommandAvailable() {
+ return context.isFocusOnClusterBuild() && isHostAssigned();
+ }
+
+ /**
+ * Shows the currently assigned hosts.
+ *
+ * @return formatted host - host group table
+ */
+ @CliCommand(value = "cluster preview", help = "Shows the currently assigned hosts")
+ public String showAssignments() {
+ return renderMultiValueMap(hostGroups, "HOSTGROUP", "HOST");
+ }
+
+ /**
+ * Checks whether the cluster create command is available or not.
+ *
+ * @return true if available false otherwise
+ */
+ @CliAvailabilityIndicator("cluster create")
+ public boolean isCreateClusterCommandAvailable() {
+ return context.isFocusOnClusterBuild() && isHostAssigned();
+ }
+
+ /**
+ * Creates a new cluster based on the provided host - host group associations and the selected blueprint.
+ * If the cluster creation fails, deletes the cluster.
+ *
+ * @return status message
+ */
+ @CliCommand(value = "cluster create", help = "Create a cluster based on current blueprint and assigned hosts")
+ public String createCluster(
+ @CliOption(key = "exitOnFinish", mandatory = false, help = "Quits the shell when the cluster creation finishes") Boolean exit) {
+ String message = "Successfully created the cluster";
+ String blueprint = context.getFocusValue();
+ try {
+ client.createCluster(blueprint, blueprint, hostGroups);
+ context.setCluster(blueprint);
+ context.resetFocus();
+ context.setHint(Hints.PROGRESS);
+ flashService.showInstallProgress(exit == null ? false : exit);
+ } catch (HttpResponseException e) {
+ createNewHostGroups();
+ message = "Failed to create the cluster: " + e.getMessage();
+ try {
+ deleteCluster(blueprint);
+ } catch (HttpResponseException e1) {
+ message += ". Failed to cleanup cluster creation: " + e1.getMessage();
+ }
+ }
+ return message;
+ }
+
+ /**
+ * Checks whether the cluster delete command is available or not.
+ *
+ * @return true if available false otherwise
+ */
+ @CliAvailabilityIndicator("cluster delete")
+ public boolean isDeleteClusterCommandAvailable() {
+ return context.isConnectedToCluster();
+ }
+
+ /**
+ * Deletes the cluster.
+ *
+ * @return status message
+ */
+ @CliCommand(value = "cluster delete", help = "Delete the cluster")
+ public String deleteCluster() {
+ String message = "Successfully deleted the cluster";
+ try {
+ deleteCluster(context.getCluster());
+ } catch (HttpResponseException e) {
+ message = "Could not delete the cluster: " + e.getMessage();
+ }
+ return message;
+ }
+
+ /**
+ * Checks whether the cluster reset command is available or not.
+ *
+ * @return true if available false otherwise
+ */
+ @CliAvailabilityIndicator(value = "cluster reset")
+ public boolean isClusterResetCommandAvailable() {
+ return context.isFocusOnClusterBuild() && isHostAssigned();
+ }
+
+ @CliCommand(value = "cluster reset", help = "Clears the host - host group assignments")
+ public void reset() {
+ context.setHint(Hints.ASSIGN_HOSTS);
+ createNewHostGroups();
+ }
+
+ private void deleteCluster(String id) throws HttpResponseException {
+ client.deleteCluster(id);
+ }
+
+ private void createNewHostGroups() {
+ Map<String, List<String>> groups = new HashMap<String, List<String>>();
+ for (String hostGroup : client.getHostGroups(context.getFocusValue())) {
+ groups.put(hostGroup, new ArrayList<String>());
+ }
+ this.hostGroups = groups;
+ }
+
+ private boolean addHostToGroup(String host, String group) {
+ boolean result = true;
+ List<String> hosts = hostGroups.get(group);
+ if (hosts == null) {
+ result = false;
+ } else {
+ hosts.add(host);
+ }
+ return result;
+ }
+
+ private boolean isHostAssigned() {
+ boolean result = false;
+ for (String group : hostGroups.keySet()) {
+ if (!hostGroups.get(group).isEmpty()) {
+ result = true;
+ break;
+ }
+ }
+ return result;
+ }
+}
http://git-wip-us.apache.org/repos/asf/ambari/blob/c8eceafc/ambari-shell/ambari-groovy-shell/src/main/java/org/apache/ambari/shell/commands/ElephantCommand.java
----------------------------------------------------------------------
diff --git a/ambari-shell/ambari-groovy-shell/src/main/java/org/apache/ambari/shell/commands/ElephantCommand.java b/ambari-shell/ambari-groovy-shell/src/main/java/org/apache/ambari/shell/commands/ElephantCommand.java
new file mode 100644
index 0000000..a236054
--- /dev/null
+++ b/ambari-shell/ambari-groovy-shell/src/main/java/org/apache/ambari/shell/commands/ElephantCommand.java
@@ -0,0 +1,53 @@
+/**
+ * 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.ambari.shell.commands;
+
+import java.io.IOException;
+
+import org.apache.commons.io.IOUtils;
+import org.springframework.shell.core.CommandMarker;
+import org.springframework.shell.core.annotation.CliAvailabilityIndicator;
+import org.springframework.shell.core.annotation.CliCommand;
+import org.springframework.stereotype.Component;
+
+/**
+ * Draws an elephant to the console.
+ */
+@Component
+public class ElephantCommand implements CommandMarker {
+
+ /**
+ * Checks whether the hello command is available or not.
+ *
+ * @return true if available false otherwise
+ */
+ @CliAvailabilityIndicator("hello")
+ public boolean isCommandAvailable() {
+ return true;
+ }
+
+ /**
+ * Prints an elephant to the console.
+ *
+ * @return elephant
+ */
+ @CliCommand(value = "hello", help = "Prints a simple elephant to the console")
+ public String elephant() throws IOException {
+ return IOUtils.toString(getClass().getResourceAsStream("/elephant.txt"));
+ }
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/ambari/blob/c8eceafc/ambari-shell/ambari-groovy-shell/src/main/java/org/apache/ambari/shell/commands/HostCommands.java
----------------------------------------------------------------------
diff --git a/ambari-shell/ambari-groovy-shell/src/main/java/org/apache/ambari/shell/commands/HostCommands.java b/ambari-shell/ambari-groovy-shell/src/main/java/org/apache/ambari/shell/commands/HostCommands.java
new file mode 100644
index 0000000..dd3c775
--- /dev/null
+++ b/ambari-shell/ambari-groovy-shell/src/main/java/org/apache/ambari/shell/commands/HostCommands.java
@@ -0,0 +1,119 @@
+/**
+ * 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.ambari.shell.commands;
+
+import static org.apache.ambari.shell.support.TableRenderer.renderSingleMap;
+
+import org.apache.ambari.groovy.client.AmbariClient;
+import org.apache.ambari.shell.completion.Host;
+import org.apache.ambari.shell.model.AmbariContext;
+import org.apache.ambari.shell.model.FocusType;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.shell.core.CommandMarker;
+import org.springframework.shell.core.annotation.CliAvailabilityIndicator;
+import org.springframework.shell.core.annotation.CliCommand;
+import org.springframework.shell.core.annotation.CliOption;
+import org.springframework.stereotype.Component;
+
+/**
+ * Host related commands used in the shell.
+ *
+ * @see org.apache.ambari.groovy.client.AmbariClient
+ */
+@Component
+public class HostCommands implements CommandMarker {
+
+ private AmbariClient client;
+ private AmbariContext context;
+
+ @Autowired
+ public HostCommands(AmbariClient client, AmbariContext context) {
+ this.client = client;
+ this.context = context;
+ }
+
+ /**
+ * Checks whether the host list command is available or not.
+ *
+ * @return true if available false otherwise
+ */
+ @CliAvailabilityIndicator("host list")
+ public boolean isHostsCommandAvailable() {
+ return true;
+ }
+
+ /**
+ * Prints the available hosts of the Ambari Server.
+ *
+ * @return host list
+ */
+ @CliCommand(value = "host list", help = "Lists the available hosts")
+ public String hosts() {
+ return client.showHostList();
+ }
+
+ /**
+ * Checks whether the host focus command is available or not.
+ *
+ * @return true if available false otherwise
+ */
+ @CliAvailabilityIndicator("host focus")
+ public boolean isFocusHostCommandAvailable() {
+ return context.isConnectedToCluster();
+ }
+
+ /**
+ * Sets the focus to the specified host.
+ *
+ * @param host the host to set the focus to
+ * @return status message
+ */
+ @CliCommand(value = "host focus", help = "Sets the useHost to the specified host")
+ public String focusHost(
+ @CliOption(key = "host", mandatory = true, help = "hostname") Host host) {
+ String message;
+ String hostName = host.getName();
+ if (client.getHostNames().keySet().contains(hostName)) {
+ context.setFocus(hostName, FocusType.HOST);
+ message = "Focus set to: " + hostName;
+ } else {
+ message = hostName + " is not a valid host name";
+ }
+ return message;
+ }
+
+ /**
+ * Checks whether the host components command is available or not.
+ *
+ * @return true if available false otherwise
+ */
+ @CliAvailabilityIndicator("host components")
+ public boolean isHostComponentsCommandAvailable() {
+ return context.isFocusOnHost();
+ }
+
+ /**
+ * Prints the components which belongs to the host being focused on.
+ *
+ * @return list of host components
+ */
+ @CliCommand(value = "host components", help = "Lists the components assigned to the selected host")
+ public String hostComponents() {
+ return renderSingleMap(client.getHostComponentsMap(context.getFocusValue()), "COMPONENT", "STATE");
+ }
+}
http://git-wip-us.apache.org/repos/asf/ambari/blob/c8eceafc/ambari-shell/ambari-groovy-shell/src/main/java/org/apache/ambari/shell/completion/Blueprint.java
----------------------------------------------------------------------
diff --git a/ambari-shell/ambari-groovy-shell/src/main/java/org/apache/ambari/shell/completion/Blueprint.java b/ambari-shell/ambari-groovy-shell/src/main/java/org/apache/ambari/shell/completion/Blueprint.java
new file mode 100644
index 0000000..4eec7b1
--- /dev/null
+++ b/ambari-shell/ambari-groovy-shell/src/main/java/org/apache/ambari/shell/completion/Blueprint.java
@@ -0,0 +1,34 @@
+/**
+ * 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.ambari.shell.completion;
+
+/**
+ * Wrapper class for TAB completion to blueprint names.
+ */
+public class Blueprint {
+
+ private final String name;
+
+ public Blueprint(String name) {
+ this.name = name;
+ }
+
+ public String getName() {
+ return name;
+ }
+}
http://git-wip-us.apache.org/repos/asf/ambari/blob/c8eceafc/ambari-shell/ambari-groovy-shell/src/main/java/org/apache/ambari/shell/completion/Host.java
----------------------------------------------------------------------
diff --git a/ambari-shell/ambari-groovy-shell/src/main/java/org/apache/ambari/shell/completion/Host.java b/ambari-shell/ambari-groovy-shell/src/main/java/org/apache/ambari/shell/completion/Host.java
new file mode 100644
index 0000000..f64e97b
--- /dev/null
+++ b/ambari-shell/ambari-groovy-shell/src/main/java/org/apache/ambari/shell/completion/Host.java
@@ -0,0 +1,34 @@
+/**
+ * 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.ambari.shell.completion;
+
+/**
+ * Wrapper class for TAB completion to host names.
+ */
+public class Host {
+
+ private final String name;
+
+ public Host(String name) {
+ this.name = name;
+ }
+
+ public String getName() {
+ return name;
+ }
+}
http://git-wip-us.apache.org/repos/asf/ambari/blob/c8eceafc/ambari-shell/ambari-groovy-shell/src/main/java/org/apache/ambari/shell/configuration/ConverterConfiguration.java
----------------------------------------------------------------------
diff --git a/ambari-shell/ambari-groovy-shell/src/main/java/org/apache/ambari/shell/configuration/ConverterConfiguration.java b/ambari-shell/ambari-groovy-shell/src/main/java/org/apache/ambari/shell/configuration/ConverterConfiguration.java
new file mode 100644
index 0000000..049c52f
--- /dev/null
+++ b/ambari-shell/ambari-groovy-shell/src/main/java/org/apache/ambari/shell/configuration/ConverterConfiguration.java
@@ -0,0 +1,142 @@
+/**
+ * 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.ambari.shell.configuration;
+
+import org.apache.ambari.groovy.client.AmbariClient;
+import org.apache.ambari.shell.converter.BlueprintConverter;
+import org.apache.ambari.shell.converter.HostConverter;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.shell.converters.AvailableCommandsConverter;
+import org.springframework.shell.converters.BigDecimalConverter;
+import org.springframework.shell.converters.BigIntegerConverter;
+import org.springframework.shell.converters.BooleanConverter;
+import org.springframework.shell.converters.CharacterConverter;
+import org.springframework.shell.converters.DateConverter;
+import org.springframework.shell.converters.DoubleConverter;
+import org.springframework.shell.converters.EnumConverter;
+import org.springframework.shell.converters.FloatConverter;
+import org.springframework.shell.converters.IntegerConverter;
+import org.springframework.shell.converters.LocaleConverter;
+import org.springframework.shell.converters.LongConverter;
+import org.springframework.shell.converters.ShortConverter;
+import org.springframework.shell.converters.SimpleFileConverter;
+import org.springframework.shell.converters.StaticFieldConverterImpl;
+import org.springframework.shell.converters.StringConverter;
+import org.springframework.shell.core.Converter;
+
+/**
+ * Configures the converters used by the shell.
+ */
+@Configuration
+public class ConverterConfiguration {
+
+ @Autowired
+ private AmbariClient client;
+
+ @Bean
+ Converter simpleFileConverter() {
+ return new SimpleFileConverter();
+ }
+
+ @Bean
+ Converter stringConverter() {
+ return new StringConverter();
+ }
+
+ @Bean
+ Converter availableCommandsConverter() {
+ return new AvailableCommandsConverter();
+ }
+
+ @Bean
+ Converter bigDecimalConverter() {
+ return new BigDecimalConverter();
+ }
+
+ @Bean
+ Converter bigIntegerConverter() {
+ return new BigIntegerConverter();
+ }
+
+ @Bean
+ Converter booleanConverter() {
+ return new BooleanConverter();
+ }
+
+ @Bean
+ Converter characterConverter() {
+ return new CharacterConverter();
+ }
+
+ @Bean
+ Converter dateConverter() {
+ return new DateConverter();
+ }
+
+ @Bean
+ Converter doubleConverter() {
+ return new DoubleConverter();
+ }
+
+ @Bean
+ Converter enumConverter() {
+ return new EnumConverter();
+ }
+
+ @Bean
+ Converter floatConverter() {
+ return new FloatConverter();
+ }
+
+ @Bean
+ Converter integerConverter() {
+ return new IntegerConverter();
+ }
+
+ @Bean
+ Converter localeConverter() {
+ return new LocaleConverter();
+ }
+
+ @Bean
+ Converter longConverter() {
+ return new LongConverter();
+ }
+
+ @Bean
+ Converter shortConverter() {
+ return new ShortConverter();
+ }
+
+ @Bean
+ Converter staticFieldConverterImpl() {
+ return new StaticFieldConverterImpl();
+ }
+
+ @Bean
+ Converter blueprintConverter() {
+ return new BlueprintConverter(client);
+ }
+
+ @Bean
+ Converter hostConverter() {
+ return new HostConverter(client);
+ }
+}
http://git-wip-us.apache.org/repos/asf/ambari/blob/c8eceafc/ambari-shell/ambari-groovy-shell/src/main/java/org/apache/ambari/shell/configuration/ShellConfiguration.java
----------------------------------------------------------------------
diff --git a/ambari-shell/ambari-groovy-shell/src/main/java/org/apache/ambari/shell/configuration/ShellConfiguration.java b/ambari-shell/ambari-groovy-shell/src/main/java/org/apache/ambari/shell/configuration/ShellConfiguration.java
new file mode 100644
index 0000000..4c493b0
--- /dev/null
+++ b/ambari-shell/ambari-groovy-shell/src/main/java/org/apache/ambari/shell/configuration/ShellConfiguration.java
@@ -0,0 +1,114 @@
+/**
+ * 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.ambari.shell.configuration;
+
+import org.apache.ambari.groovy.client.AmbariClient;
+import org.codehaus.jackson.map.ObjectMapper;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.context.support.PropertySourcesPlaceholderConfigurer;
+import org.springframework.scheduling.concurrent.ThreadPoolExecutorFactoryBean;
+import org.springframework.shell.CommandLine;
+import org.springframework.shell.SimpleShellCommandLineOptions;
+import org.springframework.shell.commands.ExitCommands;
+import org.springframework.shell.commands.HelpCommands;
+import org.springframework.shell.commands.ScriptCommands;
+import org.springframework.shell.commands.VersionCommands;
+import org.springframework.shell.core.CommandMarker;
+import org.springframework.shell.core.JLineShellComponent;
+import org.springframework.shell.plugin.HistoryFileNameProvider;
+import org.springframework.shell.plugin.support.DefaultHistoryFileNameProvider;
+
+/**
+ * Spring bean definitions.
+ */
+@Configuration
+public class ShellConfiguration {
+
+ @Value("${ambari.host:localhost}")
+ private String host;
+
+ @Value("${ambari.port:8080}")
+ private String port;
+
+ @Value("${ambari.user:admin}")
+ private String user;
+
+ @Value("${ambari.password:admin}")
+ private String password;
+
+ @Value("${cmdfile:}")
+ private String cmdFile;
+
+ @Bean
+ AmbariClient createAmbariClient() {
+ return new AmbariClient(host, port, user, password);
+ }
+
+ @Bean
+ static PropertySourcesPlaceholderConfigurer propertyPlaceholderConfigurer() {
+ return new PropertySourcesPlaceholderConfigurer();
+ }
+
+ @Bean
+ HistoryFileNameProvider defaultHistoryFileNameProvider() {
+ return new DefaultHistoryFileNameProvider();
+ }
+
+ @Bean(name = "shell")
+ JLineShellComponent shell() {
+ return new JLineShellComponent();
+ }
+
+ @Bean
+ CommandLine commandLine() throws Exception {
+ String[] args = cmdFile.length() > 0 ? new String[]{"--cmdfile", cmdFile} : new String[0];
+ return SimpleShellCommandLineOptions.parseCommandLine(args);
+ }
+
+ @Bean
+ ThreadPoolExecutorFactoryBean getThreadPoolExecutorFactoryBean() {
+ return new ThreadPoolExecutorFactoryBean();
+ }
+
+ @Bean
+ ObjectMapper getObjectMapper() {
+ return new ObjectMapper();
+ }
+
+ @Bean
+ CommandMarker exitCommand() {
+ return new ExitCommands();
+ }
+
+ @Bean
+ CommandMarker versionCommands() {
+ return new VersionCommands();
+ }
+
+ @Bean
+ CommandMarker helpCommands() {
+ return new HelpCommands();
+ }
+
+ @Bean
+ CommandMarker scriptCommands() {
+ return new ScriptCommands();
+ }
+}
http://git-wip-us.apache.org/repos/asf/ambari/blob/c8eceafc/ambari-shell/ambari-groovy-shell/src/main/java/org/apache/ambari/shell/converter/BlueprintConverter.java
----------------------------------------------------------------------
diff --git a/ambari-shell/ambari-groovy-shell/src/main/java/org/apache/ambari/shell/converter/BlueprintConverter.java b/ambari-shell/ambari-groovy-shell/src/main/java/org/apache/ambari/shell/converter/BlueprintConverter.java
new file mode 100644
index 0000000..7984e7f
--- /dev/null
+++ b/ambari-shell/ambari-groovy-shell/src/main/java/org/apache/ambari/shell/converter/BlueprintConverter.java
@@ -0,0 +1,58 @@
+/**
+ * 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.ambari.shell.converter;
+
+import java.util.List;
+import java.util.Set;
+
+import org.apache.ambari.groovy.client.AmbariClient;
+import org.apache.ambari.shell.completion.Blueprint;
+import org.springframework.shell.core.Completion;
+import org.springframework.shell.core.Converter;
+import org.springframework.shell.core.MethodTarget;
+
+/**
+ * Converter used to complete blueprint names.
+ */
+public class BlueprintConverter implements Converter<Blueprint> {
+
+ private AmbariClient client;
+
+ public BlueprintConverter(AmbariClient client) {
+ this.client = client;
+ }
+
+ @Override
+ public boolean supports(Class<?> type, String optionContext) {
+ return Blueprint.class.isAssignableFrom(type);
+ }
+
+ @Override
+ public Blueprint convertFromText(String value, Class<?> targetType, String optionContext) {
+ return new Blueprint(value);
+ }
+
+ @Override
+ public boolean getAllPossibleValues(List<Completion> completions, Class<?> targetType, String existingData, String optionContext, MethodTarget target) {
+ Set<String> blueprints = client.getBlueprintsMap().keySet();
+ for (String blueprint : blueprints) {
+ completions.add(new Completion(blueprint));
+ }
+ return true;
+ }
+}
http://git-wip-us.apache.org/repos/asf/ambari/blob/c8eceafc/ambari-shell/ambari-groovy-shell/src/main/java/org/apache/ambari/shell/converter/HostConverter.java
----------------------------------------------------------------------
diff --git a/ambari-shell/ambari-groovy-shell/src/main/java/org/apache/ambari/shell/converter/HostConverter.java b/ambari-shell/ambari-groovy-shell/src/main/java/org/apache/ambari/shell/converter/HostConverter.java
new file mode 100644
index 0000000..39aa6e9
--- /dev/null
+++ b/ambari-shell/ambari-groovy-shell/src/main/java/org/apache/ambari/shell/converter/HostConverter.java
@@ -0,0 +1,58 @@
+/**
+ * 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.ambari.shell.converter;
+
+import java.util.List;
+import java.util.Set;
+
+import org.apache.ambari.groovy.client.AmbariClient;
+import org.apache.ambari.shell.completion.Host;
+import org.springframework.shell.core.Completion;
+import org.springframework.shell.core.Converter;
+import org.springframework.shell.core.MethodTarget;
+
+/**
+ * Converter used to complete host names.
+ */
+public class HostConverter implements Converter<Host> {
+
+ private AmbariClient client;
+
+ public HostConverter(AmbariClient client) {
+ this.client = client;
+ }
+
+ @Override
+ public boolean supports(Class<?> type, String optionContext) {
+ return Host.class.isAssignableFrom(type);
+ }
+
+ @Override
+ public Host convertFromText(String value, Class<?> targetType, String optionContext) {
+ return new Host(value);
+ }
+
+ @Override
+ public boolean getAllPossibleValues(List<Completion> completions, Class<?> targetType, String existingData, String optionContext, MethodTarget target) {
+ Set<String> hosts = client.getHostNames().keySet();
+ for (String host : hosts) {
+ completions.add(new Completion(host));
+ }
+ return true;
+ }
+}
http://git-wip-us.apache.org/repos/asf/ambari/blob/c8eceafc/ambari-shell/ambari-groovy-shell/src/main/java/org/apache/ambari/shell/customization/AmbariBanner.java
----------------------------------------------------------------------
diff --git a/ambari-shell/ambari-groovy-shell/src/main/java/org/apache/ambari/shell/customization/AmbariBanner.java b/ambari-shell/ambari-groovy-shell/src/main/java/org/apache/ambari/shell/customization/AmbariBanner.java
new file mode 100644
index 0000000..f97ef59
--- /dev/null
+++ b/ambari-shell/ambari-groovy-shell/src/main/java/org/apache/ambari/shell/customization/AmbariBanner.java
@@ -0,0 +1,50 @@
+/**
+ * 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.ambari.shell.customization;
+
+import org.springframework.shell.plugin.BannerProvider;
+import org.springframework.stereotype.Component;
+
+import com.github.lalyos.jfiglet.FigletFont;
+
+/**
+ * Prints the banner when the user starts the shell.
+ */
+@Component
+public class AmbariBanner implements BannerProvider {
+
+ @Override
+ public String getProviderName() {
+ return "AmbariShell";
+ }
+
+ @Override
+ public String getBanner() {
+ return FigletFont.convertOneLine("AmbariShell");
+ }
+
+ @Override
+ public String getVersion() {
+ return getClass().getPackage().getImplementationVersion();
+ }
+
+ @Override
+ public String getWelcomeMessage() {
+ return "Welcome to Ambari Shell. For command and param completion press TAB, for assistance type 'hint'.";
+ }
+}
http://git-wip-us.apache.org/repos/asf/ambari/blob/c8eceafc/ambari-shell/ambari-groovy-shell/src/main/java/org/apache/ambari/shell/customization/AmbariHistory.java
----------------------------------------------------------------------
diff --git a/ambari-shell/ambari-groovy-shell/src/main/java/org/apache/ambari/shell/customization/AmbariHistory.java b/ambari-shell/ambari-groovy-shell/src/main/java/org/apache/ambari/shell/customization/AmbariHistory.java
new file mode 100644
index 0000000..c23fc9a
--- /dev/null
+++ b/ambari-shell/ambari-groovy-shell/src/main/java/org/apache/ambari/shell/customization/AmbariHistory.java
@@ -0,0 +1,40 @@
+/**
+ * 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.ambari.shell.customization;
+
+import org.springframework.shell.plugin.HistoryFileNameProvider;
+import org.springframework.stereotype.Component;
+
+/**
+ * Specifies the name of the Ambari command log. Later this log can be used
+ * to re-execute the commands with either the --cmdfile option at startup
+ * or with the script --file command.
+ */
+@Component
+public class AmbariHistory implements HistoryFileNameProvider {
+
+ @Override
+ public String getHistoryFileName() {
+ return "ambari-log.ash";
+ }
+
+ @Override
+ public String getProviderName() {
+ return "AmbariShell";
+ }
+}
http://git-wip-us.apache.org/repos/asf/ambari/blob/c8eceafc/ambari-shell/ambari-groovy-shell/src/main/java/org/apache/ambari/shell/customization/AmbariPrompt.java
----------------------------------------------------------------------
diff --git a/ambari-shell/ambari-groovy-shell/src/main/java/org/apache/ambari/shell/customization/AmbariPrompt.java b/ambari-shell/ambari-groovy-shell/src/main/java/org/apache/ambari/shell/customization/AmbariPrompt.java
new file mode 100644
index 0000000..b91e76e
--- /dev/null
+++ b/ambari-shell/ambari-groovy-shell/src/main/java/org/apache/ambari/shell/customization/AmbariPrompt.java
@@ -0,0 +1,43 @@
+/**
+ * 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.ambari.shell.customization;
+
+import org.apache.ambari.shell.model.AmbariContext;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.shell.plugin.PromptProvider;
+import org.springframework.stereotype.Component;
+
+/**
+ * Manages the text of the shell's prompt.
+ */
+@Component
+public class AmbariPrompt implements PromptProvider {
+
+ @Autowired
+ private AmbariContext context;
+
+ @Override
+ public String getProviderName() {
+ return AmbariPrompt.class.getSimpleName();
+ }
+
+ @Override
+ public String getPrompt() {
+ return context.getPrompt();
+ }
+}
[2/4] AMBARI-6176. Integrate python shell into Ambari-shell
module(subin)
Posted by su...@apache.org.
http://git-wip-us.apache.org/repos/asf/ambari/blob/c8eceafc/ambari-shell/ambari-python-shell/src/main/python/ambari_shell/ambari_shell.py
----------------------------------------------------------------------
diff --git a/ambari-shell/ambari-python-shell/src/main/python/ambari_shell/ambari_shell.py b/ambari-shell/ambari-python-shell/src/main/python/ambari_shell/ambari_shell.py
new file mode 100644
index 0000000..79af1a6
--- /dev/null
+++ b/ambari-shell/ambari-python-shell/src/main/python/ambari_shell/ambari_shell.py
@@ -0,0 +1,412 @@
+#!/usr/bin/env python
+#
+# 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.
+
+
+import logging
+import logging.handlers
+import sys
+import signal
+import json
+import time
+import pdb
+import os
+import stat
+import cmd
+import string
+import bz2
+import datetime
+# import traceback
+import getpass
+import argparse
+import readline
+import ConfigParser
+import StringIO
+import subprocess
+import textwrap
+
+import utils.displayutils
+import utils.osutils
+import utils.pluginutils
+from ambari_client.ambari_api import AmbariClient
+
+
+configFile = "/etc/ambari-shell/conf/ambari-shell.ini"
+
+
+formatstr = "%(levelname)s %(asctime)s %(filename)s:%(lineno)d - %(message)s"
+LOG_MAX_BYTES = 10000000
+LOG_BACKUP = 2
+
+SHELL_CONFIG = {
+ 'clustername': None,
+ 'hostname': 'localhost',
+ 'port': 8080,
+ 'username': 'admin',
+ 'password': 'admin',
+ 'display_type': 'table',
+ 'client': None,
+ 'configFile': configFile}
+
+########################################################################
+#
+# Utility methods
+#
+########################################################################
+
+
+def exit_gracefully(signum, frame):
+ # restore the original signal handler as otherwise evil things will happen
+ # in raw_input when CTRL+C is pressed, and our signal handler is not
+ # re-entrant
+ signal.signal(signal.SIGINT, original_sigint)
+ print "\nExiting"
+ sys.exit(1)
+
+ # restore the exit gracefully handler here
+ signal.signal(signal.SIGINT, exit_gracefully)
+
+
+def exit_gracefully1(signum, frame):
+ # restore the original signal handler as otherwise evil things will happen
+ # in raw_input when CTRL+C is pressed, and our signal handler is not
+ # re-entrant
+ signal.signal(signal.SIGQUIT, original_sigint)
+ print "\nExiting"
+ sys.exit(1)
+
+ # restore the exit gracefully handler here
+ signal.signal(signal.SIGQUIT, exit_gracefully)
+
+
+def resolve_config():
+ try:
+ config = ConfigParser.RawConfigParser()
+ if os.path.exists(configFile):
+ print "looking from " + configFile
+ config.read(configFile)
+ else:
+ raise Exception("No config found")
+ except Exception as err:
+ logging.warn(err)
+ print "found " + configFile
+ return config
+
+
+def get_log_level(loglevel):
+ loglev = loglevel.upper()
+ if loglev == "DEBUG":
+ return logging.DEBUG
+ elif loglev == "INFO":
+ return logging.INFO
+ elif loglev == "WARNING":
+ return logging.WARNING
+ elif loglev == "CRITICAL":
+ return logging.CRITICAL
+ elif loglev == "ERROR":
+ return logging.ERROR
+ elif loglev == "FATAL":
+ return logging.FATAL
+ else:
+ return logging.NOTSET
+
+
+def setup_logging(loglevel, logPath="./"):
+ try:
+ logging.root
+ curTimestamp = str(datetime.datetime.now())
+ ct = curTimestamp.split('.')[0]
+ curTime = ct.replace(':', '-')
+ datee = curTime.split(' ')[0]
+ timee = curTime.split(' ')[1]
+ # Set Log directory and log file name. Each run generates a new log
+ # file
+
+ logFile = logPath + 'ambaricli_' + datee + "_" + timee + '.log'
+ fh = open(logFile, 'w')
+ fh.write('*****************************************************\n')
+ fh.write(' Amabri Python CLI Log\n')
+ t = ' Timestamp: ' + ct + '\n'
+ fh.write(t)
+ fh.write('*****************************************************\n\n\n')
+ fh.close()
+ # Set the config for logging
+ logging.basicConfig(
+ filename=logFile,
+ format='%(asctime)s : %(levelname)s: %(message)s',
+ level=get_log_level(loglevel))
+ except IOError as e:
+ errStr = " I/O error({0}): {1}".format(e.errno, e.strerror)
+ print errStr
+ sys.exit(1)
+ except Exception as exception:
+ print exception
+ sys.exit(1)
+
+
+def getLogLevel(configg):
+ loglevel = "debug"
+ try:
+ loglevel = configg.get('python_shell', 'loglevel')
+ except Exception:
+ logging.error("No loglevel found ")
+ return loglevel
+ return loglevel
+
+
+def getLogPath(configg):
+ logPath = "./"
+ try:
+ logPath = configg.get('python_shell', 'log_folder')
+ except Exception:
+ logging.error("No log_folder found")
+ return logPath
+ return logPath
+
+
+def getPluginPath(configg):
+ cliplugin_path = "./"
+ try:
+ cliplugin_path = configg.get('python_shell', 'cliplugin_folder')
+ except Exception:
+ logging.error("No cliplugin_folder found")
+ return cliplugin_path
+ return cliplugin_path
+
+
+def getDefaultPluginPath(configg):
+ cliplugin_path = "./"
+ try:
+ cliplugin_path = configg.get('python_shell', 'default_plugin_folder')
+ except Exception:
+ logging.error("No default_plugin_folder found")
+ return cliplugin_path
+ return cliplugin_path
+
+
+def getCommandsDict(ppath, cliplugin_path):
+ default_dictt = utils.pluginutils.getPlugins(ppath)
+ logging.debug("pluginutils returned default plugins >> %s ", default_dictt)
+ dictt = utils.pluginutils.getPlugins(cliplugin_path)
+ logging.debug("pluginutils returned >> %s ", dictt)
+ if(not set(default_dictt).isdisjoint(set(dictt))):
+ common_commands = set(default_dictt).intersection(set(dictt))
+ common_commands = " & ".join(str(x) for x in common_commands)
+ logging.error(
+ "ERROR :plugins folder has duplicate commands already present in default commands")
+ logging.error(common_commands)
+ print "ERROR :plugins folder has duplicate command already present in default commands"
+ print "pls remove following commands from plugin folder >" + str(common_commands)
+ sys.exit(1)
+ default_dictt.update(dictt)
+ return default_dictt
+
+
+class CmdBase(cmd.Cmd):
+
+ """CLI .
+ """
+
+ intro = utils.displayutils.shellBanner()
+ prompt = 'ambari>'
+ http_proxy = ''
+ https_proxy = ''
+ # headers
+ doc_header = "Commands"
+ undoc_header = "Other Commands"
+
+ def __init__(self):
+ cmd.Cmd.__init__(self)
+
+ def do_EOF(self, line):
+ logging.info("====== do_EOF ======")
+ return True
+
+ def do_exit(self, line):
+ logging.info("====== do_exit ======")
+ return True
+
+ def postloop(self):
+ logging.info("====== exit ======")
+
+# def parseline(self, line):
+# print 'parseline(%s) =>' % line,
+# ret = cmd.Cmd.parseline(self, line)
+# print ret
+# return ret
+
+ def emptyline(self):
+ # print 'emptyline()'
+ # return cmd.Cmd.emptyline(self)
+ return
+
+ def default(self, line):
+ """Called on an input line when the command prefix is not recognized.
+
+ If this method is not overridden, it prints an error message and
+ returns.
+
+ """
+ self.stdout.write(
+ '*** Unknown command *** : %s \n type "help" to list all commands \n' %
+ line)
+
+
+class AmbariShell(CmdBase):
+
+ COMPONENTS = {}
+ SERVICES = None
+ CLUSTERS = None
+
+ def __init__(self):
+ CmdBase.__init__(self)
+ self.config = None
+ self.global_shell_config = SHELL_CONFIG
+
+ def preloop(self):
+ "Checks if the cluster was pre-defined"
+ self._set_prompt()
+
+ def _set_prompt(self):
+ if self.global_shell_config['clustername']:
+ self.prompt = "ambari-" + \
+ str(self.global_shell_config['clustername']) + ">"
+ logging.debug("found a cluster >" +
+ str(self.global_shell_config['clustername']))
+ else:
+ self.prompt = 'ambari>'
+
+ def postcmd(self, stop, line):
+ # print 'postcmd(%s, %s)' % (stop, line)
+ self._set_prompt()
+ return cmd.Cmd.postcmd(self, stop, line)
+
+ def setConfig(self, customConfig):
+ self.config = customConfig
+
+ # core code should begin here
+
+ def generate_output(self, headers, rows):
+ if self.global_shell_config['display_type'] == "table":
+ print utils.displayutils.display_table(headers, rows)
+
+ if self.global_shell_config['display_type'] == "csv":
+ utils.displayutils.createCSV(headers, rows)
+
+ if self.global_shell_config['display_type'] == "xml":
+ print utils.displayutils.createXML(headers, rows)
+
+#
+# The "main" function
+
+
+def main():
+ parser = argparse.ArgumentParser(description='Ambari CLI')
+ parser.add_argument('-H', '--host', action='store', dest='host')
+ parser.add_argument(
+ '-p',
+ '--port',
+ action='store',
+ dest='port',
+ type=int,
+ default=8080)
+ parser.add_argument(
+ '-u',
+ '--user',
+ action='store',
+ dest='user',
+ default='admin')
+ parser.add_argument(
+ '-c',
+ '--clustername',
+ action='store',
+ dest='clustername')
+ parser.add_argument(
+ '--password',
+ action='store',
+ dest='password',
+ default='admin')
+ parser.add_argument(
+ '-d',
+ '--display_type',
+ action='store',
+ dest='display_type',
+ default='table')
+ parser.add_argument('-r', '--run', action='store', dest='run')
+ args = parser.parse_args()
+
+ # Check if a username was suplied, if not, prompt the user
+ if not args.host:
+ args.host = raw_input("Enter Ambari Server host: ")
+
+ if args.host:
+ SHELL_CONFIG['hostname'] = args.host
+ if args.clustername:
+ SHELL_CONFIG['clustername'] = args.clustername
+ if args.display_type:
+ SHELL_CONFIG['display_type'] = args.display_type
+
+ headers_dict = {'X-Requested-By': 'mycompany'}
+ client = AmbariClient(
+ SHELL_CONFIG['hostname'],
+ SHELL_CONFIG['port'],
+ SHELL_CONFIG['username'],
+ SHELL_CONFIG['password'],
+ version=1,
+ http_header=headers_dict)
+ SHELL_CONFIG['client'] = client
+
+ # do some plumbing
+ config = resolve_config()
+ logPath = getLogPath(config)
+ loglevel = getLogLevel(config)
+ cliplugin_path = getPluginPath(config)
+ dpath = getDefaultPluginPath(config)
+ setup_logging(loglevel, logPath)
+ # get ready to create a shell
+ utils.osutils.doclearScreen()
+ shell = AmbariShell()
+ logging.info("cliplugin_folder = %s", getPluginPath(config))
+ logging.info("SHELL_CONFIG = %s", str(SHELL_CONFIG))
+ # Get all commands
+
+ commands_dictt = getCommandsDict(dpath, cliplugin_path)
+ for k, v in commands_dictt.items():
+ setattr(AmbariShell, str(k), v)
+ shell.setConfig(config)
+
+ # Check if user is attempting non-interactive shell
+ if args.run:
+ print args.run
+ for command in args.run.split(';'):
+ shell.onecmd(command)
+ sys.exit(0)
+ else:
+ try:
+ shell.cmdloop()
+ except KeyboardInterrupt:
+ sys.stdout.write("\n")
+ sys.exit(0)
+ logging.info("finished")
+
+
+if __name__ == '__main__':
+ original_sigint = signal.getsignal(signal.SIGINT)
+ signal.signal(signal.SIGINT, exit_gracefully)
+ signal.signal(signal.SIGQUIT, exit_gracefully1)
+ signal.signal(signal.SIGTERM, exit_gracefully1)
+ main()
http://git-wip-us.apache.org/repos/asf/ambari/blob/c8eceafc/ambari-shell/ambari-python-shell/src/main/python/ambari_shell/plugins/__init__.py
----------------------------------------------------------------------
diff --git a/ambari-shell/ambari-python-shell/src/main/python/ambari_shell/plugins/__init__.py b/ambari-shell/ambari-python-shell/src/main/python/ambari_shell/plugins/__init__.py
new file mode 100644
index 0000000..278df2e
--- /dev/null
+++ b/ambari-shell/ambari-python-shell/src/main/python/ambari_shell/plugins/__init__.py
@@ -0,0 +1,16 @@
+#
+# 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.
http://git-wip-us.apache.org/repos/asf/ambari/blob/c8eceafc/ambari-shell/ambari-python-shell/src/main/python/ambari_shell/plugins/blueprint.py
----------------------------------------------------------------------
diff --git a/ambari-shell/ambari-python-shell/src/main/python/ambari_shell/plugins/blueprint.py b/ambari-shell/ambari-python-shell/src/main/python/ambari_shell/plugins/blueprint.py
new file mode 100644
index 0000000..4d65163
--- /dev/null
+++ b/ambari-shell/ambari-python-shell/src/main/python/ambari_shell/plugins/blueprint.py
@@ -0,0 +1,21 @@
+#!/usr/bin/env python
+#
+# 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.
+import logging
+import textwrap
+
+LOG = logging.getLogger(__name__)
http://git-wip-us.apache.org/repos/asf/ambari/blob/c8eceafc/ambari-shell/ambari-python-shell/src/main/python/ambari_shell/plugins/connect_cluster.py
----------------------------------------------------------------------
diff --git a/ambari-shell/ambari-python-shell/src/main/python/ambari_shell/plugins/connect_cluster.py b/ambari-shell/ambari-python-shell/src/main/python/ambari_shell/plugins/connect_cluster.py
new file mode 100644
index 0000000..c28d493
--- /dev/null
+++ b/ambari-shell/ambari-python-shell/src/main/python/ambari_shell/plugins/connect_cluster.py
@@ -0,0 +1,81 @@
+#!/usr/bin/env python
+#
+# 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.
+import logging
+import textwrap
+
+LOG = logging.getLogger(__name__)
+
+
+def do_connect_cluster(self, cluster):
+
+ if not cluster:
+ self.help_connect_cluster()
+ return None
+
+ if not self.CLUSTERS:
+ clusters = [str(c.cluster_name).encode('ascii', 'ignore')
+ for c in self.global_shell_config['client'].get_all_clusters()]
+ self.CLUSTERS = clusters
+
+ if cluster not in self.CLUSTERS:
+ print "ERROR ! cluster %s not found " % str(cluster)
+ print " valid clusters are " + str(self.CLUSTERS)
+ return None
+ if self.global_shell_config['clustername']:
+ LOG.debug("old cluster = " + self.global_shell_config['clustername'])
+ self.global_shell_config['clustername'] = str(cluster)
+ else:
+ self.global_shell_config['clustername'] = cluster
+ self.prompt = "ambari-" + \
+ str(self.global_shell_config['clustername']) + ">"
+
+
+def help_connect_cluster(self):
+ print '\n'.join([' Usage:', ' connect_cluster <cluster_name>'])
+
+
+def do_disconnect_cluster(self, line):
+
+ if self.global_shell_config['clustername']:
+ LOG.debug("old cluster = " + self.global_shell_config['clustername'])
+ self.global_shell_config['clustername'] = None
+ self.prompt = "ambari>"
+
+
+def help_disconnect_cluster(self):
+ print '\n'.join([' Usage:', ' disconnect_cluster'])
+
+
+def complete_connect_cluster(self, pattern, line, start_index, end_index):
+ if not self.CLUSTERS:
+ clusters = [
+ (c.cluster_name).encode(
+ 'ascii',
+ 'ignore') for c in self.global_shell_config['client'].get_all_clusters()]
+ self.CLUSTERS = clusters
+
+ LOG.debug(
+ ("self.CLUSTERS = %s pattern = %s ") %
+ (str(
+ self.CLUSTERS),
+ pattern))
+ if pattern:
+ return [
+ c for c in self.CLUSTERS if c.startswith(pattern)]
+ else:
+ return self.CLUSTERS
http://git-wip-us.apache.org/repos/asf/ambari/blob/c8eceafc/ambari-shell/ambari-python-shell/src/main/python/ambari_shell/plugins/create_cluster.py
----------------------------------------------------------------------
diff --git a/ambari-shell/ambari-python-shell/src/main/python/ambari_shell/plugins/create_cluster.py b/ambari-shell/ambari-python-shell/src/main/python/ambari_shell/plugins/create_cluster.py
new file mode 100644
index 0000000..f9947d7
--- /dev/null
+++ b/ambari-shell/ambari-python-shell/src/main/python/ambari_shell/plugins/create_cluster.py
@@ -0,0 +1,34 @@
+#!/usr/bin/env python
+#
+# 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.
+
+
+import logging
+import textwrap
+
+
+LOG = logging.getLogger(__name__)
+
+
+def do_create_cluster(self, line):
+ # logging = self.LOG
+ print "TODO"
+ self.prompt = "ambari>"
+
+
+def help_create_cluster(self):
+ print '\n'.join([' Usage:', ' create_cluster <cluster_name>'])
http://git-wip-us.apache.org/repos/asf/ambari/blob/c8eceafc/ambari-shell/ambari-python-shell/src/main/python/ambari_shell/plugins/service.py
----------------------------------------------------------------------
diff --git a/ambari-shell/ambari-python-shell/src/main/python/ambari_shell/plugins/service.py b/ambari-shell/ambari-python-shell/src/main/python/ambari_shell/plugins/service.py
new file mode 100644
index 0000000..d44769a
--- /dev/null
+++ b/ambari-shell/ambari-python-shell/src/main/python/ambari_shell/plugins/service.py
@@ -0,0 +1,125 @@
+#!/usr/bin/env python
+#
+# 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.
+
+
+import logging
+import textwrap
+
+
+LOG = logging.getLogger(__name__)
+
+
+def do_start_service(self, service):
+ if not service:
+ self.help_stop_service()
+ return None
+ clustername = self.global_shell_config['clustername']
+ if not clustername:
+ print("Error! No cluster currently selected")
+ return None
+
+ if self.t_service_action(service=service, action="start"):
+ print("%s is being started" % (service))
+ else:
+ print("Error! cannot start service")
+ return
+
+
+def do_stop_service(self, service):
+ if not service:
+ self.help_start_service()
+ return None
+
+ clustername = self.global_shell_config['clustername']
+ if not clustername:
+ print("Error! No cluster currently selected")
+ return None
+
+ if self.t_service_action(service=service, action="stop"):
+ print("%s is being stopped" % (service))
+ else:
+ print("Error! cannot stop service")
+ return
+
+
+def help_stop_service(self):
+ print textwrap.dedent("""
+ Usage:
+ > stop_service <service_name>
+ """)
+
+
+def help_start_service(self):
+ print textwrap.dedent("""
+ Usage:
+ > start_service <service_name>
+ """)
+
+
+def complete_start_service(self, pattern, line, start_index, end_index):
+ return self.services_complete(pattern, line, start_index, end_index)
+
+
+def complete_stop_service(self, pattern, line, start_index, end_index):
+ client = self.global_shell_config['client']
+ clustername = self.global_shell_config['clustername']
+ if not clustername:
+ return None
+ else:
+ if not self.SERVICES:
+ services = [
+ s.service_name for s in client.get_cluster(clustername).get_all_services()]
+ self.SERVICES = services
+
+ if pattern:
+ return [s for s in self.SERVICES if s.startswith(pattern)]
+ else:
+ return self.SERVICES
+
+
+def services_complete(self, pattern, line, start_index, end_index, append=[]):
+ client = self.global_shell_config['client']
+ clustername = self.global_shell_config['clustername']
+ if not clustername:
+ return None
+ else:
+ if not self.SERVICES:
+ services = [
+ s.service_name for s in client.get_cluster(clustername).get_all_services()]
+ self.SERVICES = services
+
+ if pattern:
+ return [s for s in self.SERVICES + append if s.startswith(pattern)]
+ else:
+ return self.SERVICES + append
+
+
+def t_service_action(self, service, action):
+ try:
+ client = self.global_shell_config['client']
+ cluster = self.global_shell_config['clustername']
+ service = client.get_cluster(cluster).get_service(service)
+ except Exception:
+ print("Service not found")
+ return None
+
+ if action == "start":
+ service.start(message='started by Ambari python CLI')
+ if action == "stop":
+ service.stop(message='stopped by Ambari python CLI')
+ return True
http://git-wip-us.apache.org/repos/asf/ambari/blob/c8eceafc/ambari-shell/ambari-python-shell/src/main/python/ambari_shell/plugins/shell_config.py
----------------------------------------------------------------------
diff --git a/ambari-shell/ambari-python-shell/src/main/python/ambari_shell/plugins/shell_config.py b/ambari-shell/ambari-python-shell/src/main/python/ambari_shell/plugins/shell_config.py
new file mode 100644
index 0000000..2facd02
--- /dev/null
+++ b/ambari-shell/ambari-python-shell/src/main/python/ambari_shell/plugins/shell_config.py
@@ -0,0 +1,77 @@
+#!/usr/bin/env python
+#
+# 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.
+import logging
+import textwrap
+
+LOG = logging.getLogger(__name__)
+
+
+def do_get_shell_config(self, config_name):
+ rows = []
+ headers = ["KEY", "VAlUE"]
+ if not config_name:
+ for i in self.global_shell_config.items():
+ rows.append([i[0], i[1]])
+ else:
+ if config_name in self.global_shell_config.keys():
+ rows.append([config_name, self.global_shell_config[config_name]])
+
+ self.generate_output(headers, rows)
+
+
+def do_set_shell_config(self, config=None):
+ kv = config.split(" ")
+ if len(kv) != 2:
+ self.help_set_shell_config()
+ return
+ config_name = kv[0]
+ config_value = kv[1]
+ if config_name in self.global_shell_config.keys():
+ self.global_shell_config[config_name] = config_value
+
+ self.do_get_shell_config(config_name=None)
+
+
+def help_get_shell_config(self):
+ print textwrap.dedent("""
+ Usage:
+ > get_shell_config <config_name> get all shell config
+ """)
+
+
+def help_set_shell_config(self):
+ print textwrap.dedent("""
+ Usage:
+ > set_shell_config <config_name> <config_value> sets shell config
+ """)
+
+
+def complete_get_shell_config(self, pattern, line, start_index, end_index):
+ if pattern:
+ return [
+ c for c in self.global_shell_config.keys() if c.startswith(pattern)]
+ else:
+ return self.CLUSTERS
+
+
+def complete_set_shell_config(self, pattern, line, start_index, end_index):
+ if pattern:
+ return [
+ c for c in self.global_shell_config.keys() if c.startswith(pattern)]
+ else:
+ return self.CLUSTERS
http://git-wip-us.apache.org/repos/asf/ambari/blob/c8eceafc/ambari-shell/ambari-python-shell/src/main/python/ambari_shell/plugins/show.py
----------------------------------------------------------------------
diff --git a/ambari-shell/ambari-python-shell/src/main/python/ambari_shell/plugins/show.py b/ambari-shell/ambari-python-shell/src/main/python/ambari_shell/plugins/show.py
new file mode 100644
index 0000000..584b40a
--- /dev/null
+++ b/ambari-shell/ambari-python-shell/src/main/python/ambari_shell/plugins/show.py
@@ -0,0 +1,155 @@
+#!/usr/bin/env python
+#
+# 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.
+
+
+import logging
+import textwrap
+
+LOG = logging.getLogger(__name__)
+
+
+def help_show(self):
+ print textwrap.dedent("""
+ Usage:
+ > show clusters list clusters
+ > show hosts list hosts
+ > show stacks list stacks
+ > show services list services
+ > show requests list previous requests
+ > show blueprints list blueprints
+ """)
+
+
+def do_show(self, option):
+ """
+ Usage:
+ > show clusters list clusters
+ > show hosts list hosts
+ > show stacks list stacks
+ > show services list services
+ > show requests list previous requests
+ > show blueprints list blueprints
+ """
+ headers = []
+ rows = []
+ options = [
+ "clusters",
+ "stacks",
+ "status",
+ "services",
+ "hosts",
+ "requests",
+ "blueprints"]
+
+ if not option:
+ self.help_show()
+ return
+
+ if option not in options:
+ self.default(option)
+ return
+
+ client = self.global_shell_config['client']
+ clustername = self.global_shell_config['clustername']
+ # show clusters
+ if option == "clusters":
+ "Display list of clusters on system"
+ headers = ["CLUSTER NAME"]
+ clusters = client.get_all_clusters()
+ for cluster in clusters:
+ rows.append([cluster.cluster_name])
+
+ # show clusters
+ if option == "stacks":
+ "Display list of stacks on system"
+ headers = ["STACK NAME"]
+ stacks = client.get_stacks(True)
+ for stack in stacks:
+ rows.append([stack.stack_version])
+
+ if option == "blueprints":
+ "Display list of blueprints on system"
+ headers = ["BLUEPRINT NAME", "VERSION"]
+ blues = client.get_blueprint()
+ for b in blues:
+ rows.append([b.blueprint_name, b.stack_version])
+
+ if option == "status":
+ "Display list of stacks on system"
+ headers = ["HOST_NAME", "ROLE", "STATUS"]
+ if not clustername:
+ print("Error! No cluster currently selected")
+ return
+ else:
+ tasks = client.get_task_status(clustername, 2)
+ for task in tasks:
+ rows.append([task.host_name, task.role, task.status])
+
+ # show hosts
+ if option == "hosts":
+ "Display a list of hosts avaiable on the system"
+ headers = ["HOSTNAME", "IP ADDRESS"]
+ if not clustername:
+ for host in client.get_all_hosts():
+ rows.append([host.host_name, host.ip])
+ else:
+ c = client.get_cluster(clustername)
+ for host in c.get_all_hosts():
+ rows.append([host.host_name, host.ip])
+
+ if option == "requests":
+ headers = ["REQUEST-ID", "STATUS"]
+ if not clustername:
+ print("Error! No cluster currently selected")
+ return
+ else:
+ c = client.get_cluster(clustername)
+ for req in client.get_requests(clustername):
+ rows.append([req.id, req.request_status])
+
+ # show services
+ if option == "services":
+ "Show list of services on the cluster"
+ headers = ["SERVICE", "STATUS"]
+
+ if not clustername:
+ print("Error! No cluster currently selected")
+ return
+ else:
+ c = client.get_cluster(clustername)
+ for service in c.get_all_services():
+ rows.append([service.service_name, service.state])
+
+ self.generate_output(headers, rows)
+
+
+def complete_show(self, pattern, line, start_index, end_index):
+ show_commands = [
+ "clusters",
+ "hosts",
+ "services",
+ "stacks",
+ "blueprints",
+ "requests"]
+ if pattern:
+ return [c for c in show_commands if c.startswith(pattern)]
+ else:
+ return show_commands
+
+if __name__ == '__main__':
+ do_show(None, None)
http://git-wip-us.apache.org/repos/asf/ambari/blob/c8eceafc/ambari-shell/ambari-python-shell/src/main/python/ambari_shell/utils/__init__.py
----------------------------------------------------------------------
diff --git a/ambari-shell/ambari-python-shell/src/main/python/ambari_shell/utils/__init__.py b/ambari-shell/ambari-python-shell/src/main/python/ambari_shell/utils/__init__.py
new file mode 100644
index 0000000..278df2e
--- /dev/null
+++ b/ambari-shell/ambari-python-shell/src/main/python/ambari_shell/utils/__init__.py
@@ -0,0 +1,16 @@
+#
+# 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.
http://git-wip-us.apache.org/repos/asf/ambari/blob/c8eceafc/ambari-shell/ambari-python-shell/src/main/python/ambari_shell/utils/displayutils.py
----------------------------------------------------------------------
diff --git a/ambari-shell/ambari-python-shell/src/main/python/ambari_shell/utils/displayutils.py b/ambari-shell/ambari-python-shell/src/main/python/ambari_shell/utils/displayutils.py
new file mode 100644
index 0000000..3c45e7f
--- /dev/null
+++ b/ambari-shell/ambari-python-shell/src/main/python/ambari_shell/utils/displayutils.py
@@ -0,0 +1,128 @@
+#!/usr/bin/env python
+#
+# 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.
+
+import logging
+import textwrap
+import cStringIO
+import operator
+from xml.etree import ElementTree as etree
+from functools import reduce
+
+
+LOG = logging.getLogger(__name__)
+
+
+class bcolors:
+ HEADER = '\033[95m'
+ OKBLUE = '\033[94m'
+ OKGREEN = '\033[92m'
+ WARNING = '\033[93m'
+ FAIL = '\033[91m'
+ ENDC = '\033[0m'
+
+ def disable(self):
+ self.HEADER = ''
+ self.OKBLUE = ''
+ self.OKGREEN = ''
+ self.WARNING = ''
+ self.FAIL = ''
+
+
+__header__ = textwrap.dedent("""
+ ___ __ _
+ / _ | __ _ / / ___ _____(_)
+ / __ |/ ' \/ _ \/ _ `/ __/ /
+/_/ |_/_/_/_/_.__/\_,_/_/ /_/ CLI v%s
+""" % str(1))
+
+
+def shellBanner():
+ """
+ Prints the CLI Banner.
+ """
+ return __header__ + textwrap.dedent(
+ """
+ ====================================
+ Welcome to Ambari python CLI
+ type 'help' to list all commands..
+ ====================================
+ """)
+
+
+def createXML(headers, rows):
+ root = etree.Element('xmloutput')
+ for r in rows:
+ for h, relemt in zip(headers, r):
+
+ child = etree.Element(h.lower().replace(' ', '_'))
+ child.text = str(relemt)
+ root.append(child)
+
+ # pretty string
+ s = etree.tostring(root)
+ return s
+
+
+def createCSV(headers, rows):
+ headers = [x.lower().replace(' ', '_') for x in headers]
+ print(','.join(headers))
+ for r in rows:
+ print(','.join(r))
+
+
+def display_table(headers, rows):
+
+ delimiter = '='
+ delimiter1 = ' | '
+ output = cStringIO.StringIO()
+ temp_rows = [tuple(headers)] + rows
+ row_tuple = [(row,) for row in temp_rows]
+ # get max width
+ verticalrows = map(None, *reduce(operator.add, row_tuple))
+
+ if not rows:
+ widthList = [len(str(x)) for x in headers]
+ row_width = sum(widthList)
+ else:
+ widthList = [max([len(str(x)) for x in column])
+ for column in verticalrows]
+ row_width = sum(widthList)
+ header_line = delimiter * \
+ (row_width + len(delimiter1) * (len(widthList) - 1))
+
+ i = 0
+ for rr in row_tuple:
+ for row in rr:
+ print >> output, delimiter1.join(
+ [(str(x)).ljust(width) for (x, width) in zip(row, widthList)])
+ if i == 0:
+ print >> output, header_line
+ i = 9999
+ return output.getvalue()
+
+
+if __name__ == '__main__':
+ print createXML(['STACK NAME', ], [[u'HDP']])
+ createCSV(['STACK NAME', ], [[u'HDP']])
+ headers = ['First Name', 'Last Name', 'Age']
+ data = \
+ '''Sam ,Browne,21
+ Jhon,Browne,23
+ Adam,senio,21'''
+ rows = [row.strip().split(',') for row in data.splitlines()]
+ print display_table(headers, rows)
http://git-wip-us.apache.org/repos/asf/ambari/blob/c8eceafc/ambari-shell/ambari-python-shell/src/main/python/ambari_shell/utils/osutils.py
----------------------------------------------------------------------
diff --git a/ambari-shell/ambari-python-shell/src/main/python/ambari_shell/utils/osutils.py b/ambari-shell/ambari-python-shell/src/main/python/ambari_shell/utils/osutils.py
new file mode 100644
index 0000000..8aeaa34
--- /dev/null
+++ b/ambari-shell/ambari-python-shell/src/main/python/ambari_shell/utils/osutils.py
@@ -0,0 +1,69 @@
+#!/usr/bin/env python
+#
+# 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.
+
+import logging
+import os
+import sys
+import platform
+
+LOG = logging.getLogger(__name__)
+
+
+def clearScreen(operatingSys):
+ """
+ Function to clear the screen
+ Input : OS
+ """
+ logging.info('Entering..')
+
+ if operatingSys == 'Windows':
+ cmdClear = 'CLS'
+ elif operatingSys == 'Linux':
+ cmdClear = 'clear'
+ elif operatingSys == 'Darwin':
+ cmdClear = 'clear'
+ logging.debug('Running command : %s', cmdClear)
+ os.system(cmdClear)
+ logging.info('Exiting..')
+
+
+def getOperatingSystem():
+ logging.info('Entering..')
+ operatingSys = platform.system()
+ # sprint operatingSys
+ if not operatingSys:
+ logging.error('Operating system is NULL.')
+ return False, ''
+ else:
+ logging.debug('Got operating system : %s', operatingSys)
+ logging.info('Exiting..')
+ return True, operatingSys
+
+
+def doclearScreen():
+ # Determine the OS
+ result, operatingSys = getOperatingSystem()
+ if not result:
+ logging.error('Failed to determine Operating System. Exiting.')
+ sys.exit(1)
+ # clear the Screen
+ clearScreen(operatingSys)
+
+
+if __name__ == '__main__':
+ pass
http://git-wip-us.apache.org/repos/asf/ambari/blob/c8eceafc/ambari-shell/ambari-python-shell/src/main/python/ambari_shell/utils/pluginutils.py
----------------------------------------------------------------------
diff --git a/ambari-shell/ambari-python-shell/src/main/python/ambari_shell/utils/pluginutils.py b/ambari-shell/ambari-python-shell/src/main/python/ambari_shell/utils/pluginutils.py
new file mode 100644
index 0000000..fdcb97c
--- /dev/null
+++ b/ambari-shell/ambari-python-shell/src/main/python/ambari_shell/utils/pluginutils.py
@@ -0,0 +1,100 @@
+#!/usr/bin/env python
+#
+# 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.
+
+import logging
+import os
+import sys
+import inspect
+
+LOG = logging.getLogger(__name__)
+#------------------------------------------------------------------------------
+'''
+Function that searches for all plugins from a file
+Input : folder
+Output : dict
+'''
+#------------------------------------------------------------------------------
+
+
+def get_plugins(module):
+ logging.debug('[Module: %s]\n' % module.__name__)
+
+ plugin_method_map = {}
+ count = 0
+
+ for name in dir(module):
+ obj = getattr(module, name)
+ if inspect.isclass(obj):
+ count += 1
+ elif (inspect.ismethod(obj) or inspect.isfunction(obj)):
+ if obj.__name__.startswith("do_") or obj.__name__.startswith(
+ "help_") or obj.__name__.startswith("complete_") or obj.__name__.startswith("t_"):
+ logging.debug("%s ,%s ", obj.__name__, obj)
+ plugin_method_map.update({obj.__name__: obj})
+ count += 1
+ elif inspect.isbuiltin(obj):
+ count += 1
+ logging.debug(plugin_method_map)
+ if count == 0:
+ logging.debug('(No members)')
+
+ return plugin_method_map
+
+
+def import_modules(dirr):
+ module_list = []
+ for f in os.listdir(os.path.abspath(dirr)):
+ module_name, ext = os.path.splitext(f)
+ if ext == '.py' and module_name != "ambari_shell":
+ logging.debug('imported module: %s' % (module_name))
+ module = __import__(module_name)
+ module_list.append(module)
+
+ return module_list
+
+
+def getPlugins(foldername):
+ if os.path.isdir(foldername):
+ sys.path.append(foldername)
+ logging.debug('%s is a directory!' % (foldername))
+
+ mod_list = import_modules(foldername)
+ logging.debug(mod_list)
+
+ plugin_method_map = {}
+ for m in mod_list:
+ dictt = get_plugins(m)
+ if dictt:
+ plugin_method_map.update(dictt)
+
+ return plugin_method_map
+
+
+def getPluginsFromModules(modulename):
+ module = __import__(modulename)
+ logging.debug(module)
+
+ plugin_method_map = {}
+ dictt = get_plugins(module)
+ if dictt:
+ plugin_method_map.update(dictt)
+
+ return plugin_method_map
+
+if __name__ == "__main__":
+ print getPlugins("plug")
http://git-wip-us.apache.org/repos/asf/ambari/blob/c8eceafc/ambari-shell/ambari-python-shell/src/main/python/setup.py
----------------------------------------------------------------------
diff --git a/ambari-shell/ambari-python-shell/src/main/python/setup.py b/ambari-shell/ambari-python-shell/src/main/python/setup.py
new file mode 100755
index 0000000..b67d872
--- /dev/null
+++ b/ambari-shell/ambari-python-shell/src/main/python/setup.py
@@ -0,0 +1,40 @@
+# 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.
+
+
+from setuptools import setup, find_packages
+
+from sys import version_info, platform
+
+if version_info[:2] > (2, 5):
+ install_requires = []
+else:
+ install_requires = ['simplejson >= 2.0.0']
+
+# Python 2.6 and below requires argparse
+if version_info[:2] < (2, 7):
+ install_requires += ['argparse']
+
+install_requires += ['ambari_client']
+setup(
+ name='ambari_shell',
+ author_email="ambari-dev@incubator.apache.org",
+ version="1.6.0-SNAPSHOT",
+ packages=['ambari_shell'],
+ install_requires=install_requires,
+ description='Ambari Python Shell',
+ license='Apache License 2.0'
+)
http://git-wip-us.apache.org/repos/asf/ambari/blob/c8eceafc/ambari-shell/ambari-python-shell/src/packages/tarball/all.xml
----------------------------------------------------------------------
diff --git a/ambari-shell/ambari-python-shell/src/packages/tarball/all.xml b/ambari-shell/ambari-python-shell/src/packages/tarball/all.xml
new file mode 100755
index 0000000..0e4f34b
--- /dev/null
+++ b/ambari-shell/ambari-python-shell/src/packages/tarball/all.xml
@@ -0,0 +1,34 @@
+<?xml version="1.0"?>
+<!--
+ 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.
+-->
+<assembly xmlns="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.1"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.1 http://maven.apache.org/xsd/assembly-1.1.1.xsd">
+ <!--This 'all' id is not appended to the produced bundle because we do this:
+ http://maven.apache.org/plugins/maven-assembly-plugin/faq.html#required-classifiers
+ -->
+ <formats>
+ <format>dir</format>
+ </formats>
+ <includeBaseDirectory>false</includeBaseDirectory>
+ <fileSets>
+ <fileSet>
+ <directory>src/main/python</directory>
+ <outputDirectory>/</outputDirectory>
+ </fileSet>
+ </fileSets>
+</assembly>
http://git-wip-us.apache.org/repos/asf/ambari/blob/c8eceafc/ambari-shell/assemblies/client.xml
----------------------------------------------------------------------
diff --git a/ambari-shell/assemblies/client.xml b/ambari-shell/assemblies/client.xml
new file mode 100644
index 0000000..20670cd
--- /dev/null
+++ b/ambari-shell/assemblies/client.xml
@@ -0,0 +1,20 @@
+<?xml version="1.0"?>
+<!--
+ 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.
+-->
+<assembly>
+</assembly>
http://git-wip-us.apache.org/repos/asf/ambari/blob/c8eceafc/ambari-shell/pom.xml
----------------------------------------------------------------------
diff --git a/ambari-shell/pom.xml b/ambari-shell/pom.xml
index a7e3400..947c9b9 100644
--- a/ambari-shell/pom.xml
+++ b/ambari-shell/pom.xml
@@ -1,14 +1,23 @@
<?xml version="1.0"?>
-<!-- Licensed under the Apache License, Version 2.0 (the "License"); you
- may not use this file except in compliance with the License. You may obtain
- a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless
- required by applicable law or agreed to in writing, software distributed
- under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES
- OR CONDITIONS OF ANY KIND, either express or implied. See the License for
- the specific language governing permissions and limitations under the License.
- See accompanying LICENSE file. -->
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+ <!--
+ 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.
+-->
+
<parent>
<groupId>org.apache.ambari</groupId>
<artifactId>ambari-project</artifactId>
@@ -18,106 +27,33 @@
<modelVersion>4.0.0</modelVersion>
<groupId>org.apache.ambari</groupId>
<artifactId>ambari-shell</artifactId>
- <packaging>jar</packaging>
- <name>Ambari Shell</name>
+ <packaging>pom</packaging>
<version>1.3.0-SNAPSHOT</version>
+ <name>Ambari Shell</name>
<description>Ambari Shell</description>
- <properties>
- <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
- <start-class>org.apache.ambari.shell.AmbariShell</start-class>
- </properties>
- <dependencies>
- <dependency>
- <groupId>junit</groupId>
- <artifactId>junit</artifactId>
- </dependency>
- <dependency>
- <groupId>org.springframework.shell</groupId>
- <artifactId>spring-shell</artifactId>
- </dependency>
- <dependency>
- <groupId>org.springframework.boot</groupId>
- <artifactId>spring-boot-starter</artifactId>
- </dependency>
- <dependency>
- <groupId>org.springframework.boot</groupId>
- <artifactId>spring-boot-starter-test</artifactId>
- </dependency>
- <dependency>
- <groupId>com.github.lalyos</groupId>
- <artifactId>jfiglet</artifactId>
- </dependency>
- <dependency>
- <groupId>commons-io</groupId>
- <artifactId>commons-io</artifactId>
- <version>2.3</version>
- </dependency>
- <dependency>
- <groupId>org.apache.ambari</groupId>
- <artifactId>groovy-client</artifactId>
- <version>1.3.0-SNAPSHOT</version>
- </dependency>
- <dependency>
- <groupId>org.mockito</groupId>
- <artifactId>mockito-core</artifactId>
- <version>1.9.5</version>
- <scope>test</scope>
- </dependency>
- <dependency>
- <groupId>jline</groupId>
- <artifactId>jline</artifactId>
- </dependency>
- <dependency>
- <groupId>org.codehaus.jackson</groupId>
- <artifactId>jackson-mapper-asl</artifactId>
- </dependency>
- </dependencies>
+ <modules>
+ <module>ambari-python-shell</module>
+ <module>ambari-groovy-shell</module>
+ </modules>
<build>
<plugins>
<plugin>
- <artifactId>maven-compiler-plugin</artifactId>
- <version>3.0</version>
- </plugin>
- <plugin>
- <groupId>org.apache.rat</groupId>
- <artifactId>apache-rat-plugin</artifactId>
- <configuration>
- <excludes>
- <exclude>src/main/resources/elephant.txt</exclude>
- <exclude>src/test/resources/2columns</exclude>
- <exclude>src/test/resources/3columns</exclude>
- <exclude>src/test/resources/testBlueprint.json</exclude>
- </excludes>
- </configuration>
- <executions>
- <execution>
- <phase>test</phase>
- <goals>
- <goal>check</goal>
- </goals>
- </execution>
- </executions>
- </plugin>
- <plugin>
<artifactId>maven-assembly-plugin</artifactId>
<configuration>
- <skipAssembly>true</skipAssembly>
+ <tarLongFileMode>gnu</tarLongFileMode>
+ <descriptors>
+ <descriptor>assemblies/client.xml</descriptor>
+ </descriptors>
</configuration>
- </plugin>
- <plugin>
- <groupId>org.springframework.boot</groupId>
- <artifactId>spring-boot-maven-plugin</artifactId>
- <version>1.0.2.RELEASE</version>
<executions>
<execution>
+ <id>build-tarball</id>
+ <phase>prepare-package</phase>
<goals>
- <goal>repackage</goal>
+ <goal>single</goal>
</goals>
</execution>
</executions>
- <configuration>
- <mainClass>${start-class}</mainClass>
- </configuration>
</plugin>
<plugin>
<groupId>org.vafer</groupId>
@@ -132,9 +68,7 @@
</execution>
</executions>
<configuration>
- <controlDir>${basedir}/../../ambari-project/src/main/package/deb/control</controlDir>
- <skip>true</skip>
- <submodules>false</submodules>
+ <controlDir>${basedir}/../ambari-project/src/main/package/deb/control</controlDir>
</configuration>
</plugin>
</plugins>
http://git-wip-us.apache.org/repos/asf/ambari/blob/c8eceafc/ambari-shell/src/main/java/org/apache/ambari/shell/AmbariShell.java
----------------------------------------------------------------------
diff --git a/ambari-shell/src/main/java/org/apache/ambari/shell/AmbariShell.java b/ambari-shell/src/main/java/org/apache/ambari/shell/AmbariShell.java
deleted file mode 100644
index e842620..0000000
--- a/ambari-shell/src/main/java/org/apache/ambari/shell/AmbariShell.java
+++ /dev/null
@@ -1,111 +0,0 @@
-/**
- * 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.ambari.shell;
-
-import org.apache.ambari.groovy.client.AmbariClient;
-import org.apache.ambari.shell.model.AmbariContext;
-import org.apache.ambari.shell.model.Hints;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.boot.CommandLineRunner;
-import org.springframework.boot.builder.SpringApplicationBuilder;
-import org.springframework.context.annotation.ComponentScan;
-import org.springframework.context.annotation.Configuration;
-import org.springframework.shell.CommandLine;
-import org.springframework.shell.core.JLineShellComponent;
-import org.springframework.shell.event.ShellStatus;
-import org.springframework.shell.event.ShellStatusListener;
-
-/**
- * Shell bootstrap.
- */
-@Configuration
-@ComponentScan(basePackageClasses = {AmbariShell.class})
-public class AmbariShell implements CommandLineRunner, ShellStatusListener {
-
- @Autowired
- private CommandLine commandLine;
- @Autowired
- private JLineShellComponent shell;
- @Autowired
- private AmbariContext context;
- @Autowired
- private AmbariClient client;
-
- @Override
- public void run(String... arg) throws Exception {
- String[] shellCommandsToExecute = commandLine.getShellCommandsToExecute();
- if (shellCommandsToExecute != null) {
- for (String cmd : shellCommandsToExecute) {
- if (!shell.executeScriptLine(cmd)) {
- break;
- }
- }
- System.exit(0);
- } else {
- shell.addShellStatusListener(this);
- shell.start();
- shell.promptLoop();
- shell.waitForComplete();
- }
- }
-
- @Override
- public void onShellStatusChange(ShellStatus oldStatus, ShellStatus newStatus) {
- if (newStatus.getStatus() == ShellStatus.Status.STARTED) {
- try {
- String cluster = client.getClusterName();
- boolean available = client.isBlueprintAvailable();
- if (cluster == null) {
- if (available) {
- context.setHint(Hints.BUILD_CLUSTER);
- } else {
- context.setHint(Hints.ADD_BLUEPRINT);
- }
- } else {
- context.setHint(Hints.PROGRESS);
- }
- context.setCluster(cluster);
- context.setBlueprintsAvailable(available);
- } catch (Exception e) {
- System.out.println(e.getMessage());
- shell.executeCommand("quit");
- }
- }
- }
-
-
- public static void main(String[] args) {
- if (args.length == 0) {
- System.out.println(
- "\nAmbari Shell: Interactive command line tool for managing Apache Ambari.\n\n" +
- "Usage:\n" +
- " java -jar ambari-shell.jar : Starts Ambari Shell in interactive mode.\n" +
- " java -jar ambari-shell.jar --cmdfile=<FILE> : Ambari Shell executes commands read from the file.\n\n" +
- "Options:\n" +
- " --ambari.host=<HOSTNAME> Hostname of the Ambari Server [default: localhost].\n" +
- " --ambari.port=<PORT> Port of the Ambari Server [default: 8080].\n" +
- " --ambari.user=<USER> Username of the Ambari admin [default: admin].\n" +
- " --ambari.password=<PASSWORD> Password of the Ambari admin [default: admin].\n\n" +
- "Note:\n" +
- " At least one option is mandatory."
- );
- System.exit(1);
- }
- new SpringApplicationBuilder(AmbariShell.class).showBanner(false).run(args);
- }
-}
http://git-wip-us.apache.org/repos/asf/ambari/blob/c8eceafc/ambari-shell/src/main/java/org/apache/ambari/shell/commands/BasicCommands.java
----------------------------------------------------------------------
diff --git a/ambari-shell/src/main/java/org/apache/ambari/shell/commands/BasicCommands.java b/ambari-shell/src/main/java/org/apache/ambari/shell/commands/BasicCommands.java
deleted file mode 100644
index 9babe12..0000000
--- a/ambari-shell/src/main/java/org/apache/ambari/shell/commands/BasicCommands.java
+++ /dev/null
@@ -1,207 +0,0 @@
-/**
- * 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.ambari.shell.commands;
-
-import static org.apache.ambari.shell.support.TableRenderer.renderMapValueMap;
-import static org.apache.ambari.shell.support.TableRenderer.renderSingleMap;
-
-import org.apache.ambari.groovy.client.AmbariClient;
-import org.apache.ambari.shell.model.AmbariContext;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.shell.core.CommandMarker;
-import org.springframework.shell.core.annotation.CliAvailabilityIndicator;
-import org.springframework.shell.core.annotation.CliCommand;
-import org.springframework.shell.core.annotation.CliOption;
-import org.springframework.stereotype.Component;
-
-/**
- * Basic commands used in the shell. Delegating the commands
- * to the Ambari Server via a Groovy based client.
- *
- * @see org.apache.ambari.groovy.client.AmbariClient
- */
-@Component
-public class BasicCommands implements CommandMarker {
-
- private AmbariClient client;
- private AmbariContext context;
-
- @Autowired
- public BasicCommands(AmbariClient client, AmbariContext context) {
- this.client = client;
- this.context = context;
- }
-
- /**
- * Checks whether the tasks command is available or not.
- *
- * @return true if its available false otherwise
- */
- @CliAvailabilityIndicator("tasks")
- public boolean isTasksCommandAvailable() {
- return context.isConnectedToCluster();
- }
-
- /**
- * Prints the tasks of the Ambari Server.
- *
- * @param id id of the request
- * @return task list
- */
- @CliCommand(value = "tasks", help = "Lists the Ambari tasks")
- public String tasks(
- @CliOption(key = "id", mandatory = false, help = "Id of the request; default is: 1", unspecifiedDefaultValue = "1") String id) {
- return renderSingleMap(client.getTaskMap(id), "TASK", "STATUS");
- }
-
- /**
- * Checks whether the service list command is available or not.
- *
- * @return true if available false otherwise
- */
- @CliAvailabilityIndicator("services list")
- public boolean isServiceListCommandAvailable() {
- return context.isConnectedToCluster();
- }
-
- /**
- * Prints the available service list of the Ambari Server.
- *
- * @return service list
- */
- @CliCommand(value = "services list", help = "Lists the available services")
- public String servicesList() {
- return renderSingleMap(client.getServicesMap(), "SERVICE", "STATE");
- }
-
- /**
- * Checks whether the service components command is available or not.
- *
- * @return true if available false otherwise
- */
- @CliAvailabilityIndicator("services components")
- public boolean isServiceComponentsCommandAvailable() {
- return context.isConnectedToCluster();
- }
-
- /**
- * Prints the service components of the Ambari Server.
- *
- * @return service component list
- */
- @CliCommand(value = "services components", help = "Lists all services with their components")
- public String serviceComponents() {
- return renderMapValueMap(client.getServiceComponentsMap(), "SERVICE", "COMPONENT", "STATE");
- }
-
- /**
- * Checks whether the debug on command is available or not.
- *
- * @return true if available false otherwise
- */
- @CliAvailabilityIndicator("debug on")
- public boolean isDebugOnCommandAvailable() {
- return !client.isDebugEnabled();
- }
-
- /**
- * Turns the debug on. From now on users will see the URLs of the API calls.
- *
- * @return status message
- */
- @CliCommand(value = "debug on", help = "Shows the URL of the API calls")
- public String debugOn() {
- client.setDebugEnabled(true);
- return "debug enabled";
- }
-
- /**
- * Checks whether the debug off command is available or not.
- *
- * @return true if available false otherwise
- */
- @CliAvailabilityIndicator("debug off")
- public boolean isDebugOffCommandAvailable() {
- return client.isDebugEnabled();
- }
-
- /**
- * Turns the debug off. URLs are not visible anymore.
- *
- * @return status message
- */
- @CliCommand(value = "debug off", help = "Stops showing the URL of the API calls")
- public String debugOff() {
- client.setDebugEnabled(false);
- return "debug disabled";
- }
-
- /**
- * Checks whether the hint command is available or not.
- *
- * @return true if available false otherwise
- */
- @CliAvailabilityIndicator("hint")
- public boolean isHintCommandAvailable() {
- return true;
- }
-
- /**
- * Provides some hints what you can do in the current context.
- *
- * @return hint message
- */
- @CliCommand(value = "hint", help = "Shows some hints")
- public String hint() {
- return context.getHint();
- }
-
- @CliAvailabilityIndicator("services stop")
- public boolean isServiceStopCommandAvailable() {
- return context.isConnectedToCluster();
- }
-
- @CliCommand(value = "services stop", help = "Stops all the running services")
- public String stopServices() {
- String message;
- try {
- client.stopAllServices();
- message = "Stopping all services..";
- } catch (Exception e) {
- message = "Cannot stop services";
- }
- return String.format("%s\n\n%s", message, servicesList());
- }
-
- @CliAvailabilityIndicator("services start")
- public boolean isServiceStartCommandAvailable() {
- return context.isConnectedToCluster();
- }
-
- @CliCommand(value = "services start", help = "Starts all the services")
- public String startServices() {
- String message;
- try {
- client.startAllServices();
- message = "Starting all services..";
- } catch (Exception e) {
- message = "Cannot start services";
- }
- return String.format("%s\n\n%s", message, servicesList());
- }
-}
http://git-wip-us.apache.org/repos/asf/ambari/blob/c8eceafc/ambari-shell/src/main/java/org/apache/ambari/shell/commands/BlueprintCommands.java
----------------------------------------------------------------------
diff --git a/ambari-shell/src/main/java/org/apache/ambari/shell/commands/BlueprintCommands.java b/ambari-shell/src/main/java/org/apache/ambari/shell/commands/BlueprintCommands.java
deleted file mode 100644
index 73000d0..0000000
--- a/ambari-shell/src/main/java/org/apache/ambari/shell/commands/BlueprintCommands.java
+++ /dev/null
@@ -1,198 +0,0 @@
-/**
- * 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.ambari.shell.commands;
-
-import static org.apache.ambari.shell.support.TableRenderer.renderMultiValueMap;
-import static org.apache.ambari.shell.support.TableRenderer.renderSingleMap;
-
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.IOException;
-import java.net.URL;
-
-import org.apache.ambari.groovy.client.AmbariClient;
-import org.apache.ambari.shell.completion.Blueprint;
-import org.apache.ambari.shell.model.AmbariContext;
-import org.apache.ambari.shell.model.Hints;
-import org.apache.commons.io.IOUtils;
-import org.codehaus.jackson.map.ObjectMapper;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.shell.core.CommandMarker;
-import org.springframework.shell.core.annotation.CliAvailabilityIndicator;
-import org.springframework.shell.core.annotation.CliCommand;
-import org.springframework.shell.core.annotation.CliOption;
-import org.springframework.stereotype.Component;
-
-/**
- * Blueprint related commands used in the shell.
- *
- * @see org.apache.ambari.groovy.client.AmbariClient
- */
-@Component
-public class BlueprintCommands implements CommandMarker {
-
- private AmbariClient client;
- private AmbariContext context;
- private ObjectMapper jsonMapper;
-
- @Autowired
- public BlueprintCommands(AmbariClient client, AmbariContext context, ObjectMapper jsonMapper) {
- this.client = client;
- this.context = context;
- this.jsonMapper = jsonMapper;
- }
-
- /**
- * Checks whether the blueprints command is available or not.
- *
- * @return true if available false otherwise
- */
- @CliAvailabilityIndicator("blueprint list")
- public boolean isBlueprintListCommandAvailable() {
- return context.areBlueprintsAvailable();
- }
-
- /**
- * Prints all the blueprints.
- *
- * @return list of blueprints
- */
- @CliCommand(value = "blueprint list", help = "Lists all known blueprints")
- public String listBlueprints() {
- return renderSingleMap(client.getBlueprintsMap(), "BLUEPRINT", "STACK");
- }
-
- /**
- * Checks whether the blueprint show command is available or not.
- *
- * @return true if available false otherwise
- */
- @CliAvailabilityIndicator(value = "blueprint show")
- public boolean isBlueprintShowCommandAvailable() {
- return context.areBlueprintsAvailable();
- }
-
- /**
- * Shows the requested blueprint's details.
- *
- * @param id id of the blueprint
- * @return blueprint as formatted table
- */
- @CliCommand(value = "blueprint show", help = "Shows the blueprint by its id")
- public String showBlueprint(
- @CliOption(key = "id", mandatory = true, help = "Id of the blueprint") Blueprint id) {
- return renderMultiValueMap(client.getBlueprintMap(id.getName()), "HOSTGROUP", "COMPONENT");
- }
-
- /**
- * Checks whether the blueprint add command is available or not.
- *
- * @return true if available false otherwise
- */
- @CliAvailabilityIndicator(value = "blueprint add")
- public boolean isBlueprintAddCommandAvailable() {
- return true;
- }
-
- /**
- * Adds a blueprint to the Ambari server either through an URL or from a file.
- * If both specified the file takes precedence.
- *
- * @param url -optional, URL containing the blueprint json
- * @param file - optional, file containing the blueprint json
- * @return status message
- */
- @CliCommand(value = "blueprint add", help = "Add a new blueprint with either --url or --file")
- public String addBlueprint(
- @CliOption(key = "url", mandatory = false, help = "URL of the blueprint to download from") String url,
- @CliOption(key = "file", mandatory = false, help = "File which contains the blueprint") File file) {
- String message;
- try {
- String json = file == null ? readContent(url) : readContent(file);
- if (json != null) {
- client.addBlueprint(json);
- context.setHint(Hints.BUILD_CLUSTER);
- context.setBlueprintsAvailable(true);
- message = String.format("Blueprint: '%s' has been added", getBlueprintName(json));
- } else {
- message = "No blueprint specified";
- }
- } catch (Exception e) {
- message = "Cannot add blueprint: " + e.getMessage();
- }
- return message;
- }
-
- /**
- * Checks whether the blueprint defaults command is available or not.
- *
- * @return true if available false otherwise
- */
- @CliAvailabilityIndicator(value = "blueprint defaults")
- public boolean isBlueprintDefaultsAddCommandAvailable() {
- return !context.areBlueprintsAvailable();
- }
-
- /**
- * Adds two default blueprints to the Ambari server.
- *
- * @return status message
- */
- @CliCommand(value = "blueprint defaults", help = "Adds the default blueprints to Ambari")
- public String addBlueprint() {
- String message = "Default blueprints added";
- try {
- client.addDefaultBlueprints();
- context.setHint(Hints.BUILD_CLUSTER);
- context.setBlueprintsAvailable(true);
- } catch (Exception e) {
- message = "Failed to add the default blueprints: " + e.getMessage();
- }
- return message;
- }
-
- private String readContent(File file) {
- String content = null;
- try {
- content = IOUtils.toString(new FileInputStream(file));
- } catch (IOException e) {
- // not important
- }
- return content;
- }
-
- private String readContent(String url) {
- String content = null;
- try {
- content = IOUtils.toString(new URL(url));
- } catch (IOException e) {
- // not important
- }
- return content;
- }
-
- private String getBlueprintName(String json) {
- String result = "";
- try {
- result = jsonMapper.readTree(json.getBytes()).get("Blueprints").get("blueprint_name").asText();
- } catch (IOException e) {
- // not important
- }
- return result;
- }
-}
http://git-wip-us.apache.org/repos/asf/ambari/blob/c8eceafc/ambari-shell/src/main/java/org/apache/ambari/shell/commands/ClusterCommands.java
----------------------------------------------------------------------
diff --git a/ambari-shell/src/main/java/org/apache/ambari/shell/commands/ClusterCommands.java b/ambari-shell/src/main/java/org/apache/ambari/shell/commands/ClusterCommands.java
deleted file mode 100644
index dafdb85..0000000
--- a/ambari-shell/src/main/java/org/apache/ambari/shell/commands/ClusterCommands.java
+++ /dev/null
@@ -1,294 +0,0 @@
-/**
- * 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.ambari.shell.commands;
-
-import static org.apache.ambari.shell.support.TableRenderer.renderMultiValueMap;
-import static org.apache.ambari.shell.support.TableRenderer.renderSingleMap;
-
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-
-import org.apache.ambari.groovy.client.AmbariClient;
-import org.apache.ambari.shell.completion.Blueprint;
-import org.apache.ambari.shell.completion.Host;
-import org.apache.ambari.shell.flash.FlashService;
-import org.apache.ambari.shell.model.AmbariContext;
-import org.apache.ambari.shell.model.FocusType;
-import org.apache.ambari.shell.model.Hints;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.shell.core.CommandMarker;
-import org.springframework.shell.core.annotation.CliAvailabilityIndicator;
-import org.springframework.shell.core.annotation.CliCommand;
-import org.springframework.shell.core.annotation.CliOption;
-import org.springframework.stereotype.Component;
-
-import groovyx.net.http.HttpResponseException;
-
-/**
- * Cluster related commands used in the shell.
- *
- * @see org.apache.ambari.groovy.client.AmbariClient
- */
-@Component
-public class ClusterCommands implements CommandMarker {
-
- private AmbariClient client;
- private AmbariContext context;
- private FlashService flashService;
- private Map<String, List<String>> hostGroups;
-
- @Autowired
- public ClusterCommands(AmbariClient client, AmbariContext context, FlashService flashService) {
- this.client = client;
- this.context = context;
- this.flashService = flashService;
- }
-
- /**
- * Checks whether the cluster build command is available or not.
- *
- * @return true if available false otherwise
- */
- @CliAvailabilityIndicator("cluster build")
- public boolean isClusterBuildCommandAvailable() {
- return !context.isConnectedToCluster() && !context.isFocusOnClusterBuild() && context.areBlueprintsAvailable();
- }
-
- /**
- * Sets the focus on cluster building. Takes a blueprint id, if it does not exists it wont focus.
- * After focus the users are able to assign hosts to host groups.
- *
- * @param id id of the blueprint
- * @return prints the blueprint as formatted table if exists, otherwise error message
- */
- @CliCommand(value = "cluster build", help = "Starts to build a cluster")
- public String buildCluster(
- @CliOption(key = "blueprint", mandatory = true, help = "Id of the blueprint, use 'blueprints' command to see the list") Blueprint id) {
- String message;
- String blueprint = id.getName();
- if (client.doesBlueprintExist(blueprint)) {
- context.setFocus(blueprint, FocusType.CLUSTER_BUILD);
- context.setHint(Hints.ASSIGN_HOSTS);
- message = String.format("%s\n%s",
- renderSingleMap(client.getHostNames(), "HOSTNAME", "STATE"),
- renderMultiValueMap(client.getBlueprintMap(blueprint), "HOSTGROUP", "COMPONENT"));
- createNewHostGroups();
- } else {
- message = "Not a valid blueprint id";
- }
- return message;
- }
-
- /**
- * Checks whether the cluster assign command is available or not.
- *
- * @return true if available false otherwise
- */
- @CliAvailabilityIndicator("cluster assign")
- public boolean isAssignCommandAvailable() {
- return context.isFocusOnClusterBuild();
- }
-
- /**
- * Assign hosts to host groups provided in the blueprint.
- *
- * @param host host to assign
- * @param group which host group to
- * @return status message
- */
- @CliCommand(value = "cluster assign", help = "Assign host to host group")
- public String assign(
- @CliOption(key = "host", mandatory = true, help = "Fully qualified host name") Host host,
- @CliOption(key = "hostGroup", mandatory = true, help = "Host group which to assign the host") String group) {
- String message;
- String hostName = host.getName();
- if (client.getHostNames().keySet().contains(hostName)) {
- if (addHostToGroup(hostName, group)) {
- context.setHint(Hints.CREATE_CLUSTER);
- message = String.format("%s has been added to %s", hostName, group);
- } else {
- message = String.format("%s is not a valid host group", group);
- }
- } else {
- message = String.format("%s is not a valid hostname", hostName);
- }
- return message;
- }
-
- /**
- * Checks whether the cluster auto command is available or not.
- *
- * @return true if available false otherwise
- */
- @CliAvailabilityIndicator(value = "cluster autoAssign")
- public boolean isClusterAutoAssignAvailable() {
- return context.isFocusOnClusterBuild() && !isHostAssigned();
- }
-
- /**
- * Tries to auto associate hosts to host groups.
- *
- * @return prints the auto assignments
- */
- @CliCommand(value = "cluster autoAssign", help = "Automatically assigns hosts to different host groups base on the provided strategy")
- public String autoAssign() {
- Map<String, List<String>> assignments = client.recommendAssignments(context.getFocusValue());
- if (!assignments.isEmpty()) {
- hostGroups = assignments;
- context.setHint(Hints.CREATE_CLUSTER);
- }
- return showAssignments();
- }
-
- /**
- * Checks whether the cluster preview command is available or not.
- *
- * @return true if available false otherwise
- */
- @CliAvailabilityIndicator("cluster preview")
- public boolean isClusterPreviewCommandAvailable() {
- return context.isFocusOnClusterBuild() && isHostAssigned();
- }
-
- /**
- * Shows the currently assigned hosts.
- *
- * @return formatted host - host group table
- */
- @CliCommand(value = "cluster preview", help = "Shows the currently assigned hosts")
- public String showAssignments() {
- return renderMultiValueMap(hostGroups, "HOSTGROUP", "HOST");
- }
-
- /**
- * Checks whether the cluster create command is available or not.
- *
- * @return true if available false otherwise
- */
- @CliAvailabilityIndicator("cluster create")
- public boolean isCreateClusterCommandAvailable() {
- return context.isFocusOnClusterBuild() && isHostAssigned();
- }
-
- /**
- * Creates a new cluster based on the provided host - host group associations and the selected blueprint.
- * If the cluster creation fails, deletes the cluster.
- *
- * @return status message
- */
- @CliCommand(value = "cluster create", help = "Create a cluster based on current blueprint and assigned hosts")
- public String createCluster(
- @CliOption(key = "exitOnFinish", mandatory = false, help = "Quits the shell when the cluster creation finishes") Boolean exit) {
- String message = "Successfully created the cluster";
- String blueprint = context.getFocusValue();
- try {
- client.createCluster(blueprint, blueprint, hostGroups);
- context.setCluster(blueprint);
- context.resetFocus();
- context.setHint(Hints.PROGRESS);
- flashService.showInstallProgress(exit == null ? false : exit);
- } catch (HttpResponseException e) {
- createNewHostGroups();
- message = "Failed to create the cluster: " + e.getMessage();
- try {
- deleteCluster(blueprint);
- } catch (HttpResponseException e1) {
- message += ". Failed to cleanup cluster creation: " + e1.getMessage();
- }
- }
- return message;
- }
-
- /**
- * Checks whether the cluster delete command is available or not.
- *
- * @return true if available false otherwise
- */
- @CliAvailabilityIndicator("cluster delete")
- public boolean isDeleteClusterCommandAvailable() {
- return context.isConnectedToCluster();
- }
-
- /**
- * Deletes the cluster.
- *
- * @return status message
- */
- @CliCommand(value = "cluster delete", help = "Delete the cluster")
- public String deleteCluster() {
- String message = "Successfully deleted the cluster";
- try {
- deleteCluster(context.getCluster());
- } catch (HttpResponseException e) {
- message = "Could not delete the cluster: " + e.getMessage();
- }
- return message;
- }
-
- /**
- * Checks whether the cluster reset command is available or not.
- *
- * @return true if available false otherwise
- */
- @CliAvailabilityIndicator(value = "cluster reset")
- public boolean isClusterResetCommandAvailable() {
- return context.isFocusOnClusterBuild() && isHostAssigned();
- }
-
- @CliCommand(value = "cluster reset", help = "Clears the host - host group assignments")
- public void reset() {
- context.setHint(Hints.ASSIGN_HOSTS);
- createNewHostGroups();
- }
-
- private void deleteCluster(String id) throws HttpResponseException {
- client.deleteCluster(id);
- }
-
- private void createNewHostGroups() {
- Map<String, List<String>> groups = new HashMap<String, List<String>>();
- for (String hostGroup : client.getHostGroups(context.getFocusValue())) {
- groups.put(hostGroup, new ArrayList<String>());
- }
- this.hostGroups = groups;
- }
-
- private boolean addHostToGroup(String host, String group) {
- boolean result = true;
- List<String> hosts = hostGroups.get(group);
- if (hosts == null) {
- result = false;
- } else {
- hosts.add(host);
- }
- return result;
- }
-
- private boolean isHostAssigned() {
- boolean result = false;
- for (String group : hostGroups.keySet()) {
- if (!hostGroups.get(group).isEmpty()) {
- result = true;
- break;
- }
- }
- return result;
- }
-}
http://git-wip-us.apache.org/repos/asf/ambari/blob/c8eceafc/ambari-shell/src/main/java/org/apache/ambari/shell/commands/ElephantCommand.java
----------------------------------------------------------------------
diff --git a/ambari-shell/src/main/java/org/apache/ambari/shell/commands/ElephantCommand.java b/ambari-shell/src/main/java/org/apache/ambari/shell/commands/ElephantCommand.java
deleted file mode 100644
index a236054..0000000
--- a/ambari-shell/src/main/java/org/apache/ambari/shell/commands/ElephantCommand.java
+++ /dev/null
@@ -1,53 +0,0 @@
-/**
- * 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.ambari.shell.commands;
-
-import java.io.IOException;
-
-import org.apache.commons.io.IOUtils;
-import org.springframework.shell.core.CommandMarker;
-import org.springframework.shell.core.annotation.CliAvailabilityIndicator;
-import org.springframework.shell.core.annotation.CliCommand;
-import org.springframework.stereotype.Component;
-
-/**
- * Draws an elephant to the console.
- */
-@Component
-public class ElephantCommand implements CommandMarker {
-
- /**
- * Checks whether the hello command is available or not.
- *
- * @return true if available false otherwise
- */
- @CliAvailabilityIndicator("hello")
- public boolean isCommandAvailable() {
- return true;
- }
-
- /**
- * Prints an elephant to the console.
- *
- * @return elephant
- */
- @CliCommand(value = "hello", help = "Prints a simple elephant to the console")
- public String elephant() throws IOException {
- return IOUtils.toString(getClass().getResourceAsStream("/elephant.txt"));
- }
-}
\ No newline at end of file
[3/4] AMBARI-6176. Integrate python shell into Ambari-shell
module(subin)
Posted by su...@apache.org.
http://git-wip-us.apache.org/repos/asf/ambari/blob/c8eceafc/ambari-shell/ambari-groovy-shell/src/main/java/org/apache/ambari/shell/flash/AbstractFlash.java
----------------------------------------------------------------------
diff --git a/ambari-shell/ambari-groovy-shell/src/main/java/org/apache/ambari/shell/flash/AbstractFlash.java b/ambari-shell/ambari-groovy-shell/src/main/java/org/apache/ambari/shell/flash/AbstractFlash.java
new file mode 100644
index 0000000..58abb75
--- /dev/null
+++ b/ambari-shell/ambari-groovy-shell/src/main/java/org/apache/ambari/shell/flash/AbstractFlash.java
@@ -0,0 +1,66 @@
+/**
+ * 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.ambari.shell.flash;
+
+import static java.lang.Thread.sleep;
+
+import java.util.logging.Level;
+
+import org.springframework.shell.core.JLineShellComponent;
+
+/**
+ * Base class for showing flash messages.
+ */
+public abstract class AbstractFlash implements Runnable {
+
+ private static final int SLEEP_TIME = 1500;
+ private volatile boolean stop;
+ private FlashType flashType;
+ private JLineShellComponent shell;
+
+ protected AbstractFlash(JLineShellComponent shell, FlashType flashType) {
+ this.shell = shell;
+ this.flashType = flashType;
+ }
+
+ @Override
+ public void run() {
+ while (!stop) {
+ String text = null;
+ try {
+ text = getText();
+ if (text.isEmpty()) {
+ stop = true;
+ }
+ sleep(SLEEP_TIME);
+ } catch (Exception e) {
+ // ignore
+ } finally {
+ shell.flash(Level.SEVERE, text == null ? "" : text, flashType.getName());
+ }
+ }
+ }
+
+ /**
+ * Returns the actual text of the flash messages. To remove the flash
+ * return an empty string.
+ *
+ * @return message
+ */
+ public abstract String getText();
+}
http://git-wip-us.apache.org/repos/asf/ambari/blob/c8eceafc/ambari-shell/ambari-groovy-shell/src/main/java/org/apache/ambari/shell/flash/FlashService.java
----------------------------------------------------------------------
diff --git a/ambari-shell/ambari-groovy-shell/src/main/java/org/apache/ambari/shell/flash/FlashService.java b/ambari-shell/ambari-groovy-shell/src/main/java/org/apache/ambari/shell/flash/FlashService.java
new file mode 100644
index 0000000..78977a6
--- /dev/null
+++ b/ambari-shell/ambari-groovy-shell/src/main/java/org/apache/ambari/shell/flash/FlashService.java
@@ -0,0 +1,47 @@
+/**
+ * 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.ambari.shell.flash;
+
+import java.util.concurrent.ExecutorService;
+
+import org.apache.ambari.groovy.client.AmbariClient;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.shell.core.JLineShellComponent;
+import org.springframework.stereotype.Service;
+
+/**
+ * Service for managing the flashes.
+ */
+@Service
+public class FlashService {
+
+ private AmbariClient client;
+ private JLineShellComponent shell;
+ private ExecutorService executorService;
+
+ @Autowired
+ public FlashService(AmbariClient client, JLineShellComponent shell, ExecutorService executorService) {
+ this.client = client;
+ this.shell = shell;
+ this.executorService = executorService;
+ }
+
+ public void showInstallProgress(boolean exit) {
+ executorService.submit(new InstallProgress(shell, client, exit));
+ }
+}
http://git-wip-us.apache.org/repos/asf/ambari/blob/c8eceafc/ambari-shell/ambari-groovy-shell/src/main/java/org/apache/ambari/shell/flash/FlashType.java
----------------------------------------------------------------------
diff --git a/ambari-shell/ambari-groovy-shell/src/main/java/org/apache/ambari/shell/flash/FlashType.java b/ambari-shell/ambari-groovy-shell/src/main/java/org/apache/ambari/shell/flash/FlashType.java
new file mode 100644
index 0000000..754a269
--- /dev/null
+++ b/ambari-shell/ambari-groovy-shell/src/main/java/org/apache/ambari/shell/flash/FlashType.java
@@ -0,0 +1,39 @@
+/**
+ * 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.ambari.shell.flash;
+
+/**
+ * Holds the unique names of the flashes.
+ */
+public enum FlashType {
+
+ /**
+ * Install progress percentage flash.
+ */
+ INSTALL("install");
+
+ private String name;
+
+ private FlashType(String name) {
+ this.name = name;
+ }
+
+ public String getName() {
+ return name;
+ }
+}
http://git-wip-us.apache.org/repos/asf/ambari/blob/c8eceafc/ambari-shell/ambari-groovy-shell/src/main/java/org/apache/ambari/shell/flash/InstallProgress.java
----------------------------------------------------------------------
diff --git a/ambari-shell/ambari-groovy-shell/src/main/java/org/apache/ambari/shell/flash/InstallProgress.java b/ambari-shell/ambari-groovy-shell/src/main/java/org/apache/ambari/shell/flash/InstallProgress.java
new file mode 100644
index 0000000..69164ea
--- /dev/null
+++ b/ambari-shell/ambari-groovy-shell/src/main/java/org/apache/ambari/shell/flash/InstallProgress.java
@@ -0,0 +1,79 @@
+/**
+ * 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.ambari.shell.flash;
+
+import static java.lang.Math.round;
+
+import java.math.BigDecimal;
+
+import org.apache.ambari.groovy.client.AmbariClient;
+import org.springframework.shell.core.JLineShellComponent;
+
+/**
+ * Show the install progress in % value.
+ */
+public class InstallProgress extends AbstractFlash {
+
+ private static final int SUCCESS = 100;
+ private static final int FAILED = -1;
+ private final boolean exit;
+ private AmbariClient client;
+ private volatile boolean done;
+
+ public InstallProgress(JLineShellComponent shell, AmbariClient client, boolean exit) {
+ super(shell, FlashType.INSTALL);
+ this.client = client;
+ this.exit = exit;
+ }
+
+ @Override
+ public String getText() {
+ StringBuilder sb = new StringBuilder();
+ if (!done) {
+ BigDecimal progress = client.getInstallProgress();
+ if (progress != null) {
+ BigDecimal decimal = progress.setScale(2, BigDecimal.ROUND_HALF_UP);
+ int intValue = decimal.intValue();
+ if (intValue != SUCCESS && intValue != FAILED) {
+ sb.append("Installation: ").append(decimal).append("% ");
+ int rounded = round(progress.setScale(0, BigDecimal.ROUND_UP).intValue() / 10);
+ for (int i = 0; i < 10; i++) {
+ if (i < rounded) {
+ sb.append("=");
+ } else {
+ sb.append("-");
+ }
+ }
+ } else if (intValue == FAILED) {
+ sb.append("Installation: FAILED");
+ done = true;
+ } else {
+ sb.append("Installation: COMPLETE");
+ done = true;
+ }
+ } else {
+ sb.append("Installation: WAITING..");
+ }
+ } else {
+ if (exit) {
+ System.exit(0);
+ }
+ }
+ return sb.toString();
+ }
+}
http://git-wip-us.apache.org/repos/asf/ambari/blob/c8eceafc/ambari-shell/ambari-groovy-shell/src/main/java/org/apache/ambari/shell/model/AmbariContext.java
----------------------------------------------------------------------
diff --git a/ambari-shell/ambari-groovy-shell/src/main/java/org/apache/ambari/shell/model/AmbariContext.java b/ambari-shell/ambari-groovy-shell/src/main/java/org/apache/ambari/shell/model/AmbariContext.java
new file mode 100644
index 0000000..af45dd6
--- /dev/null
+++ b/ambari-shell/ambari-groovy-shell/src/main/java/org/apache/ambari/shell/model/AmbariContext.java
@@ -0,0 +1,159 @@
+/**
+ * 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.ambari.shell.model;
+
+import org.springframework.stereotype.Component;
+
+/**
+ * Holds information about the connected Ambari Server.
+ */
+@Component
+public class AmbariContext {
+
+ private String cluster;
+ private boolean blueprintsAvailable;
+ private Focus focus;
+ private Hints hint;
+
+ public AmbariContext() {
+ this.focus = getRootFocus();
+ }
+
+ /**
+ * Sets the name of the cluster.
+ *
+ * @param cluster
+ */
+ public void setCluster(String cluster) {
+ this.cluster = cluster;
+ }
+
+ /**
+ * Sets the focus to the root.
+ */
+ public void resetFocus() {
+ this.focus = getRootFocus();
+ }
+
+ /**
+ * Sets the focus.
+ *
+ * @param id target of the focus, can be anything (blueprint id, host id..)
+ * @param type type of the focus
+ */
+ public void setFocus(String id, FocusType type) {
+ this.focus = new Focus(id, type);
+ }
+
+ /**
+ * Returns the target of the focus.
+ *
+ * @return target
+ */
+ public String getFocusValue() {
+ return focus.getValue();
+ }
+
+ /**
+ * Checks whether blueprints are available or not.
+ */
+ public boolean areBlueprintsAvailable() {
+ return blueprintsAvailable;
+ }
+
+ /**
+ * Sets what should be the next hint message.
+ *
+ * @param hint the new message
+ */
+ public void setHint(Hints hint) {
+ this.hint = hint;
+ }
+
+ /**
+ * Returns the context sensitive prompt.
+ *
+ * @return text of the prompt
+ */
+ public String getPrompt() {
+ return focus.isType(FocusType.ROOT) ?
+ isConnectedToCluster() ? formatPrompt(focus.getPrefix(), cluster) : "ambari-shell>" :
+ formatPrompt(focus.getPrefix(), focus.getValue());
+ }
+
+ public boolean isConnectedToCluster() {
+ return cluster != null;
+ }
+
+ /**
+ * Checks whether the focus is on the host or not.
+ *
+ * @return true if the focus is on a host false otherwise
+ */
+ public boolean isFocusOnHost() {
+ return isFocusOn(FocusType.HOST);
+ }
+
+ /**
+ * Checks whether the focus is on the cluster build or not.
+ *
+ * @return true if the focus is on a cluster build false otherwise
+ */
+ public boolean isFocusOnClusterBuild() {
+ return isFocusOn(FocusType.CLUSTER_BUILD);
+ }
+
+ /**
+ * Returns some context sensitive hint.
+ *
+ * @return hint
+ */
+ public String getHint() {
+ return "Hint: " + hint.message();
+ }
+
+ /**
+ * Returns the name of the cluster.
+ *
+ * @return cluster's name
+ */
+ public String getCluster() {
+ return cluster;
+ }
+
+ /**
+ * Sets whether there are blueprints available or not.
+ *
+ * @param blueprintsAvailable
+ */
+ public void setBlueprintsAvailable(boolean blueprintsAvailable) {
+ this.blueprintsAvailable = blueprintsAvailable;
+ }
+
+ private boolean isFocusOn(FocusType type) {
+ return focus.isType(type);
+ }
+
+ private Focus getRootFocus() {
+ return new Focus("root", FocusType.ROOT);
+ }
+
+ private String formatPrompt(String prefix, String postfix) {
+ return String.format("%s:%s>", prefix, postfix);
+ }
+}
http://git-wip-us.apache.org/repos/asf/ambari/blob/c8eceafc/ambari-shell/ambari-groovy-shell/src/main/java/org/apache/ambari/shell/model/Focus.java
----------------------------------------------------------------------
diff --git a/ambari-shell/ambari-groovy-shell/src/main/java/org/apache/ambari/shell/model/Focus.java b/ambari-shell/ambari-groovy-shell/src/main/java/org/apache/ambari/shell/model/Focus.java
new file mode 100644
index 0000000..b637c87
--- /dev/null
+++ b/ambari-shell/ambari-groovy-shell/src/main/java/org/apache/ambari/shell/model/Focus.java
@@ -0,0 +1,53 @@
+/**
+ * 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.ambari.shell.model;
+
+/**
+ * Holds information about the focus. Focus give you the ability to
+ * provide context sensitive commands.
+ *
+ * @see org.apache.ambari.shell.model.FocusType
+ */
+public class Focus {
+
+ private final String value;
+ private final FocusType type;
+
+ public Focus(String value, FocusType type) {
+ this.value = value;
+ this.type = type;
+ }
+
+ public String getPrefix() {
+ return type.prefix();
+ }
+
+ public String getValue() {
+ return value;
+ }
+
+ /**
+ * Checks if the current focus exists with the provided one.
+ *
+ * @param type type to check with the current
+ * @return true if they match false otherwise
+ */
+ public boolean isType(FocusType type) {
+ return this.type == type;
+ }
+}
http://git-wip-us.apache.org/repos/asf/ambari/blob/c8eceafc/ambari-shell/ambari-groovy-shell/src/main/java/org/apache/ambari/shell/model/FocusType.java
----------------------------------------------------------------------
diff --git a/ambari-shell/ambari-groovy-shell/src/main/java/org/apache/ambari/shell/model/FocusType.java b/ambari-shell/ambari-groovy-shell/src/main/java/org/apache/ambari/shell/model/FocusType.java
new file mode 100644
index 0000000..121f7b4
--- /dev/null
+++ b/ambari-shell/ambari-groovy-shell/src/main/java/org/apache/ambari/shell/model/FocusType.java
@@ -0,0 +1,55 @@
+/**
+ * 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.ambari.shell.model;
+
+/**
+ * Types for different focuses. Its purpose to give the command availability
+ * checkers a chance in decision making.
+ */
+public enum FocusType {
+
+ /**
+ * The focus is on a selected host.
+ */
+ HOST("HOST"),
+
+ /**
+ * The focus is on the cluster building phase.
+ */
+ CLUSTER_BUILD("CLUSTER_BUILD"),
+
+ /**
+ * No focus at all.
+ */
+ ROOT("CLUSTER");
+
+ private final String prefix;
+
+ private FocusType(String prefix) {
+ this.prefix = prefix;
+ }
+
+ /**
+ * Prefix provided for the prompt.
+ *
+ * @return focus prefix
+ */
+ public String prefix() {
+ return prefix;
+ }
+}
http://git-wip-us.apache.org/repos/asf/ambari/blob/c8eceafc/ambari-shell/ambari-groovy-shell/src/main/java/org/apache/ambari/shell/model/Hints.java
----------------------------------------------------------------------
diff --git a/ambari-shell/ambari-groovy-shell/src/main/java/org/apache/ambari/shell/model/Hints.java b/ambari-shell/ambari-groovy-shell/src/main/java/org/apache/ambari/shell/model/Hints.java
new file mode 100644
index 0000000..990c832
--- /dev/null
+++ b/ambari-shell/ambari-groovy-shell/src/main/java/org/apache/ambari/shell/model/Hints.java
@@ -0,0 +1,59 @@
+/**
+ * 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.ambari.shell.model;
+
+/**
+ * Provides some guidance's to the user, what he/she can follow.
+ */
+public enum Hints {
+
+ /**
+ * Hint for adding blueprints.
+ */
+ ADD_BLUEPRINT("Add a blueprint with the 'blueprint add' or add the default blueprints with the 'blueprint defaults' command."),
+
+ /**
+ * Hint for start building a cluster.
+ */
+ BUILD_CLUSTER("Start building a cluster with the 'cluster build' command using a previously added blueprint."),
+
+ /**
+ * Hint for start assigning hosts to host groups in cluster build phase.
+ */
+ ASSIGN_HOSTS("Assign hosts to different host groups with the 'cluster assign' command."),
+
+ /**
+ * Hint for create a cluster from the assigned hosts.
+ */
+ CREATE_CLUSTER("Create the cluster with the 'cluster create' command or use the 'cluster reset' command and start over."),
+
+ /**
+ * Hint for check the cluster creation result.
+ */
+ PROGRESS("See the install progress with the 'tasks' command.");
+
+ private final String message;
+
+ private Hints(String message) {
+ this.message = message;
+ }
+
+ public String message() {
+ return message;
+ }
+}
http://git-wip-us.apache.org/repos/asf/ambari/blob/c8eceafc/ambari-shell/ambari-groovy-shell/src/main/java/org/apache/ambari/shell/support/TableRenderer.java
----------------------------------------------------------------------
diff --git a/ambari-shell/ambari-groovy-shell/src/main/java/org/apache/ambari/shell/support/TableRenderer.java b/ambari-shell/ambari-groovy-shell/src/main/java/org/apache/ambari/shell/support/TableRenderer.java
new file mode 100644
index 0000000..3e5af1f
--- /dev/null
+++ b/ambari-shell/ambari-groovy-shell/src/main/java/org/apache/ambari/shell/support/TableRenderer.java
@@ -0,0 +1,121 @@
+/**
+ * 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.ambari.shell.support;
+
+import static java.util.Collections.singletonList;
+
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import org.springframework.shell.support.table.Table;
+import org.springframework.shell.support.table.TableHeader;
+
+/**
+ * Utility class used to render tables.
+ */
+public final class TableRenderer {
+
+ private TableRenderer() {
+ throw new IllegalStateException();
+ }
+
+ /**
+ * Renders a 2 columns wide table with the given headers and rows. If headers are provided it should match with the
+ * number of columns.
+ *
+ * @param rows rows of the table
+ * @param headers headers of the table
+ * @return the formatted table
+ */
+ public static String renderSingleMap(Map<String, String> rows, String... headers) {
+ return renderMultiValueMap(convert(rows), headers);
+ }
+
+ /**
+ * Renders a 2 columns wide table with the given headers and rows. If headers are provided it should match with the
+ * number of columns.
+ *
+ * @param rows rows of the table, each value will be added as a new row with the same key
+ * @param headers headers of the table
+ * @return formatted table
+ */
+ public static String renderMultiValueMap(Map<String, List<String>> rows, String... headers) {
+ Table table = createTable(headers);
+ if (rows != null) {
+ for (String key : rows.keySet()) {
+ List<String> values = rows.get(key);
+ if (values != null) {
+ for (String value : values) {
+ table.addRow(key, value);
+ }
+ }
+ }
+ }
+ return format(table);
+ }
+
+ /**
+ * Renders a 3 columns wide table with the given headers and rows. If headers are provided it should match with the
+ * number of columns.
+ *
+ * @param rows rows of the table, value map will be added as the last 2 columns to the table
+ * @param headers headers of the table
+ * @return formatted table
+ */
+ public static String renderMapValueMap(Map<String, Map<String, String>> rows, String... headers) {
+ Table table = createTable(headers);
+ if (rows != null) {
+ for (String key1 : rows.keySet()) {
+ Map<String, String> values = rows.get(key1);
+ if (values != null) {
+ for (String key2 : values.keySet()) {
+ table.addRow(key1, key2, values.get(key2));
+ }
+ }
+ }
+ }
+ return format(table);
+ }
+
+ private static Table createTable(String... headers) {
+ Table table = new Table();
+ if (headers != null) {
+ int column = 1;
+ for (String header : headers) {
+ table.addHeader(column++, new TableHeader(header));
+ }
+ }
+ return table;
+ }
+
+ private static Map<String, List<String>> convert(Map<String, String> map) {
+ Map<String, List<String>> result = new HashMap<String, List<String>>(map.size());
+ if (map != null) {
+ for (String key : map.keySet()) {
+ result.put(key, singletonList(map.get(key)));
+ }
+ }
+ return result;
+ }
+
+ private static String format(Table table) {
+ table.calculateColumnWidths();
+ return table.toString();
+ }
+}
http://git-wip-us.apache.org/repos/asf/ambari/blob/c8eceafc/ambari-shell/ambari-groovy-shell/src/main/resources/elephant.txt
----------------------------------------------------------------------
diff --git a/ambari-shell/ambari-groovy-shell/src/main/resources/elephant.txt b/ambari-shell/ambari-groovy-shell/src/main/resources/elephant.txt
new file mode 100644
index 0000000..f51e284
--- /dev/null
+++ b/ambari-shell/ambari-groovy-shell/src/main/resources/elephant.txt
@@ -0,0 +1,8 @@
+ .-.._
+ __ /` '.
+ .-' `/ ( a \
+ / ( \,_ \
+ /| '---` |\ =|
+ ` \ /__.-/ / | |
+ | / / \ \ \ \_\
+ |__|_| |_|__\
http://git-wip-us.apache.org/repos/asf/ambari/blob/c8eceafc/ambari-shell/ambari-groovy-shell/src/test/java/org/apache/ambari/shell/commands/BlueprintCommandsTest.java
----------------------------------------------------------------------
diff --git a/ambari-shell/ambari-groovy-shell/src/test/java/org/apache/ambari/shell/commands/BlueprintCommandsTest.java b/ambari-shell/ambari-groovy-shell/src/test/java/org/apache/ambari/shell/commands/BlueprintCommandsTest.java
new file mode 100644
index 0000000..3c9277c
--- /dev/null
+++ b/ambari-shell/ambari-groovy-shell/src/test/java/org/apache/ambari/shell/commands/BlueprintCommandsTest.java
@@ -0,0 +1,128 @@
+/**
+ * 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.ambari.shell.commands;
+
+import static org.junit.Assert.assertEquals;
+import static org.mockito.Mockito.doThrow;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.IOException;
+
+import org.apache.ambari.groovy.client.AmbariClient;
+import org.apache.ambari.shell.model.AmbariContext;
+import org.apache.ambari.shell.model.Hints;
+import org.apache.commons.io.IOUtils;
+import org.codehaus.jackson.JsonNode;
+import org.codehaus.jackson.map.ObjectMapper;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.InjectMocks;
+import org.mockito.Mock;
+import org.mockito.runners.MockitoJUnitRunner;
+
+import groovyx.net.http.HttpResponseException;
+
+@RunWith(MockitoJUnitRunner.class)
+public class BlueprintCommandsTest {
+
+ @InjectMocks
+ private BlueprintCommands blueprintCommands;
+
+ @Mock
+ private AmbariClient ambariClient;
+ @Mock
+ private HttpResponseException responseException;
+ @Mock
+ private AmbariContext context;
+ @Mock
+ private ObjectMapper objectMapper;
+
+ @Test
+ public void testAddBlueprintForFileReadPrecedence() throws IOException {
+ File file = new File("src/test/resources/testBlueprint.json");
+ String json = IOUtils.toString(new FileInputStream(file));
+ JsonNode jsonNode = mock(JsonNode.class);
+ when(objectMapper.readTree(json.getBytes())).thenReturn(jsonNode);
+ when(jsonNode.get("Blueprints")).thenReturn(jsonNode);
+ when(jsonNode.get("blueprint_name")).thenReturn(jsonNode);
+ when(jsonNode.asText()).thenReturn("blueprintName");
+
+ String result = blueprintCommands.addBlueprint("url", file);
+
+ verify(ambariClient).addBlueprint(json);
+ verify(context).setHint(Hints.BUILD_CLUSTER);
+ verify(context).setBlueprintsAvailable(true);
+ assertEquals("Blueprint: 'blueprintName' has been added", result);
+ }
+
+ @Test
+ public void testAddBlueprintForException() throws IOException {
+ File file = new File("src/test/resources/testBlueprint.json");
+ String json = IOUtils.toString(new FileInputStream(file));
+ doThrow(responseException).when(ambariClient).addBlueprint(json);
+ when(responseException.getMessage()).thenReturn("error");
+
+ String result = blueprintCommands.addBlueprint("url", file);
+
+ verify(ambariClient).addBlueprint(json);
+ verify(responseException).getMessage();
+ assertEquals("Cannot add blueprint: error", result);
+ }
+
+ @Test
+ public void testAddBlueprintForDefaults() throws HttpResponseException {
+ String result = blueprintCommands.addBlueprint();
+
+ verify(ambariClient).addDefaultBlueprints();
+ assertEquals("Default blueprints added", result);
+ }
+
+ @Test
+ public void testAddBlueprintForUnspecifiedValue() throws HttpResponseException {
+ String response = blueprintCommands.addBlueprint(null, null);
+
+ assertEquals("No blueprint specified", response);
+ verify(ambariClient, times(0)).addBlueprint(null);
+ }
+
+ @Test
+ public void testAddBlueprintDefaultsForException() throws HttpResponseException {
+ doThrow(responseException).when(ambariClient).addDefaultBlueprints();
+ when(responseException.getMessage()).thenReturn("error");
+
+ String result = blueprintCommands.addBlueprint();
+
+ verify(responseException).getMessage();
+ assertEquals("Failed to add the default blueprints: error", result);
+ }
+
+ @Test
+ public void testAddBlueprintDefaultsForConnectionRefused() throws HttpResponseException {
+ doThrow(new RuntimeException("Connection refused")).when(ambariClient).addDefaultBlueprints();
+ when(responseException.getMessage()).thenReturn("error");
+
+ String result = blueprintCommands.addBlueprint();
+
+ assertEquals("Failed to add the default blueprints: Connection refused", result);
+ }
+}
http://git-wip-us.apache.org/repos/asf/ambari/blob/c8eceafc/ambari-shell/ambari-groovy-shell/src/test/java/org/apache/ambari/shell/commands/ClusterCommandsTest.java
----------------------------------------------------------------------
diff --git a/ambari-shell/ambari-groovy-shell/src/test/java/org/apache/ambari/shell/commands/ClusterCommandsTest.java b/ambari-shell/ambari-groovy-shell/src/test/java/org/apache/ambari/shell/commands/ClusterCommandsTest.java
new file mode 100644
index 0000000..777d05d
--- /dev/null
+++ b/ambari-shell/ambari-groovy-shell/src/test/java/org/apache/ambari/shell/commands/ClusterCommandsTest.java
@@ -0,0 +1,279 @@
+/**
+ * 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.ambari.shell.commands;
+
+import static java.util.Arrays.asList;
+import static java.util.Collections.emptyList;
+import static java.util.Collections.singletonMap;
+import static org.apache.ambari.shell.support.TableRenderer.renderMultiValueMap;
+import static org.apache.ambari.shell.support.TableRenderer.renderSingleMap;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+import static org.mockito.Mockito.doThrow;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import org.apache.ambari.groovy.client.AmbariClient;
+import org.apache.ambari.shell.completion.Blueprint;
+import org.apache.ambari.shell.completion.Host;
+import org.apache.ambari.shell.flash.FlashService;
+import org.apache.ambari.shell.model.AmbariContext;
+import org.apache.ambari.shell.model.Hints;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.InjectMocks;
+import org.mockito.Mock;
+import org.mockito.runners.MockitoJUnitRunner;
+import org.springframework.test.util.ReflectionTestUtils;
+
+import groovyx.net.http.HttpResponseException;
+
+@RunWith(MockitoJUnitRunner.class)
+public class ClusterCommandsTest {
+
+ @InjectMocks
+ private ClusterCommands clusterCommands;
+
+ @Mock
+ private AmbariClient client;
+ @Mock
+ private AmbariContext context;
+ @Mock
+ private HttpResponseException responseException;
+ @Mock
+ private FlashService flashService;
+
+ @Test
+ public void testIsClusterBuildCommandAvailable() {
+ when(context.isConnectedToCluster()).thenReturn(false);
+ when(context.isFocusOnClusterBuild()).thenReturn(false);
+ when(context.areBlueprintsAvailable()).thenReturn(true);
+
+ boolean result = clusterCommands.isClusterBuildCommandAvailable();
+
+ assertTrue(result);
+ }
+
+ @Test
+ public void testIsClusterBuildCommandAvailableAndFocusOnBuild() {
+ when(context.isConnectedToCluster()).thenReturn(false);
+ when(context.isFocusOnClusterBuild()).thenReturn(true);
+ when(context.areBlueprintsAvailable()).thenReturn(true);
+
+ boolean result = clusterCommands.isClusterBuildCommandAvailable();
+
+ assertFalse(result);
+ }
+
+ @Test
+ public void testIsClusterBuildCommandAvailableAndNoBlueprints() {
+ when(context.isConnectedToCluster()).thenReturn(false);
+ when(context.isFocusOnClusterBuild()).thenReturn(false);
+ when(context.areBlueprintsAvailable()).thenReturn(false);
+
+ boolean result = clusterCommands.isClusterBuildCommandAvailable();
+
+ assertFalse(result);
+ }
+
+ @Test
+ public void testBuildClusterForNonExistingBlueprint() {
+ when(client.doesBlueprintExist("id")).thenReturn(false);
+
+ String result = clusterCommands.buildCluster(new Blueprint("id"));
+
+ verify(client).doesBlueprintExist("id");
+ assertEquals("Not a valid blueprint id", result);
+ }
+
+ @Test
+ public void testBuildCluster() {
+ Map<String, String> hostNames = singletonMap("host1", "HEALTHY");
+ Map<String, List<String>> map = singletonMap("group1", asList("comp1", "comp2"));
+ when(client.doesBlueprintExist("id")).thenReturn(true);
+ when(client.getBlueprintMap("id")).thenReturn(map);
+ when(context.getFocusValue()).thenReturn("id");
+ when(client.getHostNames()).thenReturn(hostNames);
+
+ String result = clusterCommands.buildCluster(new Blueprint("id"));
+
+ verify(client).doesBlueprintExist("id");
+ verify(client).getBlueprintMap("id");
+ verify(client).getHostGroups("id");
+ assertEquals(String.format("%s\n%s", renderSingleMap(hostNames, "HOSTNAME", "STATE"),
+ renderMultiValueMap(map, "HOSTGROUP", "COMPONENT")), result);
+ }
+
+ @Test
+ public void testAssignForInvalidHostGroup() {
+ Map<String, List<String>> map = singletonMap("group1", asList("host", "host2"));
+ ReflectionTestUtils.setField(clusterCommands, "hostGroups", map);
+ when(client.getHostNames()).thenReturn(singletonMap("host3", "HEALTHY"));
+
+ String result = clusterCommands.assign(new Host("host3"), "group0");
+
+ assertEquals("group0 is not a valid host group", result);
+ }
+
+ @Test
+ public void testAssignForValidHostGroup() {
+ Map<String, List<String>> map = new HashMap<String, List<String>>();
+ map.put("group1", new ArrayList<String>());
+ ReflectionTestUtils.setField(clusterCommands, "hostGroups", map);
+ when(client.getHostNames()).thenReturn(singletonMap("host3", "HEALTHY"));
+
+ String result = clusterCommands.assign(new Host("host3"), "group1");
+
+ assertEquals("host3 has been added to group1", result);
+ }
+
+ @Test
+ public void testAssignForInvalidHost() {
+ Map<String, List<String>> map = new HashMap<String, List<String>>();
+ map.put("group1", new ArrayList<String>());
+ ReflectionTestUtils.setField(clusterCommands, "hostGroups", map);
+ when(client.getHostNames()).thenReturn(singletonMap("host2", "HEALTHY"));
+
+ String result = clusterCommands.assign(new Host("host3"), "group1");
+
+ assertEquals("host3 is not a valid hostname", result);
+ }
+
+ @Test
+ public void testCreateClusterForException() throws HttpResponseException {
+ String blueprint = "blueprint";
+ Map<String, List<String>> map = singletonMap("group1", asList("host", "host2"));
+ ReflectionTestUtils.setField(clusterCommands, "hostGroups", map);
+ when(context.getFocusValue()).thenReturn(blueprint);
+ doThrow(responseException).when(client).createCluster(blueprint, blueprint, map);
+ doThrow(responseException).when(client).deleteCluster(blueprint);
+
+ String result = clusterCommands.createCluster(false);
+
+ verify(client).createCluster(blueprint, blueprint, map);
+ verify(client).getHostGroups(blueprint);
+ verify(client).deleteCluster(blueprint);
+ assertTrue(result.contains("Failed"));
+ }
+
+ @Test
+ public void testCreateCluster() throws HttpResponseException {
+ String blueprint = "blueprint";
+ Map<String, List<String>> map = singletonMap("group1", asList("host", "host2"));
+ ReflectionTestUtils.setField(clusterCommands, "hostGroups", map);
+ when(context.getFocusValue()).thenReturn(blueprint);
+ when(client.getClusterName()).thenReturn("cluster");
+
+ String result = clusterCommands.createCluster(false);
+
+ verify(client).createCluster(blueprint, blueprint, map);
+ verify(context).resetFocus();
+ assertFalse(result.contains("Failed"));
+ assertTrue(result.contains("Successfully"));
+ }
+
+ @Test
+ public void testDeleteClusterForException() throws HttpResponseException {
+ when(context.getCluster()).thenReturn("cluster");
+ when(responseException.getMessage()).thenReturn("msg");
+ doThrow(responseException).when(client).deleteCluster("cluster");
+
+ String result = clusterCommands.deleteCluster();
+
+ verify(client).deleteCluster("cluster");
+ verify(context).getCluster();
+ verify(responseException).getMessage();
+ assertEquals("Could not delete the cluster: msg", result);
+ }
+
+ @Test
+ public void testDeleteCluster() throws HttpResponseException {
+ when(context.getCluster()).thenReturn("cluster");
+ when(responseException.getMessage()).thenReturn("msg");
+
+ String result = clusterCommands.deleteCluster();
+
+ verify(client).deleteCluster("cluster");
+ verify(context).getCluster();
+ assertEquals("Successfully deleted the cluster", result);
+ }
+
+ @Test
+ public void testIsClusterPreviewCommandAvailable() {
+ when(context.isFocusOnClusterBuild()).thenReturn(true);
+ ReflectionTestUtils.setField(clusterCommands, "hostGroups", singletonMap("group1", asList("host1")));
+
+ boolean result = clusterCommands.isClusterPreviewCommandAvailable();
+
+ assertTrue(result);
+ }
+
+ @Test
+ public void testIsClusterPreviewCommandAvailableForNoAssignments() {
+ when(context.isFocusOnClusterBuild()).thenReturn(true);
+ ReflectionTestUtils.setField(clusterCommands, "hostGroups", singletonMap("group1", emptyList()));
+
+ boolean result = clusterCommands.isClusterPreviewCommandAvailable();
+
+ assertFalse(result);
+ }
+
+ @Test
+ public void testIsClusterResetCommandAvailable() {
+ when(context.isFocusOnClusterBuild()).thenReturn(true);
+ ReflectionTestUtils.setField(clusterCommands, "hostGroups", singletonMap("group1", asList("host1")));
+
+ boolean result = clusterCommands.isClusterResetCommandAvailable();
+
+ assertTrue(result);
+ }
+
+ @Test
+ public void testAutoAssignForEmptyResult() {
+ Map<String, List<String>> hostGroups = singletonMap("group1", asList("host1"));
+ ReflectionTestUtils.setField(clusterCommands, "hostGroups", hostGroups);
+ when(context.getFocusValue()).thenReturn("blueprint");
+ when(client.recommendAssignments("blueprint")).thenReturn(new HashMap<String, List<String>>());
+
+ clusterCommands.autoAssign();
+
+ Map<String, List<String>> result = (Map<String, List<String>>) ReflectionTestUtils.getField(clusterCommands, "hostGroups");
+ assertEquals(hostGroups, result);
+ }
+
+ @Test
+ public void testAutoAssign() {
+ Map<String, List<String>> hostGroups = singletonMap("group1", asList("host1"));
+ Map<String, List<String>> newAssignments = singletonMap("group1", asList("host1"));
+ ReflectionTestUtils.setField(clusterCommands, "hostGroups", hostGroups);
+ when(context.getFocusValue()).thenReturn("blueprint");
+ when(client.recommendAssignments("blueprint")).thenReturn(newAssignments);
+
+ clusterCommands.autoAssign();
+
+ Map<String, List<String>> result = (Map<String, List<String>>) ReflectionTestUtils.getField(clusterCommands, "hostGroups");
+ assertEquals(newAssignments, result);
+ verify(context).setHint(Hints.CREATE_CLUSTER);
+ }
+}
http://git-wip-us.apache.org/repos/asf/ambari/blob/c8eceafc/ambari-shell/ambari-groovy-shell/src/test/java/org/apache/ambari/shell/commands/HostCommandsTest.java
----------------------------------------------------------------------
diff --git a/ambari-shell/ambari-groovy-shell/src/test/java/org/apache/ambari/shell/commands/HostCommandsTest.java b/ambari-shell/ambari-groovy-shell/src/test/java/org/apache/ambari/shell/commands/HostCommandsTest.java
new file mode 100644
index 0000000..6ca6d4d
--- /dev/null
+++ b/ambari-shell/ambari-groovy-shell/src/test/java/org/apache/ambari/shell/commands/HostCommandsTest.java
@@ -0,0 +1,66 @@
+/**
+ * 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.ambari.shell.commands;
+
+import static java.util.Collections.singletonMap;
+import static org.junit.Assert.assertEquals;
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+import org.apache.ambari.groovy.client.AmbariClient;
+import org.apache.ambari.shell.completion.Host;
+import org.apache.ambari.shell.model.AmbariContext;
+import org.apache.ambari.shell.model.FocusType;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.InjectMocks;
+import org.mockito.Mock;
+import org.mockito.runners.MockitoJUnitRunner;
+
+@RunWith(MockitoJUnitRunner.class)
+public class HostCommandsTest {
+
+ @InjectMocks
+ private HostCommands hostCommands;
+
+ @Mock
+ private AmbariClient client;
+ @Mock
+ private AmbariContext context;
+
+ @Test
+ public void testFocusHostForValidHost() {
+ when(client.getHostNames()).thenReturn(singletonMap("host1", "HEALTHY"));
+
+ String result = hostCommands.focusHost(new Host("host1"));
+
+ verify(context).setFocus("host1", FocusType.HOST);
+ assertEquals("Focus set to: host1", result);
+ }
+
+ @Test
+ public void testFocusHostForInvalidHost() {
+ when(client.getHostNames()).thenReturn(singletonMap("host3", "HEALTHY"));
+
+ String result = hostCommands.focusHost(new Host("host1"));
+
+ verify(context, times(0)).setFocus("host1", FocusType.HOST);
+ assertEquals("host1 is not a valid host name", result);
+ }
+}
http://git-wip-us.apache.org/repos/asf/ambari/blob/c8eceafc/ambari-shell/ambari-groovy-shell/src/test/java/org/apache/ambari/shell/customization/AmbariPromptTest.java
----------------------------------------------------------------------
diff --git a/ambari-shell/ambari-groovy-shell/src/test/java/org/apache/ambari/shell/customization/AmbariPromptTest.java b/ambari-shell/ambari-groovy-shell/src/test/java/org/apache/ambari/shell/customization/AmbariPromptTest.java
new file mode 100644
index 0000000..ba90d00
--- /dev/null
+++ b/ambari-shell/ambari-groovy-shell/src/test/java/org/apache/ambari/shell/customization/AmbariPromptTest.java
@@ -0,0 +1,54 @@
+/**
+ * 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.ambari.shell.customization;
+
+import static org.junit.Assert.assertEquals;
+import static org.mockito.Mockito.when;
+
+import org.apache.ambari.shell.model.AmbariContext;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.InjectMocks;
+import org.mockito.Mock;
+import org.mockito.runners.MockitoJUnitRunner;
+
+@RunWith(MockitoJUnitRunner.class)
+public class AmbariPromptTest {
+
+ @InjectMocks
+ private AmbariPrompt prompt;
+
+ @Mock
+ private AmbariContext context;
+
+ @Test
+ public void testGetProviderName() {
+ String result = prompt.getProviderName();
+
+ assertEquals(AmbariPrompt.class.getSimpleName(), result);
+ }
+
+ @Test
+ public void testGetPrompt(){
+ when(context.getPrompt()).thenReturn("prompt");
+
+ String result = prompt.getPrompt();
+
+ assertEquals("prompt", result);
+ }
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/ambari/blob/c8eceafc/ambari-shell/ambari-groovy-shell/src/test/java/org/apache/ambari/shell/model/AmbariContextTest.java
----------------------------------------------------------------------
diff --git a/ambari-shell/ambari-groovy-shell/src/test/java/org/apache/ambari/shell/model/AmbariContextTest.java b/ambari-shell/ambari-groovy-shell/src/test/java/org/apache/ambari/shell/model/AmbariContextTest.java
new file mode 100644
index 0000000..ca9e919
--- /dev/null
+++ b/ambari-shell/ambari-groovy-shell/src/test/java/org/apache/ambari/shell/model/AmbariContextTest.java
@@ -0,0 +1,66 @@
+/**
+ * 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.ambari.shell.model;
+
+import static org.junit.Assert.assertEquals;
+
+import org.apache.ambari.groovy.client.AmbariClient;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.InjectMocks;
+import org.mockito.Mock;
+import org.mockito.runners.MockitoJUnitRunner;
+import org.springframework.test.util.ReflectionTestUtils;
+
+@RunWith(MockitoJUnitRunner.class)
+public class AmbariContextTest {
+
+ @InjectMocks
+ private AmbariContext ambariContext;
+
+ @Mock
+ private AmbariClient ambariClient;
+
+ @Test
+ public void testGetPromptForRoot() {
+ ReflectionTestUtils.setField(ambariContext, "cluster", "single-node");
+
+ String result = ambariContext.getPrompt();
+
+ assertEquals(FocusType.ROOT.prefix() + ":single-node>", result);
+ }
+
+ @Test
+ public void testGetPromptForRootButNotConnected() {
+ ReflectionTestUtils.setField(ambariContext, "cluster", null);
+
+ String result = ambariContext.getPrompt();
+
+ assertEquals("ambari-shell>", result);
+ }
+
+ @Test
+ public void testGetPromptForFocus() {
+ ReflectionTestUtils.setField(ambariContext, "cluster", "single-node");
+ ReflectionTestUtils.setField(ambariContext, "focus", new Focus("target", FocusType.HOST));
+
+ String result = ambariContext.getPrompt();
+
+ assertEquals(String.format("%s:%s>", FocusType.HOST.prefix(), "target"), result);
+ }
+}
http://git-wip-us.apache.org/repos/asf/ambari/blob/c8eceafc/ambari-shell/ambari-groovy-shell/src/test/java/org/apache/ambari/shell/support/TableRendererTest.java
----------------------------------------------------------------------
diff --git a/ambari-shell/ambari-groovy-shell/src/test/java/org/apache/ambari/shell/support/TableRendererTest.java b/ambari-shell/ambari-groovy-shell/src/test/java/org/apache/ambari/shell/support/TableRendererTest.java
new file mode 100644
index 0000000..e576390
--- /dev/null
+++ b/ambari-shell/ambari-groovy-shell/src/test/java/org/apache/ambari/shell/support/TableRendererTest.java
@@ -0,0 +1,54 @@
+/**
+ * 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.ambari.shell.support;
+
+import static org.junit.Assert.assertEquals;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import org.apache.commons.io.IOUtils;
+import org.junit.Test;
+
+public class TableRendererTest {
+
+ @Test
+ public void testRenderMultiValueMap() throws IOException {
+ Map<String, List<String>> map = new HashMap<String, List<String>>();
+ map.put("HDFS", Collections.singletonList("DATANODE"));
+ map.put("MAPREDUCE2", Collections.singletonList("HISTORYSERVER"));
+ map.put("ZOOKEEPER", Collections.singletonList("ZOOKEEPER_SERVER"));
+ assertEquals(IOUtils.toString(new FileInputStream(new File("src/test/resources/2columns"))),
+ TableRenderer.renderMultiValueMap(map, "SERVICE", "COMPONENT"));
+ }
+
+ @Test
+ public void testRenderMapValueMap() throws IOException {
+ Map<String, Map<String, String>> map = new HashMap<String, Map<String, String>>();
+ map.put("HDFS", Collections.singletonMap("DATANODE", "STARTED"));
+ map.put("MAPREDUCE2", Collections.singletonMap("HISTORYSERVER", "STARTED"));
+ map.put("ZOOKEEPER", Collections.singletonMap("ZOOKEEPER_SERVER", "INSTALLED"));
+ assertEquals(IOUtils.toString(new FileInputStream(new File("src/test/resources/3columns"))),
+ TableRenderer.renderMapValueMap(map, "SERVICE", "COMPONENT", "STATE"));
+ }
+}
http://git-wip-us.apache.org/repos/asf/ambari/blob/c8eceafc/ambari-shell/ambari-groovy-shell/src/test/resources/2columns
----------------------------------------------------------------------
diff --git a/ambari-shell/ambari-groovy-shell/src/test/resources/2columns b/ambari-shell/ambari-groovy-shell/src/test/resources/2columns
new file mode 100644
index 0000000..190771b
--- /dev/null
+++ b/ambari-shell/ambari-groovy-shell/src/test/resources/2columns
@@ -0,0 +1,5 @@
+ SERVICE COMPONENT
+ ---------- ----------------
+ ZOOKEEPER ZOOKEEPER_SERVER
+ MAPREDUCE2 HISTORYSERVER
+ HDFS DATANODE
http://git-wip-us.apache.org/repos/asf/ambari/blob/c8eceafc/ambari-shell/ambari-groovy-shell/src/test/resources/3columns
----------------------------------------------------------------------
diff --git a/ambari-shell/ambari-groovy-shell/src/test/resources/3columns b/ambari-shell/ambari-groovy-shell/src/test/resources/3columns
new file mode 100644
index 0000000..127a414
--- /dev/null
+++ b/ambari-shell/ambari-groovy-shell/src/test/resources/3columns
@@ -0,0 +1,5 @@
+ SERVICE COMPONENT STATE
+ ---------- ---------------- ---------
+ ZOOKEEPER ZOOKEEPER_SERVER INSTALLED
+ MAPREDUCE2 HISTORYSERVER STARTED
+ HDFS DATANODE STARTED
http://git-wip-us.apache.org/repos/asf/ambari/blob/c8eceafc/ambari-shell/ambari-groovy-shell/src/test/resources/testBlueprint.json
----------------------------------------------------------------------
diff --git a/ambari-shell/ambari-groovy-shell/src/test/resources/testBlueprint.json b/ambari-shell/ambari-groovy-shell/src/test/resources/testBlueprint.json
new file mode 100644
index 0000000..971c46d
--- /dev/null
+++ b/ambari-shell/ambari-groovy-shell/src/test/resources/testBlueprint.json
@@ -0,0 +1,48 @@
+{
+ "host_groups" : [
+ {
+ "name" : "host_group_1",
+ "components" : [
+ {
+ "name" : "NAMENODE"
+ },
+ {
+ "name" : "SECONDARY_NAMENODE"
+ },
+ {
+ "name" : "DATANODE"
+ },
+ {
+ "name" : "HDFS_CLIENT"
+ },
+ {
+ "name" : "RESOURCEMANAGER"
+ },
+ {
+ "name" : "NODEMANAGER"
+ },
+ {
+ "name" : "YARN_CLIENT"
+ },
+ {
+ "name" : "HISTORYSERVER"
+ },
+ {
+ "name" : "MAPREDUCE2_CLIENT"
+ },
+ {
+ "name" : "ZOOKEEPER_SERVER"
+ },
+ {
+ "name" : "ZOOKEEPER_CLIENT"
+ }
+ ],
+ "cardinality" : "1"
+ }
+ ],
+ "Blueprints" : {
+ "blueprint_name" : "single-node-hdfs-yarn",
+ "stack_name" : "HDP",
+ "stack_version" : "2.0"
+ }
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/ambari/blob/c8eceafc/ambari-shell/ambari-python-shell/conf/unix/ambari-shell
----------------------------------------------------------------------
diff --git a/ambari-shell/ambari-python-shell/conf/unix/ambari-shell b/ambari-shell/ambari-python-shell/conf/unix/ambari-shell
new file mode 100644
index 0000000..b6109fe
--- /dev/null
+++ b/ambari-shell/ambari-python-shell/conf/unix/ambari-shell
@@ -0,0 +1,62 @@
+#!/usr/bin/env bash
+
+# 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
+
+
+# Because Ambari rpm unpacks modules here on all systems
+PARAM="$@"
+export PYTHONPATH=/usr/lib/python2.6/site-packages:$PYTHONPATH
+SHELL_SCRIPT=/usr/lib/python2.6/site-packages/ambari_shell/ambari_shell.py
+OK=1
+NOTOK=0
+if [ -a /usr/bin/python2.7 ] && [ -z "$PYTHON" ]; then
+ PYTHON=/usr/bin/python2.7
+fi
+
+if [ -a /usr/bin/python2.6 ] && [ -z "$PYTHON" ]; then
+ PYTHON=/usr/bin/python2.6
+fi
+
+if [ "x$PYTHON" == "x" ]; then
+ PYTHON=/usr/bin/python
+fi
+
+export PYTHON=$PYTHON
+
+
+
+# check for version
+check_python_version ()
+{
+ echo "Verifying Python version compatibility..."
+ majversion=`$PYTHON -V 2>&1 | awk '{print $2}' | cut -d'.' -f1`
+ minversion=`$PYTHON -V 2>&1 | awk '{print $2}' | cut -d'.' -f2`
+ numversion=$(( 10 * $majversion + $minversion))
+ if (( $numversion < 26 )); then
+ echo "ERROR: Found Python version $majversion.$minversion. Ambari Agent requires Python version > 2.6"
+ return $NOTOK
+ fi
+ echo "Using python " $PYTHON
+ return $OK
+}
+
+retcode=0
+check_python_version
+if [ "$?" -eq "$NOTOK" ]; then
+ exit -1
+fi
+$PYTHON $SHELL_SCRIPT $PARAM
+
+exit $retcode
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/ambari/blob/c8eceafc/ambari-shell/ambari-python-shell/conf/unix/ambari-shell.ini
----------------------------------------------------------------------
diff --git a/ambari-shell/ambari-python-shell/conf/unix/ambari-shell.ini b/ambari-shell/ambari-python-shell/conf/unix/ambari-shell.ini
new file mode 100644
index 0000000..9ac158d
--- /dev/null
+++ b/ambari-shell/ambari-python-shell/conf/unix/ambari-shell.ini
@@ -0,0 +1,19 @@
+# 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
+
+[python_shell]
+loglevel=debug
+log_folder=/var/log/ambari-shell/
+cliplugin_folder=/root/workspace/python_shell/plugins
+default_plugin_folder=/usr/lib/python2.6/site-packages/ambari_shell/plugins
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/ambari/blob/c8eceafc/ambari-shell/ambari-python-shell/pom.xml
----------------------------------------------------------------------
diff --git a/ambari-shell/ambari-python-shell/pom.xml b/ambari-shell/ambari-python-shell/pom.xml
new file mode 100644
index 0000000..881f745
--- /dev/null
+++ b/ambari-shell/ambari-python-shell/pom.xml
@@ -0,0 +1,237 @@
+<?xml version="1.0"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+ <!--
+ 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 Licenseam for the specific language governing permissions and
+ limitations under the License.
+-->
+ <parent>
+ <groupId>org.apache.ambari</groupId>
+ <artifactId>ambari-shell</artifactId>
+ <version>1.3.0-SNAPSHOT</version>
+ <relativePath>../../ambari-shell</relativePath>
+ </parent>
+ <modelVersion>4.0.0</modelVersion>
+ <groupId>org.apache.ambari</groupId>
+ <artifactId>ambari-python-shell</artifactId>
+ <packaging>pom</packaging>
+ <version>1.3.0-SNAPSHOT</version>
+ <name>Ambari Python Shell</name>
+ <description>Ambari Python Shell</description>
+ <properties>
+ <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
+ <final.name>${project.artifactId}-${project.version}</final.name>
+ <package.release>1</package.release>
+ <package.prefix>/usr</package.prefix>
+ <package.log.dir>/var/log/ambari-shell</package.log.dir>
+ <package.pid.dir>/var/run/ambari-shell</package.pid.dir>
+ <skipTests>false</skipTests>
+ <install.dir>/usr/lib/python2.6/site-packages/ambari_shell</install.dir>
+ <lib.dir>/usr/lib/ambari-shell/lib</lib.dir>
+ <python.ver>python >= 2.6</python.ver>
+ <deb.python.ver>python (>= 2.6)</deb.python.ver>
+ <deb.architecture>amd64</deb.architecture>
+ <deb.dependency.list>openssl, zlibc, ${deb.python.ver}</deb.dependency.list>
+ </properties>
+ <build>
+ <plugins>
+ <plugin>
+ <artifactId>maven-compiler-plugin</artifactId>
+ <version>3.0</version>
+ </plugin>
+ <plugin>
+ <artifactId>maven-assembly-plugin</artifactId>
+ <configuration>
+ <tarLongFileMode>gnu</tarLongFileMode>
+ <descriptors>
+ <descriptor>src/packages/tarball/all.xml</descriptor>
+ </descriptors>
+ </configuration>
+ <executions>
+ <execution>
+ <id>build-tarball</id>
+ <phase>prepare-package</phase>
+ <goals>
+ <goal>single</goal>
+ </goals>
+ </execution>
+ </executions>
+ </plugin>
+ <plugin>
+ <groupId>org.codehaus.mojo</groupId>
+ <artifactId>exec-maven-plugin</artifactId>
+ <version>1.2</version>
+ <executions>
+ <execution>
+ <configuration>
+ <executable>${project.basedir}/../../ambari-common/src/main/unix/ambari-python-wrap</executable>
+ <workingDirectory>src/test/python</workingDirectory>
+ <arguments>
+ <argument>unitTests.py</argument>
+ </arguments>
+ <environmentVariables>
+ <PYTHONPATH>${project.basedir}/../../ambari-common/src/test/python:${project.basedir}/../../ambari-client/python-client/src/test/python:${project.basedir}/../../ambari-client/python-client/src/main/python/ambari_client:${project.basedir}/src/main/python/ambari_shell:${project.basedir}/src/test/python/utils:$PYTHONPATH</PYTHONPATH>
+ </environmentVariables>
+ <skip>${skipTests}</skip>
+ </configuration>
+ <id>python-test</id>
+ <phase>test</phase>
+ <goals>
+ <goal>exec</goal>
+ </goals>
+ </execution>
+ <execution>
+ <configuration>
+ <executable>${project.basedir}/../../ambari-common/src/main/unix/ambari-python-wrap</executable>
+ <workingDirectory>target/ambari-python-shell-${project.version}</workingDirectory>
+ <arguments>
+ <argument>${project.basedir}/src/main/python/setup.py</argument>
+ <argument>clean</argument>
+ <argument>bdist_dumb</argument>
+ </arguments>
+ <environmentVariables>
+ <PYTHONPATH>target/python-client-${project.version}:$PYTHONPATH</PYTHONPATH>
+ </environmentVariables>
+ </configuration>
+ <id>python-package</id>
+ <phase>package</phase>
+ <goals>
+ <goal>exec</goal>
+ </goals>
+ </execution>
+ </executions>
+ </plugin>
+ <plugin>
+ <groupId>org.codehaus.mojo</groupId>
+ <artifactId>rpm-maven-plugin</artifactId>
+ <version>2.0.1</version>
+ <executions>
+ <execution>
+ <phase>none</phase>
+ <goals>
+ <goal>rpm</goal>
+ </goals>
+ </execution>
+ </executions>
+ <configuration>
+ <copyright>2012, Apache Software Foundation</copyright>
+ <group>Development</group>
+ <description>Maven Recipe: RPM Package.</description>
+ <requires>
+ <require>openssl</require>
+ <require>zlib</require>
+ <require>${python.ver}</require>
+ </requires>
+ <needarch>x86_64</needarch>
+ <autoRequires>false</autoRequires>
+ <mappings>
+ <mapping>
+ <directory>/etc/ambari-shell/conf</directory>
+ <filemode>755</filemode>
+ <username>root</username>
+ <groupname>root</groupname>
+ <sources>
+ <source>
+ <location>conf/unix/ambari-shell.ini</location>
+ </source>
+ </sources>
+ </mapping>
+ <mapping>
+ <directory>/usr/sbin</directory>
+ <filemode>755</filemode>
+ <username>root</username>
+ <groupname>root</groupname>
+ <directoryIncluded>false</directoryIncluded>
+ <sources>
+ <source>
+ <location>conf/unix/ambari-shell</location>
+ <filter>true</filter>
+ </source>
+ </sources>
+ </mapping>
+ <mapping>
+ <directory>${package.log.dir}</directory>
+ <filemode>755</filemode>
+ <username>root</username>
+ <groupname>root</groupname>
+ </mapping>
+ <mapping>
+ <directory>${install.dir}</directory>
+ <sources>
+ <source>
+ <location>${project.build.directory}/${project.artifactId}-${project.version}/ambari_shell</location>
+ </source>
+ </sources>
+ </mapping>
+ </mappings>
+ </configuration>
+ </plugin>
+ <plugin>
+ <groupId>org.apache.rat</groupId>
+ <artifactId>apache-rat-plugin</artifactId>
+ <configuration>
+ <excludes>
+ <exclude>src/examples/*</exclude>
+ <exclude>src/test/python/dummy*.txt</exclude>
+ <exclude>src/main/python/ambari_client/imports.txt</exclude>
+ <exclude>src/main/puppet/modules/stdlib/**</exclude>
+ <exclude>**/*.erb</exclude>
+ <exclude>**/*.json</exclude>
+ </excludes>
+ </configuration>
+ <executions>
+ <execution>
+ <phase>test</phase>
+ <goals>
+ <goal>check</goal>
+ </goals>
+ </execution>
+ </executions>
+ </plugin>
+ <plugin>
+ <groupId>org.vafer</groupId>
+ <artifactId>jdeb</artifactId>
+ <version>1.0.1</version>
+ <executions>
+ <execution>
+ <phase>none</phase>
+ <goals>
+ <goal>jdeb</goal>
+ </goals>
+ </execution>
+ </executions>
+ <configuration>
+ <controlDir>${basedir}/src/main/package/deb/control</controlDir>
+ <deb>${basedir}/target/${artifactId}_${package-version}-${package-release}.deb</deb>
+ <dataSet>
+ <data>
+ <src>${project.build.directory}/${project.artifactId}-${project.version}/ambari_shell</src>
+ <type>directory</type>
+ <mapper>
+ <type>perm</type>
+ <prefix>${install.dir}</prefix>
+ </mapper>
+ </data>
+ </dataSet>
+ </configuration>
+ </plugin>
+ </plugins>
+ <extensions>
+ <extension>
+ <groupId>org.apache.maven.wagon</groupId>
+ <artifactId>wagon-ssh-external</artifactId>
+ </extension>
+ </extensions>
+ </build>
+</project>
http://git-wip-us.apache.org/repos/asf/ambari/blob/c8eceafc/ambari-shell/ambari-python-shell/src/main/package/deb/control/control
----------------------------------------------------------------------
diff --git a/ambari-shell/ambari-python-shell/src/main/package/deb/control/control b/ambari-shell/ambari-python-shell/src/main/package/deb/control/control
new file mode 100644
index 0000000..40cd855
--- /dev/null
+++ b/ambari-shell/ambari-python-shell/src/main/package/deb/control/control
@@ -0,0 +1,22 @@
+# 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: [[artifactId]]
+Version: [[package-version]]-[[package-release]]
+Section: [[deb.section]]
+Priority: [[deb.priority]]
+Depends: [[deb.dependency.list]]
+Architecture: [[deb.architecture]]
+Description: [[description]]
+Maintainer: [[deb.publisher]]
http://git-wip-us.apache.org/repos/asf/ambari/blob/c8eceafc/ambari-shell/ambari-python-shell/src/main/package/deb/control/postinst
----------------------------------------------------------------------
diff --git a/ambari-shell/ambari-python-shell/src/main/package/deb/control/postinst b/ambari-shell/ambari-python-shell/src/main/package/deb/control/postinst
new file mode 100644
index 0000000..21a01fa
--- /dev/null
+++ b/ambari-shell/ambari-python-shell/src/main/package/deb/control/postinst
@@ -0,0 +1,15 @@
+#!/bin/bash
+# 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
http://git-wip-us.apache.org/repos/asf/ambari/blob/c8eceafc/ambari-shell/ambari-python-shell/src/main/package/deb/control/postrm
----------------------------------------------------------------------
diff --git a/ambari-shell/ambari-python-shell/src/main/package/deb/control/postrm b/ambari-shell/ambari-python-shell/src/main/package/deb/control/postrm
new file mode 100644
index 0000000..21a01fa
--- /dev/null
+++ b/ambari-shell/ambari-python-shell/src/main/package/deb/control/postrm
@@ -0,0 +1,15 @@
+#!/bin/bash
+# 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
http://git-wip-us.apache.org/repos/asf/ambari/blob/c8eceafc/ambari-shell/ambari-python-shell/src/main/package/deb/control/posttrm
----------------------------------------------------------------------
diff --git a/ambari-shell/ambari-python-shell/src/main/package/deb/control/posttrm b/ambari-shell/ambari-python-shell/src/main/package/deb/control/posttrm
new file mode 100644
index 0000000..21a01fa
--- /dev/null
+++ b/ambari-shell/ambari-python-shell/src/main/package/deb/control/posttrm
@@ -0,0 +1,15 @@
+#!/bin/bash
+# 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
http://git-wip-us.apache.org/repos/asf/ambari/blob/c8eceafc/ambari-shell/ambari-python-shell/src/main/package/deb/control/preinst
----------------------------------------------------------------------
diff --git a/ambari-shell/ambari-python-shell/src/main/package/deb/control/preinst b/ambari-shell/ambari-python-shell/src/main/package/deb/control/preinst
new file mode 100644
index 0000000..21a01fa
--- /dev/null
+++ b/ambari-shell/ambari-python-shell/src/main/package/deb/control/preinst
@@ -0,0 +1,15 @@
+#!/bin/bash
+# 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
http://git-wip-us.apache.org/repos/asf/ambari/blob/c8eceafc/ambari-shell/ambari-python-shell/src/main/package/deb/control/prerm
----------------------------------------------------------------------
diff --git a/ambari-shell/ambari-python-shell/src/main/package/deb/control/prerm b/ambari-shell/ambari-python-shell/src/main/package/deb/control/prerm
new file mode 100644
index 0000000..21a01fa
--- /dev/null
+++ b/ambari-shell/ambari-python-shell/src/main/package/deb/control/prerm
@@ -0,0 +1,15 @@
+#!/bin/bash
+# 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
http://git-wip-us.apache.org/repos/asf/ambari/blob/c8eceafc/ambari-shell/ambari-python-shell/src/main/python/ambari_shell/__init__.py
----------------------------------------------------------------------
diff --git a/ambari-shell/ambari-python-shell/src/main/python/ambari_shell/__init__.py b/ambari-shell/ambari-python-shell/src/main/python/ambari_shell/__init__.py
new file mode 100644
index 0000000..278df2e
--- /dev/null
+++ b/ambari-shell/ambari-python-shell/src/main/python/ambari_shell/__init__.py
@@ -0,0 +1,16 @@
+#
+# 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.