Statistics
| Branch: | Tag: | Revision:

root / htools / Ganeti / Query / Common.hs @ 4cab6703

History | View | Annotate | Download (5.1 kB)

1
{-| Implementation of the Ganeti Query2 common objects.
2

    
3
 -}
4

    
5
{-
6

    
7
Copyright (C) 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.Query.Common
27
  ( rsNoData
28
  , rsNormal
29
  , rsMaybe
30
  , rsUnknown
31
  , missingRuntime
32
  , timeStampFields
33
  , uuidFields
34
  , serialFields
35
  , tagsFields
36
  , dictFieldGetter
37
  , buildQFTLookup
38
  , buildNdParamField
39
  ) where
40

    
41
import qualified Data.Map as Map
42
import Data.Maybe (fromMaybe)
43
import Text.JSON (JSON, showJSON)
44

    
45
import qualified Ganeti.Constants as C
46
import Ganeti.Config
47
import Ganeti.Objects
48
import Ganeti.Query.Language
49
import Ganeti.Query.Types
50

    
51
-- * Generic functions
52

    
53
-- | Conversion from 'VType' to 'FieldType'.
54
vTypeToQFT :: VType -> FieldType
55
vTypeToQFT VTypeString      = QFTOther
56
vTypeToQFT VTypeMaybeString = QFTOther
57
vTypeToQFT VTypeBool        = QFTBool
58
vTypeToQFT VTypeSize        = QFTUnit
59
vTypeToQFT VTypeInt         = QFTNumber
60

    
61
-- * Result helpers
62

    
63
-- | Helper for a result with no data.
64
rsNoData :: ResultEntry
65
rsNoData = ResultEntry RSNoData Nothing
66

    
67
-- | Helper to declare a normal result.
68
rsNormal :: (JSON a) => a -> ResultEntry
69
rsNormal a = ResultEntry RSNormal $ Just (showJSON a)
70

    
71
-- | Helper to declare a result from a 'Maybe' (the item might be
72
-- missing, in which case we return no data). Note that there's some
73
-- ambiguity here: in some cases, we mean 'RSNoData', but in other
74
-- 'RSUnavail'; this is easy to solve in simple cases, but not in
75
-- nested dicts.
76
rsMaybe :: (JSON a) => Maybe a -> ResultEntry
77
rsMaybe = maybe rsNoData rsNormal
78

    
79
-- | Helper for unknown field result.
80
rsUnknown :: ResultEntry
81
rsUnknown = ResultEntry RSUnknown Nothing
82

    
83
-- | Helper for a missing runtime parameter.
84
missingRuntime :: FieldGetter a b
85
missingRuntime = FieldRuntime (\_ _ -> ResultEntry RSNoData Nothing)
86

    
87
-- * Common fields
88

    
89
-- | The list of timestamp fields.
90
timeStampFields :: (TimeStampObject a) => FieldList a b
91
timeStampFields =
92
  [ (FieldDefinition "ctime" "CTime" QFTTimestamp "Creation timestamp",
93
     FieldSimple (rsNormal . cTimeOf))
94
  , (FieldDefinition "mtime" "MTime" QFTTimestamp "Modification timestamp",
95
     FieldSimple (rsNormal . mTimeOf))
96
  ]
97

    
98
-- | The list of UUID fields.
99
uuidFields :: (UuidObject a) => String -> FieldList a b
100
uuidFields name =
101
  [ (FieldDefinition "uuid" "UUID" QFTText  (name ++ " UUID"),
102
     FieldSimple (rsNormal . uuidOf)) ]
103

    
104
-- | The list of serial number fields.
105
serialFields :: (SerialNoObject a) => String -> FieldList a b
106
serialFields name =
107
  [ (FieldDefinition "serial_no" "SerialNo" QFTNumber
108
     (name ++ " object serial number, incremented on each modification"),
109
     FieldSimple (rsNormal . serialOf)) ]
110

    
111
-- | The list of tag fields.
112
tagsFields :: (TagsObject a) => FieldList a b
113
tagsFields =
114
  [ (FieldDefinition "tags" "Tags" QFTOther "Tags",
115
     FieldSimple (rsNormal . tagsOf)) ]
116

    
117
-- * Generic parameter functions
118

    
119
-- | Returns a field from a (possibly missing) 'DictObject'. This is
120
-- used by parameter dictionaries, usually. Note that we have two
121
-- levels of maybe: the top level dict might be missing, or one key in
122
-- the dictionary might be.
123
dictFieldGetter :: (DictObject a) => String -> Maybe a -> ResultEntry
124
dictFieldGetter k = maybe rsNoData (rsMaybe . lookup k . toDict)
125

    
126
-- | Build an optimised lookup map from a Python _PARAMETER_TYPES
127
-- association list.
128
buildQFTLookup :: [(String, String)] -> Map.Map String FieldType
129
buildQFTLookup =
130
  Map.fromList .
131
  map (\(k, v) -> (k, maybe QFTOther vTypeToQFT (vTypeFromRaw v)))
132

    
133
-- | Ndparams optimised lookup map.
134
ndParamTypes :: Map.Map String FieldType
135
ndParamTypes = buildQFTLookup C.ndsParameterTypes
136

    
137
-- | Ndparams title map.
138
ndParamTitles :: Map.Map String FieldTitle
139
ndParamTitles = Map.fromList C.ndsParameterTitles
140

    
141
-- | Ndparam getter builder: given a field, it returns a FieldConfig
142
-- getter, that is a function that takes the config and the object and
143
-- returns the Ndparam field specified when the getter was built.
144
ndParamGetter :: (NdParamObject a) =>
145
                 String -- ^ The field we're building the getter for
146
              -> ConfigData -> a -> ResultEntry
147
ndParamGetter field config =
148
  dictFieldGetter field . getNdParamsOf config
149

    
150
-- | Builds the ndparam fields for an object.
151
buildNdParamField :: (NdParamObject a) => String -> FieldData a b
152
buildNdParamField field =
153
  let full_name = "ndp/" ++ field
154
      title = fromMaybe field $ field `Map.lookup` ndParamTitles
155
      qft = fromMaybe QFTOther $ field `Map.lookup` ndParamTypes
156
      desc = "The \"" ++ field ++ "\" node parameter"
157
  in (FieldDefinition full_name title qft desc,
158
      FieldConfig (ndParamGetter field))