diff --git a/spring-boot-actuator/pom.xml b/spring-boot-actuator/pom.xml index 9f93125852..73af07380b 100644 --- a/spring-boot-actuator/pom.xml +++ b/spring-boot-actuator/pom.xml @@ -234,21 +234,6 @@ tomcat-embed-el true - - org.crashub - crash.shell - true - - - org.crashub - crash.cli - true - - - org.crashub - crash.embed.spring - true - org.jolokia jolokia-core @@ -334,11 +319,6 @@ aspectjrt test - - org.crashub - crash.connectors.telnet - test - org.hsqldb hsqldb diff --git a/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/autoconfigure/CrshAutoConfiguration.java b/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/autoconfigure/CrshAutoConfiguration.java deleted file mode 100644 index 6e167535ba..0000000000 --- a/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/autoconfigure/CrshAutoConfiguration.java +++ /dev/null @@ -1,573 +0,0 @@ -/* - * Copyright 2012-2016 the original author or authors. - * - * 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. - */ - -package org.springframework.boot.actuate.autoconfigure; - -import java.io.IOException; -import java.io.InputStream; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collection; -import java.util.Collections; -import java.util.HashMap; -import java.util.Iterator; -import java.util.List; -import java.util.Map; -import java.util.Set; - -import javax.annotation.PostConstruct; -import javax.annotation.PreDestroy; - -import org.crsh.auth.AuthenticationPlugin; -import org.crsh.plugin.CRaSHPlugin; -import org.crsh.plugin.PluginContext; -import org.crsh.plugin.PluginDiscovery; -import org.crsh.plugin.PluginLifeCycle; -import org.crsh.plugin.PropertyDescriptor; -import org.crsh.plugin.ServiceLoaderDiscovery; -import org.crsh.vfs.FS; -import org.crsh.vfs.spi.AbstractFSDriver; -import org.crsh.vfs.spi.FSDriver; - -import org.springframework.beans.factory.ListableBeanFactory; -import org.springframework.beans.factory.ObjectProvider; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.beans.factory.annotation.Qualifier; -import org.springframework.boot.actuate.autoconfigure.ShellProperties.CrshShellAuthenticationProperties; -import org.springframework.boot.actuate.autoconfigure.ShellProperties.CrshShellProperties; -import org.springframework.boot.actuate.autoconfigure.ShellProperties.JaasAuthenticationProperties; -import org.springframework.boot.actuate.autoconfigure.ShellProperties.KeyAuthenticationProperties; -import org.springframework.boot.actuate.autoconfigure.ShellProperties.SimpleAuthenticationProperties; -import org.springframework.boot.actuate.autoconfigure.ShellProperties.SpringAuthenticationProperties; -import org.springframework.boot.autoconfigure.AutoConfigureAfter; -import org.springframework.boot.autoconfigure.EnableAutoConfiguration; -import org.springframework.boot.autoconfigure.condition.ConditionalOnBean; -import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; -import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; -import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; -import org.springframework.boot.autoconfigure.security.SecurityAutoConfiguration; -import org.springframework.boot.context.properties.EnableConfigurationProperties; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; -import org.springframework.core.SpringVersion; -import org.springframework.core.env.Environment; -import org.springframework.core.io.Resource; -import org.springframework.core.io.support.ResourcePatternResolver; -import org.springframework.security.access.AccessDecisionManager; -import org.springframework.security.access.AccessDeniedException; -import org.springframework.security.access.SecurityConfig; -import org.springframework.security.authentication.AuthenticationManager; -import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; -import org.springframework.security.core.Authentication; -import org.springframework.security.core.AuthenticationException; -import org.springframework.util.AntPathMatcher; -import org.springframework.util.Assert; -import org.springframework.util.ClassUtils; -import org.springframework.util.ObjectUtils; -import org.springframework.util.StringUtils; - -/** - * {@link EnableAutoConfiguration Auto-configuration} for embedding an extensible shell - * into a Spring Boot enabled application. By default a SSH daemon is started on port - * 2000. If the CRaSH Telnet plugin is available on the classpath, Telnet daemon will be - * launched on port 5000. - *

- * The default shell authentication method uses a username and password combination. If no - * configuration is provided the default username is 'user' and the password will be - * printed to console during application startup. Those default values can be overridden - * by using {@code management.shell.auth.simple.username} and - * {@code management.shell.auth.simple.password}. - *

- * If a Spring Security {@link AuthenticationManager} is detected, this configuration will - * create a {@link CRaSHPlugin} to forward shell authentication requests to Spring - * Security. This authentication method will get enabled if - * {@code management.shell.auth.type} is set to {@code spring} or if no explicit - * {@code management.shell.auth} is provided and a {@link AuthenticationManager} is - * available. In the latter case shell access will be restricted to users having roles - * that match those configured in {@link ManagementServerProperties}. Required roles can - * be overridden by {@code management.shell.auth.spring.roles}. - *

- * To add customizations to the shell simply define beans of type {@link CRaSHPlugin} in - * the application context. Those beans will get auto detected during startup and - * registered with the underlying shell infrastructure. To configure plugins and the CRaSH - * infrastructure add beans of type {@link CrshShellProperties} to the application - * context. - *

- * Additional shell commands can be implemented using the guide and documentation at - * crashub.org. By default Boot will search for - * commands using the following classpath scanning pattern {@code classpath*:/commands/**} - * . To add different locations or override the default use - * {@code management.shell.command-path-patterns} in your application configuration. - * - * @author Christian Dupuis - * @author Matt Benson - * @see ShellProperties - */ -@Configuration -@ConditionalOnClass(PluginLifeCycle.class) -@EnableConfigurationProperties(ShellProperties.class) -@AutoConfigureAfter({ SecurityAutoConfiguration.class, - ManagementWebSecurityAutoConfiguration.class }) -@Deprecated -public class CrshAutoConfiguration { - - public static final String AUTH_PREFIX = ShellProperties.SHELL_PREFIX + ".auth"; - - private final ShellProperties properties; - - public CrshAutoConfiguration(ShellProperties properties) { - this.properties = properties; - } - - @Bean - @ConditionalOnMissingBean(PluginLifeCycle.class) - public CrshBootstrapBean shellBootstrap() { - CrshBootstrapBean bootstrapBean = new CrshBootstrapBean(); - bootstrapBean.setConfig(this.properties.asCrshShellConfig()); - return bootstrapBean; - } - - @Configuration - static class CrshAdditionalPropertiesConfiguration { - - @Bean - @ConditionalOnProperty(prefix = AUTH_PREFIX, name = "type", havingValue = "jaas") - @ConditionalOnMissingBean(CrshShellAuthenticationProperties.class) - public JaasAuthenticationProperties jaasAuthenticationProperties() { - return new JaasAuthenticationProperties(); - } - - @Bean - @ConditionalOnProperty(prefix = AUTH_PREFIX, name = "type", havingValue = "key") - @ConditionalOnMissingBean(CrshShellAuthenticationProperties.class) - public KeyAuthenticationProperties keyAuthenticationProperties() { - return new KeyAuthenticationProperties(); - } - - @Bean - @ConditionalOnProperty(prefix = AUTH_PREFIX, name = "type", havingValue = "simple", matchIfMissing = true) - @ConditionalOnMissingBean(CrshShellAuthenticationProperties.class) - public SimpleAuthenticationProperties simpleAuthenticationProperties() { - return new SimpleAuthenticationProperties(); - } - - } - - /** - * Class to configure CRaSH to authenticate against Spring Security. - */ - @Configuration - @ConditionalOnProperty(prefix = AUTH_PREFIX, name = "type", havingValue = "spring", matchIfMissing = true) - @ConditionalOnBean(AuthenticationManager.class) - public static class AuthenticationManagerAdapterConfiguration { - - private final ManagementServerProperties management; - - public AuthenticationManagerAdapterConfiguration( - ObjectProvider managementProvider) { - this.management = managementProvider.getIfAvailable(); - } - - @Bean - public AuthenticationManagerAdapter shellAuthenticationManager() { - return new AuthenticationManagerAdapter(); - } - - @Bean - @ConditionalOnMissingBean(CrshShellAuthenticationProperties.class) - public SpringAuthenticationProperties springAuthenticationProperties() { - // In case no management.shell.auth.type property is provided fall back to - // Spring Security based authentication and get role to access shell from - // ManagementServerProperties. - // In case management.shell.auth.type is set to spring and roles are - // configured using shell.auth.spring.roles the below default role will be - // overridden by ConfigurationProperties. - SpringAuthenticationProperties authenticationProperties = new SpringAuthenticationProperties(); - if (this.management != null) { - List roles = this.management.getSecurity().getRoles(); - authenticationProperties - .setRoles(roles.toArray(new String[roles.size()])); - } - return authenticationProperties; - } - - } - - /** - * Spring Bean used to bootstrap the CRaSH shell. - */ - public static class CrshBootstrapBean extends PluginLifeCycle { - - @Autowired - private ListableBeanFactory beanFactory; - - @Autowired - private Environment environment; - - @Autowired - private ShellProperties properties; - - @Autowired - private ResourcePatternResolver resourceLoader; - - @PreDestroy - public void destroy() { - stop(); - } - - @PostConstruct - public void init() { - FS commandFileSystem = createFileSystem( - this.properties.getCommandPathPatterns(), - this.properties.getDisabledCommands()); - FS configurationFileSystem = createFileSystem( - this.properties.getConfigPathPatterns(), new String[0]); - - PluginDiscovery discovery = new BeanFactoryFilteringPluginDiscovery( - this.resourceLoader.getClassLoader(), this.beanFactory, - this.properties.getDisabledPlugins()); - - PluginContext context = new PluginContext(discovery, - createPluginContextAttributes(), commandFileSystem, - configurationFileSystem, this.resourceLoader.getClassLoader()); - - context.refresh(); - start(context); - } - - protected FS createFileSystem(String[] pathPatterns, String[] filterPatterns) { - Assert.notNull(pathPatterns, "PathPatterns must not be null"); - Assert.notNull(filterPatterns, "FilterPatterns must not be null"); - FS fileSystem = new FS(); - for (String pathPattern : pathPatterns) { - try { - fileSystem.mount(new SimpleFileSystemDriver(new DirectoryHandle( - pathPattern, this.resourceLoader, filterPatterns))); - } - catch (IOException ex) { - throw new IllegalStateException( - "Failed to mount file system for '" + pathPattern + "'", ex); - } - } - return fileSystem; - } - - protected Map createPluginContextAttributes() { - Map attributes = new HashMap(); - String bootVersion = CrshAutoConfiguration.class.getPackage() - .getImplementationVersion(); - if (bootVersion != null) { - attributes.put("spring.boot.version", bootVersion); - } - attributes.put("spring.version", SpringVersion.getVersion()); - if (this.beanFactory != null) { - attributes.put("spring.beanfactory", this.beanFactory); - } - if (this.environment != null) { - attributes.put("spring.environment", this.environment); - } - return attributes; - } - - } - - /** - * Adapts a Spring Security {@link AuthenticationManager} for use with CRaSH. - */ - @SuppressWarnings("rawtypes") - private static class AuthenticationManagerAdapter extends - CRaSHPlugin implements AuthenticationPlugin { - - private static final PropertyDescriptor ROLES = PropertyDescriptor.create( - "auth.spring.roles", "ADMIN", - "Comma separated list of roles required to access the shell"); - - @Autowired - private AuthenticationManager authenticationManager; - - @Autowired(required = false) - @Qualifier("shellAccessDecisionManager") - private AccessDecisionManager accessDecisionManager; - - private String[] roles = new String[] { "ADMIN" }; - - @Override - public boolean authenticate(String username, String password) throws Exception { - Authentication token = new UsernamePasswordAuthenticationToken(username, - password); - try { - // Authenticate first to make sure credentials are valid - token = this.authenticationManager.authenticate(token); - } - catch (AuthenticationException ex) { - return false; - } - - // Test access rights if a Spring Security AccessDecisionManager is installed - if (this.accessDecisionManager != null && token.isAuthenticated() - && this.roles != null) { - try { - this.accessDecisionManager.decide(token, this, - SecurityConfig.createList(this.roles)); - } - catch (AccessDeniedException ex) { - return false; - } - } - return token.isAuthenticated(); - } - - @Override - public Class getCredentialType() { - return String.class; - } - - @Override - public AuthenticationPlugin getImplementation() { - return this; - } - - @Override - public String getName() { - return "spring"; - } - - @Override - public void init() { - String rolesPropertyValue = getContext().getProperty(ROLES); - if (rolesPropertyValue != null) { - this.roles = StringUtils - .commaDelimitedListToStringArray(rolesPropertyValue); - } - } - - @Override - protected Iterable> createConfigurationCapabilities() { - return Arrays.>asList(ROLES); - } - - } - - /** - * {@link ServiceLoaderDiscovery} to expose {@link CRaSHPlugin} Beans from Spring and - * deal with filtering disabled plugins. - */ - private static class BeanFactoryFilteringPluginDiscovery - extends ServiceLoaderDiscovery { - - private final ListableBeanFactory beanFactory; - - private final String[] disabledPlugins; - - BeanFactoryFilteringPluginDiscovery(ClassLoader classLoader, - ListableBeanFactory beanFactory, String[] disabledPlugins) - throws NullPointerException { - super(classLoader); - this.beanFactory = beanFactory; - this.disabledPlugins = disabledPlugins; - } - - @Override - @SuppressWarnings("rawtypes") - public Iterable> getPlugins() { - List> plugins = new ArrayList>(); - - for (CRaSHPlugin p : super.getPlugins()) { - if (isEnabled(p)) { - plugins.add(p); - } - } - - Collection pluginBeans = this.beanFactory - .getBeansOfType(CRaSHPlugin.class).values(); - for (CRaSHPlugin pluginBean : pluginBeans) { - if (isEnabled(pluginBean)) { - plugins.add(pluginBean); - } - } - - return plugins; - } - - protected boolean isEnabled(CRaSHPlugin plugin) { - Assert.notNull(plugin, "Plugin must not be null"); - - if (ObjectUtils.isEmpty(this.disabledPlugins)) { - return true; - } - - Set> pluginClasses = ClassUtils.getAllInterfacesAsSet(plugin); - pluginClasses.add(plugin.getClass()); - - for (Class pluginClass : pluginClasses) { - if (!isEnabled(pluginClass)) { - return false; - } - } - return true; - } - - private boolean isEnabled(Class pluginClass) { - for (String disabledPlugin : this.disabledPlugins) { - if (ClassUtils.getShortName(pluginClass).equalsIgnoreCase(disabledPlugin) - || ClassUtils.getQualifiedName(pluginClass) - .equalsIgnoreCase(disabledPlugin)) { - return false; - } - } - return true; - } - } - - /** - * {@link FSDriver} to wrap Spring's {@link Resource} abstraction to CRaSH. - */ - private static class SimpleFileSystemDriver extends AbstractFSDriver { - - private final ResourceHandle root; - - SimpleFileSystemDriver(ResourceHandle handle) { - this.root = handle; - } - - @Override - public Iterable children(ResourceHandle handle) - throws IOException { - if (handle instanceof DirectoryHandle) { - return ((DirectoryHandle) handle).members(); - } - return Collections.emptySet(); - } - - @Override - public long getLastModified(ResourceHandle handle) throws IOException { - if (handle instanceof FileHandle) { - return ((FileHandle) handle).getLastModified(); - } - return -1; - } - - @Override - public boolean isDir(ResourceHandle handle) throws IOException { - return handle instanceof DirectoryHandle; - } - - @Override - public String name(ResourceHandle handle) throws IOException { - return handle.getName(); - } - - @Override - public Iterator open(ResourceHandle handle) throws IOException { - if (handle instanceof FileHandle) { - return Collections.singletonList(((FileHandle) handle).openStream()) - .iterator(); - } - return Collections.emptyList().iterator(); - } - - @Override - public ResourceHandle root() throws IOException { - return this.root; - } - - } - - /** - * Base for handles to Spring {@link Resource}s. - */ - private abstract static class ResourceHandle { - - private final String name; - - ResourceHandle(String name) { - this.name = name; - } - - public String getName() { - return this.name; - } - - } - - /** - * {@link ResourceHandle} for a directory. - */ - private static class DirectoryHandle extends ResourceHandle { - - private final ResourcePatternResolver resourceLoader; - - private final String[] filterPatterns; - - private final AntPathMatcher matcher = new AntPathMatcher(); - - DirectoryHandle(String name, ResourcePatternResolver resourceLoader, - String[] filterPatterns) { - super(name); - this.resourceLoader = resourceLoader; - this.filterPatterns = filterPatterns; - } - - public List members() throws IOException { - Resource[] resources = this.resourceLoader.getResources(getName()); - List files = new ArrayList(); - for (Resource resource : resources) { - if (!resource.getURL().getPath().endsWith("/") - && !shouldFilter(resource)) { - files.add(new FileHandle(resource.getFilename(), resource)); - } - } - return files; - } - - private boolean shouldFilter(Resource resource) { - for (String filterPattern : this.filterPatterns) { - if (this.matcher.match(filterPattern, resource.getFilename())) { - return true; - } - } - return false; - } - } - - /** - * {@link ResourceHandle} for a file backed by a Spring {@link Resource}. - */ - private static class FileHandle extends ResourceHandle { - - private final Resource resource; - - FileHandle(String name, Resource resource) { - super(name); - this.resource = resource; - } - - public InputStream openStream() throws IOException { - return this.resource.getInputStream(); - } - - public long getLastModified() { - try { - return this.resource.lastModified(); - } - catch (IOException ex) { - return -1; - } - } - - } - -} diff --git a/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/autoconfigure/ShellProperties.java b/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/autoconfigure/ShellProperties.java deleted file mode 100644 index d0de4dcc91..0000000000 --- a/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/autoconfigure/ShellProperties.java +++ /dev/null @@ -1,547 +0,0 @@ -/* - * Copyright 2012-2016 the original author or authors. - * - * 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. - */ - -package org.springframework.boot.actuate.autoconfigure; - -import java.util.ArrayList; -import java.util.Arrays; -import java.util.List; -import java.util.Properties; -import java.util.UUID; - -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; - -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.context.properties.ConfigurationProperties; -import org.springframework.util.Assert; -import org.springframework.util.ClassUtils; -import org.springframework.util.StringUtils; - -/** - * Configuration properties for the shell subsystem. - * - * @author Christian Dupuis - * @author Phillip Webb - * @author Eddú Meléndez - * @author Stephane Nicoll - */ -@ConfigurationProperties(prefix = ShellProperties.SHELL_PREFIX, ignoreUnknownFields = true) -@Deprecated -public class ShellProperties { - - public static final String SHELL_PREFIX = "management.shell"; - - private static final Log logger = LogFactory.getLog(ShellProperties.class); - - private final Auth auth = new Auth(); - - @Autowired(required = false) - private CrshShellProperties[] additionalProperties = new CrshShellProperties[] { - new SimpleAuthenticationProperties() }; - - /** - * Scan for changes and update the command if necessary (in seconds). - */ - private int commandRefreshInterval = -1; - - /** - * Patterns to use to look for commands. - */ - private String[] commandPathPatterns = new String[] { "classpath*:/commands/**", - "classpath*:/crash/commands/**" }; - - /** - * Patterns to use to look for configurations. - */ - private String[] configPathPatterns = new String[] { "classpath*:/crash/*" }; - - /** - * Comma-separated list of commands to disable. - */ - private String[] disabledCommands = new String[] { "jpa*", "jdbc*", "jndi*" }; - - /** - * Comma-separated list of plugins to disable. Certain plugins are disabled by default - * based on the environment. - */ - private String[] disabledPlugins = new String[0]; - - private final Ssh ssh = new Ssh(); - - private final Telnet telnet = new Telnet(); - - public Auth getAuth() { - return this.auth; - } - - public CrshShellProperties[] getAdditionalProperties() { - return this.additionalProperties; - } - - public void setCommandRefreshInterval(int commandRefreshInterval) { - this.commandRefreshInterval = commandRefreshInterval; - } - - public int getCommandRefreshInterval() { - return this.commandRefreshInterval; - } - - public void setCommandPathPatterns(String[] commandPathPatterns) { - Assert.notEmpty(commandPathPatterns, "CommandPathPatterns must not be empty"); - this.commandPathPatterns = commandPathPatterns; - } - - public String[] getCommandPathPatterns() { - return this.commandPathPatterns; - } - - public void setConfigPathPatterns(String[] configPathPatterns) { - Assert.notEmpty(configPathPatterns, "ConfigPathPatterns must not be empty"); - this.configPathPatterns = configPathPatterns; - } - - public String[] getConfigPathPatterns() { - return this.configPathPatterns; - } - - public void setDisabledCommands(String[] disabledCommands) { - Assert.notEmpty(disabledCommands); - this.disabledCommands = disabledCommands; - } - - public String[] getDisabledCommands() { - return this.disabledCommands; - } - - public void setDisabledPlugins(String[] disabledPlugins) { - Assert.notEmpty(disabledPlugins); - this.disabledPlugins = disabledPlugins; - } - - public String[] getDisabledPlugins() { - return this.disabledPlugins; - } - - public Ssh getSsh() { - return this.ssh; - } - - public Telnet getTelnet() { - return this.telnet; - } - - /** - * Return a properties file configured from these settings that can be applied to a - * CRaSH shell instance. - * @return the CRaSH properties - */ - public Properties asCrshShellConfig() { - Properties properties = new Properties(); - this.ssh.applyToCrshShellConfig(properties); - this.telnet.applyToCrshShellConfig(properties); - - for (CrshShellProperties shellProperties : this.additionalProperties) { - shellProperties.applyToCrshShellConfig(properties); - } - - if (this.commandRefreshInterval > 0) { - properties.put("crash.vfs.refresh_period", - String.valueOf(this.commandRefreshInterval)); - } - - // special handling for disabling Ssh and Telnet support - List dp = new ArrayList(Arrays.asList(this.disabledPlugins)); - if (!this.ssh.isEnabled()) { - dp.add("org.crsh.ssh.SSHPlugin"); - } - if (!this.telnet.isEnabled()) { - dp.add("org.crsh.telnet.TelnetPlugin"); - } - this.disabledPlugins = dp.toArray(new String[dp.size()]); - - validateCrshShellConfig(properties); - - return properties; - } - - /** - * Basic validation of applied CRaSH shell configuration. - * @param properties the properties to validate - */ - protected void validateCrshShellConfig(Properties properties) { - getAuth().validateCrshShellConfig(properties); - } - - /** - * Base class for CRaSH properties. - */ - public static abstract class CrshShellProperties { - - /** - * Apply the properties to a CRaSH configuration. - * @param config the CRaSH configuration properties - */ - protected abstract void applyToCrshShellConfig(Properties config); - - } - - /** - * Base class for Auth specific properties. - */ - public static abstract class CrshShellAuthenticationProperties - extends CrshShellProperties { - - } - - public static class Auth { - - /** - * Authentication type. Auto-detected according to the environment (i.e. if Spring - * Security is available, "spring" is used by default). - */ - private String type = "simple"; - - private boolean defaultAuth = true; - - public String getType() { - return this.type; - } - - public void setType(String type) { - Assert.hasLength(type, "Auth type must not be empty"); - this.type = type; - this.defaultAuth = false; - } - - /** - * Basic validation of applied CRaSH shell configuration. - * @param properties the properties to validate - */ - protected void validateCrshShellConfig(Properties properties) { - String finalAuth = properties.getProperty("crash.auth"); - if (!this.defaultAuth && !this.type.equals(finalAuth)) { - logger.warn(String.format( - "Shell authentication fell back to method '%s' opposed to " - + "configured method '%s'. Please check your classpath.", - finalAuth, this.type)); - } - // Make sure we keep track of final authentication method - this.type = finalAuth; - } - - } - - /** - * SSH properties. - */ - public static class Ssh extends CrshShellProperties { - - /** - * Enable CRaSH SSH support. - */ - private boolean enabled = true; - - /** - * Path to the SSH server key. - */ - private String keyPath; - - /** - * SSH port. - */ - private Integer port = 2000; - - /** - * Number of milliseconds after user will be prompted to login again. - */ - private Integer authTimeout = 600000; - - /** - * Number of milliseconds after which unused connections are closed. - */ - private Integer idleTimeout = 600000; - - @Override - protected void applyToCrshShellConfig(Properties config) { - if (this.enabled) { - config.put("crash.ssh.port", String.valueOf(this.port)); - config.put("crash.ssh.auth_timeout", String.valueOf(this.authTimeout)); - config.put("crash.ssh.idle_timeout", String.valueOf(this.idleTimeout)); - if (this.keyPath != null) { - config.put("crash.ssh.keypath", this.keyPath); - } - } - } - - public void setEnabled(boolean enabled) { - this.enabled = enabled; - } - - public boolean isEnabled() { - return this.enabled; - } - - public void setKeyPath(String keyPath) { - Assert.hasText(keyPath, "keyPath must have text"); - this.keyPath = keyPath; - } - - public String getKeyPath() { - return this.keyPath; - } - - public void setPort(Integer port) { - Assert.notNull(port, "port must not be null"); - this.port = port; - } - - public Integer getPort() { - return this.port; - } - - public Integer getIdleTimeout() { - return this.idleTimeout; - } - - public void setIdleTimeout(Integer idleTimeout) { - this.idleTimeout = idleTimeout; - } - - public Integer getAuthTimeout() { - return this.authTimeout; - } - - public void setAuthTimeout(Integer authTimeout) { - this.authTimeout = authTimeout; - } - } - - /** - * Telnet properties. - */ - public static class Telnet extends CrshShellProperties { - - /** - * Enable CRaSH telnet support. Enabled by default if the TelnetPlugin is - * available. - */ - private boolean enabled = ClassUtils.isPresent("org.crsh.telnet.TelnetPlugin", - ClassUtils.getDefaultClassLoader()); - - /** - * Telnet port. - */ - private Integer port = 5000; - - @Override - protected void applyToCrshShellConfig(Properties config) { - if (this.enabled) { - config.put("crash.telnet.port", String.valueOf(this.port)); - } - } - - public void setEnabled(boolean enabled) { - this.enabled = enabled; - } - - public boolean isEnabled() { - return this.enabled; - } - - public void setPort(Integer port) { - Assert.notNull(port, "port must not be null"); - this.port = port; - } - - public Integer getPort() { - return this.port; - } - - } - - /** - * Auth specific properties for JAAS authentication. - */ - @ConfigurationProperties(prefix = SHELL_PREFIX - + ".auth.jaas", ignoreUnknownFields = false) - public static class JaasAuthenticationProperties - extends CrshShellAuthenticationProperties { - - /** - * JAAS domain. - */ - private String domain = "my-domain"; - - @Override - protected void applyToCrshShellConfig(Properties config) { - config.put("crash.auth", "jaas"); - config.put("crash.auth.jaas.domain", this.domain); - } - - public void setDomain(String domain) { - Assert.hasText(domain, "domain must have text"); - this.domain = domain; - } - - public String getDomain() { - return this.domain; - } - - } - - /** - * Auth specific properties for key authentication. - */ - @ConfigurationProperties(prefix = SHELL_PREFIX - + ".auth.key", ignoreUnknownFields = false) - public static class KeyAuthenticationProperties - extends CrshShellAuthenticationProperties { - - /** - * Path to the authentication key. This should point to a valid ".pem" file. - */ - private String path; - - @Override - protected void applyToCrshShellConfig(Properties config) { - config.put("crash.auth", "key"); - if (this.path != null) { - config.put("crash.auth.key.path", this.path); - } - } - - public void setPath(String path) { - Assert.hasText(path, "path must have text"); - this.path = path; - } - - public String getPath() { - return this.path; - } - - } - - /** - * Auth specific properties for simple authentication. - */ - @ConfigurationProperties(prefix = SHELL_PREFIX - + ".auth.simple", ignoreUnknownFields = false) - public static class SimpleAuthenticationProperties - extends CrshShellAuthenticationProperties { - - private static final Log logger = LogFactory - .getLog(SimpleAuthenticationProperties.class); - - private User user = new User(); - - @Override - protected void applyToCrshShellConfig(Properties config) { - config.put("crash.auth", "simple"); - config.put("crash.auth.simple.username", this.user.getName()); - config.put("crash.auth.simple.password", this.user.getPassword()); - if (this.user.isDefaultPassword()) { - logger.info(String.format( - "%n%nUsing default password for shell access: %s%n%n", - this.user.getPassword())); - } - } - - public User getUser() { - return this.user; - } - - public void setUser(User user) { - this.user = user; - } - - public static class User { - - /** - * Login user. - */ - private String name = "user"; - - /** - * Login password. - */ - private String password = UUID.randomUUID().toString(); - - private boolean defaultPassword = true; - - boolean isDefaultPassword() { - return this.defaultPassword; - } - - public String getName() { - return this.name; - } - - public String getPassword() { - return this.password; - } - - public void setName(String name) { - Assert.hasLength(name, "name must have text"); - this.name = name; - } - - public void setPassword(String password) { - if (password.startsWith("${") && password.endsWith("}") - || !StringUtils.hasLength(password)) { - return; - } - this.password = password; - this.defaultPassword = false; - } - - } - - } - - /** - * Auth specific properties for Spring authentication. - */ - @ConfigurationProperties(prefix = SHELL_PREFIX - + ".auth.spring", ignoreUnknownFields = false) - public static class SpringAuthenticationProperties - extends CrshShellAuthenticationProperties { - - /** - * Comma-separated list of required roles to login to the CRaSH console. - */ - private String[] roles = new String[] { "ADMIN" }; - - @Override - protected void applyToCrshShellConfig(Properties config) { - config.put("crash.auth", "spring"); - config.put("crash.auth.spring.roles", - StringUtils.arrayToCommaDelimitedString(this.roles)); - } - - public void setRoles(String[] roles) { - // 'roles' can be null. This means no special to access right to connect to - // shell is required. - this.roles = roles; - } - - public String[] getRoles() { - return this.roles; - } - - } - -} diff --git a/spring-boot-actuator/src/main/resources/META-INF/additional-spring-configuration-metadata.json b/spring-boot-actuator/src/main/resources/META-INF/additional-spring-configuration-metadata.json index 8ce47a4b0b..45fa5c995d 100644 --- a/spring-boot-actuator/src/main/resources/META-INF/additional-spring-configuration-metadata.json +++ b/spring-boot-actuator/src/main/resources/META-INF/additional-spring-configuration-metadata.json @@ -253,27 +253,6 @@ "name": "any" } ] - }, - { - "name": "management.shell.auth.type", - "values": [ - { - "value": "simple", - "description": "Use a simple user/password based authentication." - }, - { - "value": "spring", - "description": "Integrate with Spring Security." - }, - { - "value": "key", - "description": "Use a Key-based authentication." - }, - { - "value": "jaas", - "description": "Use JAAS authentication." - } - ] } ]} diff --git a/spring-boot-actuator/src/main/resources/META-INF/spring.factories b/spring-boot-actuator/src/main/resources/META-INF/spring.factories index 41a4f14ced..d619fa69d8 100644 --- a/spring-boot-actuator/src/main/resources/META-INF/spring.factories +++ b/spring-boot-actuator/src/main/resources/META-INF/spring.factories @@ -1,7 +1,6 @@ org.springframework.boot.autoconfigure.EnableAutoConfiguration=\ org.springframework.boot.actuate.autoconfigure.AuditAutoConfiguration,\ org.springframework.boot.actuate.autoconfigure.CacheStatisticsAutoConfiguration,\ -org.springframework.boot.actuate.autoconfigure.CrshAutoConfiguration,\ org.springframework.boot.actuate.autoconfigure.EndpointAutoConfiguration,\ org.springframework.boot.actuate.autoconfigure.EndpointMBeanExportAutoConfiguration,\ org.springframework.boot.actuate.autoconfigure.EndpointWebMvcAutoConfiguration,\ diff --git a/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/autoconfigure/CrshAutoConfigurationTests.java b/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/autoconfigure/CrshAutoConfigurationTests.java deleted file mode 100644 index 764605e0bd..0000000000 --- a/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/autoconfigure/CrshAutoConfigurationTests.java +++ /dev/null @@ -1,372 +0,0 @@ -/* - * Copyright 2012-2016 the original author or authors. - * - * 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. - */ - -package org.springframework.boot.actuate.autoconfigure; - -import java.util.ArrayList; -import java.util.Collections; -import java.util.Iterator; -import java.util.List; -import java.util.Map; -import java.util.UUID; - -import org.crsh.auth.AuthenticationPlugin; -import org.crsh.auth.JaasAuthenticationPlugin; -import org.crsh.lang.impl.java.JavaLanguage; -import org.crsh.lang.spi.Language; -import org.crsh.plugin.PluginContext; -import org.crsh.plugin.PluginLifeCycle; -import org.crsh.plugin.ResourceKind; -import org.crsh.telnet.term.processor.ProcessorIOHandler; -import org.crsh.telnet.term.spi.TermIOHandler; -import org.crsh.vfs.Resource; -import org.junit.After; -import org.junit.Test; - -import org.springframework.boot.autoconfigure.security.SecurityAutoConfiguration; -import org.springframework.boot.test.util.EnvironmentTestUtils; -import org.springframework.boot.testutil.Matched; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; -import org.springframework.mock.env.MockEnvironment; -import org.springframework.mock.web.MockServletContext; -import org.springframework.security.access.AccessDecisionManager; -import org.springframework.security.access.AccessDecisionVoter; -import org.springframework.security.access.vote.RoleVoter; -import org.springframework.security.access.vote.UnanimousBased; -import org.springframework.security.authentication.AuthenticationManager; -import org.springframework.security.authentication.BadCredentialsException; -import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; -import org.springframework.security.core.Authentication; -import org.springframework.security.core.AuthenticationException; -import org.springframework.security.core.authority.SimpleGrantedAuthority; -import org.springframework.web.context.support.AnnotationConfigWebApplicationContext; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.hamcrest.CoreMatchers.isA; - -/** - * Tests for {@link CrshAutoConfiguration}. - * - * @author Christian Dupuis - * @author Andreas Ahlenstorf - * @author Eddú Meléndez - * @author Matt Benson - * @author Stephane Nicoll - */ -@SuppressWarnings({ "rawtypes", "unchecked" }) -@Deprecated -public class CrshAutoConfigurationTests { - - private AnnotationConfigWebApplicationContext context; - - @After - public void close() { - if (this.context != null) { - this.context.close(); - } - } - - @Test - public void testDisabledPlugins() throws Exception { - load("management.shell.disabled_plugins=" - + "termIOHandler, org.crsh.auth.AuthenticationPlugin, javaLanguage"); - PluginLifeCycle lifeCycle = this.context.getBean(PluginLifeCycle.class); - assertThat(lifeCycle).isNotNull(); - assertThat(lifeCycle.getContext().getPlugins(TermIOHandler.class)) - .filteredOn(Matched.when(isA(ProcessorIOHandler.class))) - .isEmpty(); - assertThat(lifeCycle.getContext().getPlugins(AuthenticationPlugin.class)) - .filteredOn(Matched - .when(isA(JaasAuthenticationPlugin.class))) - .isEmpty(); - assertThat(lifeCycle.getContext().getPlugins(Language.class)) - .filteredOn(Matched.when(isA(JavaLanguage.class))).isEmpty(); - } - - @Test - public void testAttributes() throws Exception { - load(); - PluginLifeCycle lifeCycle = this.context.getBean(PluginLifeCycle.class); - Map attributes = lifeCycle.getContext().getAttributes(); - assertThat(attributes.containsKey("spring.version")).isTrue(); - assertThat(attributes.containsKey("spring.beanfactory")).isTrue(); - assertThat(attributes.get("spring.beanfactory")) - .isEqualTo(this.context.getBeanFactory()); - } - - @Test - public void testSshConfiguration() { - load("management.shell.ssh.enabled=true", "management.shell.ssh.port=3333"); - PluginLifeCycle lifeCycle = this.context.getBean(PluginLifeCycle.class); - assertThat(lifeCycle.getConfig().getProperty("crash.ssh.port")).isEqualTo("3333"); - assertThat(lifeCycle.getConfig().getProperty("crash.ssh.auth_timeout")) - .isEqualTo("600000"); - assertThat(lifeCycle.getConfig().getProperty("crash.ssh.idle_timeout")) - .isEqualTo("600000"); - } - - @Test - public void testSshConfigurationWithKeyPath() { - load("management.shell.ssh.enabled=true", - "management.shell.ssh.key_path=~/.ssh/id.pem"); - PluginLifeCycle lifeCycle = this.context.getBean(PluginLifeCycle.class); - assertThat(lifeCycle.getConfig().getProperty("crash.ssh.keypath")) - .isEqualTo("~/.ssh/id.pem"); - } - - @Test - public void testSshConfigurationCustomTimeouts() { - load("management.shell.ssh.enabled=true", - "management.shell.ssh.auth-timeout=300000", - "management.shell.ssh.idle-timeout=400000"); - PluginLifeCycle lifeCycle = this.context.getBean(PluginLifeCycle.class); - assertThat(lifeCycle.getConfig().getProperty("crash.ssh.auth_timeout")) - .isEqualTo("300000"); - assertThat(lifeCycle.getConfig().getProperty("crash.ssh.idle_timeout")) - .isEqualTo("400000"); - } - - @Test - public void testCommandResolution() { - load(); - PluginLifeCycle lifeCycle = this.context.getBean(PluginLifeCycle.class); - int count = 0; - Iterator resources = lifeCycle.getContext() - .loadResources("login", ResourceKind.LIFECYCLE).iterator(); - while (resources.hasNext()) { - count++; - resources.next(); - } - assertThat(count).isEqualTo(1); - count = 0; - resources = lifeCycle.getContext() - .loadResources("sleep.groovy", ResourceKind.COMMAND).iterator(); - while (resources.hasNext()) { - count++; - resources.next(); - } - assertThat(count).isEqualTo(1); - } - - @Test - public void testDisabledCommandResolution() { - load(); - PluginLifeCycle lifeCycle = this.context.getBean(PluginLifeCycle.class); - int count = 0; - Iterator resources = lifeCycle.getContext() - .loadResources("jdbc.groovy", ResourceKind.COMMAND).iterator(); - while (resources.hasNext()) { - count++; - resources.next(); - } - assertThat(count).isEqualTo(0); - } - - @Test - public void testAuthenticationProvidersAreInstalled() { - this.context = new AnnotationConfigWebApplicationContext(); - this.context.setServletContext(new MockServletContext()); - this.context.register(SecurityConfiguration.class); - this.context.register(CrshAutoConfiguration.class); - this.context.refresh(); - PluginLifeCycle lifeCycle = this.context.getBean(PluginLifeCycle.class); - PluginContext pluginContext = lifeCycle.getContext(); - int count = 0; - Iterator plugins = pluginContext - .getPlugins(AuthenticationPlugin.class).iterator(); - while (plugins.hasNext()) { - count++; - plugins.next(); - } - assertThat(count).isEqualTo(3); - } - - @Test - public void testDefaultAuthenticationProvider() { - MockEnvironment env = new MockEnvironment(); - this.context = new AnnotationConfigWebApplicationContext(); - this.context.setEnvironment(env); - this.context.setServletContext(new MockServletContext()); - this.context.register(CrshAutoConfiguration.class); - this.context.refresh(); - PluginLifeCycle lifeCycle = this.context.getBean(PluginLifeCycle.class); - assertThat(lifeCycle.getConfig().get("crash.auth")).isEqualTo("simple"); - } - - @Test - public void testJaasAuthenticationProvider() { - this.context = new AnnotationConfigWebApplicationContext(); - EnvironmentTestUtils.addEnvironment(this.context, - "management.shell.auth.type=jaas", - "management.shell.auth.jaas.domain=my-test-domain"); - this.context.setServletContext(new MockServletContext()); - this.context.register(SecurityConfiguration.class); - this.context.register(CrshAutoConfiguration.class); - this.context.refresh(); - PluginLifeCycle lifeCycle = this.context.getBean(PluginLifeCycle.class); - assertThat(lifeCycle.getConfig().get("crash.auth")).isEqualTo("jaas"); - assertThat(lifeCycle.getConfig().get("crash.auth.jaas.domain")) - .isEqualTo("my-test-domain"); - } - - @Test - public void testKeyAuthenticationProvider() { - this.context = new AnnotationConfigWebApplicationContext(); - EnvironmentTestUtils.addEnvironment(this.context, - "management.shell.auth.type=key", - "management.shell.auth.key.path=~/test.pem"); - this.context.setServletContext(new MockServletContext()); - this.context.register(SecurityConfiguration.class); - this.context.register(CrshAutoConfiguration.class); - this.context.refresh(); - PluginLifeCycle lifeCycle = this.context.getBean(PluginLifeCycle.class); - assertThat(lifeCycle.getConfig().get("crash.auth")).isEqualTo("key"); - assertThat(lifeCycle.getConfig().get("crash.auth.key.path")) - .isEqualTo("~/test.pem"); - } - - @Test - public void testSimpleAuthenticationProvider() throws Exception { - this.context = new AnnotationConfigWebApplicationContext(); - EnvironmentTestUtils.addEnvironment(this.context, - "management.shell.auth.type=simple", - "management.shell.auth.simple.user.name=user", - "management.shell.auth.simple.user.password=password"); - this.context.setServletContext(new MockServletContext()); - this.context.register(SecurityConfiguration.class); - this.context.register(CrshAutoConfiguration.class); - this.context.refresh(); - PluginLifeCycle lifeCycle = this.context.getBean(PluginLifeCycle.class); - assertThat(lifeCycle.getConfig().get("crash.auth")).isEqualTo("simple"); - AuthenticationPlugin authenticationPlugin = null; - String authentication = lifeCycle.getConfig().getProperty("crash.auth"); - assertThat(authentication).isNotNull(); - for (AuthenticationPlugin plugin : lifeCycle.getContext() - .getPlugins(AuthenticationPlugin.class)) { - if (authentication.equals(plugin.getName())) { - authenticationPlugin = plugin; - break; - } - } - assertThat(authenticationPlugin).isNotNull(); - assertThat(authenticationPlugin.authenticate("user", "password")).isTrue(); - assertThat(authenticationPlugin.authenticate(UUID.randomUUID().toString(), - "password")).isFalse(); - } - - @Test - public void testSpringAuthenticationProvider() throws Exception { - this.context = new AnnotationConfigWebApplicationContext(); - EnvironmentTestUtils.addEnvironment(this.context, - "management.shell.auth.type=spring"); - this.context.setServletContext(new MockServletContext()); - this.context.register(SecurityConfiguration.class); - this.context.register(CrshAutoConfiguration.class); - this.context.refresh(); - PluginLifeCycle lifeCycle = this.context.getBean(PluginLifeCycle.class); - AuthenticationPlugin authenticationPlugin = null; - String authentication = lifeCycle.getConfig().getProperty("crash.auth"); - assertThat(authentication).isNotNull(); - for (AuthenticationPlugin plugin : lifeCycle.getContext() - .getPlugins(AuthenticationPlugin.class)) { - if (authentication.equals(plugin.getName())) { - authenticationPlugin = plugin; - break; - } - } - assertThat(authenticationPlugin.authenticate(SecurityConfiguration.USERNAME, - SecurityConfiguration.PASSWORD)).isTrue(); - assertThat(authenticationPlugin.authenticate(UUID.randomUUID().toString(), - SecurityConfiguration.PASSWORD)).isFalse(); - } - - @Test - public void testSpringAuthenticationProviderAsDefaultConfiguration() - throws Exception { - this.context = new AnnotationConfigWebApplicationContext(); - this.context.setServletContext(new MockServletContext()); - this.context.register(ManagementServerPropertiesAutoConfiguration.class); - this.context.register(SecurityAutoConfiguration.class); - this.context.register(SecurityConfiguration.class); - this.context.register(CrshAutoConfiguration.class); - this.context.refresh(); - PluginLifeCycle lifeCycle = this.context.getBean(PluginLifeCycle.class); - AuthenticationPlugin authenticationPlugin = null; - String authentication = lifeCycle.getConfig().getProperty("crash.auth"); - assertThat(authentication).isNotNull(); - for (AuthenticationPlugin plugin : lifeCycle.getContext() - .getPlugins(AuthenticationPlugin.class)) { - if (authentication.equals(plugin.getName())) { - authenticationPlugin = plugin; - break; - } - } - assertThat(authenticationPlugin.authenticate(SecurityConfiguration.USERNAME, - SecurityConfiguration.PASSWORD)).isTrue(); - assertThat(authenticationPlugin.authenticate(UUID.randomUUID().toString(), - SecurityConfiguration.PASSWORD)).isFalse(); - } - - private void load(String... environment) { - this.context = new AnnotationConfigWebApplicationContext(); - EnvironmentTestUtils.addEnvironment(this.context, environment); - this.context.register(CrshAutoConfiguration.class); - this.context.refresh(); - } - - @Configuration - public static class SecurityConfiguration { - - public static final String USERNAME = UUID.randomUUID().toString(); - - public static final String PASSWORD = UUID.randomUUID().toString(); - - @Bean - public AuthenticationManager authenticationManager() { - return new AuthenticationManager() { - - @Override - public Authentication authenticate(Authentication authentication) - throws AuthenticationException { - if (authentication.getName().equals(USERNAME) - && authentication.getCredentials().equals(PASSWORD)) { - authentication = new UsernamePasswordAuthenticationToken( - authentication.getPrincipal(), - authentication.getCredentials(), Collections - .singleton(new SimpleGrantedAuthority("ADMIN"))); - } - else { - throw new BadCredentialsException( - "Invalid username and password"); - } - return authentication; - } - }; - } - - @Bean - public AccessDecisionManager shellAccessDecisionManager() { - List> voters = new ArrayList>(); - RoleVoter voter = new RoleVoter(); - voter.setRolePrefix(""); - voters.add(voter); - return new UnanimousBased(voters); - } - - } - -} diff --git a/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/autoconfigure/ShellPropertiesTests.java b/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/autoconfigure/ShellPropertiesTests.java deleted file mode 100644 index 1bdd66ce28..0000000000 --- a/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/autoconfigure/ShellPropertiesTests.java +++ /dev/null @@ -1,271 +0,0 @@ -/* - * Copyright 2012-2016 the original author or authors. - * - * 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. - */ - -package org.springframework.boot.actuate.autoconfigure; - -import java.util.Properties; -import java.util.UUID; - -import org.crsh.plugin.PluginLifeCycle; -import org.junit.After; -import org.junit.Assert; -import org.junit.Rule; -import org.junit.Test; -import org.junit.rules.ExpectedException; - -import org.springframework.beans.factory.BeanCreationException; -import org.springframework.boot.actuate.autoconfigure.ShellProperties.CrshShellProperties; -import org.springframework.boot.actuate.autoconfigure.ShellProperties.JaasAuthenticationProperties; -import org.springframework.boot.actuate.autoconfigure.ShellProperties.KeyAuthenticationProperties; -import org.springframework.boot.actuate.autoconfigure.ShellProperties.SimpleAuthenticationProperties; -import org.springframework.boot.actuate.autoconfigure.ShellProperties.SpringAuthenticationProperties; -import org.springframework.boot.context.properties.EnableConfigurationProperties; -import org.springframework.boot.test.util.EnvironmentTestUtils; -import org.springframework.context.annotation.AnnotationConfigApplicationContext; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; -import org.springframework.mock.env.MockEnvironment; -import org.springframework.mock.web.MockServletContext; -import org.springframework.web.context.support.AnnotationConfigWebApplicationContext; - -import static org.assertj.core.api.Assertions.assertThat; - -/** - * Tests for {@link ShellProperties}. - * - * @author Christian Dupuis - * @author Stephane Nicoll - */ -@Deprecated -public class ShellPropertiesTests { - - @Rule - public final ExpectedException thrown = ExpectedException.none(); - - private AnnotationConfigApplicationContext context; - - @After - public void close() { - if (this.context != null) { - this.context.close(); - } - } - - @Test - public void testBindingAuth() { - ShellProperties props = load(ShellProperties.class, - "management.shell.auth.type=spring"); - assertThat(props.getAuth().getType()).isEqualTo("spring"); - } - - @Test - public void testBindingAuthIfEmpty() { - this.thrown.expect(BeanCreationException.class); - this.thrown.expectMessage("Auth type must not be empty"); - load(ShellProperties.class, "management.shell.auth.type= "); - } - - @Test - public void testBindingCommandRefreshInterval() { - ShellProperties props = load(ShellProperties.class, - "management.shell.command-refresh-interval=1"); - assertThat(props.getCommandRefreshInterval()).isEqualTo(1); - } - - @Test - public void testBindingCommandPathPatterns() { - ShellProperties props = load(ShellProperties.class, - "management.shell.command-path-patterns=pattern1, pattern2"); - assertThat(props.getCommandPathPatterns().length).isEqualTo(2); - Assert.assertArrayEquals(new String[] { "pattern1", "pattern2" }, - props.getCommandPathPatterns()); - } - - @Test - public void testBindingConfigPathPatterns() { - ShellProperties props = load(ShellProperties.class, - "management.shell.config-path-patterns=pattern1, pattern2"); - assertThat(props.getConfigPathPatterns().length).isEqualTo(2); - Assert.assertArrayEquals(new String[] { "pattern1", "pattern2" }, - props.getConfigPathPatterns()); - } - - @Test - public void testBindingDisabledPlugins() { - ShellProperties props = load(ShellProperties.class, - "management.shell.disabled-plugins=pattern1, pattern2"); - assertThat(props.getDisabledPlugins().length).isEqualTo(2); - assertThat(props.getDisabledPlugins()).containsExactly("pattern1", "pattern2"); - } - - @Test - public void testBindingDisabledCommands() { - ShellProperties props = load(ShellProperties.class, - "management.shell.disabled-commands=pattern1, pattern2"); - assertThat(props.getDisabledCommands()).containsExactly("pattern1", "pattern2"); - } - - @Test - public void testBindingSsh() { - ShellProperties props = load(ShellProperties.class, - "management.shell.ssh.enabled=true", "management.shell.ssh.port=2222", - "management.shell.ssh.key-path=~/.ssh/test.pem"); - Properties p = props.asCrshShellConfig(); - assertThat(p.get("crash.ssh.port")).isEqualTo("2222"); - assertThat(p.get("crash.ssh.keypath")).isEqualTo("~/.ssh/test.pem"); - } - - @Test - public void testBindingSshIgnored() { - ShellProperties props = load(ShellProperties.class, - "management.shell.ssh.enabled=false", "management.shell.ssh.port=2222", - "management.shell.ssh.key-path=~/.ssh/test.pem"); - Properties p = props.asCrshShellConfig(); - assertThat(p.get("crash.ssh.port")).isNull(); - assertThat(p.get("crash.ssh.keypath")).isNull(); - } - - @Test - public void testBindingTelnet() { - ShellProperties props = load(ShellProperties.class, - "management.shell.telnet.enabled=true", - "management.shell.telnet.port=2222"); - Properties p = props.asCrshShellConfig(); - assertThat(p.get("crash.telnet.port")).isEqualTo("2222"); - } - - @Test - public void testBindingTelnetIgnored() { - ShellProperties props = load(ShellProperties.class, - "management.shell.telnet.enabled=false", - "management.shell.telnet.port=2222"); - Properties p = props.asCrshShellConfig(); - assertThat(p.get("crash.telnet.port")).isNull(); - } - - @Test - public void testBindingJaas() { - JaasAuthenticationProperties props = load(JaasAuthenticationProperties.class, - "management.shell.auth.jaas.domain=my-test-domain"); - Properties p = new Properties(); - props.applyToCrshShellConfig(p); - assertThat(p.get("crash.auth.jaas.domain")).isEqualTo("my-test-domain"); - } - - @Test - public void testBindingKey() { - KeyAuthenticationProperties props = load(KeyAuthenticationProperties.class, - "management.shell.auth.key.path=~/.ssh/test.pem"); - Properties p = new Properties(); - props.applyToCrshShellConfig(p); - assertThat(p.get("crash.auth.key.path")).isEqualTo("~/.ssh/test.pem"); - } - - @Test - public void testBindingKeyIgnored() { - KeyAuthenticationProperties props = load(KeyAuthenticationProperties.class); - Properties p = new Properties(); - props.applyToCrshShellConfig(p); - assertThat(p.get("crash.auth.key.path")).isNull(); - } - - @Test - public void testBindingSimple() { - SimpleAuthenticationProperties props = load(SimpleAuthenticationProperties.class, - "management.shell.auth.simple.user.name=username123", - "management.shell.auth.simple.user.password=password123"); - Properties p = new Properties(); - props.applyToCrshShellConfig(p); - assertThat(p.get("crash.auth.simple.username")).isEqualTo("username123"); - assertThat(p.get("crash.auth.simple.password")).isEqualTo("password123"); - } - - @Test - public void testDefaultPasswordAutoGeneratedIfUnresolvedPlaceholder() { - SimpleAuthenticationProperties security = load( - SimpleAuthenticationProperties.class, - "management.shell.auth.simple.user.password=${ADMIN_PASSWORD}"); - assertThat(security.getUser().isDefaultPassword()).isTrue(); - } - - @Test - public void testDefaultPasswordAutoGeneratedIfEmpty() { - SimpleAuthenticationProperties security = load( - SimpleAuthenticationProperties.class, - "management.shell.auth.simple.user.password="); - assertThat(security.getUser().isDefaultPassword()).isTrue(); - } - - @Test - public void testBindingSpring() { - SpringAuthenticationProperties props = load(SpringAuthenticationProperties.class, - "management.shell.auth.spring.roles=role1,role2"); - Properties p = new Properties(); - props.applyToCrshShellConfig(p); - assertThat(p.get("crash.auth.spring.roles")).isEqualTo("role1,role2"); - } - - @Test - public void testCustomShellProperties() throws Exception { - MockEnvironment env = new MockEnvironment(); - env.setProperty("management.shell.auth.type", "simple"); - AnnotationConfigWebApplicationContext ctx = new AnnotationConfigWebApplicationContext(); - ctx.setEnvironment(env); - ctx.setServletContext(new MockServletContext()); - ctx.register(TestShellConfiguration.class); - ctx.register(CrshAutoConfiguration.class); - ctx.refresh(); - - PluginLifeCycle lifeCycle = ctx.getBean(PluginLifeCycle.class); - String uuid = lifeCycle.getConfig().getProperty("test.uuid"); - assertThat(uuid).isEqualTo(TestShellConfiguration.uuid); - ctx.close(); - } - - private T load(Class type, String... environment) { - AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext(); - EnvironmentTestUtils.addEnvironment(ctx, environment); - ctx.register(TestConfiguration.class); - ctx.refresh(); - this.context = ctx; - return this.context.getBean(type); - } - - @Configuration - @EnableConfigurationProperties({ ShellProperties.class, - JaasAuthenticationProperties.class, KeyAuthenticationProperties.class, - SimpleAuthenticationProperties.class, SpringAuthenticationProperties.class }) - static class TestConfiguration { - - } - - @Configuration - public static class TestShellConfiguration { - - public static String uuid = UUID.randomUUID().toString(); - - @Bean - public CrshShellProperties testProperties() { - return new CrshShellProperties() { - - @Override - protected void applyToCrshShellConfig(Properties config) { - config.put("test.uuid", uuid); - } - }; - } - } -} diff --git a/spring-boot-cli/src/test/java/org/springframework/boot/cli/ReproIntegrationTests.java b/spring-boot-cli/src/test/java/org/springframework/boot/cli/ReproIntegrationTests.java index 6b3027dcf9..0abdb7cfac 100644 --- a/spring-boot-cli/src/test/java/org/springframework/boot/cli/ReproIntegrationTests.java +++ b/spring-boot-cli/src/test/java/org/springframework/boot/cli/ReproIntegrationTests.java @@ -51,12 +51,6 @@ public class ReproIntegrationTests { assertThat(this.cli.getOutput()).contains("Hello World"); } - @Test - public void shellDependencies() throws Exception { - this.cli.run("crsh.groovy"); - assertThat(this.cli.getHttpOutput()).contains("{\"message\":\"Hello World\"}"); - } - @Test public void dataJpaDependencies() throws Exception { this.cli.run("data-jpa.groovy"); @@ -67,7 +61,7 @@ public class ReproIntegrationTests { public void jarFileExtensionNeeded() throws Exception { this.thrown.expect(IllegalStateException.class); this.thrown.expectMessage("is not a JAR file"); - this.cli.jar("secure.groovy", "crsh.groovy"); + this.cli.jar("secure.groovy"); } } diff --git a/spring-boot-cli/src/test/resources/repro-samples/crsh.groovy b/spring-boot-cli/src/test/resources/repro-samples/crsh.groovy deleted file mode 100644 index 51f9af955a..0000000000 --- a/spring-boot-cli/src/test/resources/repro-samples/crsh.groovy +++ /dev/null @@ -1,14 +0,0 @@ -package org.test - -@Grab("spring-boot-starter-remote-shell") - -@RestController -class SampleController { - - @RequestMapping("/") - public def hello() { - [message: "Hello World"] - } -} - - diff --git a/spring-boot-dependencies/pom.xml b/spring-boot-dependencies/pom.xml index 858c8312c3..52ef9d25f5 100644 --- a/spring-boot-dependencies/pom.xml +++ b/spring-boot-dependencies/pom.xml @@ -63,7 +63,6 @@ 2.4.2 2.2.8 2.0.0 - 1.3.2 10.12.1.1 1.6.1 3.1.2 @@ -442,11 +441,6 @@ spring-boot-starter-jta-narayana 2.0.0.BUILD-SNAPSHOT - - org.springframework.boot - spring-boot-starter-remote-shell - 2.0.0.BUILD-SNAPSHOT - org.springframework.boot spring-boot-starter-security @@ -1454,47 +1448,6 @@ janino ${janino.version} - - org.crashub - crash.cli - ${crashub.version} - - - org.crashub - crash.connectors.ssh - ${crashub.version} - - - commons-logging - commons-logging - - - - - org.crashub - crash.connectors.telnet - ${crashub.version} - - - org.crashub - crash.embed.spring - ${crashub.version} - - - org.crashub - crash.plugins.cron - ${crashub.version} - - - org.crashub - crash.plugins.mail - ${crashub.version} - - - org.crashub - crash.shell - ${crashub.version} - org.eclipse.jetty jetty-annotations diff --git a/spring-boot-docs/pom.xml b/spring-boot-docs/pom.xml index 0680d2169e..a4b664d05f 100644 --- a/spring-boot-docs/pom.xml +++ b/spring-boot-docs/pom.xml @@ -348,22 +348,6 @@ groovy-templates true - - org.crashub - crash.cli - true - - - org.crashub - crash.shell - true - - - groovy-all - org.codehaus.groovy - - - org.eclipse.jetty jetty-util diff --git a/spring-boot-docs/src/main/asciidoc/appendix-application-properties.adoc b/spring-boot-docs/src/main/asciidoc/appendix-application-properties.adoc index 898da23a76..8068e1ec50 100644 --- a/spring-boot-docs/src/main/asciidoc/appendix-application-properties.adoc +++ b/spring-boot-docs/src/main/asciidoc/appendix-application-properties.adoc @@ -1042,26 +1042,6 @@ content into your application; rather pick only the properties that you need. management.info.git.enabled=true # Enable git info. management.info.git.mode=simple # Mode to use to expose git information. - # REMOTE SHELL ({sc-spring-boot-actuator}/autoconfigure/ShellProperties.{sc-ext}[ShellProperties]) - management.shell.auth.type=simple # Authentication type. Auto-detected according to the environment. - management.shell.auth.jaas.domain=my-domain # JAAS domain. - management.shell.auth.key.path= # Path to the authentication key. This should point to a valid ".pem" file. - management.shell.auth.simple.user.name=user # Login user. - management.shell.auth.simple.user.password= # Login password. - management.shell.auth.spring.roles=ADMIN # Comma-separated list of required roles to login to the CRaSH console. - management.shell.command-path-patterns=classpath*:/commands/**,classpath*:/crash/commands/** # Patterns to use to look for commands. - management.shell.command-refresh-interval=-1 # Scan for changes and update the command if necessary (in seconds). - management.shell.config-path-patterns=classpath*:/crash/* # Patterns to use to look for configurations. - management.shell.disabled-commands=jpa*,jdbc*,jndi* # Comma-separated list of commands to disable. - management.shell.disabled-plugins= # Comma-separated list of plugins to disable. Certain plugins are disabled by default based on the environment. - management.shell.ssh.auth-timeout = # Number of milliseconds after user will be prompted to login again. - management.shell.ssh.enabled=true # Enable CRaSH SSH support. - management.shell.ssh.idle-timeout = # Number of milliseconds after which unused connections are closed. - management.shell.ssh.key-path= # Path to the SSH server key. - management.shell.ssh.port=2000 # SSH port. - management.shell.telnet.enabled=false # Enable CRaSH telnet support. Enabled by default if the TelnetPlugin is available. - management.shell.telnet.port=5000 # Telnet port. - # TRACING ({sc-spring-boot-actuator}/trace/TraceProperties.{sc-ext}[TraceProperties]) management.trace.include=request-headers,response-headers,cookies,errors # Items to be included in the trace. diff --git a/spring-boot-docs/src/main/asciidoc/documentation-overview.adoc b/spring-boot-docs/src/main/asciidoc/documentation-overview.adoc index c810bcae1c..a2d94672f3 100644 --- a/spring-boot-docs/src/main/asciidoc/documentation-overview.adoc +++ b/spring-boot-docs/src/main/asciidoc/documentation-overview.adoc @@ -124,7 +124,6 @@ When you're ready to push your Spring Boot application to production, we've got * *Connection options:* <> | <> | -<> * *Monitoring:* <> | <> | diff --git a/spring-boot-docs/src/main/asciidoc/production-ready-features.adoc b/spring-boot-docs/src/main/asciidoc/production-ready-features.adoc index 8e531225e4..f06d057cac 100644 --- a/spring-boot-docs/src/main/asciidoc/production-ready-features.adoc +++ b/spring-boot-docs/src/main/asciidoc/production-ready-features.adoc @@ -5,8 +5,8 @@ -- Spring Boot includes a number of additional features to help you monitor and manage your application when it's pushed to production. You can choose to manage and monitor your -application using HTTP endpoints, with JMX or even by remote shell (SSH or Telnet). -Auditing, health and metrics gathering can be automatically applied to your application. +application using HTTP endpoints or with JMX. Auditing, health and metrics gathering can +be automatically applied to your application. Actuator HTTP endpoints are only available with a Spring MVC-based application. In particular, it will not work with Jersey < - org.springframework.boot - spring-boot-starter-remote-shell - ----- - -TIP: If you want to also enable telnet access you will additionally need a dependency -on `org.crsh:crsh.shell.telnet`. - -NOTE: CRaSH requires to run with a JDK as it compiles commands on the fly. If a basic -`help` command fails, you are probably running with a JRE. - - -[[production-ready-connecting-to-the-remote-shell]] -=== Connecting to the remote shell -By default the remote shell will listen for connections on port `2000`. The default user -is `user` and the default password will be randomly generated and displayed in the log -output. If your application is using Spring Security, the shell will use -<> by default. If not, a simple -authentication will be applied and you should see a message like this: - -[indent=0] ----- - Using default password for shell access: ec03e16c-4cf4-49ee-b745-7c8255c1dd7e ----- - -Linux and OSX users can use `ssh` to connect to the remote shell, Windows users can -download and install http://www.putty.org/[PuTTY]. - -[indent=0,subs="attributes"] ----- - $ ssh -p 2000 user@localhost - - user@localhost's password: - . ____ _ __ _ _ - /\\ / ___'_ __ _ _(_)_ __ __ _ \ \ \ \ - ( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \ - \\/ ___)| |_)| | | | | || (_| | ) ) ) ) - ' |____| .__|_| |_|_| |_\__, | / / / / - =========|_|==============|___/=/_/_/_/ - :: Spring Boot :: (v{spring-boot-version}) on myhost ----- - -Type `help` for a list of commands. Spring Boot provides `metrics`, `beans`, `autoconfig` -and `endpoint` commands. - - - -[[production-ready-remote-shell-credentials]] -==== Remote shell credentials -You can use the `management.shell.auth.simple.user.name` and -`management.shell.auth.simple.user.password` properties to configure custom connection -credentials. It is also possible to use a '`Spring Security`' `AuthenticationManager` to -handle login duties. See the -{dc-spring-boot-actuator}/autoconfigure/CrshAutoConfiguration.{dc-ext}[`CrshAutoConfiguration`] -and {dc-spring-boot-actuator}/autoconfigure/ShellProperties.{dc-ext}[`ShellProperties`] -Javadoc for full details. - - - -[[production-ready-extending-the-remote-shell]] -=== Extending the remote shell -The remote shell can be extended in a number of interesting ways. - - - -[[production-ready-remote-commands]] -==== Remote shell commands -You can write additional shell commands using Groovy or Java (see the CRaSH documentation -for details). By default Spring Boot will search for commands in the following locations: - -* `+classpath*:/commands/**+` -* `+classpath*:/crash/commands/**+` - -TIP: You can change the search path by settings a `shell.command-path-patterns` property. - -NOTE: If you are using an executable archive, any classes that a shell command depends -upon must be packaged in a nested jar rather than directly in the executable jar or war. - -Here is a simple '`hello`' command that could be loaded from -`src/main/resources/commands/hello.groovy` - -[source,groovy,indent=0] ----- - package commands - - import org.crsh.cli.Command - import org.crsh.cli.Usage - import org.crsh.command.InvocationContext - - class hello { - - @Usage("Say Hello") - @Command - def main(InvocationContext context) { - return "Hello" - } - - } ----- - -Spring Boot adds some additional attributes to `InvocationContext` that you can access -from your command: - -[cols="2,3"] -|=== -| Attribute Name | Description - -|`spring.boot.version` -|The version of Spring Boot - -|`spring.version` -|The version of the core Spring Framework - -|`spring.beanfactory` -|Access to the Spring `BeanFactory` - -|`spring.environment` -|Access to the Spring `Environment` -|=== - - - -[[production-ready-remote-shell-plugins]] -==== Remote shell plugins -In addition to new commands, it is also possible to extend other CRaSH shell features. -All Spring Beans that extend `org.crsh.plugin.CRaSHPlugin` will be automatically -registered with the shell. - -For more information please refer to the http://www.crashub.org/[CRaSH reference -documentation]. - - - [[production-ready-metrics]] == Metrics Spring Boot Actuator includes a metrics service with '`gauge`' and '`counter`' support. diff --git a/spring-boot-docs/src/main/groovy/generateStarterTables.groovy b/spring-boot-docs/src/main/groovy/generateStarterTables.groovy index 82c27a6d27..967ab6433a 100644 --- a/spring-boot-docs/src/main/groovy/generateStarterTables.groovy +++ b/spring-boot-docs/src/main/groovy/generateStarterTables.groovy @@ -29,7 +29,7 @@ boolean isTechnicalStarter(def starter) { } boolean isProductionStarter(def starter) { - starter.name in ['spring-boot-starter-actuator', 'spring-boot-starter-remote-shell'] + starter.name in ['spring-boot-starter-actuator'] } boolean isStarter(def dependencies) { diff --git a/spring-boot-samples/spring-boot-sample-actuator-log4j2/src/main/resources/application.properties b/spring-boot-samples/spring-boot-sample-actuator-log4j2/src/main/resources/application.properties index 23b700c536..49b66eab6f 100644 --- a/spring-boot-samples/spring-boot-sample-actuator-log4j2/src/main/resources/application.properties +++ b/spring-boot-samples/spring-boot-sample-actuator-log4j2/src/main/resources/application.properties @@ -2,14 +2,6 @@ #server.port=8080 #management.port=8080 management.address=127.0.0.1 -management.shell.ssh.enabled=true -management.shell.ssh.port=2222 -#management.shell.telnet.enabled=false -#management.shell.telnet.port=1111 -management.shell.auth.type=spring -#management.shell.auth.type=key -#management.shell.auth.key.path=${user.home}/test/id_rsa.pub.pem -#management.shell.auth.type=simple endpoints.shutdown.enabled=true server.tomcat.basedir=target/tomcat diff --git a/spring-boot-samples/spring-boot-sample-actuator-noweb/pom.xml b/spring-boot-samples/spring-boot-sample-actuator-noweb/pom.xml index 3b25e9b693..f9ef72f3bd 100644 --- a/spring-boot-samples/spring-boot-sample-actuator-noweb/pom.xml +++ b/spring-boot-samples/spring-boot-sample-actuator-noweb/pom.xml @@ -23,10 +23,6 @@ org.springframework.boot spring-boot-starter-actuator - - org.springframework.boot - spring-boot-starter-remote-shell - org.springframework.boot spring-boot-starter-test diff --git a/spring-boot-samples/spring-boot-sample-actuator-noweb/src/main/resources/application.properties b/spring-boot-samples/spring-boot-sample-actuator-noweb/src/main/resources/application.properties index b7fe4cf9e3..64d1c0743e 100644 --- a/spring-boot-samples/spring-boot-sample-actuator-noweb/src/main/resources/application.properties +++ b/spring-boot-samples/spring-boot-sample-actuator-noweb/src/main/resources/application.properties @@ -1,6 +1 @@ service.name=Phil - -management.shell.ssh.enabled=true -management.shell.ssh.port=2222 -management.shell.auth.type=simple -management.shell.auth.simple.user.password=password diff --git a/spring-boot-samples/spring-boot-sample-actuator/pom.xml b/spring-boot-samples/spring-boot-sample-actuator/pom.xml index c19b9e4900..73b57036ac 100644 --- a/spring-boot-samples/spring-boot-sample-actuator/pom.xml +++ b/spring-boot-samples/spring-boot-sample-actuator/pom.xml @@ -35,10 +35,6 @@ org.springframework.boot spring-boot-starter-jdbc - - org.springframework.boot - spring-boot-starter-remote-shell - com.h2database h2 @@ -48,20 +44,6 @@ spring-boot-starter-test test - diff --git a/spring-boot-samples/spring-boot-sample-actuator/src/main/resources/application.properties b/spring-boot-samples/spring-boot-sample-actuator/src/main/resources/application.properties index 01a63220a3..a14be4eb4b 100644 --- a/spring-boot-samples/spring-boot-sample-actuator/src/main/resources/application.properties +++ b/spring-boot-samples/spring-boot-sample-actuator/src/main/resources/application.properties @@ -2,14 +2,6 @@ # logging.level.org.springframework.security=DEBUG management.address=127.0.0.1 #management.port=8181 -management.shell.ssh.enabled=true -management.shell.ssh.port=2222 -#management.shell.telnet.enabled=false -#management.shell.telnet.port=1111 -management.shell.auth.type=spring -#management.shell.auth.type=key -#management.shell.auth.key.path=${user.home}/test/id_rsa.pub.pem -#management.shell.auth.type=simple management.info.build.mode=full diff --git a/spring-boot-starters/pom.xml b/spring-boot-starters/pom.xml index 6fd74b59ce..6dda14cb0d 100644 --- a/spring-boot-starters/pom.xml +++ b/spring-boot-starters/pom.xml @@ -60,7 +60,6 @@ spring-boot-starter-social-facebook spring-boot-starter-social-twitter spring-boot-starter-social-linkedin - spring-boot-starter-remote-shell spring-boot-starter-test spring-boot-starter-thymeleaf spring-boot-starter-tomcat diff --git a/spring-boot-starters/spring-boot-starter-remote-shell/pom.xml b/spring-boot-starters/spring-boot-starter-remote-shell/pom.xml deleted file mode 100644 index 980da7afc6..0000000000 --- a/spring-boot-starters/spring-boot-starter-remote-shell/pom.xml +++ /dev/null @@ -1,142 +0,0 @@ - - - 4.0.0 - - org.springframework.boot - spring-boot-starters - 2.0.0.BUILD-SNAPSHOT - - spring-boot-starter-remote-shell - spring-boot-starter-remote-shell (DEPRECATED) - Starter for using the CRaSH remote shell to monitor and manage your - application over SSH. Deprecated since 1.5 - http://projects.spring.io/spring-boot/ - - Pivotal Software, Inc. - http://www.spring.io - - - ${basedir}/../.. - - - - org.springframework.boot - spring-boot-starter - - - org.springframework.boot - spring-boot-starter-actuator - - - org.crashub - crash.cli - - - org.crashub - crash.connectors.ssh - - - org.codehaus.groovy - groovy-all - - - - - org.crashub - crash.connectors.telnet - - - javax.servlet - servlet-api - - - log4j - log4j - - - commons-logging - commons-logging - - - true - - - org.crashub - crash.embed.spring - - - spring-web - org.springframework - - - org.codehaus.groovy - groovy-all - - - - - org.crashub - crash.plugins.cron - - - org.codehaus.groovy - groovy-all - - - - - org.crashub - crash.plugins.mail - - - org.codehaus.groovy - groovy-all - - - javax.mail - mail - - - - - org.crashub - crash.shell - - - org.codehaus.groovy - groovy-all - - - - - org.codehaus.groovy - groovy - - - com.sun.mail - javax.mail - - - - - - org.basepom.maven - duplicate-finder-maven-plugin - - - duplicate-dependencies - validate - - check - - - - crash/crash.properties - - - - - - - - diff --git a/spring-boot-starters/spring-boot-starter-remote-shell/src/main/java/org/springframework/boot/starter/remote/shell/RemoteShellStarterDeprecatedWarningAutoConfiguration.java b/spring-boot-starters/spring-boot-starter-remote-shell/src/main/java/org/springframework/boot/starter/remote/shell/RemoteShellStarterDeprecatedWarningAutoConfiguration.java deleted file mode 100644 index acb14e8702..0000000000 --- a/spring-boot-starters/spring-boot-starter-remote-shell/src/main/java/org/springframework/boot/starter/remote/shell/RemoteShellStarterDeprecatedWarningAutoConfiguration.java +++ /dev/null @@ -1,49 +0,0 @@ -/* - * Copyright 2012-2016 the original author or authors. - * - * 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. - */ - -package org.springframework.boot.starter.remote.shell; - -import javax.annotation.PostConstruct; - -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; - -import org.springframework.boot.autoconfigure.EnableAutoConfiguration; -import org.springframework.context.annotation.Configuration; - -/** - * {@link EnableAutoConfiguration Auto-configuration} to print a deprecation warning about - * the starter. - * - * @author Stephane Nicoll - * @since 1.4.0 - */ -@Configuration -@Deprecated -public class RemoteShellStarterDeprecatedWarningAutoConfiguration { - - private static final Log logger = LogFactory - .getLog(RemoteShellStarterDeprecatedWarningAutoConfiguration.class); - - @PostConstruct - public void logWarning() { - logger.warn("spring-boot-starter-remote-shell is deprecated since Spring Boot " + - "1.5 and will be removed in Spring Boot 2.0"); - } - -} - - diff --git a/spring-boot-starters/spring-boot-starter-remote-shell/src/main/resources/META-INF/spring.factories b/spring-boot-starters/spring-boot-starter-remote-shell/src/main/resources/META-INF/spring.factories deleted file mode 100644 index aa178205ab..0000000000 --- a/spring-boot-starters/spring-boot-starter-remote-shell/src/main/resources/META-INF/spring.factories +++ /dev/null @@ -1,2 +0,0 @@ -org.springframework.boot.autoconfigure.EnableAutoConfiguration=\ -org.springframework.boot.starter.remote.shell.RemoteShellStarterDeprecatedWarningAutoConfiguration \ No newline at end of file diff --git a/spring-boot-starters/spring-boot-starter-remote-shell/src/main/resources/META-INF/spring.provides b/spring-boot-starters/spring-boot-starter-remote-shell/src/main/resources/META-INF/spring.provides deleted file mode 100644 index 22bf5ab66a..0000000000 --- a/spring-boot-starters/spring-boot-starter-remote-shell/src/main/resources/META-INF/spring.provides +++ /dev/null @@ -1 +0,0 @@ -provides: crash.cli,crash.shell,crash.plugins.cron,crash.embed.spring,crash.connectors.ssh \ No newline at end of file diff --git a/spring-boot-starters/spring-boot-starter-remote-shell/src/main/resources/commands/crash/autoconfig.groovy b/spring-boot-starters/spring-boot-starter-remote-shell/src/main/resources/commands/crash/autoconfig.groovy deleted file mode 100644 index 3f4dc27bee..0000000000 --- a/spring-boot-starters/spring-boot-starter-remote-shell/src/main/resources/commands/crash/autoconfig.groovy +++ /dev/null @@ -1,29 +0,0 @@ -package commands - -import org.springframework.boot.actuate.endpoint.AutoConfigurationReportEndpoint - -class autoconfig { - - @Usage("Display auto configuration report from ApplicationContext") - @Command - void main(InvocationContext context) { - context.attributes['spring.beanfactory'].getBeansOfType(AutoConfigurationReportEndpoint.class).each { name, endpoint -> - def report = endpoint.invoke() - out.println "Endpoint: " + name + "\n\nPositive Matches:\n================\n" - report.positiveMatches.each { key, list -> - out.println key + ":" - list.each { mandc -> - out.println " " + mandc.condition + ": " + mandc.message - } - } - out.println "\nNegative Matches\n================\n" - report.negativeMatches.each { key, list -> - out.println key + ":" - list.each { mandc -> - out.println " " + mandc.condition + ": " + mandc.message - } - } - } - } - -} \ No newline at end of file diff --git a/spring-boot-starters/spring-boot-starter-remote-shell/src/main/resources/commands/crash/beans.groovy b/spring-boot-starters/spring-boot-starter-remote-shell/src/main/resources/commands/crash/beans.groovy deleted file mode 100644 index 67fea1cada..0000000000 --- a/spring-boot-starters/spring-boot-starter-remote-shell/src/main/resources/commands/crash/beans.groovy +++ /dev/null @@ -1,17 +0,0 @@ -package commands - -import org.springframework.boot.actuate.endpoint.BeansEndpoint - -class beans { - - @Usage("Display beans in ApplicationContext") - @Command - def main(InvocationContext context) { - def result = [:] - context.attributes['spring.beanfactory'].getBeansOfType(BeansEndpoint.class).each { name, endpoint -> - result.put(name, endpoint.invoke()) - } - result.size() == 1 ? result.values()[0] : result - } - -} \ No newline at end of file diff --git a/spring-boot-starters/spring-boot-starter-remote-shell/src/main/resources/commands/crash/endpoint.groovy b/spring-boot-starters/spring-boot-starter-remote-shell/src/main/resources/commands/crash/endpoint.groovy deleted file mode 100644 index d27c2cc83c..0000000000 --- a/spring-boot-starters/spring-boot-starter-remote-shell/src/main/resources/commands/crash/endpoint.groovy +++ /dev/null @@ -1,46 +0,0 @@ -package commands - -import org.springframework.boot.actuate.endpoint.Endpoint -import org.springframework.boot.actuate.endpoint.jmx.* - -@Usage("Invoke actuator endpoints") -class endpoint { - - @Usage("List all available and enabled actuator endpoints") - @Command - def list(InvocationContext context) { - - context.attributes['spring.beanfactory'].getBeansOfType(Endpoint.class).each { name, endpoint -> - if (endpoint.isEnabled()) { - out.println name - } - } - "" - } - - @Usage("Invoke provided actuator endpoint") - @Command - def invoke(InvocationContext context, @Usage("The name of the Endpoint to invoke") @Required @Argument String name) { - - // Don't require passed argument to end with 'Endpoint' - if (!name.endsWith("Endpoint")) { - name = name + "Endpoint" - } - - context.attributes['spring.beanfactory'].getBeansOfType(Endpoint.class).each { n, endpoint -> - if (n.equals(name) && endpoint.isEnabled()) { - - EndpointMBean mbean = context.attributes['spring.beanfactory'].getBean(EndpointMBeanExporter.class).getEndpointMBean(name, endpoint) - if (mbean instanceof DataEndpointMBean) { - out.println mbean.getData() - } - else { - out.println mbean.endpoint.invoke() - } - - } - } - "" - } - -} diff --git a/spring-boot-starters/spring-boot-starter-remote-shell/src/main/resources/commands/crash/login.groovy b/spring-boot-starters/spring-boot-starter-remote-shell/src/main/resources/commands/crash/login.groovy deleted file mode 100644 index 465bd4a012..0000000000 --- a/spring-boot-starters/spring-boot-starter-remote-shell/src/main/resources/commands/crash/login.groovy +++ /dev/null @@ -1,48 +0,0 @@ -welcome = { -> - - def environment = crash.context.attributes['spring.environment'] - def propertyResolver = new org.springframework.boot.bind.RelaxedPropertyResolver(environment, "spring.main."); - def beanFactory = crash.context.attributes['spring.beanfactory'] - - if (!propertyResolver.getProperty("show-banner", Boolean.class, Boolean.TRUE)) { - return "" - } - - // Try to print using the banner interface - if (beanFactory != null) { - try { - def banner = beanFactory.getBean("springBootBanner") - def out = new java.io.ByteArrayOutputStream() - banner.printBanner(environment, null, new java.io.PrintStream(out)) - return out.toString() - } catch (Exception ex) { - // Ignore - } - } - - // Resolve hostname - def hostName; - try { - hostName = java.net.InetAddress.getLocalHost().getHostName(); - } - catch (java.net.UnknownHostException ignore) { - hostName = "localhost"; - } - - // Get Spring Boot version from context - def version = crash.context.attributes.get("spring.boot.version") - - return """\ - . ____ _ __ _ _ - /\\\\ / ___'_ __ _ _(_)_ __ __ _ \\ \\ \\ \\ -( ( )\\___ | '_ | '_| | '_ \\/ _` | \\ \\ \\ \\ - \\\\/ ___)| |_)| | | | | || (_| | ) ) ) ) - ' |____| .__|_| |_|_| |_\\__, | / / / / - =========|_|==============|___/=/_/_/_/ - :: Spring Boot :: (v$version) on $hostName -"""; -} - -prompt = { -> - return "> "; -} diff --git a/spring-boot-starters/spring-boot-starter-remote-shell/src/main/resources/commands/crash/metrics.groovy b/spring-boot-starters/spring-boot-starter-remote-shell/src/main/resources/commands/crash/metrics.groovy deleted file mode 100644 index 3fffed92f3..0000000000 --- a/spring-boot-starters/spring-boot-starter-remote-shell/src/main/resources/commands/crash/metrics.groovy +++ /dev/null @@ -1,49 +0,0 @@ -package commands - -import org.crsh.text.ui.UIBuilder -import org.springframework.boot.actuate.endpoint.MetricsEndpoint - -class metrics { - - @Usage("Display metrics provided by Spring Boot") - @Command - public void main(InvocationContext context) { - - context.takeAlternateBuffer(); - try { - while (!Thread.interrupted()) { - out.cls() - out.show(new UIBuilder().table(columns:[1]) { - header { - table(columns:[1], separator: dashed) { - header(bold: true, fg: black, bg: white) { label("metrics"); } - } - } - row { - table(columns:[1, 1]) { - header(bold: true, fg: black, bg: white) { - label("NAME") - label("VALUE") - } - - context.attributes['spring.beanfactory'].getBeansOfType(MetricsEndpoint.class).each { name, metrics -> - metrics.invoke().each { k, v -> - row { - label(k) - label(v) - } - } - } - } - } - } - ); - out.flush(); - Thread.sleep(1000); - } - } - finally { - context.releaseAlternateBuffer(); - } - } -} \ No newline at end of file diff --git a/spring-boot/src/main/java/org/springframework/boot/logging/logback/DefaultLogbackConfiguration.java b/spring-boot/src/main/java/org/springframework/boot/logging/logback/DefaultLogbackConfiguration.java index 0c5b831271..bb715c31c3 100644 --- a/spring-boot/src/main/java/org/springframework/boot/logging/logback/DefaultLogbackConfiguration.java +++ b/spring-boot/src/main/java/org/springframework/boot/logging/logback/DefaultLogbackConfiguration.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2015 the original author or authors. + * Copyright 2012-2016 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -101,12 +101,8 @@ class DefaultLogbackConfiguration { config.logger("org.apache.coyote.http11.Http11NioProtocol", Level.WARN); config.logger("org.apache.sshd.common.util.SecurityUtils", Level.WARN); config.logger("org.apache.tomcat.util.net.NioSelectorPool", Level.WARN); - config.logger("org.crsh.plugin", Level.WARN); - config.logger("org.crsh.ssh", Level.WARN); config.logger("org.eclipse.jetty.util.component.AbstractLifeCycle", Level.ERROR); config.logger("org.hibernate.validator.internal.util.Version", Level.WARN); - config.logger("org.springframework.boot.actuate.autoconfigure." - + "CrshAutoConfiguration", Level.WARN); config.logger("org.springframework.boot.actuate.endpoint.jmx", null, false, debugRemapAppender); config.logger("org.thymeleaf", null, false, debugRemapAppender); diff --git a/spring-boot/src/main/resources/org/springframework/boot/logging/java/logging-file.properties b/spring-boot/src/main/resources/org/springframework/boot/logging/java/logging-file.properties index f37a4a153d..33d492e9af 100644 --- a/spring-boot/src/main/resources/org/springframework/boot/logging/java/logging-file.properties +++ b/spring-boot/src/main/resources/org/springframework/boot/logging/java/logging-file.properties @@ -13,7 +13,6 @@ java.util.logging.ConsoleHandler.level = ALL org.hibernate.validator.internal.util.Version.level = WARNING org.apache.coyote.http11.Http11NioProtocol.level = WARNING -org.crsh.plugin.level = WARNING org.apache.tomcat.util.net.NioSelectorPool.level = WARNING org.apache.catalina.startup.DigesterFactory.level = SEVERE org.apache.catalina.util.LifecycleBase.level = SEVERE diff --git a/spring-boot/src/main/resources/org/springframework/boot/logging/java/logging.properties b/spring-boot/src/main/resources/org/springframework/boot/logging/java/logging.properties index 96fe648503..70a31b86a1 100644 --- a/spring-boot/src/main/resources/org/springframework/boot/logging/java/logging.properties +++ b/spring-boot/src/main/resources/org/springframework/boot/logging/java/logging.properties @@ -6,7 +6,6 @@ java.util.logging.ConsoleHandler.level = ALL org.hibernate.validator.internal.util.Version.level = WARNING org.apache.coyote.http11.Http11NioProtocol.level = WARNING -org.crsh.plugin.level = WARNING org.apache.tomcat.util.net.NioSelectorPool.level = WARNING org.apache.catalina.startup.DigesterFactory.level = SEVERE org.apache.catalina.util.LifecycleBase.level = SEVERE diff --git a/spring-boot/src/main/resources/org/springframework/boot/logging/log4j2/log4j2-file.xml b/spring-boot/src/main/resources/org/springframework/boot/logging/log4j2/log4j2-file.xml index a97cf4065e..4aae1f1b80 100644 --- a/spring-boot/src/main/resources/org/springframework/boot/logging/log4j2/log4j2-file.xml +++ b/spring-boot/src/main/resources/org/springframework/boot/logging/log4j2/log4j2-file.xml @@ -25,11 +25,8 @@ - - - diff --git a/spring-boot/src/main/resources/org/springframework/boot/logging/log4j2/log4j2.xml b/spring-boot/src/main/resources/org/springframework/boot/logging/log4j2/log4j2.xml index dace970e8c..840c27020d 100644 --- a/spring-boot/src/main/resources/org/springframework/boot/logging/log4j2/log4j2.xml +++ b/spring-boot/src/main/resources/org/springframework/boot/logging/log4j2/log4j2.xml @@ -17,11 +17,8 @@ - - - diff --git a/spring-boot/src/main/resources/org/springframework/boot/logging/logback/defaults.xml b/spring-boot/src/main/resources/org/springframework/boot/logging/logback/defaults.xml index 70af71b451..cda257539b 100644 --- a/spring-boot/src/main/resources/org/springframework/boot/logging/logback/defaults.xml +++ b/spring-boot/src/main/resources/org/springframework/boot/logging/logback/defaults.xml @@ -21,11 +21,8 @@ initialization performed by Boot - - -