package com.sequenceiq.cloudbreak.shell.commands.common; import java.io.File; import java.io.FileInputStream; import java.util.HashMap; import java.util.Map; import java.util.Set; import org.apache.commons.io.IOUtils; import org.springframework.shell.core.annotation.CliAvailabilityIndicator; import org.springframework.shell.core.annotation.CliCommand; import org.springframework.shell.core.annotation.CliOption; import com.sequenceiq.cloudbreak.api.model.SssdConfigRequest; import com.sequenceiq.cloudbreak.api.model.SssdConfigResponse; import com.sequenceiq.cloudbreak.shell.commands.BaseCommands; import com.sequenceiq.cloudbreak.shell.completion.SssdProviderType; import com.sequenceiq.cloudbreak.shell.completion.SssdSchemaType; import com.sequenceiq.cloudbreak.shell.completion.SssdTlsReqcertType; import com.sequenceiq.cloudbreak.shell.model.OutPutType; import com.sequenceiq.cloudbreak.shell.model.ShellContext; public class SssdConfigCommands implements BaseCommands { private ShellContext shellContext; public SssdConfigCommands(ShellContext shellContext) { this.shellContext = shellContext; } @CliAvailabilityIndicator(value = "sssdconfig list") @Override public boolean listAvailable() { return true; } @CliCommand(value = "sssdconfig list", help = "Shows the currently available configs") @Override public String list() { try { Set<SssdConfigResponse> publics = shellContext.cloudbreakClient().sssdConfigEndpoint().getPublics(); return shellContext.outputTransformer().render(shellContext.responseTransformer().transformToMap(publics, "id", "name"), "ID", "INFO"); } catch (Exception ex) { throw shellContext.exceptionTransformer().transformToRuntimeException(ex); } } @CliAvailabilityIndicator(value = { "sssdconfig select --id", "sssdconfig select --name" }) @Override public boolean selectAvailable() { return shellContext.isSssdConfigAccessible(); } @CliCommand(value = "sssdconfig select --id", help = "Select the config by its id") @Override public String selectById(@CliOption(key = "", mandatory = true) Long id) throws Exception { return select(id, null); } @CliCommand(value = "sssdconfig select --name", help = "Select the config by its name") @Override public String selectByName(@CliOption(key = "", mandatory = true) String name) throws Exception { return select(null, name); } @Override public String select(Long id, String name) { try { if (id != null) { if (shellContext.cloudbreakClient().sssdConfigEndpoint().get(id) != null) { shellContext.addSssdConfig(id.toString()); return String.format("SSSD config has been selected, id: %s", id); } } else if (name != null) { SssdConfigResponse config = shellContext.cloudbreakClient().sssdConfigEndpoint().getPublic(name); if (config != null) { shellContext.addSssdConfig(config.getId().toString()); return String.format("SSSD config has been selected, name: %s", name); } } throw shellContext.exceptionTransformer().transformToRuntimeException("No SSSD config specified (select a config by --id or --name)"); } catch (Exception ex) { throw shellContext.exceptionTransformer().transformToRuntimeException(ex); } } @CliAvailabilityIndicator(value = { "sssdconfig create --withParameters", "sssdconfig create --withFile" }) public boolean createAvailable() { return true; } @CliCommand(value = "sssdconfig create --withParameters", help = "Add a new config") public String create( @CliOption(key = "name", mandatory = true, help = "Name of the config") String name, @CliOption(key = "description", help = "Description of the config") String description, @CliOption(key = "providerType", mandatory = true, help = "Type of the provider") SssdProviderType providerType, @CliOption(key = "url", mandatory = true, help = "comma-separated list of URIs of the LDAP servers") String url, @CliOption(key = "schema", mandatory = true, help = "Schema of the database") SssdSchemaType schema, @CliOption(key = "baseSearch", mandatory = true, help = "Search base of the database") String baseSearch, @CliOption(key = "tlsReqcert", unspecifiedDefaultValue = "hard", specifiedDefaultValue = "hard", help = "TLS behavior of connection") SssdTlsReqcertType tlsReqcert, @CliOption(key = "adServer", help = "comma-separated list of IP addresses or hostnames of the AD servers") String adServer, @CliOption(key = "kerberosServer", help = "comma-separated list of IP addresses or hostnames of the Kerberos servers") String kerberosServer, @CliOption(key = "kerberosRealm", help = "name of the Kerberos realm") String kerberosRealm, @CliOption(key = "publicInAccount", unspecifiedDefaultValue = "false", specifiedDefaultValue = "true", help = "flags if the config is public in the account") Boolean publicInAccount) { try { SssdConfigRequest request = new SssdConfigRequest(); request.setName(name); request.setDescription(description); request.setProviderType(com.sequenceiq.cloudbreak.api.model.SssdProviderType.valueOf(providerType.getName())); request.setUrl(url); request.setSchema(com.sequenceiq.cloudbreak.api.model.SssdSchemaType.valueOf(schema.getName())); request.setBaseSearch(baseSearch); request.setTlsReqcert(com.sequenceiq.cloudbreak.api.model.SssdTlsReqcertType.valueOf(tlsReqcert.getName())); request.setAdServer(adServer); request.setKerberosServer(kerberosServer); request.setKerberosRealm(kerberosRealm); Long id; if (publicInAccount) { id = shellContext.cloudbreakClient().sssdConfigEndpoint().postPublic(request).getId(); } else { id = shellContext.cloudbreakClient().sssdConfigEndpoint().postPrivate(request).getId(); } return String.format("SSSD config created with id: '%d' and name: '%s'", id, request.getName()); } catch (Exception ex) { throw shellContext.exceptionTransformer().transformToRuntimeException(ex); } } @CliCommand(value = "sssdconfig create --withFile", help = "Upload a new config") public String upload( @CliOption(key = "name", mandatory = true, help = "Name of the config") String name, @CliOption(key = "description", help = "Description of the config") String description, @CliOption(key = "file", mandatory = true, help = "Path of the configuration file") File configFile, @CliOption(key = "publicInAccount", unspecifiedDefaultValue = "false", specifiedDefaultValue = "true", help = "flags if the config is public in the account") Boolean publicInAccount) { try { if (configFile != null && !configFile.exists()) { throw shellContext.exceptionTransformer().transformToRuntimeException("Configuration file not exists"); } SssdConfigRequest request = new SssdConfigRequest(); request.setName(name); request.setDescription(description); String config = IOUtils.toString(new FileInputStream(configFile)); request.setConfiguration(config); Long id; if (publicInAccount) { id = shellContext.cloudbreakClient().sssdConfigEndpoint().postPublic(request).getId(); } else { id = shellContext.cloudbreakClient().sssdConfigEndpoint().postPrivate(request).getId(); } return String.format("SSSD config created with id: '%d' and name: '%s'", id, request.getName()); } catch (Exception ex) { throw shellContext.exceptionTransformer().transformToRuntimeException(ex); } } @CliAvailabilityIndicator(value = { "sssdconfig show --id", "sssdconfig show --name" }) @Override public boolean showAvailable() { return true; } @Override public String show(Long id, String name, OutPutType outPutType) { try { outPutType = outPutType == null ? OutPutType.RAW : outPutType; SssdConfigResponse response; if (id != null) { response = shellContext.cloudbreakClient().sssdConfigEndpoint().get(id); } else if (name != null) { response = shellContext.cloudbreakClient().sssdConfigEndpoint().getPublic(name); } else { throw shellContext.exceptionTransformer().transformToRuntimeException("SSSD config not specified"); } Map<String, String> map = new HashMap<>(); map.put("id", response.getId().toString()); map.put("name", response.getName()); map.put("description", response.getDescription()); return shellContext.outputTransformer().render(outPutType, map, "FIELD", "INFO"); } catch (Exception ex) { throw shellContext.exceptionTransformer().transformToRuntimeException(ex); } } @CliCommand(value = "sssdconfig show --id", help = "Show the config by its id") @Override public String showById( @CliOption(key = "", mandatory = true) Long id, @CliOption(key = "outputType", help = "OutputType of the response") OutPutType outPutType) throws Exception { return show(id, null, outPutType); } @CliCommand(value = "sssdconfig show --name", help = "Show the config by its name") @Override public String showByName( @CliOption(key = "", mandatory = true) String name, @CliOption(key = "outputType", help = "OutputType of the response") OutPutType outPutType) throws Exception { return show(null, name, outPutType); } @CliAvailabilityIndicator(value = { "sssdconfig delete --id", "sssdconfig delete --name" }) @Override public boolean deleteAvailable() { return true; } @Override public String delete(Long id, String name) { try { if (id != null) { shellContext.cloudbreakClient().sssdConfigEndpoint().delete(id); return String.format("SSSD config deleted with %s id", id); } else if (name != null) { shellContext.cloudbreakClient().sssdConfigEndpoint().deletePublic(name); return String.format("SSSD config deleted with %s name", name); } throw shellContext.exceptionTransformer().transformToRuntimeException("SSSD config not specified (select sssd by --id or --name)"); } catch (Exception ex) { throw shellContext.exceptionTransformer().transformToRuntimeException(ex); } } @CliCommand(value = "sssdconfig delete --id", help = "Delete the config by its id") @Override public String deleteById(@CliOption(key = "", mandatory = true) Long id) throws Exception { return delete(id, null); } @CliCommand(value = "sssdconfig delete --name", help = "Delete the config by its name") @Override public String deleteByName(@CliOption(key = "", mandatory = true) String name) throws Exception { return delete(null, name); } @Override public ShellContext shellContext() { return shellContext; } }