package com.sequenceiq.cloudbreak.cloud.azure; import static com.sequenceiq.cloudbreak.util.FreeMarkerTemplateUtils.processTemplateIntoString; import java.io.IOException; import java.util.HashMap; import java.util.Map; import javax.inject.Inject; import org.apache.commons.codec.binary.Base64; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Service; import com.sequenceiq.cloudbreak.api.model.InstanceGroupType; import com.sequenceiq.cloudbreak.cloud.context.CloudContext; import com.sequenceiq.cloudbreak.cloud.exception.CloudConnectorException; import com.sequenceiq.cloudbreak.cloud.azure.view.AzureCredentialView; import com.sequenceiq.cloudbreak.cloud.azure.view.AzureSecurityView; import com.sequenceiq.cloudbreak.cloud.azure.view.AzureStackView; import com.sequenceiq.cloudbreak.cloud.model.CloudCredential; import com.sequenceiq.cloudbreak.cloud.model.CloudStack; import com.sequenceiq.cloudbreak.cloud.model.Image; import com.sequenceiq.cloudbreak.cloud.model.Network; import freemarker.template.Configuration; import freemarker.template.Template; import freemarker.template.TemplateException; @Service("AzureTemplateBuilder") public class AzureTemplateBuilder { private static final Logger LOGGER = LoggerFactory.getLogger(AzureTemplateBuilder.class); @Value("${cb.arm.template.path:}") private String armTemplatePath; @Value("${cb.arm.parameter.path:}") private String armTemplateParametersPath; @Inject private Configuration freemarkerConfiguration; @Inject private AzureUtils azureUtils; @Inject private AzureStorage azureStorage; public String build(String stackName, AzureCredentialView armCredentialView, AzureStackView armStack, CloudContext cloudContext, CloudStack cloudStack) { try { String imageUrl = cloudStack.getImage().getImageName(); String imageName = imageUrl.substring(imageUrl.lastIndexOf('/') + 1); Network network = cloudStack.getNetwork(); Map<String, Object> model = new HashMap<>(); model.put("credential", armCredentialView); String rootDiskStorage = azureStorage.getImageStorageName(armCredentialView, cloudContext, azureStorage.getPersistentStorageName(cloudStack.getParameters()), azureStorage.getArmAttachedStorageOption(cloudStack.getParameters())); AzureSecurityView armSecurityView = new AzureSecurityView(cloudStack.getGroups()); model.put("storage_account_name", rootDiskStorage); model.put("image_storage_container_name", AzureStorage.IMAGES); model.put("storage_container_name", azureStorage.getDiskContainerName(cloudContext)); model.put("storage_vhd_name", imageName); model.put("stackname", stackName); model.put("region", cloudContext.getLocation().getRegion().value()); model.put("subnet1Prefix", network.getSubnet().getCidr()); model.put("groups", armStack.getGroups()); model.put("igs", armStack.getInstanceGroups()); model.put("securities", armSecurityView.getPorts()); model.put("corecustomData", base64EncodedUserData(cloudStack.getImage().getUserData(InstanceGroupType.CORE))); model.put("gatewaycustomData", base64EncodedUserData(cloudStack.getImage().getUserData(InstanceGroupType.GATEWAY))); model.put("disablePasswordAuthentication", !armCredentialView.passwordAuthenticationRequired()); model.put("existingVPC", azureUtils.isExistingNetwork(network)); model.put("resourceGroupName", azureUtils.getCustomResourceGroupName(network)); model.put("existingVNETName", azureUtils.getCustomNetworkId(network)); model.put("existingSubnetName", azureUtils.getCustomSubnetId(network)); model.put("noPublicIp", azureUtils.isPrivateIp(network)); model.put("noFirewallRules", azureUtils.isNoSecurityGroups(network)); model.put("userDefinedTags", cloudStack.getTags()); String generatedTemplate = processTemplateIntoString(getTemplate(cloudStack), model); LOGGER.debug("Generated Arm template: {}", generatedTemplate); return generatedTemplate; } catch (IOException | TemplateException e) { throw new CloudConnectorException("Failed to process the Arm TemplateBuilder", e); } } public String buildParameters(CloudCredential credential, Network network, Image image) { try { return processTemplateIntoString(freemarkerConfiguration.getTemplate(armTemplateParametersPath, "UTF-8"), new HashMap<>()); } catch (IOException | TemplateException e) { throw new CloudConnectorException("Failed to process the Arm TemplateParameterBuilder", e); } } public String getTemplateString() { return getTemplate().toString(); } public Template getTemplate(CloudStack stack) { try { return new Template(armTemplatePath, stack.getTemplate(), freemarkerConfiguration); } catch (IOException e) { throw new CloudConnectorException("can't create template object", e); } } private Template getTemplate() { try { return freemarkerConfiguration.getTemplate(armTemplatePath, "UTF-8"); } catch (IOException e) { throw new CloudConnectorException("can't get arm template", e); } } private String base64EncodedUserData(String data) { return new String(Base64.encodeBase64(String.format("%s", data).getBytes())); } }