module Ganeti.Metad.Config where
import Control.Arrow (second)
import qualified Data.List as List (isPrefixOf)
import qualified Data.Map as Map
import Text.JSON
import qualified Text.JSON as JSON
import Ganeti.Constants as Constants
import Ganeti.Metad.Types
mergeConfig :: InstanceParams -> InstanceParams -> InstanceParams
mergeConfig cfg1 cfg2 = cfg2 `Map.union` cfg1
getOsParams :: String -> String -> JSObject JSValue -> Result (JSObject JSValue)
getOsParams key msg jsonObj =
case lookup key (fromJSObject jsonObj) of
Nothing -> Error $ "Could not find " ++ msg ++ " OS parameters"
Just x -> readJSON x
getPublicOsParams :: JSObject JSValue -> Result (JSObject JSValue)
getPublicOsParams = getOsParams "osparams" "public"
getPrivateOsParams :: JSObject JSValue -> Result (JSObject JSValue)
getPrivateOsParams = getOsParams "osparams_private" "private"
getSecretOsParams :: JSObject JSValue -> Result (JSObject JSValue)
getSecretOsParams = getOsParams "osparams_secret" "secret"
makeInstanceParams
:: JSObject JSValue -> JSObject JSValue -> JSObject JSValue -> JSValue
makeInstanceParams pub priv sec =
JSObject . JSON.toJSObject $
addVisibility "public" pub ++
addVisibility "private" priv ++
addVisibility "secret" sec
where
key = JSString . JSON.toJSString
addVisibility param params =
map (second (JSArray . (:[key param]))) (JSON.fromJSObject params)
getOsParamsWithVisibility :: JSValue -> Result JSValue
getOsParamsWithVisibility json =
do obj <- readJSON json
publicOsParams <- getPublicOsParams obj
privateOsParams <- getPrivateOsParams obj
secretOsParams <- getSecretOsParams obj
Ok $ makeInstanceParams publicOsParams privateOsParams secretOsParams
getInstanceCommunicationIp :: JSObject JSValue -> Result String
getInstanceCommunicationIp jsonObj =
getNics >>= getInstanceCommunicationNic >>= getIp
where
getIp nic =
case lookup "ip" (fromJSObject nic) of
Nothing -> Error "Could not find instance communication IP"
Just (JSString ip) -> Ok (JSON.fromJSString ip)
_ -> Error "Instance communication IP is not a string"
getInstanceCommunicationNic [] =
Error "Could not find instance communication NIC"
getInstanceCommunicationNic (JSObject nic:nics) =
case lookup "name" (fromJSObject nic) of
Just (JSString name)
| Constants.instanceCommunicationNicPrefix
`List.isPrefixOf` JSON.fromJSString name ->
Ok nic
_ -> getInstanceCommunicationNic nics
getInstanceCommunicationNic _ =
Error "Found wrong data in instance NICs"
getNics =
case lookup "nics" (fromJSObject jsonObj) of
Nothing -> Error "Could not find OS parameters key 'nics'"
Just (JSArray nics) -> Ok nics
_ -> Error "Instance nics is not an array"
getInstanceParams :: JSValue -> Result (String, InstanceParams)
getInstanceParams json =
case json of
JSObject jsonObj -> do
name <- case lookup "name" (fromJSObject jsonObj) of
Nothing -> Error "Could not find instance name"
Just (JSString x) -> Ok (JSON.fromJSString x)
_ -> Error "Name is not a string"
ip <- getInstanceCommunicationIp jsonObj
Ok (name, Map.fromList [(ip, json)])
_ ->
Error "Expecting a dictionary"