summaryrefslogtreecommitdiff
path: root/src/Propellor/Property/Unbound.hs
blob: 950f669e4ff0be33a2bd63f5a8fddf76d98d4cc9 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
-- | Properties for the Unbound caching DNS server

module Propellor.Property.Unbound
	( installed
	, restarted
	, reloaded
	, genAddressNoTtl
	, genAddress
	, genMX
	, genPTR
	, revIP
	, canonical
	, genZoneStatic
	, genZoneTransparent
	) where

import Propellor
import qualified Propellor.Property.Apt as Apt
import qualified Propellor.Property.Service as Service

import Data.List
import Data.String.Utils (split, replace)


installed :: Property NoInfo
installed = Apt.installed ["unbound"]

restarted :: Property NoInfo
restarted = Service.restarted "unbound"

reloaded :: Property NoInfo
reloaded = Service.reloaded "unbound"

dValue :: BindDomain -> String
dValue (RelDomain d) = d
dValue (AbsDomain d) = d ++ "."
dValue (RootDomain) = "@"

genAddressNoTtl :: BindDomain -> IPAddr -> String
genAddressNoTtl dom = genAddress dom Nothing

genAddress :: BindDomain -> Maybe Int -> IPAddr -> String
genAddress dom ttl addr = case addr of
	IPv4 _ -> genAddress' "A" dom ttl addr
	IPv6 _ -> genAddress' "AAAA" dom ttl addr

genAddress' :: String -> BindDomain -> Maybe Int -> IPAddr -> String
genAddress' recordtype dom ttl addr = localData $ dValue dom ++ " " ++ maybe "" (\ttl' -> show ttl' ++ " ") ttl ++ "IN " ++ recordtype ++ " " ++ fromIPAddr addr

genMX :: BindDomain -> BindDomain -> Int -> String
genMX dom dest priority = localData $ dValue dom ++ " " ++ "MX" ++ " " ++ show priority ++ " " ++ dValue dest

genPTR :: BindDomain -> IPAddr -> String
genPTR dom ip = localData $ revIP ip ++ ". " ++ "PTR" ++ " " ++ dValue dom

revIP :: IPAddr -> String
revIP (IPv4 addr) = intercalate "." (reverse $ split "." addr) ++ ".in-addr.arpa"
revIP addr@(IPv6 _) = reverse (intersperse '.' $ replace ":" "" $ fromIPAddr $ canonical addr) ++ ".ip6.arpa"

canonical :: IPAddr -> IPAddr
canonical (IPv4 addr) = IPv4 addr
canonical (IPv6 addr) = IPv6 $ intercalate ":" $ map canonicalGroup $ split ":" $ replaceImplicitGroups addr
  where
	canonicalGroup g = case length g of
		0 -> "0000"
		1 -> "000" ++ g
		2 -> "00" ++ g
		3 -> "0" ++ g
		_ -> g
	emptyGroups n = iterate (++ ":") "" !! n
	numberOfImplicitGroups a = 8 - length (split ":" $ replace "::" "" a)
	replaceImplicitGroups a = concat $ aux $ split "::" a
	  where
		aux [] = []
		aux (x : xs) = x : emptyGroups (numberOfImplicitGroups a) : xs

localData :: String -> String
localData conf = "    local-data: \"" ++ conf ++ "\""

genZoneStatic :: BindDomain -> String
genZoneStatic dom = localZone (dValue dom) "static"

genZoneTransparent :: BindDomain -> String
genZoneTransparent dom = localZone (dValue dom) "transparent"

localZone :: String -> String -> String
localZone zone confzone = "    local-zone: \"" ++ zone ++ "\" " ++ confzone