module Propellor.Property.SiteSpecific.Branchable where

import Propellor.Base
import qualified Propellor.Property.Apt as Apt
import qualified Propellor.Property.File as File
import qualified Propellor.Property.User as User
import qualified Propellor.Property.Ssh as Ssh
import qualified Propellor.Property.Postfix as Postfix
import qualified Propellor.Property.Sudo as Sudo
import qualified Propellor.Property.Borg as Borg
import qualified Propellor.Property.Cron as Cron
import Propellor.Property.SiteSpecific.JoeySites (rsyncNetBorgRepo)

server :: [Host] -> Property (HasInfo + DebianLike)
server :: [Host] -> Property (HasInfo + DebianLike)
server [Host]
hosts = forall {k} (metatypes :: k).
SingI metatypes =>
Desc
-> Props (MetaTypes metatypes) -> Property (MetaTypes metatypes)
propertyList Desc
"branchable server" forall a b. (a -> b) -> a -> b
$ Props UnixLike
props
	forall {a} p (y :: [a]) (x :: [a]).
(IsProp p, MetaTypes y ~ GetMetaTypes p,
 CheckCombinableNote x y (NoteFor ('Text "&"))) =>
Props (MetaTypes x) -> p -> Props (MetaTypes (Combine x y))
& Desc
"/etc/timezone" Desc -> [Desc] -> Property UnixLike
`File.hasContent` [Desc
"Etc/UTC"]
	forall {a} p (y :: [a]) (x :: [a]).
(IsProp p, MetaTypes y ~ GetMetaTypes p,
 CheckCombinableNote x y (NoteFor ('Text "&"))) =>
Props (MetaTypes x) -> p -> Props (MetaTypes (Combine x y))
& Desc
"/etc/locale.gen" Desc -> [Desc] -> Property UnixLike
`File.containsLines`
		[ Desc
"en_GB.UTF-8 UTF-8"
		, Desc
"en_US.UTF-8 UTF-8"
		, Desc
"fi_FI.UTF-8 UTF-8"
		]
		forall x y. Combines x y => x -> y -> CombinedType x y
`onChange` (Desc -> [Desc] -> UncheckedProperty UnixLike
cmdProperty Desc
"locale-gen" [] forall (p :: * -> *) i.
Checkable p i =>
p i -> Result -> Property i
`assume` Result
MadeChange)

	forall {a} p (y :: [a]) (x :: [a]).
(IsProp p, MetaTypes y ~ GetMetaTypes p,
 CheckCombinableNote x y (NoteFor ('Text "&"))) =>
Props (MetaTypes x) -> p -> Props (MetaTypes (Combine x y))
& [Desc] -> Property DebianLike
Apt.installed [Desc
"etckeeper", Desc
"ssh", Desc
"popularity-contest"]
	forall {a} p (y :: [a]) (x :: [a]).
(IsProp p, MetaTypes y ~ GetMetaTypes p,
 CheckCombinableNote x y (NoteFor ('Text "&"))) =>
Props (MetaTypes x) -> p -> Props (MetaTypes (Combine x y))
& Desc -> Property DebianLike
Apt.serviceInstalledRunning Desc
"apache2"
	forall {a} p (y :: [a]) (x :: [a]).
(IsProp p, MetaTypes y ~ GetMetaTypes p,
 CheckCombinableNote x y (NoteFor ('Text "&"))) =>
Props (MetaTypes x) -> p -> Props (MetaTypes (Combine x y))
& Desc -> Property DebianLike
Apt.serviceInstalledRunning Desc
"ntp"

	forall {a} p (y :: [a]) (x :: [a]).
(IsProp p, MetaTypes y ~ GetMetaTypes p,
 CheckCombinableNote x y (NoteFor ('Text "&"))) =>
Props (MetaTypes x) -> p -> Props (MetaTypes (Combine x y))
& Desc -> Property DebianLike
Apt.serviceInstalledRunning Desc
"openssh-server"
	forall {a} p (y :: [a]) (x :: [a]).
(IsProp p, MetaTypes y ~ GetMetaTypes p,
 CheckCombinableNote x y (NoteFor ('Text "&"))) =>
Props (MetaTypes x) -> p -> Props (MetaTypes (Combine x y))
& Bool -> Property DebianLike
Ssh.passwordAuthentication Bool
False
	forall {a} p (y :: [a]) (x :: [a]).
(IsProp p, MetaTypes y ~ GetMetaTypes p,
 CheckCombinableNote x y (NoteFor ('Text "&"))) =>
Props (MetaTypes x) -> p -> Props (MetaTypes (Combine x y))
& forall c.
IsContext c =>
c -> [(SshKeyType, Desc)] -> Property (HasInfo + DebianLike)
Ssh.hostKeys (Desc -> Context
Context Desc
"branchable.com")
		[ (SshKeyType
SshDsa, Desc
"ssh-dss AAAAB3NzaC1kc3MAAACBAK9HnfpyIm8aEhKuF5oz6KyaLwFs2oWeToVkqVuykyy5Y8jWDZPtkpv+1TeOnjcOvJSZ1cCqB8iXlsP9Dr5z98w5MfzsRQM2wIw0n+wvmpPmUhjVdGh+wTpfP9bcyFHhj/f1Ymdq9hEWB26bnf4pbTbJW2ip8ULshMvn5CQ/ugV3AAAAFQCAjpRd1fquRiIuLJMwej0VcyoZKQAAAIBe91Grvz/icL3nlqXYrifXyr9dsw8bPN+BMu+hQtFsQXNJBylxwf8FtbRlmvZXmRjdVYqFVyxSsrL2pMsWlds51iXOr9pdsPG5a4OgJyRHsveBz3tz6HgYYPcr3Oxp7C6G6wrzwsaGK862SgRp/bbD226k9dODRBy3ogMhk/MvAgAAAIEApfknql3vZbDVa88ZnwbNKDOv8L1hb6blbKAMt2vJbqJMvu3EP9CsP9hGyEQh5YCAl2F9KEU3bJXN1BG76b7CiYtWK95lpL1XmCCWnJBCcdEhw998GfJS424frPw7qGmXLxJKYxEyioB90/IDp2dC+WaLcLOYHM9SroCQTIK5A1g= root@pell")
		, (SshKeyType
SshRsa, Desc
"ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEA1M0aNLgcgcgf0tkmt/8vCDZLok8Xixz7Nun9wB6NqVXxfzAR4te+zyO7FucVwyTY5QHmiwwpmyNfaC21AAILhXGm12SUKSAirF9BkQk7bhQuz4T/dPlEt3d3SxQ3OZlXtPp4LzXWOyS0OXSzIb+HeaDA+hFXlQnp/gE7RyAzR1+xhWPO7Mz1q5O/+4dXANnW32t6P7Puob6NsglVDpLrMRYjkO+0RgCVbYMzB5+UnkthkZsIINaYwsNhW2GKMKbRZeyp5en5t1NJprGXdw0BqdBqd/rcBpOxmhHE1U7rw+GS1uZwCFWWv0aZbaXEJ6wY7mETFkqs0QXi5jtoKn95Gw== root@pell")
		, (SshKeyType
SshEcdsa, Desc
"ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBLRRZ3Ew6eq6d8+ID1CXwF0hLjObNM2XwCIOFI4Wml2iP5NIHwtUCg2hlVUal6v1bO+VPjvx3dkf5Y00GI2BVSY= root@pell")
		, (SshKeyType
SshEd25519, Desc
"ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIG5gaqToi0NtZH+vxXqW8E/reJW2tMHOEs2ycieMYkng root@pell")
		]

	forall {a} p (y :: [a]) (x :: [a]).
(IsProp p, MetaTypes y ~ GetMetaTypes p,
 CheckCombinableNote x y (NoteFor ('Text "&"))) =>
Props (MetaTypes x) -> p -> Props (MetaTypes (Combine x y))
& [Desc] -> Property DebianLike
Apt.installed [Desc
"procmail", Desc
"bsd-mailx"]
	forall {a} p (y :: [a]) (x :: [a]).
(IsProp p, MetaTypes y ~ GetMetaTypes p,
 CheckCombinableNote x y (NoteFor ('Text "&"))) =>
Props (MetaTypes x) -> p -> Props (MetaTypes (Combine x y))
& Desc
"/etc/aliases" forall c. IsContext c => Desc -> c -> Property (HasInfo + UnixLike)
`File.hasPrivContentExposed` (Desc -> Context
Context Desc
"branchable.com")
		forall x y. Combines x y => x -> y -> CombinedType x y
`onChange` Property UnixLike
Postfix.newaliases
	forall {a} p (y :: [a]) (x :: [a]).
(IsProp p, MetaTypes y ~ GetMetaTypes p,
 CheckCombinableNote x y (NoteFor ('Text "&"))) =>
Props (MetaTypes x) -> p -> Props (MetaTypes (Combine x y))
& Desc
"/etc/mailname" Desc -> [Desc] -> Property UnixLike
`File.hasContent` [Desc
"branchable.com"]
	forall {a} p (y :: [a]) (x :: [a]).
(IsProp p, MetaTypes y ~ GetMetaTypes p,
 CheckCombinableNote x y (NoteFor ('Text "&"))) =>
Props (MetaTypes x) -> p -> Props (MetaTypes (Combine x y))
& Property DebianLike
Postfix.installed
	forall {a} p (y :: [a]) (x :: [a]).
(IsProp p, MetaTypes y ~ GetMetaTypes p,
 CheckCombinableNote x y (NoteFor ('Text "&"))) =>
Props (MetaTypes x) -> p -> Props (MetaTypes (Combine x y))
& (Desc, Desc) -> Property UnixLike
Postfix.mainCf (Desc
"mailbox_command", Desc
"procmail -a \"$EXTENSION\"")
	
	-- backup everything except the contents of sites, which are
	-- backed up by ikiwiki-hosting.
	forall {a} p (y :: [a]) (x :: [a]).
(IsProp p, MetaTypes y ~ GetMetaTypes p,
 CheckCombinableNote x y (NoteFor ('Text "&"))) =>
Props (MetaTypes x) -> p -> Props (MetaTypes (Combine x y))
& Desc
-> BorgRepo
-> Times
-> [Desc]
-> [KeepPolicy]
-> Property DebianLike
Borg.backup Desc
"/" (Desc -> [BorgRepoOpt] -> BorgRepo
rsyncNetBorgRepo Desc
"pell.borg" []) Times
Cron.Daily
		[ Desc
"--exclude=/proc/*"
	 	, Desc
"--exclude=/sys/*"
	 	, Desc
"--exclude=/run/*"
	 	, Desc
"--exclude=/tmp/*"
	 	, Desc
"--exclude=/var/tmp/*"
	 	, Desc
"--exclude=/var/backups/ikiwiki-hosting-web/*"
	 	, Desc
"--exclude=/var/cache/*"
	 	, Desc
"--exclude=/home/*/source/*"
	 	, Desc
"--exclude=/home/*/source.git/*"
	 	, Desc
"--exclude=/home/*/public_html/*"
	 	, Desc
"--exclude=/home/*/.git/*"
	 	]
	 	[ Int -> KeepPolicy
Borg.KeepDays Int
7
	 	, Int -> KeepPolicy
Borg.KeepWeeks Int
5
	 	, Int -> KeepPolicy
Borg.KeepMonths Int
3
	 	, Int -> KeepPolicy
Borg.KeepYears Int
1
	 	]
	forall {a} p (y :: [a]) (x :: [a]).
(IsProp p, MetaTypes y ~ GetMetaTypes p,
 CheckCombinableNote x y (NoteFor ('Text "&"))) =>
Props (MetaTypes x) -> p -> Props (MetaTypes (Combine x y))
& forall c.
IsContext c =>
User -> c -> [(SshKeyType, Desc)] -> Property (HasInfo + UnixLike)
Ssh.userKeys (Desc -> User
User Desc
"root") (Desc -> Context
Context Desc
"branchable.com")
		[ (SshKeyType
SshEd25519, Desc
"ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIC20PCLAgkD6tK0vYsl0Pdpho+y7fNay8Fo8SXWrZojs root@pell")
		]
	forall {a} p (y :: [a]) (x :: [a]).
(IsProp p, MetaTypes y ~ GetMetaTypes p,
 CheckCombinableNote x y (NoteFor ('Text "&"))) =>
Props (MetaTypes x) -> p -> Props (MetaTypes (Combine x y))
& [Host] -> Desc -> User -> Property UnixLike
Ssh.knownHost [Host]
hosts Desc
"usw-s002.rsync.net" (Desc -> User
User Desc
"root")

	forall {a} p (y :: [a]) (x :: [a]).
(IsProp p, MetaTypes y ~ GetMetaTypes p,
 CheckCombinableNote x y (NoteFor ('Text "&"))) =>
Props (MetaTypes x) -> p -> Props (MetaTypes (Combine x y))
& Desc
-> Property
     (MetaTypes
        '[ 'WithInfo, 'Targeting 'OSDebian, 'Targeting 'OSBuntish])
adminuser Desc
"joey"
  where
	adminuser :: Desc
-> Property
     (MetaTypes
        (Combine
           (Combine
              (Combine
                 (Combine
                    '[ 'Targeting 'OSDebian, 'Targeting 'OSBuntish]
                    '[ 'WithInfo, 'Targeting 'OSDebian, 'Targeting 'OSBuntish])
                 '[ 'Targeting 'OSDebian, 'Targeting 'OSBuntish])
              '[ 'Targeting 'OSDebian, 'Targeting 'OSBuntish])
           '[ 'Targeting 'OSDebian, 'Targeting 'OSBuntish]))
adminuser Desc
u = forall {k} (metatypes :: k).
SingI metatypes =>
Desc
-> Props (MetaTypes metatypes) -> Property (MetaTypes metatypes)
propertyList (Desc
"admin user " forall a. [a] -> [a] -> [a]
++ Desc
u) forall a b. (a -> b) -> a -> b
$ Props UnixLike
props
		forall {a} p (y :: [a]) (x :: [a]).
(IsProp p, MetaTypes y ~ GetMetaTypes p,
 CheckCombinableNote x y (NoteFor ('Text "&"))) =>
Props (MetaTypes x) -> p -> Props (MetaTypes (Combine x y))
& User -> Property DebianLike
User.accountFor (Desc -> User
User Desc
u)
		forall {a} p (y :: [a]) (x :: [a]).
(IsProp p, MetaTypes y ~ GetMetaTypes p,
 CheckCombinableNote x y (NoteFor ('Text "&"))) =>
Props (MetaTypes x) -> p -> Props (MetaTypes (Combine x y))
& User -> Property (HasInfo + DebianLike)
User.hasSomePassword (Desc -> User
User Desc
u)
		forall {a} p (y :: [a]) (x :: [a]).
(IsProp p, MetaTypes y ~ GetMetaTypes p,
 CheckCombinableNote x y (NoteFor ('Text "&"))) =>
Props (MetaTypes x) -> p -> Props (MetaTypes (Combine x y))
& User -> RevertableProperty DebianLike DebianLike
Sudo.enabledFor (Desc -> User
User Desc
u)
		forall {a} p (y :: [a]) (x :: [a]).
(IsProp p, MetaTypes y ~ GetMetaTypes p,
 CheckCombinableNote x y (NoteFor ('Text "&"))) =>
Props (MetaTypes x) -> p -> Props (MetaTypes (Combine x y))
& User -> Group -> Property DebianLike
User.hasGroup (Desc -> User
User Desc
u) (Desc -> Group
Group Desc
"adm")
		forall {a} p (y :: [a]) (x :: [a]).
(IsProp p, MetaTypes y ~ GetMetaTypes p,
 CheckCombinableNote x y (NoteFor ('Text "&"))) =>
Props (MetaTypes x) -> p -> Props (MetaTypes (Combine x y))
& User -> Group -> Property DebianLike
User.hasGroup (Desc -> User
User Desc
u) (Desc -> Group
Group Desc
"systemd-journal")