package com.sequenceiq.cloudbreak.shell.commands.base;
import java.util.HashSet;
import java.util.Map;
import org.springframework.shell.core.CommandMarker;
import org.springframework.shell.core.annotation.CliAvailabilityIndicator;
import org.springframework.shell.core.annotation.CliCommand;
import org.springframework.shell.core.annotation.CliOption;
import com.google.common.primitives.Longs;
import com.sequenceiq.cloudbreak.api.model.RecoveryMode;
import com.sequenceiq.cloudbreak.api.model.SecurityGroupResponse;
import com.sequenceiq.cloudbreak.api.model.TemplateResponse;
import com.sequenceiq.cloudbreak.shell.commands.InstanceGroupCommands;
import com.sequenceiq.cloudbreak.shell.completion.InstanceGroup;
import com.sequenceiq.cloudbreak.shell.completion.InstanceGroupTemplateId;
import com.sequenceiq.cloudbreak.shell.completion.InstanceGroupTemplateName;
import com.sequenceiq.cloudbreak.shell.completion.SecurityGroupId;
import com.sequenceiq.cloudbreak.shell.completion.SecurityGroupName;
import com.sequenceiq.cloudbreak.shell.model.Hints;
import com.sequenceiq.cloudbreak.shell.model.HostgroupEntry;
import com.sequenceiq.cloudbreak.shell.model.InstanceGroupEntry;
import com.sequenceiq.cloudbreak.shell.model.ShellContext;
public class BaseInstanceGroupCommands implements CommandMarker, InstanceGroupCommands {
private ShellContext shellContext;
public BaseInstanceGroupCommands(ShellContext shellContext) {
this.shellContext = shellContext;
}
@CliAvailabilityIndicator(value = "instancegroup configure")
public boolean createAvailable() {
return (shellContext.isBlueprintAvailable() && shellContext.isCredentialAvailable())
&& !shellContext.isMarathonMode()
&& !shellContext.isYarnMode();
}
@CliAvailabilityIndicator(value = "instancegroup delete")
public boolean deleteAvailable() {
return (shellContext.isBlueprintAvailable() && shellContext.isCredentialAvailable())
&& !shellContext.isMarathonMode()
&& !shellContext.isYarnMode();
}
@CliAvailabilityIndicator(value = "instancegroup show")
public boolean showAvailable() {
return !shellContext.isMarathonMode() && !shellContext.isYarnMode();
}
@Override
public boolean createInstanceGroupAvailable(String platform) {
return shellContext.isCredentialAvailable() && shellContext.getActiveCloudPlatform().equals(platform);
}
@Override
public String create(InstanceGroup instanceGroup, Integer nodeCount, boolean ambariServer, InstanceGroupTemplateId instanceGroupTemplateId,
InstanceGroupTemplateName instanceGroupTemplateName, SecurityGroupId instanceGroupSecurityGroupId,
SecurityGroupName instanceGroupSecurityGroupName, Map<String, Object> parameters) {
try {
String templateId;
if (instanceGroupTemplateId != null) {
templateId = instanceGroupTemplateId.getName();
} else if (instanceGroupTemplateName != null) {
TemplateResponse aPublic = shellContext.cloudbreakClient().templateEndpoint().getPublic(instanceGroupTemplateName.getName());
if (aPublic != null) {
templateId = aPublic.getId().toString();
} else {
throw shellContext.exceptionTransformer().transformToRuntimeException(String.format("Template not found by name: %s",
instanceGroupTemplateName.getName()));
}
} else {
throw shellContext.exceptionTransformer().transformToRuntimeException(
"Template name or id is not defined for instanceGroup (use --templateName or --templateId)");
}
String securityGroupId;
if (instanceGroupSecurityGroupId != null) {
securityGroupId = instanceGroupSecurityGroupId.getName();
} else if (instanceGroupSecurityGroupName != null) {
SecurityGroupResponse aPublic = shellContext.cloudbreakClient().securityGroupEndpoint().getPublic(instanceGroupSecurityGroupName.getName());
if (aPublic != null) {
securityGroupId = aPublic.getId().toString();
} else {
throw shellContext.exceptionTransformer().transformToRuntimeException(String.format("SecurityGroup not found by name: %s",
instanceGroupSecurityGroupName.getName()));
}
} else {
throw shellContext.exceptionTransformer().transformToRuntimeException(
"SecurityGroup name or id is not defined for instanceGroup (use --securityGroupName or --securityGroupId)");
}
Long parsedTemplateId = Longs.tryParse(templateId);
Long parsedsecurityGroupId = Longs.tryParse(securityGroupId);
if (parsedTemplateId != null && parsedsecurityGroupId != null) {
if (ambariServer) {
boolean ambariSpecified = shellContext.getInstanceGroups().values()
.stream().filter(e -> e.getType().equals("GATEWAY")).findAny().isPresent();
if (ambariSpecified) {
for (Map.Entry<String, InstanceGroupEntry> stringInstanceGroupEntryEntry : shellContext.getInstanceGroups().entrySet()) {
shellContext.getInstanceGroups().get(stringInstanceGroupEntryEntry.getKey()).setType("CORE");
}
}
if (nodeCount != 1) {
throw shellContext.exceptionTransformer().transformToRuntimeException("Allowed node count for Ambari server: 1");
}
shellContext.putInstanceGroup(instanceGroup.getName(),
new InstanceGroupEntry(parsedTemplateId, parsedsecurityGroupId, nodeCount, "GATEWAY", parameters));
} else {
shellContext.putInstanceGroup(instanceGroup.getName(),
new InstanceGroupEntry(parsedTemplateId, parsedsecurityGroupId, nodeCount, "CORE", parameters));
}
shellContext.putHostGroup(instanceGroup.getName(), new HostgroupEntry(nodeCount, new HashSet<>(), RecoveryMode.MANUAL));
if (shellContext.getActiveHostGroups().size() == shellContext.getInstanceGroups().size()
&& shellContext.getActiveHostGroups().size() != 0) {
shellContext.setHint(Hints.SELECT_NETWORK);
} else {
shellContext.setHint(Hints.CONFIGURE_HOSTGROUP);
}
return shellContext.outputTransformer().render(shellContext.getInstanceGroups(), "instanceGroup");
} else {
throw shellContext.exceptionTransformer().transformToRuntimeException("TemplateId is not a number");
}
} catch (Exception ex) {
throw shellContext.exceptionTransformer().transformToRuntimeException(ex);
}
}
@CliCommand(value = "instancegroup show", help = "Show the currently available instance groups")
public String show() throws Exception {
if (shellContext.getInstanceGroups().isEmpty()) {
return "List of instance groups is empty currently";
} else {
return shellContext.outputTransformer().render(shellContext.getInstanceGroups(), "instanceGroup");
}
}
@CliCommand(value = "instancegroup delete", help = "Delete a currently available instance group")
public String delete(@CliOption(key = "name", help = "name of the instanceGroup", mandatory = true) String name) throws Exception {
if (shellContext.getInstanceGroups().isEmpty()) {
return "List of instance groups is empty currently";
} else {
shellContext.getInstanceGroups().remove(name);
return shellContext.outputTransformer().render(shellContext.getInstanceGroups(), "instanceGroup");
}
}
}