package com.sequenceiq.cloudbreak.service.stack.flow;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;
import javax.inject.Inject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;
import com.sequenceiq.cloudbreak.core.CloudbreakException;
import com.sequenceiq.cloudbreak.core.CloudbreakSecuritySetupException;
import com.sequenceiq.cloudbreak.core.bootstrap.service.OrchestratorTypeResolver;
import com.sequenceiq.cloudbreak.core.bootstrap.service.host.HostOrchestratorResolver;
import com.sequenceiq.cloudbreak.domain.InstanceMetaData;
import com.sequenceiq.cloudbreak.domain.Stack;
import com.sequenceiq.cloudbreak.orchestrator.host.HostOrchestrator;
import com.sequenceiq.cloudbreak.orchestrator.model.GatewayConfig;
import com.sequenceiq.cloudbreak.repository.InstanceMetaDataRepository;
import com.sequenceiq.cloudbreak.service.GatewayConfigService;
import com.sequenceiq.cloudbreak.service.stack.StackService;
@Service
public class HostMetadataSetup {
private static final Logger LOGGER = LoggerFactory.getLogger(HostMetadataSetup.class);
@Inject
private StackService stackService;
@Inject
private InstanceMetaDataRepository instanceMetaDataRepository;
@Inject
private GatewayConfigService gatewayConfigService;
@Inject
private HostOrchestratorResolver hostOrchestratorResolver;
@Inject
private OrchestratorTypeResolver orchestratorTypeResolver;
public void setupHostMetadata(Long stackId) throws CloudbreakException {
LOGGER.info("Setting up host metadata for the cluster.");
Stack stack = stackService.getById(stackId);
if (!orchestratorTypeResolver.resolveType(stack.getOrchestrator()).containerOrchestrator()) {
Set<InstanceMetaData> allInstanceMetaData = stack.getRunningInstanceMetaData();
updateWithHostData(stack, Collections.emptySet());
instanceMetaDataRepository.save(allInstanceMetaData);
}
}
public void setupNewHostMetadata(Long stackId, Set<String> newAddresses) throws CloudbreakException {
LOGGER.info("Extending host metadata.");
Stack stack = stackService.getById(stackId);
if (!orchestratorTypeResolver.resolveType(stack.getOrchestrator()).containerOrchestrator()) {
Set<InstanceMetaData> newInstanceMetadata = stack.getRunningInstanceMetaData().stream()
.filter(instanceMetaData -> newAddresses.contains(instanceMetaData.getPrivateIp()))
.collect(Collectors.toSet());
updateWithHostData(stack, newInstanceMetadata);
instanceMetaDataRepository.save(newInstanceMetadata);
}
}
private void updateWithHostData(Stack stack, Set<InstanceMetaData> newInstanceMetadata)
throws CloudbreakSecuritySetupException {
try {
Set<InstanceMetaData> metadataToUpdate;
if (newInstanceMetadata == null || newInstanceMetadata.isEmpty()) {
metadataToUpdate = stack.getRunningInstanceMetaData();
} else {
metadataToUpdate = newInstanceMetadata;
}
List<String> privateIps = metadataToUpdate.stream().map(InstanceMetaData::getPrivateIp).collect(Collectors.toList());
GatewayConfig gatewayConfig = gatewayConfigService.getPrimaryGatewayConfig(stack);
HostOrchestrator hostOrchestrator = hostOrchestratorResolver.get(stack.getOrchestrator().getType());
Map<String, String> members = hostOrchestrator.getMembers(gatewayConfig, privateIps);
LOGGER.info("Received host names from hosts: {}, original targets: {}", members.values(), privateIps);
for (InstanceMetaData instanceMetaData : metadataToUpdate) {
String privateIp = instanceMetaData.getPrivateIp();
String address = members.get(privateIp);
instanceMetaData.setConsulServer(false);
instanceMetaData.setDiscoveryFQDN(address);
LOGGER.info("Domain used for isntance: {} original: {}, fqdn: {}", instanceMetaData.getInstanceId(), address,
instanceMetaData.getDiscoveryFQDN());
}
} catch (Exception e) {
throw new CloudbreakSecuritySetupException(e);
}
}
}