diff --git a/Propellor/Property/Dns.hs b/Propellor/Property/Dns.hs new file mode 100644 index 0000000..34e790d --- /dev/null +++ b/Propellor/Property/Dns.hs @@ -0,0 +1,63 @@ +module Propellor.Property.Dns where + +import Propellor +import Propellor.Property.File +import qualified Propellor.Property.Apt as Apt +import qualified Propellor.Property.Service as Service + +namedconf :: FilePath +namedconf = "/etc/bind/named.conf.local" + +data Zone = Zone + { zdomain :: Domain + , ztype :: Type + , zfile :: FilePath + , zmasters :: [IPAddr] + , zconfiglines :: [String] + } + +zoneDesc :: Zone -> String +zoneDesc z = zdomain z ++ " (" ++ show (ztype z) ++ ")" + +type IPAddr = String + +type Domain = String + +data Type = Master | Secondary + deriving (Show, Eq) + +secondary :: Domain -> [IPAddr] -> Zone +secondary domain masters = Zone + { zdomain = domain + , ztype = Secondary + , zfile = "db." ++ domain + , zmasters = masters + , zconfiglines = ["allow-transfer { }"] + } + +zoneStanza :: Zone -> [Line] +zoneStanza z = + [ "// automatically generated by propellor" + , "zone \"" ++ zdomain z ++ "\" {" + , cfgline "type" (if ztype z == Master then "master" else "slave") + , cfgline "file" ("\"" ++ zfile z ++ "\"") + ] ++ + (if null (zmasters z) then [] else mastersblock) ++ + (map (\l -> "\t" ++ l ++ ";") (zconfiglines z)) ++ + [ "};" + , "" + ] + where + cfgline f v = "\t" ++ f ++ " " ++ v ++ ";" + mastersblock = + [ "\tmasters {" ] ++ + (map (\ip -> "\t\t" ++ ip ++ ";") (zmasters z)) ++ + [ "\t};" ] + +-- | Rewrites the whole named.conf.local file to serve the specificed +-- zones. +zones :: [Zone] -> Property +zones zs = hasContent namedconf (concatMap zoneStanza zs) + `describe` ("dns server for zones: " ++ unwords (map zoneDesc zs)) + `requires` Apt.serviceInstalledRunning "bind9" + `onChange` Service.reloaded "bind9" diff --git a/Propellor/Property/Service.hs b/Propellor/Property/Service.hs index 2fb3e0c..c6498e5 100644 --- a/Propellor/Property/Service.hs +++ b/Propellor/Property/Service.hs @@ -14,12 +14,18 @@ type ServiceName = String -- this means it's already running. running :: ServiceName -> Property running svc = Property ("running " ++ svc) $ do - void $ ensureProperty $ - scriptProperty ["service " ++ shellEscape svc ++ " start >/dev/null 2>&1 || true"] - return NoChange + void $ ensureProperty $ + scriptProperty ["service " ++ shellEscape svc ++ " start >/dev/null 2>&1 || true"] + return NoChange restarted :: ServiceName -> Property restarted svc = Property ("restarted " ++ svc) $ do void $ ensureProperty $ scriptProperty ["service " ++ shellEscape svc ++ " restart >/dev/null 2>&1 || true"] return NoChange + +reloaded :: ServiceName -> Property +reloaded svc = Property ("reloaded " ++ svc) $ do + void $ ensureProperty $ + scriptProperty ["service " ++ shellEscape svc ++ " reload >/dev/null 2>&1 || true"] + return NoChange diff --git a/config-joey.hs b/config-joey.hs index dfa56e5..9c64acb 100644 --- a/config-joey.hs +++ b/config-joey.hs @@ -13,6 +13,7 @@ import qualified Propellor.Property.User as User import qualified Propellor.Property.Hostname as Hostname import qualified Propellor.Property.Reboot as Reboot import qualified Propellor.Property.Tor as Tor +import qualified Propellor.Property.Dns as Dns import qualified Propellor.Property.OpenId as OpenId import qualified Propellor.Property.Docker as Docker import qualified Propellor.Property.SiteSpecific.GitHome as GitHome @@ -61,6 +62,7 @@ host hostname@"diatom.kitenet.net" = Just $ props & Apt.unattendedUpgrades & Apt.serviceInstalledRunning "ntp" & Apt.serviceInstalledRunning "bind9" + & Dns.zones myDnsSecondary & Apt.serviceInstalledRunning "apache2" & Apt.serviceInstalledRunning "git-daemon-sysvinit" & Apt.installed ["git", "git-annex", "rsync"] @@ -180,3 +182,15 @@ cleanCloudAtCost hostname = propertyList "cloudatcost cleanup" , User.nuked "user" User.YesReallyDeleteHome ] ] + +myDnsSecondary :: [Dns.Zone] +myDnsSecondary = + [ Dns.secondary "kitenet.net" master + , Dns.secondary "joeyh.name" master + , Dns.secondary "ikiwiki.info" master + , Dns.secondary "olduse.net" master + , Dns.secondary "branchable.com" branchablemaster + ] + where + master = ["80.68.85.49", "2001:41c8:125:49::10"] -- wren + branchablemaster = ["66.228.46.55", "2600:3c03::f03c:91ff:fedf:c0e5"] diff --git a/propellor.cabal b/propellor.cabal index a6510df..8f53d59 100644 --- a/propellor.cabal +++ b/propellor.cabal @@ -69,6 +69,7 @@ Library Propellor.Property.Cmd Propellor.Property.Hostname Propellor.Property.Cron + Propellor.Property.Dns Propellor.Property.Docker Propellor.Property.File Propellor.Property.Network