From 39d697ca789c04da07bb14cc7476899e717d9413 Mon Sep 17 00:00:00 2001 From: Joey Hess Date: Fri, 18 Apr 2014 17:19:28 -0400 Subject: add dns records to Attr --- Propellor/Property/Dns.hs | 121 +++++++++++++--------------------------------- 1 file changed, 33 insertions(+), 88 deletions(-) (limited to 'Propellor/Property') diff --git a/Propellor/Property/Dns.hs b/Propellor/Property/Dns.hs index 1d4a8e49..99a60145 100644 --- a/Propellor/Property/Dns.hs +++ b/Propellor/Property/Dns.hs @@ -1,6 +1,18 @@ -module Propellor.Property.Dns where +module Propellor.Property.Dns ( + module Propellor.Types.Dns, + secondary, + servingZones, + mkSOA, + nextSerialNumber, + incrSerialNumber, + currentSerialNumber, + writeZoneFile, + genZoneFile, + genSOA, +) where import Propellor +import Propellor.Types.Dns import Propellor.Property.File import qualified Propellor.Property.Apt as Apt import qualified Propellor.Property.Service as Service @@ -8,48 +20,31 @@ import Utility.Applicative import Data.List import Data.Time.Clock.POSIX -import Data.Time.Format -import Foreign.C.Types namedconf :: FilePath namedconf = "/etc/bind/named.conf.local" -data NamedConf = NamedConf - { zdomain :: Domain - , ztype :: Type - , zfile :: FilePath - , zmasters :: [IPAddr] - , zconfiglines :: [String] - } - zoneDesc :: NamedConf -> String -zoneDesc z = zdomain z ++ " (" ++ show (ztype z) ++ ")" - -type IPAddr = String - -type Domain = String - -data Type = Master | Secondary - deriving (Show, Eq) +zoneDesc z = confDomain z ++ " (" ++ show (confType z) ++ ")" secondary :: Domain -> [IPAddr] -> NamedConf secondary domain masters = NamedConf - { zdomain = domain - , ztype = Secondary - , zfile = "db." ++ domain - , zmasters = masters - , zconfiglines = ["allow-transfer { }"] + { confDomain = domain + , confType = Secondary + , confFile = "db." ++ domain + , confMasters = masters + , confLines = ["allow-transfer { }"] } -zoneStanza :: NamedConf -> [Line] -zoneStanza z = +confStanza :: NamedConf -> [Line] +confStanza c = [ "// automatically generated by propellor" - , "zone \"" ++ zdomain z ++ "\" {" - , cfgline "type" (if ztype z == Master then "master" else "slave") - , cfgline "file" ("\"" ++ zfile z ++ "\"") + , "zone \"" ++ confDomain c ++ "\" {" + , cfgline "type" (if confType c == Master then "master" else "slave") + , cfgline "file" ("\"" ++ confFile c ++ "\"") ] ++ - (if null (zmasters z) then [] else mastersblock) ++ - (map (\l -> "\t" ++ l ++ ";") (zconfiglines z)) ++ + (if null (confMasters c) then [] else mastersblock) ++ + (map (\l -> "\t" ++ l ++ ";") (confLines c)) ++ [ "};" , "" ] @@ -57,40 +52,17 @@ zoneStanza z = cfgline f v = "\t" ++ f ++ " " ++ v ++ ";" mastersblock = [ "\tmasters {" ] ++ - (map (\ip -> "\t\t" ++ ip ++ ";") (zmasters z)) ++ + (map (\ip -> "\t\t" ++ fromIPAddr ip ++ ";") (confMasters c)) ++ [ "\t};" ] -- | Rewrites the whole named.conf.local file to serve the specificed -- zones. -zones :: [NamedConf] -> Property -zones zs = hasContent namedconf (concatMap zoneStanza zs) +servingZones :: [NamedConf] -> Property +servingZones zs = hasContent namedconf (concatMap confStanza zs) `describe` ("dns server for zones: " ++ unwords (map zoneDesc zs)) `requires` Apt.serviceInstalledRunning "bind9" `onChange` Service.reloaded "bind9" --- | Represents a bind 9 zone file. -data Zone = Zone - { zSOA :: SOA - , zHosts :: [(HostName, Record)] - } - deriving (Read, Show, Eq) - --- | Every domain has a SOA record, which is big and complicated. -data SOA = SOA - { sDomain :: BindDomain - -- ^ Typically ns1.your.domain - , sSerial :: SerialNumber - -- ^ The most important parameter is the serial number, - -- which must increase after each change. - , sRefresh :: Integer - , sRetry :: Integer - , sExpire :: Integer - , sTTL :: Integer - , sRecord :: [Record] - -- ^ Records for the root of the domain. Typically NS, A, TXT - } - deriving (Read, Show, Eq) - -- | Generates a SOA with some fairly sane numbers in it. mkSOA :: Domain -> [Record] -> SOA mkSOA d rs = SOA @@ -105,49 +77,22 @@ mkSOA d rs = SOA where hours n = n * 60 * 60 --- | Types of DNS records. --- --- This is not a complete list, more can be added. -data Record - = A Ipv4 - | AAAA Ipv6 - | CNAME BindDomain - | MX Int BindDomain - | NS BindDomain - | TXT String - deriving (Read, Show, Eq) - -type Ipv4 = String -type Ipv6 = String - --- | Bind serial numbers are unsigned, 32 bit integers. -type SerialNumber = CInt - --- | Domains in the zone file must end with a period if they are absolute. --- --- 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 - deriving (Read, Show, Eq) - dValue :: BindDomain -> String dValue (RelDomain d) = d dValue (AbsDomain d) = d ++ "." dValue (SOADomain) = "@" rField :: Record -> String -rField (A _) = "A" -rField (AAAA _) = "AAAA" +rField (Address (IPv4 _)) = "A" +rField (Address (IPv6 _)) = "AAAA" rField (CNAME _) = "CNAME" rField (MX _ _) = "MX" rField (NS _) = "NS" rField (TXT _) = "TXT" rValue :: Record -> String -rValue (A addr) = addr -rValue (AAAA addr) = addr +rValue (Address (IPv4 addr)) = addr +rValue (Address (IPv6 addr)) = addr rValue (CNAME d) = dValue d rValue (MX pri d) = show pri ++ " " ++ dValue d rValue (NS d) = dValue d -- cgit v1.2.3