package com.intrbiz.bergamot.config.validator; import java.util.List; import com.codahale.metrics.Timer; import com.intrbiz.Util; import com.intrbiz.bergamot.config.model.AccessControlCfg; import com.intrbiz.bergamot.config.model.BergamotCfg; import com.intrbiz.bergamot.config.model.ClusterCfg; import com.intrbiz.bergamot.config.model.CommandCfg; import com.intrbiz.bergamot.config.model.ContactCfg; import com.intrbiz.bergamot.config.model.GroupCfg; import com.intrbiz.bergamot.config.model.HostCfg; import com.intrbiz.bergamot.config.model.LocationCfg; import com.intrbiz.bergamot.config.model.NamedObjectCfg; import com.intrbiz.bergamot.config.model.NotifyCfg; import com.intrbiz.bergamot.config.model.ResourceCfg; import com.intrbiz.bergamot.config.model.SecurityDomainCfg; import com.intrbiz.bergamot.config.model.ServiceCfg; import com.intrbiz.bergamot.config.model.TeamCfg; import com.intrbiz.bergamot.config.model.TemplatedObjectCfg; import com.intrbiz.bergamot.config.model.TrapCfg; import com.intrbiz.gerald.witchcraft.Witchcraft; public class BergamotConfigValidator extends BergamotConfigResolver { private final BergamotCfg cfg; private final Timer validateTimer = Witchcraft.get().source("com.intrbiz.config.bergamot").getRegistry().timer(Witchcraft.name(BergamotConfigValidator.class, "validate")); private final Timer computeInheritenanceTimer = Witchcraft.get().source("com.intrbiz.config.bergamot").getRegistry().timer(Witchcraft.name(BergamotConfigValidator.class, "computeInheritenance")); public BergamotConfigValidator(BergamotCfg cfg) { super(cfg); this.cfg = cfg; } public BergamotConfigValidator(BergamotCfg cfg, BergamotObjectLocator... locators) { super(BergamotObjectLocator.from(cfg, locators)); this.cfg = cfg; } /** * Validate this Bergamot configuration. Note: you must validate * a the configuration before using it. */ public ValidatedBergamotConfiguration validate() { try (Timer.Context tctx = validateTimer.time()) { BergamotValidationReport report = new BergamotValidationReport(this.cfg.getSite()); // compute the inheritance this.computeInheritenance(report); // validate the objects this.validateGroups(report); this.validateLocations(report); this.validateHosts(report); this.validateClusters(report); this.validateResources(report); this.validateServices(report); this.validateTraps(report); this.validateTeams(report); this.validateContacts(report); this.validateCommands(report); return new ValidatedBergamotConfiguration(this.cfg, report); } } @SuppressWarnings({ "rawtypes", "unchecked" }) private void computeInheritenance(BergamotValidationReport report) { try (Timer.Context tctx = computeInheritenanceTimer.time()) { // walk the object tree and compute the inheritance graph for (List<? extends TemplatedObjectCfg<?>> objects : this.cfg.getAllObjects()) { for (TemplatedObjectCfg object : objects) { this.computeInheritenance(object, report); } } } } private void validateGroups(BergamotValidationReport report) { for (GroupCfg group : this.cfg.getGroups()) { for (String groupName : group.getGroups()) { this.checkGroupExists(groupName, group, report); } for (String securityDomainName : group.getSecurityDomains()) { this.checkSecurityDomainExists(securityDomainName, group, report); } } } private void validateHosts(BergamotValidationReport report) { for (HostCfg host : this.cfg.getHosts()) { for (String groupName : host.getGroups()) { this.checkGroupExists(groupName, host, report); } for (String securityDomainName : host.getSecurityDomains()) { this.checkSecurityDomainExists(securityDomainName, host, report); } if (! Util.isEmpty(host.getLocation())) { this.checkLocationExists(host.getLocation(), host, report); } // check command for this host if (host.getCheckCommand() != null) { checkCommandExists(host.getCheckCommand().getCommand(), host, report); } // services of the host for (ServiceCfg service : host.getServices()) { for (String groupName : service.getGroups()) { this.checkGroupExists(groupName, service, report); } for (String securityDomainName : service.getSecurityDomains()) { this.checkSecurityDomainExists(securityDomainName, service, report); } this.validateNotify(service.getNotify(), service, report); } // traps of the host for (TrapCfg trap : host.getTraps()) { for (String groupName : trap.getGroups()) { this.checkGroupExists(groupName, trap, report); } for (String securityDomainName : trap.getSecurityDomains()) { this.checkSecurityDomainExists(securityDomainName, trap, report); } this.validateNotify(trap.getNotify(), trap, report); } } } private void validateClusters(BergamotValidationReport report) { for (ClusterCfg cluster : this.cfg.getClusters()) { for (String groupName : cluster.getGroups()) { this.checkGroupExists(groupName, cluster, report); } for (String securityDomainName : cluster.getSecurityDomains()) { this.checkSecurityDomainExists(securityDomainName, cluster, report); } // the condition if (Util.isEmpty(cluster.getCondition()) && (! cluster.getTemplateBooleanValue())) { report.logError("You must provide a condition for the cluster " + cluster.getName()); } // resources of the cluster for (ResourceCfg resource : cluster.getResources()) { for (String groupName : resource.getGroups()) { this.checkGroupExists(groupName, resource, report); } for (String securityDomainName : resource.getSecurityDomains()) { this.checkSecurityDomainExists(securityDomainName, resource, report); } this.validateNotify(resource.getNotify(), resource, report); } } } private void validateServices(BergamotValidationReport report) { for (ServiceCfg service : this.cfg.getServices()) { for (String groupName : service.getGroups()) { this.checkGroupExists(groupName, service, report); } for (String securityDomainName : service.getSecurityDomains()) { this.checkSecurityDomainExists(securityDomainName, service, report); } if (service.getTemplate() == null || service.getTemplate() == false) { service.setTemplate(true); report.logWarn("Top level services must be templates: " + service); } this.validateNotify(service.getNotify(), service, report); // check command for this service if (service.getCheckCommand() != null) { checkCommandExists(service.getCheckCommand().getCommand(), service, report); } } } private void validateTraps(BergamotValidationReport report) { for (TrapCfg trap : this.cfg.getTraps()) { for (String groupName : trap.getGroups()) { this.checkGroupExists(groupName, trap, report); } for (String securityDomainName : trap.getSecurityDomains()) { this.checkSecurityDomainExists(securityDomainName, trap, report); } if (trap.getTemplate() == null || trap.getTemplate() == false) { trap.setTemplate(true); report.logWarn("Top level traps must be templates: " + trap); } this.validateNotify(trap.getNotify(), trap, report); // check command for this trap if (trap.getCheckCommand() != null) { checkCommandExists(trap.getCheckCommand().getCommand(), trap, report); } } } private void validateResources(BergamotValidationReport report) { for (ResourceCfg resource : this.cfg.getResources()) { for (String groupName : resource.getGroups()) { this.checkGroupExists(groupName, resource, report); } for (String securityDomainName : resource.getSecurityDomains()) { this.checkSecurityDomainExists(securityDomainName, resource, report); } if (resource.getTemplate() == null || resource.getTemplate() == false) { resource.setTemplate(true); report.logWarn("Top level resources must be templates: " + resource); } // the condition if (Util.isEmpty(resource.getCondition()) && (! resource.getTemplateBooleanValue())) { report.logError("You must provide a condition for the resource " + resource.getName()); } this.validateNotify(resource.getNotify(), resource, report); } } private void validateNotify(NotifyCfg notify, NamedObjectCfg<?> of, BergamotValidationReport report) { if (notify != null) { for (String team : notify.getTeams()) { this.checkTeamExists(team, of, report); } for (String contact : notify.getContacts()) { this.checkContactExists(contact, of, report); } } } private void validateLocations(BergamotValidationReport report) { for (LocationCfg location : this.cfg.getLocations()) { if (! Util.isEmpty(location.getLocation())) { this.checkLocationExists(location.getLocation(), location, report); } for (String securityDomainName : location.getSecurityDomains()) { this.checkSecurityDomainExists(securityDomainName, location, report); } } } private void validateTeams(BergamotValidationReport report) { for (TeamCfg team : this.cfg.getTeams()) { for (String teamName : team.getTeams()) { this.checkTeamExists(teamName, team, report); } // validate access controls for (AccessControlCfg accessControl : team.getAccessControls()) { this.checkSecurityDomainExists(accessControl.getSecurityDomain(), team, report); } } } private void validateContacts(BergamotValidationReport report) { for (ContactCfg contact : this.cfg.getContacts()) { for (String teamName : contact.getTeams()) { this.checkTeamExists(teamName, contact, report); } // validate access controls for (AccessControlCfg accessControl : contact.getAccessControls()) { this.checkSecurityDomainExists(accessControl.getSecurityDomain(), contact, report); } } } private void validateCommands(BergamotValidationReport report) { for (CommandCfg command : this.cfg.getCommands()) { if (Util.isEmpty(command.resolve().getEngine())) { report.logError("The command engine should be specified for " + command); } } } // checks private void checkSecurityDomainExists(String name, NamedObjectCfg<?> user, BergamotValidationReport report) { SecurityDomainCfg domain = this.lookup(SecurityDomainCfg.class, name); if (domain == null) { report.logError("Cannot find the security domain '" + name + "' referenced by " + user); } } private void checkGroupExists(String name, NamedObjectCfg<?> user, BergamotValidationReport report) { GroupCfg group = this.lookup(GroupCfg.class, name); if (group == null) { report.logError("Cannot find the group '" + name + "' referenced by " + user); } } private void checkLocationExists(String name, NamedObjectCfg<?> user, BergamotValidationReport report) { LocationCfg location = this.lookup(LocationCfg.class, name); if (location == null) { report.logError("Cannot find the location '" + name + "' referenced by " + user); } } private void checkTeamExists(String name, NamedObjectCfg<?> user, BergamotValidationReport report) { TeamCfg team = this.lookup(TeamCfg.class, name); if (team == null) { report.logError("Cannot find the team '" + name + "' referenced by " + user); } } private void checkContactExists(String name, NamedObjectCfg<?> user, BergamotValidationReport report) { ContactCfg contact = this.lookup(ContactCfg.class, name); if (contact == null) { report.logError("Cannot find the contact '" + name + "' referenced by " + user); } } private void checkCommandExists(String name, NamedObjectCfg<?> user, BergamotValidationReport report) { CommandCfg command = this.lookup(CommandCfg.class, name); if (command == null) { report.logError("Cannot find the command '" + name + "' referenced by " + user); } } }