Statistics
| Branch: | Tag: | Revision:

root / htools / Ganeti / Config.hs @ 0fc8e521

History | View | Annotate | Download (4.6 kB)

1 eaa64cd8 Iustin Pop
{-| Implementation of the Ganeti configuration database.
2 eaa64cd8 Iustin Pop
3 eaa64cd8 Iustin Pop
-}
4 eaa64cd8 Iustin Pop
5 eaa64cd8 Iustin Pop
{-
6 eaa64cd8 Iustin Pop
7 eaa64cd8 Iustin Pop
Copyright (C) 2011, 2012 Google Inc.
8 eaa64cd8 Iustin Pop
9 eaa64cd8 Iustin Pop
This program is free software; you can redistribute it and/or modify
10 eaa64cd8 Iustin Pop
it under the terms of the GNU General Public License as published by
11 eaa64cd8 Iustin Pop
the Free Software Foundation; either version 2 of the License, or
12 eaa64cd8 Iustin Pop
(at your option) any later version.
13 eaa64cd8 Iustin Pop
14 eaa64cd8 Iustin Pop
This program is distributed in the hope that it will be useful, but
15 eaa64cd8 Iustin Pop
WITHOUT ANY WARRANTY; without even the implied warranty of
16 eaa64cd8 Iustin Pop
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
17 eaa64cd8 Iustin Pop
General Public License for more details.
18 eaa64cd8 Iustin Pop
19 eaa64cd8 Iustin Pop
You should have received a copy of the GNU General Public License
20 eaa64cd8 Iustin Pop
along with this program; if not, write to the Free Software
21 eaa64cd8 Iustin Pop
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
22 eaa64cd8 Iustin Pop
02110-1301, USA.
23 eaa64cd8 Iustin Pop
24 eaa64cd8 Iustin Pop
-}
25 eaa64cd8 Iustin Pop
26 eaa64cd8 Iustin Pop
module Ganeti.Config
27 eaa64cd8 Iustin Pop
    ( LinkIpMap
28 eaa64cd8 Iustin Pop
    , loadConfig
29 eaa64cd8 Iustin Pop
    , getNodeInstances
30 eaa64cd8 Iustin Pop
    , getDefaultNicLink
31 eaa64cd8 Iustin Pop
    , getInstancesIpByLink
32 eaa64cd8 Iustin Pop
    , getNode
33 eaa64cd8 Iustin Pop
    , getInstance
34 eaa64cd8 Iustin Pop
    , getInstPrimaryNode
35 eaa64cd8 Iustin Pop
    , buildLinkIpInstnameMap
36 eaa64cd8 Iustin Pop
    ) where
37 eaa64cd8 Iustin Pop
38 eaa64cd8 Iustin Pop
import Data.List (foldl')
39 eaa64cd8 Iustin Pop
import qualified Data.Map as M
40 eaa64cd8 Iustin Pop
import qualified Text.JSON as J
41 eaa64cd8 Iustin Pop
42 eaa64cd8 Iustin Pop
import Ganeti.HTools.JSON
43 eaa64cd8 Iustin Pop
import Ganeti.BasicTypes
44 eaa64cd8 Iustin Pop
45 eaa64cd8 Iustin Pop
import qualified Ganeti.Constants as C
46 eaa64cd8 Iustin Pop
import Ganeti.Objects
47 eaa64cd8 Iustin Pop
48 eaa64cd8 Iustin Pop
-- | Type alias for the link and ip map.
49 eaa64cd8 Iustin Pop
type LinkIpMap = M.Map String (M.Map String String)
50 eaa64cd8 Iustin Pop
51 eaa64cd8 Iustin Pop
-- | Reads the config file.
52 eaa64cd8 Iustin Pop
readConfig :: FilePath -> IO String
53 eaa64cd8 Iustin Pop
readConfig = readFile
54 eaa64cd8 Iustin Pop
55 eaa64cd8 Iustin Pop
-- | Parses the configuration file.
56 eaa64cd8 Iustin Pop
parseConfig :: String -> Result ConfigData
57 eaa64cd8 Iustin Pop
parseConfig = fromJResult "parsing configuration" . J.decodeStrict
58 eaa64cd8 Iustin Pop
59 eaa64cd8 Iustin Pop
-- | Wrapper over 'readConfig' and 'parseConfig'.
60 eaa64cd8 Iustin Pop
loadConfig :: FilePath -> IO (Result ConfigData)
61 eaa64cd8 Iustin Pop
loadConfig = fmap parseConfig . readConfig
62 eaa64cd8 Iustin Pop
63 eaa64cd8 Iustin Pop
-- * Query functions
64 eaa64cd8 Iustin Pop
65 eaa64cd8 Iustin Pop
-- | Get instances of a given node.
66 eaa64cd8 Iustin Pop
getNodeInstances :: ConfigData -> String -> ([Instance], [Instance])
67 eaa64cd8 Iustin Pop
getNodeInstances cfg nname =
68 eaa64cd8 Iustin Pop
    let all_inst = M.elems . configInstances $ cfg
69 eaa64cd8 Iustin Pop
        pri_inst = filter ((== nname) . instPrimaryNode) all_inst
70 eaa64cd8 Iustin Pop
        -- FIXME: actually compute the secondary nodes
71 eaa64cd8 Iustin Pop
        sec_inst = undefined
72 eaa64cd8 Iustin Pop
    in (pri_inst, sec_inst)
73 eaa64cd8 Iustin Pop
74 eaa64cd8 Iustin Pop
-- | Returns the default cluster link.
75 eaa64cd8 Iustin Pop
getDefaultNicLink :: ConfigData -> String
76 eaa64cd8 Iustin Pop
getDefaultNicLink =
77 eaa64cd8 Iustin Pop
  nicpLink . (M.! C.ppDefault) . clusterNicparams . configCluster
78 eaa64cd8 Iustin Pop
79 eaa64cd8 Iustin Pop
-- | Returns instances of a given link.
80 eaa64cd8 Iustin Pop
getInstancesIpByLink :: LinkIpMap -> String -> [String]
81 eaa64cd8 Iustin Pop
getInstancesIpByLink linkipmap link =
82 eaa64cd8 Iustin Pop
  M.keys $ M.findWithDefault M.empty link linkipmap
83 eaa64cd8 Iustin Pop
84 0fc8e521 Iustin Pop
-- | Generic lookup function that converts from a possible abbreviated
85 0fc8e521 Iustin Pop
-- name to a full name.
86 0fc8e521 Iustin Pop
getItem :: String -> String -> M.Map String a -> Result a
87 0fc8e521 Iustin Pop
getItem kind name allitems = do
88 0fc8e521 Iustin Pop
  let lresult = lookupName (M.keys allitems) name
89 0fc8e521 Iustin Pop
      err = \details -> Bad $ kind ++ " name " ++ name ++ " " ++ details
90 0fc8e521 Iustin Pop
  fullname <- case lrMatchPriority lresult of
91 0fc8e521 Iustin Pop
                PartialMatch -> Ok $ lrContent lresult
92 0fc8e521 Iustin Pop
                ExactMatch -> Ok $ lrContent lresult
93 0fc8e521 Iustin Pop
                MultipleMatch -> err "has multiple matches"
94 0fc8e521 Iustin Pop
                FailMatch -> err "not found"
95 0fc8e521 Iustin Pop
  maybe (err "not found after successfull match?!") Ok $
96 0fc8e521 Iustin Pop
        M.lookup fullname allitems
97 0fc8e521 Iustin Pop
98 eaa64cd8 Iustin Pop
-- | Looks up a node.
99 eaa64cd8 Iustin Pop
getNode :: ConfigData -> String -> Result Node
100 0fc8e521 Iustin Pop
getNode cfg name = getItem "Node" name (configNodes cfg)
101 eaa64cd8 Iustin Pop
102 eaa64cd8 Iustin Pop
-- | Looks up an instance.
103 eaa64cd8 Iustin Pop
getInstance :: ConfigData -> String -> Result Instance
104 0fc8e521 Iustin Pop
getInstance cfg name = getItem "Instance" name (configInstances cfg)
105 eaa64cd8 Iustin Pop
106 eaa64cd8 Iustin Pop
-- | Looks up an instance's primary node.
107 eaa64cd8 Iustin Pop
getInstPrimaryNode :: ConfigData -> String -> Result Node
108 eaa64cd8 Iustin Pop
getInstPrimaryNode cfg name =
109 eaa64cd8 Iustin Pop
  getInstance cfg name >>= return . instPrimaryNode >>= getNode cfg
110 eaa64cd8 Iustin Pop
111 eaa64cd8 Iustin Pop
-- | Builds link -> ip -> instname map.
112 eaa64cd8 Iustin Pop
--
113 eaa64cd8 Iustin Pop
-- TODO: improve this by splitting it into multiple independent functions:
114 eaa64cd8 Iustin Pop
--
115 eaa64cd8 Iustin Pop
-- * abstract the \"fetch instance with filled params\" functionality
116 eaa64cd8 Iustin Pop
--
117 eaa64cd8 Iustin Pop
-- * abstsract the [instance] -> [(nic, instance_name)] part
118 eaa64cd8 Iustin Pop
--
119 eaa64cd8 Iustin Pop
-- * etc.
120 eaa64cd8 Iustin Pop
buildLinkIpInstnameMap :: ConfigData -> LinkIpMap
121 eaa64cd8 Iustin Pop
buildLinkIpInstnameMap cfg =
122 eaa64cd8 Iustin Pop
  let cluster = configCluster cfg
123 eaa64cd8 Iustin Pop
      instances = M.elems . configInstances $ cfg
124 eaa64cd8 Iustin Pop
      defparams = (M.!) (clusterNicparams cluster) C.ppDefault
125 eaa64cd8 Iustin Pop
      nics = concatMap (\i -> [(instName i, nic) | nic <- instNics i])
126 eaa64cd8 Iustin Pop
             instances
127 eaa64cd8 Iustin Pop
  in foldl' (\accum (iname, nic) ->
128 eaa64cd8 Iustin Pop
               let pparams = nicNicparams nic
129 eaa64cd8 Iustin Pop
                   fparams = fillNICParams defparams pparams
130 eaa64cd8 Iustin Pop
                   link = nicpLink fparams
131 eaa64cd8 Iustin Pop
               in case nicIp nic of
132 eaa64cd8 Iustin Pop
                    Nothing -> accum
133 eaa64cd8 Iustin Pop
                    Just ip -> let oldipmap = M.findWithDefault (M.empty)
134 eaa64cd8 Iustin Pop
                                              link accum
135 eaa64cd8 Iustin Pop
                                   newipmap = M.insert ip iname oldipmap
136 eaa64cd8 Iustin Pop
                               in M.insert link newipmap accum
137 eaa64cd8 Iustin Pop
            ) M.empty nics