summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJoey Hess2014-04-19 11:42:31 -0400
committerJoey Hess2014-04-19 11:42:31 -0400
commit8c12c5b8ece4c7027c3261b8c6e59dbc750b08e9 (patch)
tree543bf2f0a6d82db926a549fad2f147f036d62a79
parent5dd316a0ad4abce5e81ea19e52caf7b57081cda3 (diff)
parenta2ef91929a19c4b70877691a66074fc42a9488ea (diff)
Merge branch 'joeyconfig'
-rw-r--r--Propellor/Attr.hs2
-rw-r--r--Propellor/Property/Dns.hs127
-rw-r--r--Propellor/Types.hs3
-rw-r--r--Propellor/Types/Dns.hs7
-rw-r--r--config-joey.hs31
-rw-r--r--debian/changelog8
-rw-r--r--propellor.cabal2
7 files changed, 98 insertions, 82 deletions
diff --git a/Propellor/Attr.hs b/Propellor/Attr.hs
index 05ea3ff5..acaf28db 100644
--- a/Propellor/Attr.hs
+++ b/Propellor/Attr.hs
@@ -43,7 +43,7 @@ ipv6 addr = pureAttrProperty ("ipv6 " ++ addr)
-- | Indicates another name for the host in the DNS.
alias :: Domain -> Property
-alias domain = pureAttrProperty ("aka " ++ domain)
+alias domain = pureAttrProperty ("alias " ++ domain)
(addDNS $ CNAME $ AbsDomain domain)
addDNS :: Record -> SetAttr
diff --git a/Propellor/Property/Dns.hs b/Propellor/Property/Dns.hs
index 0708417d..73d427c0 100644
--- a/Propellor/Property/Dns.hs
+++ b/Propellor/Property/Dns.hs
@@ -4,11 +4,11 @@ module Propellor.Property.Dns (
secondary,
secondaryFor,
mkSOA,
- rootAddressesFrom,
writeZoneFile,
nextSerialNumber,
adjustSerialNumber,
serialNumberOffset,
+ WarningMessage,
genZone,
) where
@@ -36,14 +36,22 @@ import Data.List
-- Will cause that hostmame and its alias to appear in the zone file,
-- with the configured IP address.
--
--- The [(Domain, Record)] list can be used for additional records
--- that cannot be configured elsewhere. For example, it might contain
--- CNAMEs pointing at hosts that propellor does not control.
-primary :: [Host] -> Domain -> SOA -> [(BindDomain, Record)] -> Property
-primary hosts domain soa rs = withwarnings (check needupdate baseprop)
- `requires` servingZones
- `onChange` Service.reloaded "bind9"
+-- The [(BindDomain, Record)] list can be used for additional records
+-- that cannot be configured elsewhere. This often includes NS records,
+-- TXT records and perhaps CNAMEs pointing at hosts that propellor does
+-- not control.
+primary :: [Host] -> Domain -> SOA -> [(BindDomain, Record)] -> RevertableProperty
+primary hosts domain soa rs = RevertableProperty setup cleanup
where
+ setup = withwarnings (check needupdate baseprop)
+ `requires` servingZones
+ `onChange` Service.reloaded "bind9"
+ cleanup = check (doesFileExist zonefile) $
+ property ("removed dns primary for " ++ domain)
+ (makeChange $ removeZoneFile zonefile)
+ `requires` namedConfWritten
+ `onChange` Service.reloaded "bind9"
+
(partialzone, warnings) = genZone hosts domain soa
zone = partialzone { zHosts = zHosts partialzone ++ rs }
zonefile = "/etc/bind/propellor/db." ++ domain
@@ -77,7 +85,7 @@ primary hosts domain soa rs = withwarnings (check needupdate baseprop)
--
-- Note that if a host is declared to be a primary and a secondary dns
-- server for the same domain, the primary server config always wins.
-secondary :: [Host] -> Domain -> Property
+secondary :: [Host] -> Domain -> RevertableProperty
secondary hosts domain = secondaryFor masters hosts domain
where
masters = M.keys $ M.filter ismaster $ hostAttrMap hosts
@@ -87,10 +95,13 @@ secondary hosts domain = secondaryFor masters hosts domain
-- | This variant is useful if the primary server does not have its DNS
-- configured via propellor.
-secondaryFor :: [HostName] -> [Host] -> Domain -> Property
-secondaryFor masters hosts domain = pureAttrProperty desc (addNamedConf conf)
- `requires` servingZones
+secondaryFor :: [HostName] -> [Host] -> Domain -> RevertableProperty
+secondaryFor masters hosts domain = RevertableProperty setup cleanup
where
+ setup = pureAttrProperty desc (addNamedConf conf)
+ `requires` servingZones
+ cleanup = namedConfWritten
+
desc = "dns secondary for " ++ domain
conf = NamedConf
{ confDomain = domain
@@ -104,15 +115,16 @@ secondaryFor masters hosts domain = pureAttrProperty desc (addNamedConf conf)
-- configured by `primary` and `secondary`, and ensures that bind9 is
-- running.
servingZones :: Property
-servingZones = property "serving configured dns zones" go
+servingZones = namedConfWritten
`requires` Apt.serviceInstalledRunning "bind9"
`onChange` Service.reloaded "bind9"
- where
- go = do
- zs <- getNamedConf
- ensureProperty $
- hasContent namedConfFile $
- concatMap confStanza $ M.elems zs
+
+namedConfWritten :: Property
+namedConfWritten = property "named.conf configured" $ do
+ zs <- getNamedConf
+ ensureProperty $
+ hasContent namedConfFile $
+ concatMap confStanza $ M.elems zs
confStanza :: NamedConf -> [Line]
confStanza c =
@@ -149,29 +161,22 @@ namedConfFile = "/etc/bind/named.conf.local"
-- You do not need to increment the SerialNumber when making changes!
-- Propellor will automatically add the number of commits in the git
-- repository to the SerialNumber.
---
--- Handy trick: You don't need to list IPAddrs in the [Record],
--- just make some Host sets its `alias` to the root of domain.
-mkSOA :: Domain -> SerialNumber -> [Record] -> SOA
-mkSOA d sn rs = SOA
+mkSOA :: Domain -> SerialNumber -> SOA
+mkSOA d sn = SOA
{ sDomain = AbsDomain d
, sSerial = sn
, sRefresh = hours 4
, sRetry = hours 1
, sExpire = 2419200 -- 4 weeks
, sNegativeCacheTTL = hours 8
- , sRecord = rs
}
where
hours n = n * 60 * 60
-rootAddressesFrom :: [Host] -> HostName -> [Record]
-rootAddressesFrom hosts hn = map Address (hostAddresses hn hosts)
-
dValue :: BindDomain -> String
dValue (RelDomain d) = d
dValue (AbsDomain d) = d ++ "."
-dValue (SOADomain) = "@"
+dValue (RootDomain) = "@"
rField :: Record -> String
rField (Address (IPv4 _)) = "A"
@@ -198,10 +203,9 @@ rValue (TXT s) = [q] ++ filter (/= q) s ++ [q]
where
q = '"'
--- | Adjusts the serial number of the zone to
---
--- * Always be larger than the serial number in the Zone record.
--- * Always be larger than the passed SerialNumber
+-- | Adjusts the serial number of the zone to always be larger
+-- than the serial number in the Zone record,
+-- and always be larger than the passed SerialNumber.
nextSerialNumber :: Zone -> SerialNumber -> Zone
nextSerialNumber z serial = adjustSerialNumber z $ \sn -> succ $ max sn serial
@@ -231,6 +235,11 @@ writeZoneFile z f = do
writeFile f (genZoneFile z')
writeZonePropellorFile f z'
+removeZoneFile :: FilePath -> IO ()
+removeZoneFile f = do
+ nukeFile f
+ nukeFile (zonePropellorFile f)
+
-- | Next to the zone file, is a ".propellor" file, which contains
-- the serialized Zone. This saves the bother of parsing
-- the horrible bind zone file format.
@@ -250,43 +259,37 @@ readZonePropellorFile f = catchDefaultIO Nothing $
-- | Generating a zone file.
genZoneFile :: Zone -> String
genZoneFile (Zone zdomain soa rs) = unlines $
- header : genSOA zdomain soa ++ map genr rs
+ header : genSOA soa ++ map (genRecord zdomain) rs
where
header = com $ "BIND zone file for " ++ zdomain ++ ". Generated by propellor, do not edit."
- genr (d, r) = genRecord zdomain (Just d, r)
-
-genRecord :: Domain -> (Maybe BindDomain, Record) -> String
-genRecord zdomain (mdomain, record) = intercalate "\t"
- [ hn
+genRecord :: Domain -> (BindDomain, Record) -> String
+genRecord zdomain (domain, record) = intercalate "\t"
+ [ domainHost zdomain domain
, "IN"
, rField record
, rValue record
]
- where
- hn = maybe "" (domainHost zdomain) mdomain
-genSOA :: Domain -> SOA -> [String]
-genSOA zdomain soa =
- header ++ map (genRecord zdomain) (zip (repeat Nothing) (sRecord soa))
- where
- header =
- -- "@ IN SOA ns1.example.com. root ("
- [ intercalate "\t"
- [ dValue SOADomain
- , "IN"
- , "SOA"
- , dValue (sDomain soa)
- , "root"
- , "("
- ]
- , headerline sSerial "Serial"
- , headerline sRefresh "Refresh"
- , headerline sRetry "Retry"
- , headerline sExpire "Expire"
- , headerline sNegativeCacheTTL "Negative Cache TTL"
- , inheader ")"
+genSOA :: SOA -> [String]
+genSOA soa =
+ -- "@ IN SOA ns1.example.com. root ("
+ [ intercalate "\t"
+ [ dValue RootDomain
+ , "IN"
+ , "SOA"
+ , dValue (sDomain soa)
+ , "root"
+ , "("
]
+ , headerline sSerial "Serial"
+ , headerline sRefresh "Refresh"
+ , headerline sRetry "Retry"
+ , headerline sExpire "Expire"
+ , headerline sNegativeCacheTTL "Negative Cache TTL"
+ , inheader ")"
+ ]
+ where
headerline r comment = inheader $ show (r soa) ++ "\t\t" ++ com comment
inheader l = "\t\t\t" ++ l
@@ -361,7 +364,7 @@ inDomain _ _ = False -- can't tell, so assume not
-- suitable for using in a zone file.
domainHost :: Domain -> BindDomain -> String
domainHost _ (RelDomain d) = d
-domainHost _ SOADomain = "@"
+domainHost _ RootDomain = "@"
domainHost base (AbsDomain d)
| dotbase `isSuffixOf` d = take (length d - length dotbase) d
| base == d = "@"
diff --git a/Propellor/Types.hs b/Propellor/Types.hs
index 0e412e82..22df9ddb 100644
--- a/Propellor/Types.hs
+++ b/Propellor/Types.hs
@@ -5,6 +5,7 @@
module Propellor.Types
( Host(..)
, Attr
+ , SetAttr
, Propellor(..)
, Property(..)
, RevertableProperty(..)
@@ -56,7 +57,7 @@ data Property = Property
, propertySatisfy :: Propellor Result
-- ^ must be idempotent; may run repeatedly
, propertyAttr :: SetAttr
- -- ^ a property can affect the overall Attr
+ -- ^ a property can set an Attr on the host that has the property.
}
-- | A property that can be reverted.
diff --git a/Propellor/Types/Dns.hs b/Propellor/Types/Dns.hs
index e367202a..9b2ad1e7 100644
--- a/Propellor/Types/Dns.hs
+++ b/Propellor/Types/Dns.hs
@@ -43,8 +43,6 @@ data SOA = SOA
, sRetry :: Integer
, sExpire :: Integer
, sNegativeCacheTTL :: Integer
- , sRecord :: [Record]
- -- ^ Records for the root of the domain. Typically NS, A, TXT
}
deriving (Read, Show, Eq)
@@ -76,6 +74,7 @@ type SerialNumber = Word32
-- Let's use a type to keep absolute domains straight from relative
-- domains.
--
--- The SOADomain refers to the root SOA record.
-data BindDomain = RelDomain Domain | AbsDomain Domain | SOADomain
+-- The RootDomain refers to the top level of the domain, so can be used
+-- to add nameservers, MX's, etc to a domain.
+data BindDomain = RelDomain Domain | AbsDomain Domain | RootDomain
deriving (Read, Show, Eq, Ord)
diff --git a/config-joey.hs b/config-joey.hs
index 1bda9dd2..dd848646 100644
--- a/config-joey.hs
+++ b/config-joey.hs
@@ -23,6 +23,9 @@ import qualified Propellor.Property.SiteSpecific.GitHome as GitHome
import qualified Propellor.Property.SiteSpecific.GitAnnexBuilder as GitAnnexBuilder
import qualified Propellor.Property.SiteSpecific.JoeySites as JoeySites
+main :: IO ()
+main = defaultMain hosts
+
-- _ ______`| ,-.__
{- Propellor -- / \___-=O`/|O`/__| (____.'
@@ -61,6 +64,9 @@ hosts = -- (o) `
-- I'd rather this were on diatom, but it needs unstable.
& alias "kgb.kitenet.net"
& JoeySites.kgbServer
+
+ & alias "ns9.kitenet.net"
+ & myDnsSecondary
& Docker.garbageCollected `period` Daily
& Apt.installed ["git-annex", "mtr", "screen"]
@@ -122,17 +128,17 @@ hosts = -- (o) `
& alias "resources.olduse.net"
& JoeySites.oldUseNetServer hosts
+ & alias "ns2.kitenet.net"
& myDnsSecondary
& Dns.primary hosts "olduse.net"
- ( Dns.mkSOA "ns1.kitenet.net" 100
- [ NS (AbsDomain "ns1.kitenet.net")
- , NS (AbsDomain "ns6.gandi.net")
- , NS (AbsDomain "ns2.kitenet.net")
- , MX 0 (AbsDomain "kitenet.net")
- , TXT "v=spf1 a -all"
- ]
- )
- [ (RelDomain "article", CNAME $ AbsDomain "virgil.koldfront.dk") ]
+ (Dns.mkSOA "ns2.kitenet.net" 100)
+ [ (RootDomain, NS $ AbsDomain "ns2.kitenet.net")
+ , (RootDomain, NS $ AbsDomain "ns6.gandi.net")
+ , (RootDomain, NS $ AbsDomain "ns9.kitenet.net")
+ , (RootDomain, MX 0 $ AbsDomain "kitenet.net")
+ , (RootDomain, TXT "v=spf1 a -all")
+ , (RelDomain "article", CNAME $ AbsDomain "virgil.koldfront.dk")
+ ]
& Apt.installed ["ntop"]
@@ -246,7 +252,7 @@ cleanCloudAtCost = propertyList "cloudatcost cleanup"
]
myDnsSecondary :: Property
-myDnsSecondary = propertyList "dns secondary for all my domains"
+myDnsSecondary = propertyList "dns secondary for all my domains" $ map toProp
[ Dns.secondaryFor wren hosts "kitenet.net"
, Dns.secondaryFor wren hosts "joeyh.name"
, Dns.secondaryFor wren hosts "ikiwiki.info"
@@ -257,9 +263,6 @@ myDnsSecondary = propertyList "dns secondary for all my domains"
wren = ["wren.kitenet.net"]
branchable = ["branchable.com"]
-main :: IO ()
-main = defaultMain hosts
-
-- o
@@ -287,6 +290,8 @@ monsters = -- but do want to track their public keys etc.
& ipv4 "80.68.85.49"
& ipv6 "2001:41c8:125:49::10"
& alias "kite.kitenet.net"
+ & alias "kitenet.net"
+ & alias "ns1.kitenet.net"
, host "branchable.com"
& ipv4 "66.228.46.55"
& ipv6 "2600:3c03::f03c:91ff:fedf:c0e5"
diff --git a/debian/changelog b/debian/changelog
index beaca78a..8f1e5f55 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -1,3 +1,11 @@
+propellor (0.5.0) UNRELEASED; urgency=medium
+
+ * Removed root domain records from SOA. Instead, use RootDomain
+ when calling Dns.primary.
+ * Dns primary and secondary properties are now revertable.
+
+ -- Joey Hess <joeyh@debian.org> Sat, 19 Apr 2014 10:46:35 -0400
+
propellor (0.4.0) unstable; urgency=medium
* Propellor can configure primary DNS servers, including generating
diff --git a/propellor.cabal b/propellor.cabal
index 68d7fb70..bc9f7732 100644
--- a/propellor.cabal
+++ b/propellor.cabal
@@ -1,5 +1,5 @@
Name: propellor
-Version: 0.4.0
+Version: 0.5.0
Cabal-Version: >= 1.6
License: GPL
Maintainer: Joey Hess <joey@kitenet.net>