You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@brooklyn.apache.org by al...@apache.org on 2015/08/11 22:44:18 UTC
[3/4] incubator-brooklyn git commit: brooklyn-software-network: add
org.apache package prefix
brooklyn-software-network: add org.apache package prefix
Project: http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/commit/689b49c3
Tree: http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/tree/689b49c3
Diff: http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/diff/689b49c3
Branch: refs/heads/master
Commit: 689b49c3af742ba600ac814a8bb93ab1077397e3
Parents: 0dc3911
Author: Ciprian Ciubotariu <ch...@gmx.net>
Authored: Tue Aug 11 17:05:15 2015 +0300
Committer: Ciprian Ciubotariu <ch...@gmx.net>
Committed: Tue Aug 11 17:05:15 2015 +0300
----------------------------------------------------------------------
.../entity/network/bind/BindDnsServer.java | 156 ---------
.../network/bind/BindDnsServerDriver.java | 38 ---
.../entity/network/bind/BindDnsServerImpl.java | 339 -------------------
.../network/bind/BindDnsServerSshDriver.java | 184 ----------
.../entity/network/bind/BindOsSupport.java | 113 -------
.../entity/network/bind/BindDnsServer.java | 156 +++++++++
.../network/bind/BindDnsServerDriver.java | 38 +++
.../entity/network/bind/BindDnsServerImpl.java | 339 +++++++++++++++++++
.../network/bind/BindDnsServerSshDriver.java | 184 ++++++++++
.../entity/network/bind/BindOsSupport.java | 113 +++++++
.../brooklyn/entity/network/bind/domain.zone | 46 ---
.../brooklyn/entity/network/bind/ifcfg | 24 --
.../brooklyn/entity/network/bind/named.conf | 63 ----
.../brooklyn/entity/network/bind/named.empty | 30 --
.../entity/network/bind/named.localhost | 32 --
.../brooklyn/entity/network/bind/named.loopback | 31 --
.../brooklyn/entity/network/bind/resolv.conf | 25 --
.../brooklyn/entity/network/bind/reverse.zone | 37 --
.../brooklyn/entity/network/bind/rfc1912.zone | 52 ---
.../brooklyn/entity/network/bind/domain.zone | 46 +++
.../apache/brooklyn/entity/network/bind/ifcfg | 24 ++
.../brooklyn/entity/network/bind/named.conf | 63 ++++
.../brooklyn/entity/network/bind/named.empty | 30 ++
.../entity/network/bind/named.localhost | 32 ++
.../brooklyn/entity/network/bind/named.loopback | 31 ++
.../brooklyn/entity/network/bind/resolv.conf | 25 ++
.../brooklyn/entity/network/bind/reverse.zone | 37 ++
.../brooklyn/entity/network/bind/rfc1912.zone | 52 +++
.../network/bind/BindDnsServerByonLiveTest.java | 45 ---
.../network/bind/BindDnsServerEc2LiveTest.java | 63 ----
.../bind/BindDnsServerIntegrationTest.java | 261 --------------
.../network/bind/BindDnsServerLiveTest.java | 114 -------
.../bind/BindDnsServerSoftlayerLiveTest.java | 33 --
.../bind/DoNothingSoftwareProcessDriver.java | 55 ---
.../network/bind/PrefixAndIdEnricher.java | 57 ----
.../network/bind/TestBindDnsServerImpl.java | 92 -----
.../network/bind/BindDnsServerByonLiveTest.java | 45 +++
.../network/bind/BindDnsServerEc2LiveTest.java | 63 ++++
.../bind/BindDnsServerIntegrationTest.java | 261 ++++++++++++++
.../network/bind/BindDnsServerLiveTest.java | 114 +++++++
.../bind/BindDnsServerSoftlayerLiveTest.java | 33 ++
.../bind/DoNothingSoftwareProcessDriver.java | 55 +++
.../network/bind/PrefixAndIdEnricher.java | 57 ++++
.../network/bind/TestBindDnsServerImpl.java | 90 +++++
44 files changed, 1888 insertions(+), 1890 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/689b49c3/software/network/src/main/java/brooklyn/entity/network/bind/BindDnsServer.java
----------------------------------------------------------------------
diff --git a/software/network/src/main/java/brooklyn/entity/network/bind/BindDnsServer.java b/software/network/src/main/java/brooklyn/entity/network/bind/BindDnsServer.java
deleted file mode 100644
index f46cd75..0000000
--- a/software/network/src/main/java/brooklyn/entity/network/bind/BindDnsServer.java
+++ /dev/null
@@ -1,156 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you 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.util.Map;
-
-import com.google.common.base.Predicate;
-import com.google.common.base.Predicates;
-import com.google.common.collect.Multimap;
-import com.google.common.reflect.TypeToken;
-
-import org.apache.brooklyn.catalog.Catalog;
-import brooklyn.config.ConfigKey;
-import brooklyn.entity.Entity;
-import brooklyn.entity.annotation.Effector;
-import brooklyn.entity.basic.ConfigKeys;
-import brooklyn.entity.basic.DynamicGroup;
-import brooklyn.entity.basic.SoftwareProcess;
-import brooklyn.entity.proxying.ImplementedBy;
-import brooklyn.event.AttributeSensor;
-import brooklyn.event.basic.PortAttributeSensorAndConfigKey;
-import brooklyn.event.basic.Sensors;
-import brooklyn.location.basic.PortRanges;
-import brooklyn.util.flags.SetFromFlag;
-import brooklyn.util.net.Cidr;
-
-/**
- * This sets up a BIND DNS server.
- */
-@Catalog(name="BIND", description="BIND is an Internet Domain Name Server.", iconUrl="classpath:///isc-logo.png")
-@ImplementedBy(BindDnsServerImpl.class)
-public interface BindDnsServer extends SoftwareProcess {
-
- @SetFromFlag("filter")
- ConfigKey<Predicate<? super Entity>> ENTITY_FILTER = ConfigKeys.newConfigKey(new TypeToken<Predicate<? super Entity>>() {},
- "bind.entity.filter", "Filter for entities which will use the BIND DNS service for name resolution." +
- "Default is all instances of SoftwareProcess in the application.",
- Predicates.instanceOf(SoftwareProcess.class));
-
- @SetFromFlag("domainName")
- ConfigKey<String> DOMAIN_NAME = ConfigKeys.newStringConfigKey(
- "bind.domain.name", "The DNS domain name to serve", "brooklyn.local");
-
- @SetFromFlag("reverseLookupNetwork")
- ConfigKey<String> REVERSE_LOOKUP_NETWORK = ConfigKeys.newStringConfigKey(
- "bind.reverse-lookup.address", "Network address for reverse lookup zone");
-
- @SetFromFlag("subnet")
- ConfigKey<String> MANAGEMENT_CIDR = ConfigKeys.newStringConfigKey(
- "bind.access.cidr", "Subnet CIDR or ACL allowed to access DNS", "0.0.0.0/0");
-
- @SetFromFlag("hostnameSensor")
- ConfigKey<AttributeSensor<String>> HOSTNAME_SENSOR = ConfigKeys.newConfigKey(new TypeToken<AttributeSensor<String>>() {},
- "bind.sensor.hostname", "Sensor on managed entities that reports the hostname");
-
- PortAttributeSensorAndConfigKey DNS_PORT =
- new PortAttributeSensorAndConfigKey("bind.port", "BIND DNS port for TCP and UDP", PortRanges.fromString("53"));
-
- @SetFromFlag("zoneFileTemplate")
- ConfigKey<String> DOMAIN_ZONE_FILE_TEMPLATE = ConfigKeys.newStringConfigKey(
- "bind.template.domain-zone", "The BIND domain zone file to serve (as FreeMarker template)",
- "classpath://brooklyn/entity/network/bind/domain.zone");
-
- @SetFromFlag("reverseZoneFileTemplate")
- ConfigKey<String> REVERSE_ZONE_FILE_TEMPLATE = ConfigKeys.newStringConfigKey(
- "bind.template.reverse-zone", "The BIND reverse lookup zone file to serve (as FreeMarker template)",
- "classpath://brooklyn/entity/network/bind/reverse.zone");
-
- @SetFromFlag("namedConfTemplate")
- ConfigKey<String> NAMED_CONF_TEMPLATE = ConfigKeys.newStringConfigKey(
- "bind.template.named-conf", "The BIND named configuration file (as FreeMarker template)",
- "classpath://brooklyn/entity/network/bind/named.conf");
-
- @SetFromFlag("updateRootZonesFile")
- ConfigKey<Boolean> UPDATE_ROOT_ZONES_FILE = ConfigKeys.newBooleanConfigKey(
- "bind.updateRootZones", "Instructs the entity to fetch the latest root zones file from ftp.rs.internic.net.",
- Boolean.FALSE);
-
-
- /* Reverse lookup attributes. */
-
- AttributeSensor<Cidr> REVERSE_LOOKUP_CIDR = Sensors.newSensor(Cidr.class,
- "bind.reverse-lookup.cidr", "The network CIDR that hosts must have for reverse lookup entries " +
- "to be added (default uses server address /24)");
-
- AttributeSensor<String> REVERSE_LOOKUP_DOMAIN = Sensors.newStringSensor(
- "bind.reverse-lookup.domain", "The in-addr.arpa reverse lookup domain name");
-
-
- /* Configuration applicable to clients of the BIND DNS service. */
-
- @SetFromFlag("replaceResolvConf")
- ConfigKey<Boolean> REPLACE_RESOLV_CONF = ConfigKeys.newBooleanConfigKey(
- "bind.resolv-conf.replce", "Set to replace resolv.conf with the template (default is to use eth0 script)", Boolean.FALSE);
-
- @SetFromFlag("interfaceConfigTemplate")
- ConfigKey<String> INTERFACE_CONFIG_TEMPLATE = ConfigKeys.newStringConfigKey(
- "bind.template.interface-cfg", "The network interface configuration file for clients (as FreeMarker template)",
- "classpath://brooklyn/entity/network/bind/ifcfg");
-
- @SetFromFlag("interfaceConfigTemplate")
- ConfigKey<String> RESOLV_CONF_TEMPLATE = ConfigKeys.newStringConfigKey(
- "bind.template.resolv-conf", "The resolver configuration file for clients (as FreeMarker template)",
- "classpath://brooklyn/entity/network/bind/resolv.conf");
-
- AttributeSensor<DynamicGroup> ENTITIES = Sensors.newSensor(DynamicGroup.class,
- "bind.entities", "The entities being managed by this server");
-
- AttributeSensor<Multimap<String, String>> ADDRESS_MAPPINGS = Sensors.newSensor(new TypeToken<Multimap<String, String>>() {},
- "bind.mappings", "All address mappings maintained by the server, in form address -> [names]");
-
- AttributeSensor<Map<String, String>> A_RECORDS = Sensors.newSensor(new TypeToken<Map<String, String>>() {},
- "bind.records.a", "All A records for the server, in form name -> address");
-
- AttributeSensor<Multimap<String, String>> CNAME_RECORDS = Sensors.newSensor(new TypeToken<Multimap<String, String>>() {},
- "bind.records.cname", "All CNAME records for the server, in form name -> [names]");
-
- AttributeSensor<Map<String, String>> PTR_RECORDS = Sensors.newSensor(new TypeToken<Map<String, String>>() {},
- "bind.records.ptr", "All PTR records for the server, in form address -> name. Entries will be in REVERSE_LOOKUP_CIDR. " +
- "Entries are guaranteed to have an inverse mapping in A_RECORDS.");
-
- AttributeSensor<Long> SERIAL = Sensors.newLongSensor(
- "bind.serial", "A serial number guaranteed to be valid for use in a modified domain.zone or reverse.zone file");
-
- public Multimap<String, String> getAddressMappings();
-
- /**
- * @return the IP to hostname mappings stored in this DNS server's conf file
- * @deprecated since 0.7.0 use {@link #PTR_RECORDS} instead.
- */
- @Deprecated
- @Effector(description="Gets the IP to hostname mappings stored in this DNS server's conf file")
- public Map<String, String> getReverseMappings();
-
- /**
- * @return the predicate used to filter entities for the Bind server to manage.
- */
- Predicate<? super Entity> getEntityFilter();
-
-}
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/689b49c3/software/network/src/main/java/brooklyn/entity/network/bind/BindDnsServerDriver.java
----------------------------------------------------------------------
diff --git a/software/network/src/main/java/brooklyn/entity/network/bind/BindDnsServerDriver.java b/software/network/src/main/java/brooklyn/entity/network/bind/BindDnsServerDriver.java
deleted file mode 100644
index cbc9423..0000000
--- a/software/network/src/main/java/brooklyn/entity/network/bind/BindDnsServerDriver.java
+++ /dev/null
@@ -1,38 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you 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 com.google.common.annotations.VisibleForTesting;
-
-import brooklyn.entity.basic.SoftwareProcessDriver;
-
-public interface BindDnsServerDriver extends SoftwareProcessDriver {
-
- /**
- * Uploads configuration files and restarts the service.
- */
- void updateBindConfiguration();
-
- /**
- * @return a support class appropriate for the machine the server is running on.
- */
- @VisibleForTesting
- BindOsSupport getOsSupport();
-
-}
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/689b49c3/software/network/src/main/java/brooklyn/entity/network/bind/BindDnsServerImpl.java
----------------------------------------------------------------------
diff --git a/software/network/src/main/java/brooklyn/entity/network/bind/BindDnsServerImpl.java b/software/network/src/main/java/brooklyn/entity/network/bind/BindDnsServerImpl.java
deleted file mode 100644
index 0b5331f..0000000
--- a/software/network/src/main/java/brooklyn/entity/network/bind/BindDnsServerImpl.java
+++ /dev/null
@@ -1,339 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you 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 static com.google.common.base.Preconditions.checkNotNull;
-
-import java.io.ByteArrayInputStream;
-import java.io.StringReader;
-import java.util.Collection;
-import java.util.Map;
-
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import com.google.common.base.CharMatcher;
-import com.google.common.base.Function;
-import com.google.common.base.Joiner;
-import com.google.common.base.Predicate;
-import com.google.common.base.Splitter;
-import com.google.common.collect.BiMap;
-import com.google.common.collect.FluentIterable;
-import com.google.common.collect.HashBiMap;
-import com.google.common.collect.ImmutableList;
-import com.google.common.collect.ImmutableListMultimap;
-import com.google.common.collect.ImmutableMap;
-import com.google.common.collect.ImmutableMultimap;
-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;
-import com.google.common.collect.MultimapBuilder;
-import com.google.common.collect.Multimaps;
-
-import brooklyn.entity.Entity;
-import brooklyn.entity.basic.Attributes;
-import brooklyn.entity.basic.DynamicGroup;
-import brooklyn.entity.basic.Lifecycle;
-import brooklyn.entity.basic.SoftwareProcessImpl;
-import brooklyn.entity.group.AbstractMembershipTrackingPolicy;
-import brooklyn.entity.proxying.EntitySpec;
-import brooklyn.event.Sensor;
-import brooklyn.location.basic.Machines;
-import brooklyn.location.basic.SshMachineLocation;
-import brooklyn.policy.PolicySpec;
-import brooklyn.util.guava.Maybe;
-import brooklyn.util.net.Cidr;
-import brooklyn.util.ssh.BashCommands;
-import brooklyn.util.text.Strings;
-
-/**
- * This sets up a BIND DNS server.
- * <p>
- * <b>NOTE</b> This entity has only been certified on <i>CentOS</i>, <i>RHEL</i>,
- * <i>Ubuntu</i> and <i>Debian</i> operating systems.
- */
-public class BindDnsServerImpl extends SoftwareProcessImpl implements BindDnsServer {
-
- private static final Logger LOG = LoggerFactory.getLogger(BindDnsServerImpl.class);
- private final Object serialMutex = new Object();
-
- // As per RFC 952 and RFC 1123.
- private static final CharMatcher DOMAIN_NAME_FIRST_CHAR_MATCHER = CharMatcher.inRange('a', 'z')
- .or(CharMatcher.inRange('A', 'Z'))
- .or(CharMatcher.inRange('0', '9'));
- private static final CharMatcher DOMAIN_NAME_MATCHER = DOMAIN_NAME_FIRST_CHAR_MATCHER
- .or(CharMatcher.is('-'));
-
-
- private class HostnameTransformer implements Function<Entity, String> {
- @Override
- public String apply(Entity input) {
- String hostname = input.getAttribute(getConfig(HOSTNAME_SENSOR));
- hostname = DOMAIN_NAME_FIRST_CHAR_MATCHER.negate().trimFrom(hostname);
- hostname = DOMAIN_NAME_MATCHER.negate().trimAndCollapseFrom(hostname, '-');
- if (hostname.length() > 63) {
- hostname = hostname.substring(0, 63);
- }
- return hostname;
- }
- }
-
- public BindDnsServerImpl() {
- super();
- }
-
- @Override
- public void init() {
- super.init();
- checkNotNull(getConfig(HOSTNAME_SENSOR), "%s requires value for %s", getClass().getName(), HOSTNAME_SENSOR);
- DynamicGroup entities = addChild(EntitySpec.create(DynamicGroup.class)
- .configure(DynamicGroup.ENTITY_FILTER, getEntityFilter()));
- setAttribute(ENTITIES, entities);
- setAttribute(A_RECORDS, ImmutableMap.<String, String>of());
- setAttribute(CNAME_RECORDS, ImmutableMultimap.<String, String>of());
- setAttribute(PTR_RECORDS, ImmutableMap.<String, String>of());
- setAttribute(ADDRESS_MAPPINGS, ImmutableMultimap.<String, String>of());
- synchronized (serialMutex) {
- setAttribute(SERIAL, System.currentTimeMillis());
- }
- }
-
- @Override
- public void postRebind() {
- update();
- }
-
- @Override
- public Class<?> getDriverInterface() {
- return BindDnsServerDriver.class;
- }
-
- @Override
- public Multimap<String, String> getAddressMappings() {
- return getAttribute(ADDRESS_MAPPINGS);
- }
-
- @Override
- public Map<String, String> getReverseMappings() {
- return getAttribute(PTR_RECORDS);
- }
-
- @Override
- public BindDnsServerDriver getDriver() {
- return (BindDnsServerDriver) super.getDriver();
- }
-
- @Override
- public void connectSensors() {
- connectServiceUpIsRunning();
- }
-
- @Override
- public void disconnectSensors() {
- super.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);
-
- addPolicy(PolicySpec.create(MemberTrackingPolicy.class)
- .displayName("Address tracker")
- .configure(AbstractMembershipTrackingPolicy.SENSORS_TO_TRACK, ImmutableSet.<Sensor<?>>of(getConfig(HOSTNAME_SENSOR)))
- .configure(AbstractMembershipTrackingPolicy.GROUP, getEntities()));
- }
-
- @Override
- public void postStart() {
- update();
- }
-
- public static class MemberTrackingPolicy extends AbstractMembershipTrackingPolicy {
- @Override
- protected void onEntityChange(Entity member) {
- if (LOG.isTraceEnabled()) {
- LOG.trace("State of {} on change: {}", member, member.getAttribute(Attributes.SERVICE_STATE_ACTUAL).name());
- }
- ((BindDnsServerImpl) entity).update();
- }
- @Override
- protected void onEntityAdded(Entity member) {
- if (LOG.isTraceEnabled()) {
- LOG.trace("State of {} on added: {}", member, member.getAttribute(Attributes.SERVICE_STATE_ACTUAL).name());
- }
- ((BindDnsServerImpl) entity).configureResolver(member);
- }
- }
-
- private class HasHostnameAndValidLifecycle implements Predicate<Entity> {
- @Override
- public boolean apply(Entity input) {
- switch (input.getAttribute(Attributes.SERVICE_STATE_ACTUAL)) {
- case STOPPED:
- case STOPPING:
- case DESTROYED:
- return false;
- }
- return input.getAttribute(getConfig(HOSTNAME_SENSOR)) != null;
- }
- }
-
- public void update() {
- Lifecycle serverState = getAttribute(Attributes.SERVICE_STATE_ACTUAL);
- if (Lifecycle.STOPPED.equals(serverState) || Lifecycle.STOPPING.equals(serverState)
- || Lifecycle.DESTROYED.equals(serverState) || !getAttribute(Attributes.SERVICE_UP)) {
- LOG.debug("Skipped update of {} when service state is {} and running is {}",
- new Object[]{this, getAttribute(Attributes.SERVICE_STATE_ACTUAL), getAttribute(SERVICE_UP)});
- return;
- }
- synchronized (this) {
- Iterable<Entity> availableEntities = FluentIterable.from(getEntities().getMembers())
- .filter(new HasHostnameAndValidLifecycle());
- LOG.debug("{} updating with entities: {}", this, Iterables.toString(availableEntities));
- ImmutableListMultimap<String, Entity> hostnameToEntity = Multimaps.index(availableEntities,
- new HostnameTransformer());
-
- Map<String, String> octetToName = Maps.newHashMap();
- BiMap<String, String> ipToARecord = HashBiMap.create();
- Multimap<String, String> aRecordToCnames = MultimapBuilder.hashKeys().hashSetValues().build();
- Multimap<String, String> ipToAllNames = MultimapBuilder.hashKeys().hashSetValues().build();
-
- for (Map.Entry<String, Entity> e : hostnameToEntity.entries()) {
- String domainName = e.getKey();
- Maybe<SshMachineLocation> location = Machines.findUniqueSshMachineLocation(e.getValue().getLocations());
- if (!location.isPresent()) {
- LOG.debug("Member {} of {} does not have an SSH location so will not be configured", e.getValue(), this);
- continue;
- } else if (ipToARecord.inverse().containsKey(domainName)) {
- continue;
- }
-
- String address = location.get().getAddress().getHostAddress();
- ipToAllNames.put(address, domainName);
- if (!ipToARecord.containsKey(address)) {
- ipToARecord.put(address, domainName);
- if (getReverseLookupNetwork().contains(new Cidr(address + "/32"))) {
- String octet = Iterables.get(Splitter.on('.').split(address), 3);
- if (!octetToName.containsKey(octet)) octetToName.put(octet, domainName);
- }
- } else {
- aRecordToCnames.put(ipToARecord.get(address), domainName);
- }
- }
- setAttribute(A_RECORDS, ImmutableMap.copyOf(ipToARecord.inverse()));
- setAttribute(PTR_RECORDS, ImmutableMap.copyOf(octetToName));
- setAttribute(CNAME_RECORDS, Multimaps.unmodifiableMultimap(aRecordToCnames));
- setAttribute(ADDRESS_MAPPINGS, Multimaps.unmodifiableMultimap(ipToAllNames));
-
- // Update Bind configuration files and restart the service
- getDriver().updateBindConfiguration();
- }
- }
-
- protected void configureResolver(Entity entity) {
- Maybe<SshMachineLocation> machine = Machines.findUniqueSshMachineLocation(entity.getLocations());
- if (machine.isPresent()) {
- if (getConfig(REPLACE_RESOLV_CONF)) {
- machine.get().copyTo(new StringReader(getConfig(RESOLV_CONF_TEMPLATE)), "/etc/resolv.conf");
- } else {
- appendTemplate(getConfig(INTERFACE_CONFIG_TEMPLATE), "/etc/sysconfig/network-scripts/ifcfg-eth0", machine.get());
- machine.get().execScript("reload network", ImmutableList.of(BashCommands.sudo("service network reload")));
- }
- LOG.info("configured resolver on {}", machine);
- } else {
- LOG.debug("{} can't configure resolver at {}: no SshMachineLocation", this, entity);
- }
- }
-
- protected 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)));
- }
-
-
- @Override
- public Predicate<? super Entity> getEntityFilter() {
- return getConfig(ENTITY_FILTER);
- }
-
- // Mostly used in templates
- public String getManagementCidr() {
- return getConfig(MANAGEMENT_CIDR);
- }
-
- public Integer getDnsPort() {
- return getAttribute(DNS_PORT);
- }
-
- public String getDomainName() {
- return getConfig(DOMAIN_NAME);
- }
-
- /**
- * @return A serial number guaranteed to be valid for use in a modified domain.zone or reverse.zone file.
- */
- public long getSerial() {
- synchronized (serialMutex) {
- long next = getAttribute(SERIAL) + 1;
- setAttribute(SERIAL, next);
- return next;
- }
- }
-
- public Cidr getReverseLookupNetwork() {
- return getAttribute(REVERSE_LOOKUP_CIDR);
- }
-
- public String getReverseLookupDomain() {
- return getAttribute(REVERSE_LOOKUP_DOMAIN);
- }
-
- public DynamicGroup getEntities() {
- return getAttribute(ENTITIES);
- }
-
- public Map<String, String> getAddressRecords() {
- return getAttribute(A_RECORDS);
- }
-
- public Multimap<String, String> getCanonicalNameRecords() {
- return getAttribute(CNAME_RECORDS);
- }
-
- public Map<String, Collection<String>> getCnamesForTemplates() {
- return getAttribute(CNAME_RECORDS).asMap();
- }
-
- public Map<String, String> getPointerRecords() {
- return getAttribute(PTR_RECORDS);
- }
-
-}
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/689b49c3/software/network/src/main/java/brooklyn/entity/network/bind/BindDnsServerSshDriver.java
----------------------------------------------------------------------
diff --git a/software/network/src/main/java/brooklyn/entity/network/bind/BindDnsServerSshDriver.java b/software/network/src/main/java/brooklyn/entity/network/bind/BindDnsServerSshDriver.java
deleted file mode 100644
index 983be65..0000000
--- a/software/network/src/main/java/brooklyn/entity/network/bind/BindDnsServerSshDriver.java
+++ /dev/null
@@ -1,184 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you 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.List;
-import java.util.Map;
-
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import com.google.common.collect.ImmutableList;
-import com.google.common.collect.Lists;
-
-import brooklyn.entity.basic.AbstractSoftwareProcessSshDriver;
-import brooklyn.location.basic.SshMachineLocation;
-import brooklyn.util.collections.MutableMap;
-import brooklyn.util.net.Networking;
-import brooklyn.util.net.Protocol;
-import brooklyn.util.os.Os;
-import brooklyn.util.ssh.BashCommands;
-import brooklyn.util.ssh.IptablesCommands;
-import brooklyn.util.ssh.IptablesCommands.Chain;
-import brooklyn.util.ssh.IptablesCommands.Policy;
-import brooklyn.util.text.Strings;
-
-public class BindDnsServerSshDriver extends AbstractSoftwareProcessSshDriver implements BindDnsServerDriver {
-
- private static final Logger LOG = LoggerFactory.getLogger(BindDnsServerSshDriver.class);
- private volatile BindOsSupport osSupport;
- private final Object osSupportMutex = new Object();
-
- public BindDnsServerSshDriver(BindDnsServerImpl entity, SshMachineLocation machine) {
- super(entity, machine);
- }
-
- @Override
- public BindDnsServerImpl getEntity() {
- return (BindDnsServerImpl) super.getEntity();
- }
-
- @Override
- public void install() {
- List<String> commands = ImmutableList.<String>builder()
- .add(BashCommands.installPackage(MutableMap.of(
- "yum", "bind", "apt", "bind9"), "bind"))
- .add(BashCommands.ok("which setenforce && " + BashCommands.sudo("setenforce 0")))
- .build();
- newScript(INSTALLING)
- .failOnNonZeroResultCode()
- .body.append(commands)
- .execute();
- }
-
- @Override
- public void customize() {
- Integer dnsPort = getEntity().getDnsPort();
- Map<String, Object> ports = MutableMap.<String, Object>of("dnsPort", dnsPort);
- Networking.checkPortsValid(ports);
-
- List<String> commands = Lists.newArrayList(
- BashCommands.sudo("mkdir -p " + getDataDirectory() + " " + getDynamicDirectory() + " " + getOsSupport().getConfigDirectory()),
- BashCommands.sudo("chown -R bind:bind " + getDataDirectory() + " " + getDynamicDirectory()),
- // TODO determine name of ethernet interface if not eth0?
- IptablesCommands.insertIptablesRule(Chain.INPUT, "eth0", Protocol.UDP, dnsPort, Policy.ACCEPT),
- IptablesCommands.insertIptablesRule(Chain.INPUT, "eth0", Protocol.TCP, dnsPort, Policy.ACCEPT),
- // TODO Iptables is not a service on Ubuntu
- BashCommands.sudo("service iptables save"),
- BashCommands.sudo("service iptables restart"));
- if (getEntity().getConfig(BindDnsServer.UPDATE_ROOT_ZONES_FILE)) {
- commands.add("wget --user=ftp --password=ftp ftp://ftp.rs.internic.net/domain/db.cache " +
- "-O " + getOsSupport().getRootZonesFile());
- }
- newScript(CUSTOMIZING)
- .body.append(commands)
- // fails if iptables is not a service, e.g. on ubuntu
- //.failOnNonZeroResultCode()
- .execute();
-
- copyAsRoot("classpath://brooklyn/entity/network/bind/rfc1912.zone", getRfc1912ZonesFile());
- copyAsRoot("classpath://brooklyn/entity/network/bind/named.localhost", Os.mergePathsUnix(getOsSupport().getConfigDirectory(), "named.localhost"));
- copyAsRoot("classpath://brooklyn/entity/network/bind/named.loopback", Os.mergePathsUnix(getOsSupport().getConfigDirectory(), "named.loopback"));
- copyAsRoot("classpath://brooklyn/entity/network/bind/named.empty", Os.mergePathsUnix(getOsSupport().getConfigDirectory(), "named.empty"));
-
- newScript("Checking BIND configuration")
- .body.append(BashCommands.sudo("named-checkconf"))
- .failOnNonZeroResultCode()
- .execute();
- }
-
- @Override
- public void launch() {
- newScript(MutableMap.of("usePidFile", false), LAUNCHING)
- .body.append(BashCommands.sudo("service " + getOsSupport().getServiceName() + " start"))
- .execute();
- }
-
- @Override
- public boolean isRunning() {
- return newScript(MutableMap.of("usePidFile", false), CHECK_RUNNING)
- .body.append(BashCommands.sudo("service " + getOsSupport().getServiceName() + " status"))
- .execute() == 0;
- }
-
- @Override
- public void stop() {
- newScript(MutableMap.of("usePidFile", false), STOPPING)
- .body.append(BashCommands.sudo("service " + getOsSupport().getServiceName() + " stop"))
- .execute();
- }
-
- @Override
- public void updateBindConfiguration() {
- LOG.debug("Updating bind configuration at " + getMachine());
- copyAsRoot(entity.getConfig(BindDnsServer.NAMED_CONF_TEMPLATE), getOsSupport().getRootConfigFile());
- copyAsRoot(entity.getConfig(BindDnsServer.DOMAIN_ZONE_FILE_TEMPLATE), getDomainZoneFile());
- copyAsRoot(entity.getConfig(BindDnsServer.REVERSE_ZONE_FILE_TEMPLATE), getReverseZoneFile());
- int result = getMachine().execScript("restart bind",
- ImmutableList.of(BashCommands.sudo("service " + getOsSupport().getServiceName() + " restart")));
- LOG.info("Updated named configuration and zone file for '{}' on {} (exit code {}).",
- new Object[]{entity.getConfig(BindDnsServer.DOMAIN_NAME), entity, result});
- }
-
- private void copyAsRoot(String template, String destination) {
- String content = processTemplate(template);
- String temp = "/tmp/template-" + Strings.makeRandomId(6);
- getMachine().copyTo(new ByteArrayInputStream(content.getBytes()), temp);
- getMachine().execScript("copying file", ImmutableList.of(BashCommands.sudo(String.format("mv %s %s", temp, destination))));
- }
-
- /** @return The location on the server of the domain zone file */
- public String getDomainZoneFile() {
- return Os.mergePaths(getOsSupport().getConfigDirectory(), "domain.zone");
- }
-
- /** @return The location on the server of the reverse zone file */
- public String getReverseZoneFile() {
- return Os.mergePaths(getOsSupport().getConfigDirectory(), "reverse.zone");
- }
-
- public String getDataDirectory() {
- return Os.mergePaths(getOsSupport().getWorkingDirectory(), "data");
- }
-
- public String getDynamicDirectory() {
- return Os.mergePaths(getOsSupport().getWorkingDirectory(), "dynamic");
- }
-
- public String getRfc1912ZonesFile() {
- return Os.mergePaths(getOsSupport().getConfigDirectory(), "rfc1912.zone");
- }
-
- public BindOsSupport getOsSupport() {
- BindOsSupport result = osSupport;
- if (result == null) {
- synchronized (osSupportMutex) {
- result = osSupport;
- if (result == null) {
- boolean yumExists = newScript("testing for yum")
- .body.append(BashCommands.requireExecutable("yum"))
- .execute() == 0;
- osSupport = result = yumExists ? BindOsSupport.forRhel() : BindOsSupport.forDebian();
- }
- }
- }
- return result;
- }
-}
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/689b49c3/software/network/src/main/java/brooklyn/entity/network/bind/BindOsSupport.java
----------------------------------------------------------------------
diff --git a/software/network/src/main/java/brooklyn/entity/network/bind/BindOsSupport.java b/software/network/src/main/java/brooklyn/entity/network/bind/BindOsSupport.java
deleted file mode 100644
index 8ef5f83..0000000
--- a/software/network/src/main/java/brooklyn/entity/network/bind/BindOsSupport.java
+++ /dev/null
@@ -1,113 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you 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 javax.annotation.concurrent.Immutable;
-
-/**
- * Provides operating system-specific information for working with the Bind service.
- */
-// Class would be package-private if Freemarker didn't complain vociferously.
-@Immutable
-public class BindOsSupport {
-
- // Likewise would make these package-private and have no getters if Freemarker was ok with it.
- private final String packageName;
- private final String serviceName;
- private final String rootConfigFile;
- private final String configDirectory;
- private final String workingDirectory;
- private final String rootZonesFile;
- private final String keysFile;
-
- private BindOsSupport(
- String packageName,
- String serviceName,
- String rootConfigFile,
- String configDirectory,
- String workingDirectory,
- String rootZonesFile,
- String keysFile) {
- this.packageName = packageName;
- this.serviceName = serviceName;
- this.rootConfigFile = rootConfigFile;
- this.configDirectory = configDirectory;
- this.workingDirectory = workingDirectory;
- this.rootZonesFile = rootZonesFile;
- this.keysFile = keysFile;
- }
-
- /**
- * @return support for RHEL-based operating systems.
- */
- public static BindOsSupport forRhel() {
- return new BindOsSupport(
- "bind",
- "named",
- "/etc/named.conf",
- "/var/named",
- "/var/named/data",
- "/var/named/named.ca",
- "/etc/named.iscdlv.key");
- }
-
- /**
- * @return support for Debian-based operating systems.
- */
- public static BindOsSupport forDebian() {
- return new BindOsSupport(
- "bind9",
- "bind9",
- "/etc/bind/named.conf",
- "/etc/bind",
- "/var/cache/bind",
- "/etc/bind/db.root",
- "/etc/bind/bind.keys"
- );
- }
-
- public String getPackageName() {
- return packageName;
- }
-
- public String getServiceName() {
- return serviceName;
- }
-
- public String getRootConfigFile() {
- return rootConfigFile;
- }
-
- public String getConfigDirectory() {
- return configDirectory;
- }
-
- public String getWorkingDirectory() {
- return workingDirectory;
- }
-
- public String getRootZonesFile() {
- return rootZonesFile;
- }
-
- public String getKeysFile() {
- return keysFile;
- }
-
-}
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/689b49c3/software/network/src/main/java/org/apache/brooklyn/entity/network/bind/BindDnsServer.java
----------------------------------------------------------------------
diff --git a/software/network/src/main/java/org/apache/brooklyn/entity/network/bind/BindDnsServer.java b/software/network/src/main/java/org/apache/brooklyn/entity/network/bind/BindDnsServer.java
new file mode 100644
index 0000000..8534440
--- /dev/null
+++ b/software/network/src/main/java/org/apache/brooklyn/entity/network/bind/BindDnsServer.java
@@ -0,0 +1,156 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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 org.apache.brooklyn.entity.network.bind;
+
+import java.util.Map;
+
+import com.google.common.base.Predicate;
+import com.google.common.base.Predicates;
+import com.google.common.collect.Multimap;
+import com.google.common.reflect.TypeToken;
+
+import org.apache.brooklyn.catalog.Catalog;
+import brooklyn.config.ConfigKey;
+import brooklyn.entity.Entity;
+import brooklyn.entity.annotation.Effector;
+import brooklyn.entity.basic.ConfigKeys;
+import brooklyn.entity.basic.DynamicGroup;
+import brooklyn.entity.basic.SoftwareProcess;
+import brooklyn.entity.proxying.ImplementedBy;
+import brooklyn.event.AttributeSensor;
+import brooklyn.event.basic.PortAttributeSensorAndConfigKey;
+import brooklyn.event.basic.Sensors;
+import brooklyn.location.basic.PortRanges;
+import brooklyn.util.flags.SetFromFlag;
+import brooklyn.util.net.Cidr;
+
+/**
+ * This sets up a BIND DNS server.
+ */
+@Catalog(name="BIND", description="BIND is an Internet Domain Name Server.", iconUrl="classpath:///isc-logo.png")
+@ImplementedBy(BindDnsServerImpl.class)
+public interface BindDnsServer extends SoftwareProcess {
+
+ @SetFromFlag("filter")
+ ConfigKey<Predicate<? super Entity>> ENTITY_FILTER = ConfigKeys.newConfigKey(new TypeToken<Predicate<? super Entity>>() {},
+ "bind.entity.filter", "Filter for entities which will use the BIND DNS service for name resolution." +
+ "Default is all instances of SoftwareProcess in the application.",
+ Predicates.instanceOf(SoftwareProcess.class));
+
+ @SetFromFlag("domainName")
+ ConfigKey<String> DOMAIN_NAME = ConfigKeys.newStringConfigKey(
+ "bind.domain.name", "The DNS domain name to serve", "brooklyn.local");
+
+ @SetFromFlag("reverseLookupNetwork")
+ ConfigKey<String> REVERSE_LOOKUP_NETWORK = ConfigKeys.newStringConfigKey(
+ "bind.reverse-lookup.address", "Network address for reverse lookup zone");
+
+ @SetFromFlag("subnet")
+ ConfigKey<String> MANAGEMENT_CIDR = ConfigKeys.newStringConfigKey(
+ "bind.access.cidr", "Subnet CIDR or ACL allowed to access DNS", "0.0.0.0/0");
+
+ @SetFromFlag("hostnameSensor")
+ ConfigKey<AttributeSensor<String>> HOSTNAME_SENSOR = ConfigKeys.newConfigKey(new TypeToken<AttributeSensor<String>>() {},
+ "bind.sensor.hostname", "Sensor on managed entities that reports the hostname");
+
+ PortAttributeSensorAndConfigKey DNS_PORT =
+ new PortAttributeSensorAndConfigKey("bind.port", "BIND DNS port for TCP and UDP", PortRanges.fromString("53"));
+
+ @SetFromFlag("zoneFileTemplate")
+ ConfigKey<String> DOMAIN_ZONE_FILE_TEMPLATE = ConfigKeys.newStringConfigKey(
+ "bind.template.domain-zone", "The BIND domain zone file to serve (as FreeMarker template)",
+ "classpath://org/apache/brooklyn/entity/network/bind/domain.zone");
+
+ @SetFromFlag("reverseZoneFileTemplate")
+ ConfigKey<String> REVERSE_ZONE_FILE_TEMPLATE = ConfigKeys.newStringConfigKey(
+ "bind.template.reverse-zone", "The BIND reverse lookup zone file to serve (as FreeMarker template)",
+ "classpath://org/apache/brooklyn/entity/network/bind/reverse.zone");
+
+ @SetFromFlag("namedConfTemplate")
+ ConfigKey<String> NAMED_CONF_TEMPLATE = ConfigKeys.newStringConfigKey(
+ "bind.template.named-conf", "The BIND named configuration file (as FreeMarker template)",
+ "classpath://org/apache/brooklyn/entity/network/bind/named.conf");
+
+ @SetFromFlag("updateRootZonesFile")
+ ConfigKey<Boolean> UPDATE_ROOT_ZONES_FILE = ConfigKeys.newBooleanConfigKey(
+ "bind.updateRootZones", "Instructs the entity to fetch the latest root zones file from ftp.rs.internic.net.",
+ Boolean.FALSE);
+
+
+ /* Reverse lookup attributes. */
+
+ AttributeSensor<Cidr> REVERSE_LOOKUP_CIDR = Sensors.newSensor(Cidr.class,
+ "bind.reverse-lookup.cidr", "The network CIDR that hosts must have for reverse lookup entries " +
+ "to be added (default uses server address /24)");
+
+ AttributeSensor<String> REVERSE_LOOKUP_DOMAIN = Sensors.newStringSensor(
+ "bind.reverse-lookup.domain", "The in-addr.arpa reverse lookup domain name");
+
+
+ /* Configuration applicable to clients of the BIND DNS service. */
+
+ @SetFromFlag("replaceResolvConf")
+ ConfigKey<Boolean> REPLACE_RESOLV_CONF = ConfigKeys.newBooleanConfigKey(
+ "bind.resolv-conf.replce", "Set to replace resolv.conf with the template (default is to use eth0 script)", Boolean.FALSE);
+
+ @SetFromFlag("interfaceConfigTemplate")
+ ConfigKey<String> INTERFACE_CONFIG_TEMPLATE = ConfigKeys.newStringConfigKey(
+ "bind.template.interface-cfg", "The network interface configuration file for clients (as FreeMarker template)",
+ "classpath://org/apache/brooklyn/entity/network/bind/ifcfg");
+
+ @SetFromFlag("interfaceConfigTemplate")
+ ConfigKey<String> RESOLV_CONF_TEMPLATE = ConfigKeys.newStringConfigKey(
+ "bind.template.resolv-conf", "The resolver configuration file for clients (as FreeMarker template)",
+ "classpath://org/apache/brooklyn/entity/network/bind/resolv.conf");
+
+ AttributeSensor<DynamicGroup> ENTITIES = Sensors.newSensor(DynamicGroup.class,
+ "bind.entities", "The entities being managed by this server");
+
+ AttributeSensor<Multimap<String, String>> ADDRESS_MAPPINGS = Sensors.newSensor(new TypeToken<Multimap<String, String>>() {},
+ "bind.mappings", "All address mappings maintained by the server, in form address -> [names]");
+
+ AttributeSensor<Map<String, String>> A_RECORDS = Sensors.newSensor(new TypeToken<Map<String, String>>() {},
+ "bind.records.a", "All A records for the server, in form name -> address");
+
+ AttributeSensor<Multimap<String, String>> CNAME_RECORDS = Sensors.newSensor(new TypeToken<Multimap<String, String>>() {},
+ "bind.records.cname", "All CNAME records for the server, in form name -> [names]");
+
+ AttributeSensor<Map<String, String>> PTR_RECORDS = Sensors.newSensor(new TypeToken<Map<String, String>>() {},
+ "bind.records.ptr", "All PTR records for the server, in form address -> name. Entries will be in REVERSE_LOOKUP_CIDR. " +
+ "Entries are guaranteed to have an inverse mapping in A_RECORDS.");
+
+ AttributeSensor<Long> SERIAL = Sensors.newLongSensor(
+ "bind.serial", "A serial number guaranteed to be valid for use in a modified domain.zone or reverse.zone file");
+
+ public Multimap<String, String> getAddressMappings();
+
+ /**
+ * @return the IP to hostname mappings stored in this DNS server's conf file
+ * @deprecated since 0.7.0 use {@link #PTR_RECORDS} instead.
+ */
+ @Deprecated
+ @Effector(description="Gets the IP to hostname mappings stored in this DNS server's conf file")
+ public Map<String, String> getReverseMappings();
+
+ /**
+ * @return the predicate used to filter entities for the Bind server to manage.
+ */
+ Predicate<? super Entity> getEntityFilter();
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/689b49c3/software/network/src/main/java/org/apache/brooklyn/entity/network/bind/BindDnsServerDriver.java
----------------------------------------------------------------------
diff --git a/software/network/src/main/java/org/apache/brooklyn/entity/network/bind/BindDnsServerDriver.java b/software/network/src/main/java/org/apache/brooklyn/entity/network/bind/BindDnsServerDriver.java
new file mode 100644
index 0000000..50a1994
--- /dev/null
+++ b/software/network/src/main/java/org/apache/brooklyn/entity/network/bind/BindDnsServerDriver.java
@@ -0,0 +1,38 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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 org.apache.brooklyn.entity.network.bind;
+
+import com.google.common.annotations.VisibleForTesting;
+
+import brooklyn.entity.basic.SoftwareProcessDriver;
+
+public interface BindDnsServerDriver extends SoftwareProcessDriver {
+
+ /**
+ * Uploads configuration files and restarts the service.
+ */
+ void updateBindConfiguration();
+
+ /**
+ * @return a support class appropriate for the machine the server is running on.
+ */
+ @VisibleForTesting
+ BindOsSupport getOsSupport();
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/689b49c3/software/network/src/main/java/org/apache/brooklyn/entity/network/bind/BindDnsServerImpl.java
----------------------------------------------------------------------
diff --git a/software/network/src/main/java/org/apache/brooklyn/entity/network/bind/BindDnsServerImpl.java b/software/network/src/main/java/org/apache/brooklyn/entity/network/bind/BindDnsServerImpl.java
new file mode 100644
index 0000000..05d0787
--- /dev/null
+++ b/software/network/src/main/java/org/apache/brooklyn/entity/network/bind/BindDnsServerImpl.java
@@ -0,0 +1,339 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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 org.apache.brooklyn.entity.network.bind;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+
+import java.io.ByteArrayInputStream;
+import java.io.StringReader;
+import java.util.Collection;
+import java.util.Map;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.google.common.base.CharMatcher;
+import com.google.common.base.Function;
+import com.google.common.base.Joiner;
+import com.google.common.base.Predicate;
+import com.google.common.base.Splitter;
+import com.google.common.collect.BiMap;
+import com.google.common.collect.FluentIterable;
+import com.google.common.collect.HashBiMap;
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.ImmutableListMultimap;
+import com.google.common.collect.ImmutableMap;
+import com.google.common.collect.ImmutableMultimap;
+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;
+import com.google.common.collect.MultimapBuilder;
+import com.google.common.collect.Multimaps;
+
+import brooklyn.entity.Entity;
+import brooklyn.entity.basic.Attributes;
+import brooklyn.entity.basic.DynamicGroup;
+import brooklyn.entity.basic.Lifecycle;
+import brooklyn.entity.basic.SoftwareProcessImpl;
+import brooklyn.entity.group.AbstractMembershipTrackingPolicy;
+import brooklyn.entity.proxying.EntitySpec;
+import brooklyn.event.Sensor;
+import brooklyn.location.basic.Machines;
+import brooklyn.location.basic.SshMachineLocation;
+import brooklyn.policy.PolicySpec;
+import brooklyn.util.guava.Maybe;
+import brooklyn.util.net.Cidr;
+import brooklyn.util.ssh.BashCommands;
+import brooklyn.util.text.Strings;
+
+/**
+ * This sets up a BIND DNS server.
+ * <p>
+ * <b>NOTE</b> This entity has only been certified on <i>CentOS</i>, <i>RHEL</i>,
+ * <i>Ubuntu</i> and <i>Debian</i> operating systems.
+ */
+public class BindDnsServerImpl extends SoftwareProcessImpl implements BindDnsServer {
+
+ private static final Logger LOG = LoggerFactory.getLogger(BindDnsServerImpl.class);
+ private final Object serialMutex = new Object();
+
+ // As per RFC 952 and RFC 1123.
+ private static final CharMatcher DOMAIN_NAME_FIRST_CHAR_MATCHER = CharMatcher.inRange('a', 'z')
+ .or(CharMatcher.inRange('A', 'Z'))
+ .or(CharMatcher.inRange('0', '9'));
+ private static final CharMatcher DOMAIN_NAME_MATCHER = DOMAIN_NAME_FIRST_CHAR_MATCHER
+ .or(CharMatcher.is('-'));
+
+
+ private class HostnameTransformer implements Function<Entity, String> {
+ @Override
+ public String apply(Entity input) {
+ String hostname = input.getAttribute(getConfig(HOSTNAME_SENSOR));
+ hostname = DOMAIN_NAME_FIRST_CHAR_MATCHER.negate().trimFrom(hostname);
+ hostname = DOMAIN_NAME_MATCHER.negate().trimAndCollapseFrom(hostname, '-');
+ if (hostname.length() > 63) {
+ hostname = hostname.substring(0, 63);
+ }
+ return hostname;
+ }
+ }
+
+ public BindDnsServerImpl() {
+ super();
+ }
+
+ @Override
+ public void init() {
+ super.init();
+ checkNotNull(getConfig(HOSTNAME_SENSOR), "%s requires value for %s", getClass().getName(), HOSTNAME_SENSOR);
+ DynamicGroup entities = addChild(EntitySpec.create(DynamicGroup.class)
+ .configure(DynamicGroup.ENTITY_FILTER, getEntityFilter()));
+ setAttribute(ENTITIES, entities);
+ setAttribute(A_RECORDS, ImmutableMap.<String, String>of());
+ setAttribute(CNAME_RECORDS, ImmutableMultimap.<String, String>of());
+ setAttribute(PTR_RECORDS, ImmutableMap.<String, String>of());
+ setAttribute(ADDRESS_MAPPINGS, ImmutableMultimap.<String, String>of());
+ synchronized (serialMutex) {
+ setAttribute(SERIAL, System.currentTimeMillis());
+ }
+ }
+
+ @Override
+ public void postRebind() {
+ update();
+ }
+
+ @Override
+ public Class<?> getDriverInterface() {
+ return BindDnsServerDriver.class;
+ }
+
+ @Override
+ public Multimap<String, String> getAddressMappings() {
+ return getAttribute(ADDRESS_MAPPINGS);
+ }
+
+ @Override
+ public Map<String, String> getReverseMappings() {
+ return getAttribute(PTR_RECORDS);
+ }
+
+ @Override
+ public BindDnsServerDriver getDriver() {
+ return (BindDnsServerDriver) super.getDriver();
+ }
+
+ @Override
+ public void connectSensors() {
+ connectServiceUpIsRunning();
+ }
+
+ @Override
+ public void disconnectSensors() {
+ super.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);
+
+ addPolicy(PolicySpec.create(MemberTrackingPolicy.class)
+ .displayName("Address tracker")
+ .configure(AbstractMembershipTrackingPolicy.SENSORS_TO_TRACK, ImmutableSet.<Sensor<?>>of(getConfig(HOSTNAME_SENSOR)))
+ .configure(AbstractMembershipTrackingPolicy.GROUP, getEntities()));
+ }
+
+ @Override
+ public void postStart() {
+ update();
+ }
+
+ public static class MemberTrackingPolicy extends AbstractMembershipTrackingPolicy {
+ @Override
+ protected void onEntityChange(Entity member) {
+ if (LOG.isTraceEnabled()) {
+ LOG.trace("State of {} on change: {}", member, member.getAttribute(Attributes.SERVICE_STATE_ACTUAL).name());
+ }
+ ((BindDnsServerImpl) entity).update();
+ }
+ @Override
+ protected void onEntityAdded(Entity member) {
+ if (LOG.isTraceEnabled()) {
+ LOG.trace("State of {} on added: {}", member, member.getAttribute(Attributes.SERVICE_STATE_ACTUAL).name());
+ }
+ ((BindDnsServerImpl) entity).configureResolver(member);
+ }
+ }
+
+ private class HasHostnameAndValidLifecycle implements Predicate<Entity> {
+ @Override
+ public boolean apply(Entity input) {
+ switch (input.getAttribute(Attributes.SERVICE_STATE_ACTUAL)) {
+ case STOPPED:
+ case STOPPING:
+ case DESTROYED:
+ return false;
+ }
+ return input.getAttribute(getConfig(HOSTNAME_SENSOR)) != null;
+ }
+ }
+
+ public void update() {
+ Lifecycle serverState = getAttribute(Attributes.SERVICE_STATE_ACTUAL);
+ if (Lifecycle.STOPPED.equals(serverState) || Lifecycle.STOPPING.equals(serverState)
+ || Lifecycle.DESTROYED.equals(serverState) || !getAttribute(Attributes.SERVICE_UP)) {
+ LOG.debug("Skipped update of {} when service state is {} and running is {}",
+ new Object[]{this, getAttribute(Attributes.SERVICE_STATE_ACTUAL), getAttribute(SERVICE_UP)});
+ return;
+ }
+ synchronized (this) {
+ Iterable<Entity> availableEntities = FluentIterable.from(getEntities().getMembers())
+ .filter(new HasHostnameAndValidLifecycle());
+ LOG.debug("{} updating with entities: {}", this, Iterables.toString(availableEntities));
+ ImmutableListMultimap<String, Entity> hostnameToEntity = Multimaps.index(availableEntities,
+ new HostnameTransformer());
+
+ Map<String, String> octetToName = Maps.newHashMap();
+ BiMap<String, String> ipToARecord = HashBiMap.create();
+ Multimap<String, String> aRecordToCnames = MultimapBuilder.hashKeys().hashSetValues().build();
+ Multimap<String, String> ipToAllNames = MultimapBuilder.hashKeys().hashSetValues().build();
+
+ for (Map.Entry<String, Entity> e : hostnameToEntity.entries()) {
+ String domainName = e.getKey();
+ Maybe<SshMachineLocation> location = Machines.findUniqueSshMachineLocation(e.getValue().getLocations());
+ if (!location.isPresent()) {
+ LOG.debug("Member {} of {} does not have an SSH location so will not be configured", e.getValue(), this);
+ continue;
+ } else if (ipToARecord.inverse().containsKey(domainName)) {
+ continue;
+ }
+
+ String address = location.get().getAddress().getHostAddress();
+ ipToAllNames.put(address, domainName);
+ if (!ipToARecord.containsKey(address)) {
+ ipToARecord.put(address, domainName);
+ if (getReverseLookupNetwork().contains(new Cidr(address + "/32"))) {
+ String octet = Iterables.get(Splitter.on('.').split(address), 3);
+ if (!octetToName.containsKey(octet)) octetToName.put(octet, domainName);
+ }
+ } else {
+ aRecordToCnames.put(ipToARecord.get(address), domainName);
+ }
+ }
+ setAttribute(A_RECORDS, ImmutableMap.copyOf(ipToARecord.inverse()));
+ setAttribute(PTR_RECORDS, ImmutableMap.copyOf(octetToName));
+ setAttribute(CNAME_RECORDS, Multimaps.unmodifiableMultimap(aRecordToCnames));
+ setAttribute(ADDRESS_MAPPINGS, Multimaps.unmodifiableMultimap(ipToAllNames));
+
+ // Update Bind configuration files and restart the service
+ getDriver().updateBindConfiguration();
+ }
+ }
+
+ protected void configureResolver(Entity entity) {
+ Maybe<SshMachineLocation> machine = Machines.findUniqueSshMachineLocation(entity.getLocations());
+ if (machine.isPresent()) {
+ if (getConfig(REPLACE_RESOLV_CONF)) {
+ machine.get().copyTo(new StringReader(getConfig(RESOLV_CONF_TEMPLATE)), "/etc/resolv.conf");
+ } else {
+ appendTemplate(getConfig(INTERFACE_CONFIG_TEMPLATE), "/etc/sysconfig/network-scripts/ifcfg-eth0", machine.get());
+ machine.get().execScript("reload network", ImmutableList.of(BashCommands.sudo("service network reload")));
+ }
+ LOG.info("configured resolver on {}", machine);
+ } else {
+ LOG.debug("{} can't configure resolver at {}: no SshMachineLocation", this, entity);
+ }
+ }
+
+ protected 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)));
+ }
+
+
+ @Override
+ public Predicate<? super Entity> getEntityFilter() {
+ return getConfig(ENTITY_FILTER);
+ }
+
+ // Mostly used in templates
+ public String getManagementCidr() {
+ return getConfig(MANAGEMENT_CIDR);
+ }
+
+ public Integer getDnsPort() {
+ return getAttribute(DNS_PORT);
+ }
+
+ public String getDomainName() {
+ return getConfig(DOMAIN_NAME);
+ }
+
+ /**
+ * @return A serial number guaranteed to be valid for use in a modified domain.zone or reverse.zone file.
+ */
+ public long getSerial() {
+ synchronized (serialMutex) {
+ long next = getAttribute(SERIAL) + 1;
+ setAttribute(SERIAL, next);
+ return next;
+ }
+ }
+
+ public Cidr getReverseLookupNetwork() {
+ return getAttribute(REVERSE_LOOKUP_CIDR);
+ }
+
+ public String getReverseLookupDomain() {
+ return getAttribute(REVERSE_LOOKUP_DOMAIN);
+ }
+
+ public DynamicGroup getEntities() {
+ return getAttribute(ENTITIES);
+ }
+
+ public Map<String, String> getAddressRecords() {
+ return getAttribute(A_RECORDS);
+ }
+
+ public Multimap<String, String> getCanonicalNameRecords() {
+ return getAttribute(CNAME_RECORDS);
+ }
+
+ public Map<String, Collection<String>> getCnamesForTemplates() {
+ return getAttribute(CNAME_RECORDS).asMap();
+ }
+
+ public Map<String, String> getPointerRecords() {
+ return getAttribute(PTR_RECORDS);
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/689b49c3/software/network/src/main/java/org/apache/brooklyn/entity/network/bind/BindDnsServerSshDriver.java
----------------------------------------------------------------------
diff --git a/software/network/src/main/java/org/apache/brooklyn/entity/network/bind/BindDnsServerSshDriver.java b/software/network/src/main/java/org/apache/brooklyn/entity/network/bind/BindDnsServerSshDriver.java
new file mode 100644
index 0000000..09451c6
--- /dev/null
+++ b/software/network/src/main/java/org/apache/brooklyn/entity/network/bind/BindDnsServerSshDriver.java
@@ -0,0 +1,184 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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 org.apache.brooklyn.entity.network.bind;
+
+import java.io.ByteArrayInputStream;
+import java.util.List;
+import java.util.Map;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.Lists;
+
+import brooklyn.entity.basic.AbstractSoftwareProcessSshDriver;
+import brooklyn.location.basic.SshMachineLocation;
+import brooklyn.util.collections.MutableMap;
+import brooklyn.util.net.Networking;
+import brooklyn.util.net.Protocol;
+import brooklyn.util.os.Os;
+import brooklyn.util.ssh.BashCommands;
+import brooklyn.util.ssh.IptablesCommands;
+import brooklyn.util.ssh.IptablesCommands.Chain;
+import brooklyn.util.ssh.IptablesCommands.Policy;
+import brooklyn.util.text.Strings;
+
+public class BindDnsServerSshDriver extends AbstractSoftwareProcessSshDriver implements BindDnsServerDriver {
+
+ private static final Logger LOG = LoggerFactory.getLogger(BindDnsServerSshDriver.class);
+ private volatile BindOsSupport osSupport;
+ private final Object osSupportMutex = new Object();
+
+ public BindDnsServerSshDriver(BindDnsServerImpl entity, SshMachineLocation machine) {
+ super(entity, machine);
+ }
+
+ @Override
+ public BindDnsServerImpl getEntity() {
+ return (BindDnsServerImpl) super.getEntity();
+ }
+
+ @Override
+ public void install() {
+ List<String> commands = ImmutableList.<String>builder()
+ .add(BashCommands.installPackage(MutableMap.of(
+ "yum", "bind", "apt", "bind9"), "bind"))
+ .add(BashCommands.ok("which setenforce && " + BashCommands.sudo("setenforce 0")))
+ .build();
+ newScript(INSTALLING)
+ .failOnNonZeroResultCode()
+ .body.append(commands)
+ .execute();
+ }
+
+ @Override
+ public void customize() {
+ Integer dnsPort = getEntity().getDnsPort();
+ Map<String, Object> ports = MutableMap.<String, Object>of("dnsPort", dnsPort);
+ Networking.checkPortsValid(ports);
+
+ List<String> commands = Lists.newArrayList(
+ BashCommands.sudo("mkdir -p " + getDataDirectory() + " " + getDynamicDirectory() + " " + getOsSupport().getConfigDirectory()),
+ BashCommands.sudo("chown -R bind:bind " + getDataDirectory() + " " + getDynamicDirectory()),
+ // TODO determine name of ethernet interface if not eth0?
+ IptablesCommands.insertIptablesRule(Chain.INPUT, "eth0", Protocol.UDP, dnsPort, Policy.ACCEPT),
+ IptablesCommands.insertIptablesRule(Chain.INPUT, "eth0", Protocol.TCP, dnsPort, Policy.ACCEPT),
+ // TODO Iptables is not a service on Ubuntu
+ BashCommands.sudo("service iptables save"),
+ BashCommands.sudo("service iptables restart"));
+ if (getEntity().getConfig(BindDnsServer.UPDATE_ROOT_ZONES_FILE)) {
+ commands.add("wget --user=ftp --password=ftp ftp://ftp.rs.internic.net/domain/db.cache " +
+ "-O " + getOsSupport().getRootZonesFile());
+ }
+ newScript(CUSTOMIZING)
+ .body.append(commands)
+ // fails if iptables is not a service, e.g. on ubuntu
+ //.failOnNonZeroResultCode()
+ .execute();
+
+ copyAsRoot("classpath://org/apache/brooklyn/entity/network/bind/rfc1912.zone", getRfc1912ZonesFile());
+ copyAsRoot("classpath://org/apache/brooklyn/entity/network/bind/named.localhost", Os.mergePathsUnix(getOsSupport().getConfigDirectory(), "named.localhost"));
+ copyAsRoot("classpath://org/apache/brooklyn/entity/network/bind/named.loopback", Os.mergePathsUnix(getOsSupport().getConfigDirectory(), "named.loopback"));
+ copyAsRoot("classpath://org/apache/brooklyn/entity/network/bind/named.empty", Os.mergePathsUnix(getOsSupport().getConfigDirectory(), "named.empty"));
+
+ newScript("Checking BIND configuration")
+ .body.append(BashCommands.sudo("named-checkconf"))
+ .failOnNonZeroResultCode()
+ .execute();
+ }
+
+ @Override
+ public void launch() {
+ newScript(MutableMap.of("usePidFile", false), LAUNCHING)
+ .body.append(BashCommands.sudo("service " + getOsSupport().getServiceName() + " start"))
+ .execute();
+ }
+
+ @Override
+ public boolean isRunning() {
+ return newScript(MutableMap.of("usePidFile", false), CHECK_RUNNING)
+ .body.append(BashCommands.sudo("service " + getOsSupport().getServiceName() + " status"))
+ .execute() == 0;
+ }
+
+ @Override
+ public void stop() {
+ newScript(MutableMap.of("usePidFile", false), STOPPING)
+ .body.append(BashCommands.sudo("service " + getOsSupport().getServiceName() + " stop"))
+ .execute();
+ }
+
+ @Override
+ public void updateBindConfiguration() {
+ LOG.debug("Updating bind configuration at " + getMachine());
+ copyAsRoot(entity.getConfig(BindDnsServer.NAMED_CONF_TEMPLATE), getOsSupport().getRootConfigFile());
+ copyAsRoot(entity.getConfig(BindDnsServer.DOMAIN_ZONE_FILE_TEMPLATE), getDomainZoneFile());
+ copyAsRoot(entity.getConfig(BindDnsServer.REVERSE_ZONE_FILE_TEMPLATE), getReverseZoneFile());
+ int result = getMachine().execScript("restart bind",
+ ImmutableList.of(BashCommands.sudo("service " + getOsSupport().getServiceName() + " restart")));
+ LOG.info("Updated named configuration and zone file for '{}' on {} (exit code {}).",
+ new Object[]{entity.getConfig(BindDnsServer.DOMAIN_NAME), entity, result});
+ }
+
+ private void copyAsRoot(String template, String destination) {
+ String content = processTemplate(template);
+ String temp = "/tmp/template-" + Strings.makeRandomId(6);
+ getMachine().copyTo(new ByteArrayInputStream(content.getBytes()), temp);
+ getMachine().execScript("copying file", ImmutableList.of(BashCommands.sudo(String.format("mv %s %s", temp, destination))));
+ }
+
+ /** @return The location on the server of the domain zone file */
+ public String getDomainZoneFile() {
+ return Os.mergePaths(getOsSupport().getConfigDirectory(), "domain.zone");
+ }
+
+ /** @return The location on the server of the reverse zone file */
+ public String getReverseZoneFile() {
+ return Os.mergePaths(getOsSupport().getConfigDirectory(), "reverse.zone");
+ }
+
+ public String getDataDirectory() {
+ return Os.mergePaths(getOsSupport().getWorkingDirectory(), "data");
+ }
+
+ public String getDynamicDirectory() {
+ return Os.mergePaths(getOsSupport().getWorkingDirectory(), "dynamic");
+ }
+
+ public String getRfc1912ZonesFile() {
+ return Os.mergePaths(getOsSupport().getConfigDirectory(), "rfc1912.zone");
+ }
+
+ public BindOsSupport getOsSupport() {
+ BindOsSupport result = osSupport;
+ if (result == null) {
+ synchronized (osSupportMutex) {
+ result = osSupport;
+ if (result == null) {
+ boolean yumExists = newScript("testing for yum")
+ .body.append(BashCommands.requireExecutable("yum"))
+ .execute() == 0;
+ osSupport = result = yumExists ? BindOsSupport.forRhel() : BindOsSupport.forDebian();
+ }
+ }
+ }
+ return result;
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/689b49c3/software/network/src/main/java/org/apache/brooklyn/entity/network/bind/BindOsSupport.java
----------------------------------------------------------------------
diff --git a/software/network/src/main/java/org/apache/brooklyn/entity/network/bind/BindOsSupport.java b/software/network/src/main/java/org/apache/brooklyn/entity/network/bind/BindOsSupport.java
new file mode 100644
index 0000000..c48f8a3
--- /dev/null
+++ b/software/network/src/main/java/org/apache/brooklyn/entity/network/bind/BindOsSupport.java
@@ -0,0 +1,113 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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 org.apache.brooklyn.entity.network.bind;
+
+import javax.annotation.concurrent.Immutable;
+
+/**
+ * Provides operating system-specific information for working with the Bind service.
+ */
+// Class would be package-private if Freemarker didn't complain vociferously.
+@Immutable
+public class BindOsSupport {
+
+ // Likewise would make these package-private and have no getters if Freemarker was ok with it.
+ private final String packageName;
+ private final String serviceName;
+ private final String rootConfigFile;
+ private final String configDirectory;
+ private final String workingDirectory;
+ private final String rootZonesFile;
+ private final String keysFile;
+
+ private BindOsSupport(
+ String packageName,
+ String serviceName,
+ String rootConfigFile,
+ String configDirectory,
+ String workingDirectory,
+ String rootZonesFile,
+ String keysFile) {
+ this.packageName = packageName;
+ this.serviceName = serviceName;
+ this.rootConfigFile = rootConfigFile;
+ this.configDirectory = configDirectory;
+ this.workingDirectory = workingDirectory;
+ this.rootZonesFile = rootZonesFile;
+ this.keysFile = keysFile;
+ }
+
+ /**
+ * @return support for RHEL-based operating systems.
+ */
+ public static BindOsSupport forRhel() {
+ return new BindOsSupport(
+ "bind",
+ "named",
+ "/etc/named.conf",
+ "/var/named",
+ "/var/named/data",
+ "/var/named/named.ca",
+ "/etc/named.iscdlv.key");
+ }
+
+ /**
+ * @return support for Debian-based operating systems.
+ */
+ public static BindOsSupport forDebian() {
+ return new BindOsSupport(
+ "bind9",
+ "bind9",
+ "/etc/bind/named.conf",
+ "/etc/bind",
+ "/var/cache/bind",
+ "/etc/bind/db.root",
+ "/etc/bind/bind.keys"
+ );
+ }
+
+ public String getPackageName() {
+ return packageName;
+ }
+
+ public String getServiceName() {
+ return serviceName;
+ }
+
+ public String getRootConfigFile() {
+ return rootConfigFile;
+ }
+
+ public String getConfigDirectory() {
+ return configDirectory;
+ }
+
+ public String getWorkingDirectory() {
+ return workingDirectory;
+ }
+
+ public String getRootZonesFile() {
+ return rootZonesFile;
+ }
+
+ public String getKeysFile() {
+ return keysFile;
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/689b49c3/software/network/src/main/resources/brooklyn/entity/network/bind/domain.zone
----------------------------------------------------------------------
diff --git a/software/network/src/main/resources/brooklyn/entity/network/bind/domain.zone b/software/network/src/main/resources/brooklyn/entity/network/bind/domain.zone
deleted file mode 100644
index 671d234..0000000
--- a/software/network/src/main/resources/brooklyn/entity/network/bind/domain.zone
+++ /dev/null
@@ -1,46 +0,0 @@
-[#ftl]
-;;
-;; Licensed to the Apache Software Foundation (ASF) under one
-;; or more contributor license agreements. See the NOTICE file
-;; distributed with this work for additional information
-;; regarding copyright ownership. The ASF licenses this file
-;; to you 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.
-;;
-;; Generated by Brooklyn on ${.now?string.short}
-;;
-;;
-[#noparse]$TTL[/#noparse] 86400
-@ IN SOA ns1.${entity.domainName}. root.${entity.domainName}. (
- ${entity.serial?c} ; serial
- 3600 ; refresh
- 1800 ; retry
- 604800 ; expire
- 86400 ; ttl
-)
-@ IN NS ns1.${entity.domainName}.
-@ IN NS ns2.${entity.domainName}.
-ns1 IN A ${driver.address}
-ns2 IN A ${driver.address}
-
-;; Addresses
-[#list entity.addressRecords?keys as address]
-${address} IN A ${entity.addressRecords[address]}
-[/#list]
-
-;; Canonical names
-[#list entity.cnamesForTemplates?keys as aRecord]
-[#list entity.cnamesForTemplates[aRecord] as cname]
-${cname} IN CNAME ${aRecord}
-[/#list]
-[/#list]
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/689b49c3/software/network/src/main/resources/brooklyn/entity/network/bind/ifcfg
----------------------------------------------------------------------
diff --git a/software/network/src/main/resources/brooklyn/entity/network/bind/ifcfg b/software/network/src/main/resources/brooklyn/entity/network/bind/ifcfg
deleted file mode 100644
index b8b310d..0000000
--- a/software/network/src/main/resources/brooklyn/entity/network/bind/ifcfg
+++ /dev/null
@@ -1,24 +0,0 @@
-[#ftl]
-#
-# Licensed to the Apache Software Foundation (ASF) under one
-# or more contributor license agreements. See the NOTICE file
-# distributed with this work for additional information
-# regarding copyright ownership. The ASF licenses this file
-# to you 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.
-#
-# Generated by Brooklyn on ${.now?string.short}
-#
-DOMAIN=${entity.domainName}
-DNS1=${driver.address}
-DNS2=8.8.8.8
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/689b49c3/software/network/src/main/resources/brooklyn/entity/network/bind/named.conf
----------------------------------------------------------------------
diff --git a/software/network/src/main/resources/brooklyn/entity/network/bind/named.conf b/software/network/src/main/resources/brooklyn/entity/network/bind/named.conf
deleted file mode 100644
index 5dd10d7..0000000
--- a/software/network/src/main/resources/brooklyn/entity/network/bind/named.conf
+++ /dev/null
@@ -1,63 +0,0 @@
-[#ftl]
-//
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements. See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership. The ASF licenses this file
-// to you 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.
-//
-// Generated by Brooklyn on ${.now?string.short}
-//
-options {
- listen-on port ${entity.dnsPort} { 127.0.0.1; ${driver.address}; };
- listen-on-v6 port ${entity.dnsPort} { ::1; };
- directory "${driver.osSupport.configDirectory}";
- dump-file "${driver.dataDirectory}/cache_dump.db";
- statistics-file "${driver.dataDirectory}/named_stats.txt";
- memstatistics-file "${driver.dataDirectory}/named_mem_stats.txt";
- allow-query { localhost; ${entity.managementCidr}; };
- allow-transfer { localhost; ${driver.address}; };
- recursion yes;
- dnssec-enable yes;
- dnssec-validation yes;
- dnssec-lookaside auto;
- bindkeys-file "${driver.osSupport.keysFile}";
- managed-keys-directory "${driver.dynamicDirectory}";
-};
-
-logging {
- channel default_debug {
- file "${driver.dataDirectory}/named.run";
- severity dynamic;
- };
-};
-
-zone "." IN {
- type hint;
- file "${driver.osSupport.rootZonesFile}";
-};
-
-zone "${entity.reverseLookupDomain}" IN {
- type master;
- file "${driver.reverseZoneFile}";
- allow-update { none; };
-};
-
-zone "${entity.domainName}" IN {
- type master;
- file "${driver.domainZoneFile}";
- allow-update { none; };
-};
-
-include "${driver.rfc1912ZonesFile}";
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/689b49c3/software/network/src/main/resources/brooklyn/entity/network/bind/named.empty
----------------------------------------------------------------------
diff --git a/software/network/src/main/resources/brooklyn/entity/network/bind/named.empty b/software/network/src/main/resources/brooklyn/entity/network/bind/named.empty
deleted file mode 100644
index 3197b41..0000000
--- a/software/network/src/main/resources/brooklyn/entity/network/bind/named.empty
+++ /dev/null
@@ -1,30 +0,0 @@
-;
-; Licensed to the Apache Software Foundation (ASF) under one
-; or more contributor license agreements. See the NOTICE file
-; distributed with this work for additional information
-; regarding copyright ownership. The ASF licenses this file
-; to you 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.
-;
-;
-; Reverse data for the broadcast zone
-;
-$TTL 1W
-@ IN SOA localhost. root.localhost. (
- 1 ; serial
- 1W ; refresh
- 1D ; retry
- 1M ; expire
- 1M ) ; ttl
-;
-@ IN NS localhost.
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/689b49c3/software/network/src/main/resources/brooklyn/entity/network/bind/named.localhost
----------------------------------------------------------------------
diff --git a/software/network/src/main/resources/brooklyn/entity/network/bind/named.localhost b/software/network/src/main/resources/brooklyn/entity/network/bind/named.localhost
deleted file mode 100644
index c683a83..0000000
--- a/software/network/src/main/resources/brooklyn/entity/network/bind/named.localhost
+++ /dev/null
@@ -1,32 +0,0 @@
-;
-; Licensed to the Apache Software Foundation (ASF) under one
-; or more contributor license agreements. See the NOTICE file
-; distributed with this work for additional information
-; regarding copyright ownership. The ASF licenses this file
-; to you 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.
-;
-;
-; BIND data for the local loopback interface
-;
-$TTL 1W
-@ IN SOA localhost. root.localhost. (
- 1 ; serial
- 1W ; refresh
- 1D ; retry
- 1M ; expire
- 1M ) ; ttl
-;
-@ IN NS localhost.
-@ IN A 127.0.0.1
-@ IN AAAA ::1