module Puppet.NativeTypes.Package (nativePackage) where
import Puppet.NativeTypes.Helpers
import Puppet.Interpreter.Types
import Control.Monad.Error
import qualified Data.HashSet as HS
import qualified Data.HashMap.Strict as HM
import qualified Data.Text as T
import Control.Lens
import GHC.Generics
import Data.Hashable
nativePackage :: (PuppetTypeName, PuppetTypeMethods)
nativePackage = ("package", PuppetTypeMethods validatePackage parameterset)
data PackagingFeatures = Holdable | InstallOptions | Installable | Purgeable | UninstallOptions | Uninstallable | Upgradeable | Versionable deriving (Show, Eq, Generic)
instance Hashable PackagingFeatures
isFeatureSupported :: HM.HashMap T.Text (HS.HashSet PackagingFeatures)
isFeatureSupported = HM.fromList [ ("aix", HS.fromList [Installable, Uninstallable, Upgradeable, Versionable])
, ("appdmg", HS.fromList [Installable])
, ("apple", HS.fromList [Installable])
, ("apt", HS.fromList [Holdable, Installable, Purgeable, Uninstallable, Upgradeable, Versionable])
, ("aptitude", HS.fromList [Holdable, Installable, Purgeable, Uninstallable, Upgradeable, Versionable])
, ("aptrpm", HS.fromList [Installable, Purgeable, Uninstallable, Upgradeable, Versionable])
, ("blastwave", HS.fromList [Installable, Uninstallable, Upgradeable])
, ("dpkg", HS.fromList [Holdable, Installable, Purgeable, Uninstallable, Upgradeable])
, ("fink", HS.fromList [Holdable, Installable, Purgeable, Uninstallable, Upgradeable, Versionable])
, ("freebsd", HS.fromList [Installable, Uninstallable])
, ("gem", HS.fromList [Installable, Uninstallable, Upgradeable, Versionable])
, ("hpux", HS.fromList [Installable, Uninstallable])
, ("macports", HS.fromList [Installable, Uninstallable, Upgradeable, Versionable])
, ("msi", HS.fromList [InstallOptions, Installable, UninstallOptions, Uninstallable])
, ("nim", HS.fromList [Installable, Uninstallable, Upgradeable, Versionable])
, ("openbsd", HS.fromList [Installable, Uninstallable, Versionable])
, ("pacman", HS.fromList [Installable, Uninstallable, Upgradeable])
, ("pip", HS.fromList [Installable, Uninstallable, Upgradeable, Versionable])
, ("pkg", HS.fromList [Holdable, Installable, Uninstallable, Upgradeable, Versionable])
, ("pkgdmg", HS.fromList [Installable])
, ("pkgin", HS.fromList [Installable, Uninstallable])
, ("pkgutil", HS.fromList [Installable, Uninstallable, Upgradeable])
, ("portage", HS.fromList [Installable, Uninstallable, Upgradeable, Versionable])
, ("ports", HS.fromList [Installable, Uninstallable, Upgradeable])
, ("portupgrade", HS.fromList [Installable, Uninstallable, Upgradeable])
, ("rpm", HS.fromList [Installable, Uninstallable, Upgradeable, Versionable])
, ("rug", HS.fromList [Installable, Uninstallable, Upgradeable, Versionable])
, ("sun", HS.fromList [InstallOptions, Installable, Uninstallable, Upgradeable])
, ("sunfreeware", HS.fromList [Installable, Uninstallable, Upgradeable])
, ("up2date", HS.fromList [Installable, Uninstallable, Upgradeable])
, ("urpmi", HS.fromList [Installable, Uninstallable, Upgradeable, Versionable])
, ("windows", HS.fromList [InstallOptions, Installable, UninstallOptions, Uninstallable])
, ("yum", HS.fromList [Installable, Purgeable, Uninstallable, Upgradeable, Versionable])
, ("zypper", HS.fromList [Installable, Uninstallable, Upgradeable, Versionable])
]
parameterset :: HS.HashSet T.Text
parameterset = HS.fromList $ map fst parameterfunctions
parameterfunctions :: [(T.Text, [T.Text -> PuppetTypeValidate])]
parameterfunctions =
[("adminfile" , [string, fullyQualified])
,("allowcdrom" , [string, values ["true","false"]])
,("configfiles" , [string, values ["keep","replace"]])
,("ensure" , [defaultvalue "present", string, values ["present","absent","latest","held","purged","installed"]])
,("flavor" , [])
,("install_options" , [rarray])
,("name" , [nameval])
,("provider" , [defaultvalue "apt", string])
,("responsefile" , [string, fullyQualified])
,("source" , [string])
,("uninstall_options", [rarray])
]
getFeature :: Resource -> Either Doc (HS.HashSet PackagingFeatures, Resource)
getFeature res = case res ^. rattributes . at "provider" of
Just (PString x) -> case HM.lookup x isFeatureSupported of
Just s -> Right (s,res)
Nothing -> Left ("Do not know provider" <+> ttext x)
_ -> Left "Can't happen at Puppet.NativeTypes.Package"
checkFeatures :: (HS.HashSet PackagingFeatures, Resource) -> Either Doc Resource
checkFeatures =
checkAdminFile
>=> checkEnsure
>=> checkParam "install_options" InstallOptions
>=> checkParam "uninstall_options" UninstallOptions
>=> decap
where
checkFeature :: HS.HashSet PackagingFeatures -> Resource -> PackagingFeatures -> Either Doc (HS.HashSet PackagingFeatures, Resource)
checkFeature s r f = if HS.member f s
then Right (s, r)
else Left ("Feature" <+> text (show f) <+> "is required for the current configuration")
checkParam :: T.Text -> PackagingFeatures -> (HS.HashSet PackagingFeatures, Resource) -> Either Doc (HS.HashSet PackagingFeatures, Resource)
checkParam pn f (s,r) = if r ^. rattributes . containsAt pn
then checkFeature s r f
else Right (s,r)
checkAdminFile :: (HS.HashSet PackagingFeatures, Resource) -> Either Doc (HS.HashSet PackagingFeatures, Resource)
checkAdminFile = Right
checkEnsure :: (HS.HashSet PackagingFeatures, Resource) -> Either Doc (HS.HashSet PackagingFeatures, Resource)
checkEnsure (s, res) = case res ^. rattributes . at "ensure" of
Just (PString "latest") -> checkFeature s res Installable >> checkFeature s res Versionable
Just (PString "purged") -> checkFeature s res Purgeable
Just (PString "absent") -> checkFeature s res Uninstallable
Just (PString "installed") -> checkFeature s res Installable
Just (PString "present") -> checkFeature s res Installable
Just (PString "held") -> checkFeature s res Installable >> checkFeature s res Holdable
_ -> Right (s, res)
decap :: (HS.HashSet PackagingFeatures, Resource) -> Either Doc Resource
decap = Right . snd
validatePackage :: PuppetTypeValidate
validatePackage = defaultValidate parameterset >=> parameterFunctions parameterfunctions >=> getFeature >=> checkFeatures