diff options
| author | Joey Hess <joeyh@joeyh.name> | 2016-03-28 05:53:38 -0400 |
|---|---|---|
| committer | Joey Hess <joeyh@joeyh.name> | 2016-03-28 05:55:48 -0400 |
| commit | a1655d24bbb1db9caccdf93eae8110d746389ae2 (patch) | |
| tree | 66b6890d852c19daec2306920fecf9108e055273 /src/Propellor/Property/Dns.hs | |
| parent | ebf30061d8f8a251330070e69c2710fe4a8fd9da (diff) | |
type safe targets for properties
* Property types have been improved to indicate what systems they target.
This prevents using eg, Property FreeBSD on a Debian system.
Transition guide for this sweeping API change:
- Change "host name & foo & bar"
to "host name $ props & foo & bar"
- Similarly, `propertyList` and `combineProperties` need `props`
to be used to combine together properties; they no longer accept
lists of properties. (If you have such a list, use `toProps`.)
- And similarly, Chroot, Docker, and Systemd container need `props`
to be used to combine together the properies used inside them.
- The `os` property is removed. Instead use `osDebian`, `osBuntish`,
or `osFreeBSD`. These tell the type checker the target OS of a host.
- Change "Property NoInfo" to "Property UnixLike"
- Change "Property HasInfo" to "Property (HasInfo + UnixLike)"
- Change "RevertableProperty NoInfo" to
"RevertableProperty UnixLike UnixLike"
- Change "RevertableProperty HasInfo" to
"RevertableProperty (HasInfo + UnixLike) UnixLike"
- GHC needs {-# LANGUAGE TypeOperators #-} to use these fancy types.
This is enabled by default for all modules in propellor.cabal. But
if you are using propellor as a library, you may need to enable it
manually.
- If you know a property only works on a particular OS, like Debian
or FreeBSD, use that instead of "UnixLike". For example:
"Property Debian"
- It's also possible make a property support a set of OS's, for example:
"Property (Debian + FreeBSD)"
- Removed `infoProperty` and `simpleProperty` constructors, instead use
`property` to construct a Property.
- Due to the polymorphic type returned by `property`, additional type
signatures tend to be needed when using it. For example, this will
fail to type check, because the type checker cannot guess what type
you intend the intermediate property "go" to have:
foo :: Property UnixLike
foo = go `requires` bar
where
go = property "foo" (return NoChange)
To fix, specify the type of go:
go :: Property UnixLike
- `ensureProperty` now needs to be passed a witness to the type of the
property it's used in.
change this: foo = property desc $ ... ensureProperty bar
to this: foo = property' desc $ \w -> ... ensureProperty w bar
- General purpose properties like cmdProperty have type "Property UnixLike".
When using that to run a command only available on Debian, you can
tighten the type to only the OS that your more specific property works on.
For example:
upgraded :: Property Debian
upgraded = tightenTargets (cmdProperty "apt-get" ["upgrade"])
- Several utility functions have been renamed:
getInfo to fromInfo
propertyInfo to getInfo
propertyDesc to getDesc
propertyChildren to getChildren
* The new `pickOS` property combinator can be used to combine different
properties, supporting different OS's, into one Property that chooses
which to use based on the Host's OS.
* Re-enabled -O0 in propellor.cabal to reign in ghc's memory use handling
these complex new types.
* Added dependency on concurrent-output; removed embedded copy.
Diffstat (limited to 'src/Propellor/Property/Dns.hs')
| -rw-r--r-- | src/Propellor/Property/Dns.hs | 45 |
1 files changed, 24 insertions, 21 deletions
diff --git a/src/Propellor/Property/Dns.hs b/src/Propellor/Property/Dns.hs index adc12930..2e2710a6 100644 --- a/src/Propellor/Property/Dns.hs +++ b/src/Propellor/Property/Dns.hs @@ -60,7 +60,7 @@ import Data.List -- -- In either case, the secondary dns server Host should have an ipv4 and/or -- ipv6 property defined. -primary :: [Host] -> Domain -> SOA -> [(BindDomain, Record)] -> RevertableProperty HasInfo +primary :: [Host] -> Domain -> SOA -> [(BindDomain, Record)] -> RevertableProperty (HasInfo + DebianLike) DebianLike primary hosts domain soa rs = setup <!> cleanup where setup = setupPrimary zonefile id hosts domain soa rs @@ -70,7 +70,7 @@ primary hosts domain soa rs = setup <!> cleanup zonefile = "/etc/bind/propellor/db." ++ domain -setupPrimary :: FilePath -> (FilePath -> FilePath) -> [Host] -> Domain -> SOA -> [(BindDomain, Record)] -> Property HasInfo +setupPrimary :: FilePath -> (FilePath -> FilePath) -> [Host] -> Domain -> SOA -> [(BindDomain, Record)] -> Property (HasInfo + DebianLike) setupPrimary zonefile mknamedconffile hosts domain soa rs = withwarnings baseprop `requires` servingZones @@ -80,9 +80,10 @@ setupPrimary zonefile mknamedconffile hosts domain soa rs = indomain = M.elems $ M.filterWithKey (\hn _ -> inDomain domain $ AbsDomain $ hn) hostmap (partialzone, zonewarnings) = genZone indomain hostmap domain soa - baseprop = infoProperty ("dns primary for " ++ domain) satisfy - (mempty `addInfo` addNamedConf conf) [] - satisfy = do + baseprop = primaryprop + `setInfoProperty` (toInfo (addNamedConf conf)) + primaryprop :: Property DebianLike + primaryprop = property ("dns primary for " ++ domain) $ do sshfps <- concat <$> mapM (genSSHFP domain) (M.elems hostmap) let zone = partialzone { zHosts = zHosts partialzone ++ rs ++ sshfps } @@ -120,11 +121,13 @@ setupPrimary zonefile mknamedconffile hosts domain soa rs = in z /= oldzone || oldserial < sSerial (zSOA zone) -cleanupPrimary :: FilePath -> Domain -> Property NoInfo +cleanupPrimary :: FilePath -> Domain -> Property DebianLike cleanupPrimary zonefile domain = check (doesFileExist zonefile) $ - property ("removed dns primary for " ++ domain) - (makeChange $ removeZoneFile zonefile) - `requires` namedConfWritten + go `requires` namedConfWritten + where + desc = "removed dns primary for " ++ domain + go :: Property DebianLike + go = property desc (makeChange $ removeZoneFile zonefile) -- | Primary dns server for a domain, secured with DNSSEC. -- @@ -152,7 +155,7 @@ cleanupPrimary zonefile domain = check (doesFileExist zonefile) $ -- This is different from the serial number used by 'primary', so if you -- want to later disable DNSSEC you will need to adjust the serial number -- passed to mkSOA to ensure it is larger. -signedPrimary :: Recurrance -> [Host] -> Domain -> SOA -> [(BindDomain, Record)] -> RevertableProperty HasInfo +signedPrimary :: Recurrance -> [Host] -> Domain -> SOA -> [(BindDomain, Record)] -> RevertableProperty (HasInfo + DebianLike) DebianLike signedPrimary recurrance hosts domain soa rs = setup <!> cleanup where setup = combineProperties ("dns primary for " ++ domain ++ " (signed)") @@ -184,12 +187,12 @@ signedPrimary recurrance hosts domain soa rs = setup <!> cleanup -- -- 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 -> RevertableProperty HasInfo +secondary :: [Host] -> Domain -> RevertableProperty (HasInfo + DebianLike) DebianLike secondary hosts domain = secondaryFor (otherServers Master hosts domain) hosts domain -- | This variant is useful if the primary server does not have its DNS -- configured via propellor. -secondaryFor :: [HostName] -> [Host] -> Domain -> RevertableProperty HasInfo +secondaryFor :: [HostName] -> [Host] -> Domain -> RevertableProperty (HasInfo + DebianLike) DebianLike secondaryFor masters hosts domain = setup <!> cleanup where setup = pureInfoProperty desc (addNamedConf conf) @@ -210,7 +213,7 @@ otherServers :: DnsServerType -> [Host] -> Domain -> [HostName] otherServers wantedtype hosts domain = M.keys $ M.filter wanted $ hostMap hosts where - wanted h = case M.lookup domain (fromNamedConfMap $ getInfo $ hostInfo h) of + wanted h = case M.lookup domain (fromNamedConfMap $ fromInfo $ hostInfo h) of Nothing -> False Just conf -> confDnsServerType conf == wantedtype && confDomain conf == domain @@ -218,15 +221,15 @@ otherServers wantedtype hosts domain = -- | Rewrites the whole named.conf.local file to serve the zones -- configured by `primary` and `secondary`, and ensures that bind9 is -- running. -servingZones :: Property NoInfo +servingZones :: Property DebianLike servingZones = namedConfWritten `onChange` Service.reloaded "bind9" `requires` Apt.serviceInstalledRunning "bind9" -namedConfWritten :: Property NoInfo -namedConfWritten = property "named.conf configured" $ do +namedConfWritten :: Property DebianLike +namedConfWritten = property' "named.conf configured" $ \w -> do zs <- getNamedConf - ensureProperty $ + ensureProperty w $ hasContent namedConfFile $ concatMap confStanza $ M.elems zs @@ -465,7 +468,7 @@ genZone inzdomain hostmap zdomain soa = -- So we can just use the IPAddrs. addcnames :: Host -> [Either WarningMessage (BindDomain, Record)] addcnames h = concatMap gen $ filter (inDomain zdomain) $ - mapMaybe getCNAME $ S.toList $ fromDnsInfo $ getInfo info + mapMaybe getCNAME $ S.toList $ fromDnsInfo $ fromInfo info where info = hostInfo h gen c = case getAddresses info of @@ -480,7 +483,7 @@ genZone inzdomain hostmap zdomain soa = where info = hostInfo h l = zip (repeat $ AbsDomain $ hostName h) - (S.toList $ S.filter (\r -> isNothing (getIPAddr r) && isNothing (getCNAME r)) (fromDnsInfo $ getInfo info)) + (S.toList $ S.filter (\r -> isNothing (getIPAddr r) && isNothing (getCNAME r)) (fromDnsInfo $ fromInfo info)) -- Simplifies the list of hosts. Remove duplicate entries. -- Also, filter out any CHAMES where the same domain has an @@ -515,7 +518,7 @@ addNamedConf conf = NamedConfMap (M.singleton domain conf) domain = confDomain conf getNamedConf :: Propellor (M.Map Domain NamedConf) -getNamedConf = asks $ fromNamedConfMap . getInfo . hostInfo +getNamedConf = asks $ fromNamedConfMap . fromInfo . hostInfo -- | Generates SSHFP records for hosts in the domain (or with CNAMES -- in the domain) that have configured ssh public keys. @@ -528,7 +531,7 @@ genSSHFP domain h = concatMap mk . concat <$> (gen =<< get) gen = liftIO . mapM genSSHFP' . M.elems . fromMaybe M.empty mk r = mapMaybe (\d -> if inDomain domain d then Just (d, r) else Nothing) (AbsDomain hostname : cnames) - cnames = mapMaybe getCNAME $ S.toList $ fromDnsInfo $ getInfo info + cnames = mapMaybe getCNAME $ S.toList $ fromDnsInfo $ fromInfo info hostname = hostName h info = hostInfo h |
