Revision eaa64cd8

b/Makefile.am
395 395
	htools/Ganeti/HTools/Program/Hscan.hs \
396 396
	htools/Ganeti/HTools/Program/Hspace.hs \
397 397
	htools/Ganeti/BasicTypes.hs \
398
	htools/Ganeti/Config.hs \
398 399
	htools/Ganeti/Jobs.hs \
399 400
	htools/Ganeti/Luxi.hs \
400 401
	htools/Ganeti/Objects.hs \
b/htools/Ganeti/Config.hs
1
{-| Implementation of the Ganeti configuration database.
2

  
3
-}
4

  
5
{-
6

  
7
Copyright (C) 2011, 2012 Google Inc.
8

  
9
This program is free software; you can redistribute it and/or modify
10
it under the terms of the GNU General Public License as published by
11
the Free Software Foundation; either version 2 of the License, or
12
(at your option) any later version.
13

  
14
This program is distributed in the hope that it will be useful, but
15
WITHOUT ANY WARRANTY; without even the implied warranty of
16
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
17
General Public License for more details.
18

  
19
You should have received a copy of the GNU General Public License
20
along with this program; if not, write to the Free Software
21
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
22
02110-1301, USA.
23

  
24
-}
25

  
26
module Ganeti.Config
27
    ( LinkIpMap
28
    , loadConfig
29
    , getNodeInstances
30
    , getDefaultNicLink
31
    , getInstancesIpByLink
32
    , getNode
33
    , getInstance
34
    , getInstPrimaryNode
35
    , buildLinkIpInstnameMap
36
    ) where
37

  
38
import Data.List (foldl')
39
import qualified Data.Map as M
40
import qualified Text.JSON as J
41

  
42
import Ganeti.HTools.JSON
43
import Ganeti.BasicTypes
44

  
45
import qualified Ganeti.Constants as C
46
import Ganeti.Objects
47

  
48
-- | Type alias for the link and ip map.
49
type LinkIpMap = M.Map String (M.Map String String)
50

  
51
-- | Reads the config file.
52
readConfig :: FilePath -> IO String
53
readConfig = readFile
54

  
55
-- | Parses the configuration file.
56
parseConfig :: String -> Result ConfigData
57
parseConfig = fromJResult "parsing configuration" . J.decodeStrict
58

  
59
-- | Wrapper over 'readConfig' and 'parseConfig'.
60
loadConfig :: FilePath -> IO (Result ConfigData)
61
loadConfig = fmap parseConfig . readConfig
62

  
63
-- * Query functions
64

  
65
-- | Get instances of a given node.
66
getNodeInstances :: ConfigData -> String -> ([Instance], [Instance])
67
getNodeInstances cfg nname =
68
    let all_inst = M.elems . configInstances $ cfg
69
        pri_inst = filter ((== nname) . instPrimaryNode) all_inst
70
        -- FIXME: actually compute the secondary nodes
71
        sec_inst = undefined
72
    in (pri_inst, sec_inst)
73

  
74
-- | Returns the default cluster link.
75
getDefaultNicLink :: ConfigData -> String
76
getDefaultNicLink =
77
  nicpLink . (M.! C.ppDefault) . clusterNicparams . configCluster
78

  
79
-- | Returns instances of a given link.
80
getInstancesIpByLink :: LinkIpMap -> String -> [String]
81
getInstancesIpByLink linkipmap link =
82
  M.keys $ M.findWithDefault M.empty link linkipmap
83

  
84
-- | Looks up a node.
85
getNode :: ConfigData -> String -> Result Node
86
getNode cfg name =
87
  maybe (Bad $ "Node " ++ name ++ " not found") Ok $
88
        M.lookup name (configNodes cfg)
89

  
90
-- | Looks up an instance.
91
getInstance :: ConfigData -> String -> Result Instance
92
getInstance cfg name =
93
  maybe (Bad $ "Instance " ++ name ++ " not found") Ok $
94
        M.lookup name (configInstances cfg)
95

  
96
-- | Looks up an instance's primary node.
97
getInstPrimaryNode :: ConfigData -> String -> Result Node
98
getInstPrimaryNode cfg name =
99
  getInstance cfg name >>= return . instPrimaryNode >>= getNode cfg
100

  
101
-- | Builds link -> ip -> instname map.
102
--
103
-- TODO: improve this by splitting it into multiple independent functions:
104
--
105
-- * abstract the \"fetch instance with filled params\" functionality
106
--
107
-- * abstsract the [instance] -> [(nic, instance_name)] part
108
--
109
-- * etc.
110
buildLinkIpInstnameMap :: ConfigData -> LinkIpMap
111
buildLinkIpInstnameMap cfg =
112
  let cluster = configCluster cfg
113
      instances = M.elems . configInstances $ cfg
114
      defparams = (M.!) (clusterNicparams cluster) C.ppDefault
115
      nics = concatMap (\i -> [(instName i, nic) | nic <- instNics i])
116
             instances
117
  in foldl' (\accum (iname, nic) ->
118
               let pparams = nicNicparams nic
119
                   fparams = fillNICParams defparams pparams
120
                   link = nicpLink fparams
121
               in case nicIp nic of
122
                    Nothing -> accum
123
                    Just ip -> let oldipmap = M.findWithDefault (M.empty)
124
                                              link accum
125
                                   newipmap = M.insert ip iname oldipmap
126
                               in M.insert link newipmap accum
127
            ) M.empty nics

Also available in: Unified diff