-- | Retrieves the instance hypervisor params, missing values filled with
-- cluster defaults.
getFilledInstHvParams :: [String] -> ConfigData -> Instance -> HvParams
getFilledInstHvParams globals cfg inst =
  -- First get the defaults of the parent
  let maybeHvName = instHypervisor inst
      hvParamMap = fromContainer . clusterHvparams $ configCluster cfg
      parentHvParams =
        maybe M.empty fromContainer (maybeHvName >>= flip M.lookup hvParamMap)
  -- Then the os defaults for the given hypervisor
      maybeOsName = UTF8.fromString <$> instOs inst
      osParamMap = fromContainer . clusterOsHvp $ configCluster cfg
      osHvParamMap =
        maybe M.empty (maybe M.empty fromContainer . flip M.lookup osParamMap)
          maybeOsName
      osHvParams =
        maybe M.empty (maybe M.empty fromContainer . flip M.lookup osHvParamMap)
          maybeHvName
  -- Then the child
      childHvParams = fromContainer . instHvparams $ inst
  -- Helper function
      fillFn con val = fillDict con val $ fmap UTF8.fromString globals
  in GenericContainer $ fillFn (fillFn parentHvParams osHvParams) childHvParams
getFilledInstHvParams :: [String] -> ConfigData -> Instance -> HvParams
getFilledInstHvParams globals cfg inst =
  -- First get the defaults of the parent
  let maybeHvName = instHypervisor inst
      hvParamMap = fromContainer . clusterHvparams $ configCluster cfg
      parentHvParams =
        maybe M.empty fromContainer (maybeHvName >>= flip M.lookup hvParamMap)
  -- Then the os defaults for the given hypervisor
      maybeOsName = UTF8.fromString <$> instOs inst
      osParamMap = fromContainer . clusterOsHvp $ configCluster cfg
      osHvParamMap =
        maybe M.empty (maybe M.empty fromContainer . flip M.lookup osParamMap)
          maybeOsName
      osHvParams =
        maybe M.empty (maybe M.empty fromContainer . flip M.lookup osHvParamMap)
          maybeHvName
  -- Then the child
      childHvParams = fromContainer . instHvparams $ inst
  -- Helper function
      fillFn con val = fillDict con val $ fmap UTF8.fromString globals
  in GenericContainer $ fillFn (fillFn parentHvParams osHvParams) childHvParams
getFilledInstHvParams globals cfg inst =
  -- First get the defaults of the parent
  let maybeHvName = instHypervisor inst
      hvParamMap = fromContainer . clusterHvparams $ configCluster cfg
      parentHvParams =
        maybe M.empty fromContainer (maybeHvName >>= flip M.lookup hvParamMap)
  -- Then the os defaults for the given hypervisor
      maybeOsName = UTF8.fromString <$> instOs inst
      osParamMap = fromContainer . clusterOsHvp $ configCluster cfg
      osHvParamMap =
        maybe M.empty (maybe M.empty fromContainer . flip M.lookup osParamMap)
          maybeOsName
      osHvParams =
        maybe M.empty (maybe M.empty fromContainer . flip M.lookup osHvParamMap)
          maybeHvName
  -- Then the child
      childHvParams = fromContainer . instHvparams $ inst
  -- Helper function
      fillFn con val = fillDict con val $ fmap UTF8.fromString globals
  in GenericContainer $ fillFn (fillFn parentHvParams osHvParams) childHvParams