package com.sequenceiq.cloudbreak.shell.commands.common;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
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.LdapConfigRequest;
import com.sequenceiq.cloudbreak.api.model.LdapConfigResponse;
import com.sequenceiq.cloudbreak.shell.commands.BaseCommands;
import com.sequenceiq.cloudbreak.shell.model.OutPutType;
import com.sequenceiq.cloudbreak.shell.model.ShellContext;
public class LdapConfigCommands implements BaseCommands {
private ShellContext shellContext;
public LdapConfigCommands(ShellContext shellContext) {
this.shellContext = shellContext;
}
@CliAvailabilityIndicator(value = { "ldapconfig create" })
public boolean createAvailable() {
return true;
}
@CliCommand(value = "ldapconfig create", help = "Adds a new Ldap configuration")
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 = "serverHost", mandatory = true, help = "Public host or IP address of LDAP server") String serverHost,
@CliOption(key = "serverPort", mandatory = true, help = "Port of LDAP server (typically: 389 or 636 for LDAPS)") Integer serverPort,
@CliOption(key = "protocol", unspecifiedDefaultValue = "ldap",
help = "Determines if LDAP or LDAP over SSL is to be used") String protocol,
@CliOption(key = "bindDn", mandatory = true,
help = "Bind distinguished name for connection test and group search (e.g. cn=admin,dc=example,dc=org)") String bindDn,
@CliOption(key = "bindPassword", mandatory = true, help = "password for the provided bind DN") String bindPassword,
@CliOption(key = "userSearchBase", mandatory = true,
help = "template for user search for authentication (e.g. dc=hadoop,dc=apache,dc=org)") String userSearchBase,
@CliOption(key = "userSearchFilter",
help = "filter for user search for authentication (e.g. (&(objectclass=person)(sAMAccountName={2})) )") String userSearchFilter,
@CliOption(key = "groupSearchBase",
help = "template for group search for authorization (e.g. dc=hadoop,dc=apache,dc=org)") String groupSearchBase,
@CliOption(key = "groupSearchFilter", help = "filter for group search for authorization") String groupSearchFilter,
@CliOption(key = "principalRegex", help = "parses the principal for insertion into templates via regex.") String principalRegex,
@CliOption(key = "publicInAccount", unspecifiedDefaultValue = "false", specifiedDefaultValue = "true",
help = "flags if the config is public in the account") Boolean publicInAccount) {
try {
LdapConfigRequest config = new LdapConfigRequest();
config.setName(name);
config.setDescription(description);
config.setBindDn(bindDn);
config.setBindPassword(bindPassword);
config.setServerHost(serverHost);
config.setServerPort(serverPort);
config.setProtocol(protocol);
config.setGroupSearchBase(groupSearchBase);
config.setGroupSearchFilter(groupSearchFilter);
config.setUserSearchBase(userSearchBase);
config.setUserSearchFilter(userSearchFilter);
config.setPrincipalRegex(principalRegex);
Long id;
if (publicInAccount) {
id = shellContext.cloudbreakClient().ldapConfigEndpoint().postPublic(config).getId();
} else {
id = shellContext.cloudbreakClient().ldapConfigEndpoint().postPrivate(config).getId();
}
return String.format("Ldap config created with id: '%d' and name: '%s'", id, config.getName());
} catch (Exception e) {
throw shellContext.exceptionTransformer().transformToRuntimeException(e);
}
}
@Override
@CliAvailabilityIndicator(value = { "ldapconfig select --id", "ldapconfig select --name" })
public boolean selectAvailable() {
return true;
}
@Override
public String select(Long id, String name) throws Exception {
try {
if (id != null) {
if (shellContext.cloudbreakClient().ldapConfigEndpoint().get(id) != null) {
shellContext.addLdapConfig(id.toString());
return String.format("Ldap config has been selected, id: %s", id);
}
} else if (name != null) {
LdapConfigResponse config = shellContext.cloudbreakClient().ldapConfigEndpoint().getPublic(name);
if (config != null) {
shellContext.addLdapConfig(config.getId().toString());
return String.format("Ldap config has been selected, name: %s", name);
}
}
return "No LDAP config specified (select a config by --id or --name)";
} catch (Exception ex) {
throw shellContext.exceptionTransformer().transformToRuntimeException(ex);
}
}
@CliCommand(value = "ldapconfig select --id", help = "Selects the Ldap config by its id")
@Override
public String selectById(@CliOption(key = "", mandatory = true) Long id) throws Exception {
return select(id, null);
}
@CliCommand(value = "ldapconfig select --name", help = "Selects the Ldap config by its name")
@Override
public String selectByName(@CliOption(key = "", mandatory = true) String name) throws Exception {
return select(null, name);
}
@Override
public boolean showAvailable() {
return true;
}
@Override
public String show(Long id, String name, OutPutType outPutType) throws Exception {
try {
outPutType = outPutType == null ? OutPutType.RAW : outPutType;
LdapConfigResponse response;
if (id != null) {
response = shellContext.cloudbreakClient().ldapConfigEndpoint().get(id);
} else if (name != null) {
response = shellContext.cloudbreakClient().ldapConfigEndpoint().getPublic(name);
} else {
throw shellContext.exceptionTransformer().transformToRuntimeException("Ldap config not specified");
}
Map<String, String> map = new HashMap<>();
map.put("id", response.getId().toString());
map.put("name", response.getName());
map.put("serverHost", response.getServerHost());
map.put("serverPort", response.getServerPort().toString());
map.put("protocol", response.getProtocol());
map.put("bindDn", response.getBindDn());
map.put("userSearchBase", response.getUserSearchBase());
map.put("userSearchFilter", response.getUserSearchFilter());
map.put("groupSearchBase", response.getGroupSearchBase());
map.put("groupSearchFilter", response.getGroupSearchFilter());
return shellContext.outputTransformer().render(outPutType, map, "FIELD", "INFO");
} catch (Exception ex) {
throw shellContext.exceptionTransformer().transformToRuntimeException(ex);
}
}
@CliCommand(value = "ldapconfig show --id", help = "Show the Ldap 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 = "ldapconfig show --name", help = "Show the Ldap 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 = { "ldapconfig delete --id", "ldapconfig delete --name" })
@Override
public boolean deleteAvailable() {
return true;
}
@Override
public String delete(Long id, String name) throws Exception {
try {
if (id != null) {
shellContext.cloudbreakClient().ldapConfigEndpoint().delete(id);
return String.format("Ldap config deleted with %s id", id);
} else if (name != null) {
shellContext.cloudbreakClient().ldapConfigEndpoint().deletePublic(name);
return String.format("Ldap config deleted with %s name", name);
}
throw shellContext.exceptionTransformer().transformToRuntimeException("Ldap config not specified (select Ldap config with --id or --name)");
} catch (Exception ex) {
throw shellContext.exceptionTransformer().transformToRuntimeException(ex);
}
}
@CliCommand(value = "ldapconfig delete --id", help = "Deletes the Ldap config by its id")
@Override
public String deleteById(@CliOption(key = "", mandatory = true) Long id) throws Exception {
return delete(id, null);
}
@CliCommand(value = "ldapconfig delete --name", help = "Deletes the Ldap config by its name")
@Override
public String deleteByName(@CliOption(key = "", mandatory = true) String name) throws Exception {
return delete(null, name);
}
@CliAvailabilityIndicator(value = "ldapconfig list")
@Override
public boolean listAvailable() {
return true;
}
@CliCommand(value = "ldapconfig list", help = "Shows the currently available Ldap configurations")
@Override
public String list() {
try {
Set<LdapConfigResponse> publics = shellContext.cloudbreakClient().ldapConfigEndpoint().getPublics();
return shellContext.outputTransformer().render(shellContext.responseTransformer().transformToMap(publics, "id", "name"), "ID", "NAME");
} catch (Exception ex) {
throw shellContext.exceptionTransformer().transformToRuntimeException(ex);
}
}
@Override
public ShellContext shellContext() {
return shellContext;
}
}