io.datarouter.aws.elb.service.AwsElbStatusDailyDigest Maven / Gradle / Ivy
The newest version!
/*
* Copyright © 2009 HotPads ([email protected])
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package io.datarouter.aws.elb.service;
import static j2html.TagCreator.div;
import java.time.ZoneId;
import java.util.HashMap;
import java.util.Map;
import java.util.Optional;
import com.amazonaws.services.elasticloadbalancingv2.model.LoadBalancer;
import com.amazonaws.services.elasticloadbalancingv2.model.LoadBalancerSchemeEnum;
import io.datarouter.aws.elb.config.DatarouterAwsElbSettingRoot;
import io.datarouter.instrumentation.relay.rml.Rml;
import io.datarouter.instrumentation.relay.rml.RmlBlock;
import io.datarouter.storage.config.properties.DatarouterServerTypeSupplier;
import io.datarouter.storage.util.Ec2InstanceDetailsDto;
import io.datarouter.storage.util.Ec2InstanceTool;
import io.datarouter.web.config.service.PrivateDomain;
import io.datarouter.web.config.service.PublicDomain;
import io.datarouter.web.digest.DailyDigest;
import io.datarouter.web.digest.DailyDigestGrouping;
import io.datarouter.web.digest.DailyDigestService;
import j2html.tags.specialized.DivTag;
import jakarta.inject.Inject;
import jakarta.inject.Singleton;
@Singleton
public class AwsElbStatusDailyDigest implements DailyDigest{
private static final String HAS_PUBLIC_LOAD_BALANCER_KEY = "hasPublicAlb";
private static final String HAS_PRIVATE_LOAD_BALANCER_KEY = "hasPrivateAlb";
private static final String UNKNOWN_LOAD_BALANCER = "unknownAlb";
@Inject
private DatarouterServerTypeSupplier serverTypeSupplier;
@Inject
private ElbService elbService;
@Inject
private PrivateDomain privateDomain;
@Inject
private PublicDomain publicDomain;
@Inject
private DatarouterAwsElbSettingRoot settings;
@Override
public String getTitle(){
return "ELB status";
}
@Override
public DailyDigestType getType(){
return DailyDigestType.ACTIONABLE;
}
@Override
public DailyDigestGrouping getGrouping(){
return DailyDigestGrouping.LOW;
}
@Override
public Optional getEmailContent(ZoneId zoneId){
return checkAlbSchemeForEc2Instance();
}
@Override
public Optional getRelayContent(ZoneId zoneId){
if(!settings.enableDailyDigest.get()){
return Optional.empty();
}
Optional ec2InstanceDetailsDto = Ec2InstanceTool.getEc2InstanceDetails(false);
String serverType = serverTypeSupplier.getServerTypeString();
if(ec2InstanceDetailsDto.isEmpty()){
return Optional.empty();
}
String ec2InstanceId = ec2InstanceDetailsDto.get().instanceId;
Map privatePublicAlbsMap = getAlbSchemeForEc2Instance(serverType, ec2InstanceId);
boolean hasPublicAlb = privatePublicAlbsMap.get(HAS_PUBLIC_LOAD_BALANCER_KEY);
boolean hasPrivateAlb = privatePublicAlbsMap.get(HAS_PRIVATE_LOAD_BALANCER_KEY);
boolean hasUnknownAlb = privatePublicAlbsMap.get(UNKNOWN_LOAD_BALANCER);
var header = DailyDigestService.makeHeading("ELB Status");
if(hasUnknownAlb){
return Optional.of(Rml.paragraph(header, Rml.text(
"Server does not have any known load balancers or something might be wrong, e.g ALB name does not "
+ "match, instance not registered with target group, etc")));
}
if(publicDomain.hasPublicDomain() && !hasPublicAlb){
return Optional.of(Rml.paragraph(header, Rml.text("Server expects public load balancer")));
}
if(!publicDomain.hasPublicDomain() && hasPublicAlb){
return Optional.of(Rml.paragraph(header, Rml.text("Server has unexpected public load balancer")));
}
if(publicDomain.hasPublicDomain()
&& !hasPublicAlb
&& privateDomain.hasPrivateDomain()
&& !hasPrivateAlb){
return Optional.of(Rml.paragraph(header, Rml.text("Server expects both public and private load balancers "
+ "but it is " + hasPublicAlb + " for public ALB and " + hasPrivateAlb + " for private ALB")));
}
return Optional.empty();
}
private Optional checkAlbSchemeForEc2Instance(){
if(!settings.enableDailyDigest.get()){
return Optional.empty();
}
Optional ec2InstanceDetailsDto = Ec2InstanceTool.getEc2InstanceDetails(false);
String serverType = serverTypeSupplier.getServerTypeString();
if(ec2InstanceDetailsDto.isEmpty()){
return Optional.empty();
}
String ec2InstanceId = ec2InstanceDetailsDto.get().instanceId;
Map privatePublicAlbsMap = getAlbSchemeForEc2Instance(serverType, ec2InstanceId);
boolean hasPublicAlb = privatePublicAlbsMap.get(HAS_PUBLIC_LOAD_BALANCER_KEY);
boolean hasPrivateAlb = privatePublicAlbsMap.get(HAS_PRIVATE_LOAD_BALANCER_KEY);
boolean hasUnknownAlb = privatePublicAlbsMap.get(UNKNOWN_LOAD_BALANCER);
var header = DailyDigestService.makeHeader("ELB Status", "");
if(hasUnknownAlb){
DivTag tag = div("Server does not have any known load balancers or"
+ " something might be wrong, e.g ALB name does not match, instance not registered with"
+ " target group, etc");
return Optional.of(div(header, tag));
}
if(publicDomain.hasPublicDomain() && !hasPublicAlb){
DivTag tag = div("Server expects public load balancer");
return Optional.of(div(header, tag));
}
if(!publicDomain.hasPublicDomain() && hasPublicAlb){
DivTag tag = div("Server has unexpected public load balancer");
return Optional.of(div(header, tag));
}
if(publicDomain.hasPublicDomain()
&& !hasPublicAlb
&& privateDomain.hasPrivateDomain()
&& !hasPrivateAlb){
DivTag tag = div("Server expects both public and private load"
+ " balancers but it is " + hasPublicAlb + " for public ALB and " + hasPrivateAlb
+ " for private ALB");
return Optional.of(div(header, tag));
}
return Optional.empty();
}
private Map getAlbSchemeForEc2Instance(String serverType, String ec2InstanceId){
Map privatePublicAlbsMap = new HashMap<>();
boolean unknownAlb = true;
boolean instanceHasPublicAlb = false;
boolean instanceHasPrivateAlb = false;
for(LoadBalancer loadBalancer : elbService.getLoadBalancers()){
// due to teraform/aws naming character limitation, the ALB for some services with long names will have
// the to be truncated - "some-example-service-joblet-privat" (missing last char), so can't check for
// exact ALB name
if(!loadBalancer.getLoadBalancerName().equals(serverType)
&& !loadBalancer.getLoadBalancerName().startsWith(serverType + "-privat")){
continue;
}
for(String targetGroupArn : elbService.getTargetGroupsArn(loadBalancer.getLoadBalancerArn())){
for(String targetEc2InstanceId : elbService.getTargetEc2InstancesId(targetGroupArn)){
if(!targetEc2InstanceId.equals(ec2InstanceId)){
continue;
}
LoadBalancerSchemeEnum loadBalancerScheme = LoadBalancerSchemeEnum.fromValue(
loadBalancer.getScheme());
if(LoadBalancerSchemeEnum.InternetFacing == loadBalancerScheme){
instanceHasPublicAlb = true;
}
if(LoadBalancerSchemeEnum.Internal == loadBalancerScheme){
instanceHasPrivateAlb = true;
}
unknownAlb = false;
}
}
}
privatePublicAlbsMap.put(HAS_PUBLIC_LOAD_BALANCER_KEY, instanceHasPublicAlb);
privatePublicAlbsMap.put(HAS_PRIVATE_LOAD_BALANCER_KEY, instanceHasPrivateAlb);
privatePublicAlbsMap.put(UNKNOWN_LOAD_BALANCER, unknownAlb);
return privatePublicAlbsMap;
}
}
© 2015 - 2024 Weber Informatics LLC | Privacy Policy