package com.sequenceiq.cloudbreak.service.securitygroup; import static com.sequenceiq.cloudbreak.api.model.ExposedService.GATEWAY; import static com.sequenceiq.cloudbreak.api.model.ExposedService.HTTPS; import static com.sequenceiq.cloudbreak.api.model.ExposedService.SSH; import static com.sequenceiq.cloudbreak.common.type.ResourceStatus.DEFAULT_DELETED; import java.util.ArrayList; import java.util.Collections; import java.util.HashSet; import java.util.Iterator; import java.util.List; import java.util.Set; import java.util.stream.Collectors; import javax.inject.Inject; import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Service; import com.sequenceiq.cloudbreak.api.model.Port; import com.sequenceiq.cloudbreak.common.type.CloudConstants; import com.sequenceiq.cloudbreak.common.type.ResourceStatus; import com.sequenceiq.cloudbreak.domain.CbUser; import com.sequenceiq.cloudbreak.domain.SecurityGroup; import com.sequenceiq.cloudbreak.domain.SecurityRule; import com.sequenceiq.cloudbreak.repository.SecurityGroupRepository; import com.sequenceiq.cloudbreak.util.NameUtil; @Service public class DefaultSecurityGroupCreator { private static final String[] PLATFORMS_WITH_SEC_GROUP_SUPPORT = {CloudConstants.AWS, CloudConstants.AZURE, CloudConstants.GCP, CloudConstants.OPENSTACK}; private static final String TCP_PROTOCOL = "tcp"; @Inject private SecurityGroupService securityGroupService; @Inject private SecurityGroupRepository groupRepository; @Value("${cb.nginx.port:9443}") private int nginxPort; public void createDefaultSecurityGroups(CbUser user) { Set<SecurityGroup> defaultSecurityGroups = groupRepository.findAllDefaultInAccount(user.getAccount()); List<String> defSecGroupNames = defaultSecurityGroups.stream() .map(g -> g.getStatus() == DEFAULT_DELETED ? NameUtil.cutTimestampPostfix(g.getName()) : g.getName()) .collect(Collectors.toList()); for (String platform : PLATFORMS_WITH_SEC_GROUP_SUPPORT) { String securityGroupName = "default-" + platform.toLowerCase() + "-only-ssh-and-ssl"; if (!defSecGroupNames.contains(securityGroupName)) { createDefaultStrictSecurityGroup(user, platform, securityGroupName); } } } private void createDefaultStrictSecurityGroup(CbUser user, String platform, String securityGroupName) { List<Port> strictSecurityGroupPorts = new ArrayList<>(); strictSecurityGroupPorts.add(new Port(SSH, "22", "tcp")); strictSecurityGroupPorts.add(new Port(HTTPS, "443", "tcp")); strictSecurityGroupPorts.add(new Port(GATEWAY, Integer.toString(nginxPort), "tcp")); String strictSecurityGroupDesc = getPortsOpenDesc(strictSecurityGroupPorts); addSecurityGroup(user, platform, securityGroupName, strictSecurityGroupPorts, strictSecurityGroupDesc); } private void addSecurityGroup(CbUser user, String platform, String name, List<Port> securityGroupPorts, String securityGroupDesc) { SecurityGroup onlySshAndSsl = createSecurityGroup(user, platform, name, securityGroupDesc); SecurityRule sshAndSslRule = createSecurityRule(concatenatePorts(securityGroupPorts), onlySshAndSsl); onlySshAndSsl.setSecurityRules(new HashSet<>(Collections.singletonList(sshAndSslRule))); securityGroupService.create(user, onlySshAndSsl); } private String getPortsOpenDesc(List<Port> portsWithoutAclRules) { StringBuilder allPortsOpenDescBuilder = new StringBuilder(); allPortsOpenDescBuilder.append("Open ports:"); for (Port port : portsWithoutAclRules) { allPortsOpenDescBuilder.append(" ").append(port.getPort()).append(" (").append(port.getName()).append(")"); } return allPortsOpenDescBuilder.toString(); } private SecurityGroup createSecurityGroup(CbUser user, String platform, String name, String description) { SecurityGroup securityGroup = new SecurityGroup(); securityGroup.setName(name); securityGroup.setOwner(user.getUserId()); securityGroup.setAccount(user.getAccount()); securityGroup.setDescription(description); securityGroup.setPublicInAccount(true); securityGroup.setCloudPlatform(platform); securityGroup.setStatus(ResourceStatus.DEFAULT); return securityGroup; } private SecurityRule createSecurityRule(String ports, SecurityGroup securityGroup) { SecurityRule securityRule = new SecurityRule(); securityRule.setCidr("0.0.0.0/0"); securityRule.setModifiable(false); securityRule.setPorts(ports); securityRule.setProtocol(TCP_PROTOCOL); securityRule.setSecurityGroup(securityGroup); return securityRule; } private String concatenatePorts(List<Port> ports) { StringBuilder builder = new StringBuilder(""); Iterator<Port> portsIterator = ports.iterator(); while (portsIterator.hasNext()) { Port port = portsIterator.next(); builder.append(port.getPort()); if (portsIterator.hasNext()) { builder.append(","); } } return builder.toString(); } }