+-- | Convert a string to an alloc policy
+apolFromString :: (Monad m) => String -> m AllocPolicy
+apolFromString s =
+ case s of
+ "preferred" -> return AllocPreferred
+ "last_resort" -> return AllocLastResort
+ "unallocable" -> return AllocUnallocable
+ o -> fail $ "Invalid alloc policy mode: " ++ o
+
+-- | Convert an alloc policy to the Ganeti string equivalent
+apolToString :: AllocPolicy -> String
+apolToString AllocPreferred = "preferred"
+apolToString AllocLastResort = "last_resort"
+apolToString AllocUnallocable = "unallocable"
+
+instance JSON.JSON AllocPolicy where
+ showJSON = JSON.showJSON . apolToString
+ readJSON s = case JSON.readJSON s of
+ JSON.Ok s' -> apolFromString s'
+ JSON.Error e -> JSON.Error $
+ "Can't parse alloc_policy: " ++ e
+