All Downloads are FREE. Search and download functionalities are using the official Maven repository.

brooklyn.entity.network.bind.BindDnsServerImpl Maven / Gradle / Ivy

The newest version!
/*
 * Copyright 2013 by Cloudsoft Corp.
 *
 * 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 brooklyn.entity.network.bind;

import java.io.ByteArrayInputStream;
import java.util.Map;
import java.util.concurrent.ConcurrentMap;
import java.util.concurrent.atomic.AtomicLong;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import brooklyn.entity.Entity;
import brooklyn.entity.basic.DynamicGroup;
import brooklyn.entity.basic.SoftwareProcessImpl;
import brooklyn.entity.group.AbstractMembershipTrackingPolicy;
import brooklyn.entity.proxying.EntitySpec;
import brooklyn.entity.trait.Startable;
import brooklyn.location.Location;
import brooklyn.location.MachineLocation;
import brooklyn.location.basic.SshMachineLocation;
import brooklyn.util.collections.MutableMap;
import brooklyn.util.net.Cidr;
import brooklyn.util.ssh.BashCommands;
import brooklyn.util.text.Strings;

import com.google.common.base.Joiner;
import com.google.common.base.Optional;
import com.google.common.base.Predicates;
import com.google.common.base.Splitter;
import com.google.common.collect.HashMultimap;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.Iterables;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.google.common.collect.Multimap;

/**
 * This sets up a BIND DNS server.
 * 

* NOTE This entity has only been certified on CentOS and RHEL operating systems. */ public class BindDnsServerImpl extends SoftwareProcessImpl implements BindDnsServer { private static final Logger LOG = LoggerFactory.getLogger(BindDnsServerImpl.class); private AtomicLong serial = new AtomicLong(System.currentTimeMillis()); private Object[] mutex = new Object[0]; private DynamicGroup entities; private AbstractMembershipTrackingPolicy policy; private Multimap entityLocations = HashMultimap.create(); private ConcurrentMap addressMappings = Maps.newConcurrentMap(); private ConcurrentMap reverseMappings = Maps.newConcurrentMap(); public BindDnsServerImpl() { super(); } public String getManagementCidr() { return getConfig(MANAGEMENT_CIDR); } public Integer getDnsPort() { return getAttribute(DNS_PORT); } public String getDomainName() { return getConfig(DOMAIN_NAME); } public long getSerial() { return serial.incrementAndGet(); } public Cidr getReverseLookupNetwork() { return getAttribute(REVERSE_LOOKUP_CIDR); } public String getReverseLookupDomain() { return getAttribute(REVERSE_LOOKUP_DOMAIN); } @Override public void init() { entities = addChild(EntitySpec.create(DynamicGroup.class) .configure("entityFilter", getConfig(ENTITY_FILTER))); } @Override public Class getDriverInterface() { return BindDnsServerDriver.class; } @Override public Map getAddressMappings() { return addressMappings; } @Override public Map getReverseMappings() { return reverseMappings; } @Override public BindDnsServerDriver getDriver() { return (BindDnsServerDriver) super.getDriver(); } @Override public void connectSensors() { connectServiceUpIsRunning(); } @Override public void disconnectSensors() { disconnectServiceUpIsRunning(); } @Override protected void preStart() { String reverse = getConfig(REVERSE_LOOKUP_NETWORK); if (Strings.isBlank(reverse)) reverse = getAttribute(ADDRESS); setAttribute(REVERSE_LOOKUP_CIDR, new Cidr(reverse + "/24")); String reverseLookupDomain = Joiner.on('.').join(Iterables.skip(Lists.reverse(Lists.newArrayList(Splitter.on('.').split(reverse))), 1)) + ".in-addr.arpa"; setAttribute(REVERSE_LOOKUP_DOMAIN, reverseLookupDomain); Map flags = MutableMap.builder() .put("name", "Address tracker") .put("sensorsToTrack", ImmutableSet.of(getConfig(HOSTNAME_SENSOR))) .build(); policy = new AbstractMembershipTrackingPolicy(flags) { @Override protected void onEntityChange(Entity member) { added(member); } @Override protected void onEntityAdded(Entity member) { if (Strings.isNonBlank(member.getAttribute(getConfig(HOSTNAME_SENSOR)))) added(member); // Ignore, unless hostname set } @Override protected void onEntityRemoved(Entity member) { removed(member); } }; // For any entities that have already come up for (Entity member : entities.getMembers()) { if (Strings.isNonBlank(member.getAttribute(getConfig(HOSTNAME_SENSOR)))) added(member); // Ignore, unless hostname set } addPolicy(policy); policy.setGroup(entities); } @Override public void postStart() { update(); } public void added(Entity member) { synchronized (mutex) { Optional location = Iterables.tryFind(member.getLocations(), Predicates.instanceOf(SshMachineLocation.class)); String hostname = member.getAttribute(getConfig(HOSTNAME_SENSOR)); if (location.isPresent() && Strings.isNonBlank(hostname)) { SshMachineLocation machine = (SshMachineLocation) location.get(); String address = machine.getAddress().getHostAddress(); if (!entityLocations.containsKey(machine)) { entityLocations.put(machine, member); addressMappings.putIfAbsent(address, hostname); if (getReverseLookupNetwork().contains(new Cidr(address + "/32"))) { String octet = Iterables.get(Splitter.on('.').split(address), 3); reverseMappings.putIfAbsent(hostname, octet); } if (getAttribute(Startable.SERVICE_UP)) { update(); } configure(machine); LOG.info("{} added at location {} with name {}", new Object[] { member, machine, hostname }); } } } } public void removed(Entity member) { synchronized (mutex) { Location location = findLocation(member); if (location != null) { entityLocations.remove(location, member); if (!entityLocations.containsKey(location)) { addressMappings.remove(((MachineLocation)location).getAddress().getHostAddress()); } } update(); } } private Location findLocation(Entity member) { // don't use member.getLocations(), because when being stopped the location might not be set if (entityLocations.containsValue(member)) { for (Map.Entry entry : entityLocations.entries()) { if (member.equals(entry.getValue())) { return entry.getKey(); } } } return null; } public void update() { Optional location = Iterables.tryFind(getLocations(), Predicates.instanceOf(SshMachineLocation.class)); SshMachineLocation machine = (SshMachineLocation) location.get(); copyTemplate(getConfig(NAMED_CONF_TEMPLATE), "/etc/named.conf", machine); copyTemplate(getConfig(DOMAIN_ZONE_FILE_TEMPLATE), "/var/named/domain.zone", machine); copyTemplate(getConfig(REVERSE_ZONE_FILE_TEMPLATE), "/var/named/reverse.zone", machine); machine.execScript("restart bind", ImmutableList.of(BashCommands.sudo("service named restart"))); LOG.info("updated named configuration and zone file for '{}' on {}", getDomainName(), this); } public void configure(SshMachineLocation machine) { if (getConfig(REPLACE_RESOLV_CONF)) { copyTemplate(getConfig(RESOLV_CONF_TEMPLATE), "/etc/resolv.conf", machine); } else { appendTemplate(getConfig(INTERFACE_CONFIG_TEMPLATE), "/etc/sysconfig/network-scripts/ifcfg-eth0", machine); machine.execScript("reload network", ImmutableList.of(BashCommands.sudo("service network reload"))); } LOG.info("configured resolver on {}", machine); } public void copyTemplate(String template, String destination, SshMachineLocation machine) { String content = ((BindDnsServerSshDriver) getDriver()).processTemplate(template); String temp = "/tmp/template-" + Strings.makeRandomId(6); machine.copyTo(new ByteArrayInputStream(content.getBytes()), temp); machine.execScript("copying file", ImmutableList.of(BashCommands.sudo(String.format("mv %s %s", temp, destination)))); } public void appendTemplate(String template, String destination, SshMachineLocation machine) { String content = ((BindDnsServerSshDriver) getDriver()).processTemplate(template); String temp = "/tmp/template-" + Strings.makeRandomId(6); machine.copyTo(new ByteArrayInputStream(content.getBytes()), temp); machine.execScript("updating file", ImmutableList.of( BashCommands.sudo(String.format("tee -a %s < %s", destination, temp)), String.format("rm -f %s", temp))); } }





© 2015 - 2025 Weber Informatics LLC | Privacy Policy