Statistics
| Branch: | Tag: | Revision:

root / htools / Ganeti / Query / Common.hs @ 7ae97c33

History | View | Annotate | Download (5.4 kB)

1 046fe3f5 Iustin Pop
{-| Implementation of the Ganeti Query2 common objects.
2 046fe3f5 Iustin Pop
3 046fe3f5 Iustin Pop
 -}
4 046fe3f5 Iustin Pop
5 046fe3f5 Iustin Pop
{-
6 046fe3f5 Iustin Pop
7 046fe3f5 Iustin Pop
Copyright (C) 2012 Google Inc.
8 046fe3f5 Iustin Pop
9 046fe3f5 Iustin Pop
This program is free software; you can redistribute it and/or modify
10 046fe3f5 Iustin Pop
it under the terms of the GNU General Public License as published by
11 046fe3f5 Iustin Pop
the Free Software Foundation; either version 2 of the License, or
12 046fe3f5 Iustin Pop
(at your option) any later version.
13 046fe3f5 Iustin Pop
14 046fe3f5 Iustin Pop
This program is distributed in the hope that it will be useful, but
15 046fe3f5 Iustin Pop
WITHOUT ANY WARRANTY; without even the implied warranty of
16 046fe3f5 Iustin Pop
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
17 046fe3f5 Iustin Pop
General Public License for more details.
18 046fe3f5 Iustin Pop
19 046fe3f5 Iustin Pop
You should have received a copy of the GNU General Public License
20 046fe3f5 Iustin Pop
along with this program; if not, write to the Free Software
21 046fe3f5 Iustin Pop
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
22 046fe3f5 Iustin Pop
02110-1301, USA.
23 046fe3f5 Iustin Pop
24 046fe3f5 Iustin Pop
-}
25 046fe3f5 Iustin Pop
26 046fe3f5 Iustin Pop
module Ganeti.Query.Common
27 046fe3f5 Iustin Pop
  ( rsNoData
28 046fe3f5 Iustin Pop
  , rsNormal
29 046fe3f5 Iustin Pop
  , rsMaybe
30 046fe3f5 Iustin Pop
  , rsUnknown
31 046fe3f5 Iustin Pop
  , missingRuntime
32 4393e075 Agata Murawska
  , rpcErrorToStatus
33 046fe3f5 Iustin Pop
  , timeStampFields
34 046fe3f5 Iustin Pop
  , uuidFields
35 046fe3f5 Iustin Pop
  , serialFields
36 046fe3f5 Iustin Pop
  , tagsFields
37 046fe3f5 Iustin Pop
  , dictFieldGetter
38 046fe3f5 Iustin Pop
  , buildQFTLookup
39 046fe3f5 Iustin Pop
  , buildNdParamField
40 046fe3f5 Iustin Pop
  ) where
41 046fe3f5 Iustin Pop
42 046fe3f5 Iustin Pop
import qualified Data.Map as Map
43 046fe3f5 Iustin Pop
import Data.Maybe (fromMaybe)
44 046fe3f5 Iustin Pop
import Text.JSON (JSON, showJSON)
45 046fe3f5 Iustin Pop
46 046fe3f5 Iustin Pop
import qualified Ganeti.Constants as C
47 046fe3f5 Iustin Pop
import Ganeti.Config
48 046fe3f5 Iustin Pop
import Ganeti.Objects
49 4393e075 Agata Murawska
import Ganeti.Rpc
50 4cab6703 Iustin Pop
import Ganeti.Query.Language
51 046fe3f5 Iustin Pop
import Ganeti.Query.Types
52 046fe3f5 Iustin Pop
53 046fe3f5 Iustin Pop
-- * Generic functions
54 046fe3f5 Iustin Pop
55 046fe3f5 Iustin Pop
-- | Conversion from 'VType' to 'FieldType'.
56 046fe3f5 Iustin Pop
vTypeToQFT :: VType -> FieldType
57 046fe3f5 Iustin Pop
vTypeToQFT VTypeString      = QFTOther
58 046fe3f5 Iustin Pop
vTypeToQFT VTypeMaybeString = QFTOther
59 046fe3f5 Iustin Pop
vTypeToQFT VTypeBool        = QFTBool
60 046fe3f5 Iustin Pop
vTypeToQFT VTypeSize        = QFTUnit
61 046fe3f5 Iustin Pop
vTypeToQFT VTypeInt         = QFTNumber
62 046fe3f5 Iustin Pop
63 046fe3f5 Iustin Pop
-- * Result helpers
64 046fe3f5 Iustin Pop
65 046fe3f5 Iustin Pop
-- | Helper for a result with no data.
66 046fe3f5 Iustin Pop
rsNoData :: ResultEntry
67 046fe3f5 Iustin Pop
rsNoData = ResultEntry RSNoData Nothing
68 046fe3f5 Iustin Pop
69 046fe3f5 Iustin Pop
-- | Helper to declare a normal result.
70 046fe3f5 Iustin Pop
rsNormal :: (JSON a) => a -> ResultEntry
71 046fe3f5 Iustin Pop
rsNormal a = ResultEntry RSNormal $ Just (showJSON a)
72 046fe3f5 Iustin Pop
73 046fe3f5 Iustin Pop
-- | Helper to declare a result from a 'Maybe' (the item might be
74 046fe3f5 Iustin Pop
-- missing, in which case we return no data). Note that there's some
75 046fe3f5 Iustin Pop
-- ambiguity here: in some cases, we mean 'RSNoData', but in other
76 046fe3f5 Iustin Pop
-- 'RSUnavail'; this is easy to solve in simple cases, but not in
77 046fe3f5 Iustin Pop
-- nested dicts.
78 046fe3f5 Iustin Pop
rsMaybe :: (JSON a) => Maybe a -> ResultEntry
79 046fe3f5 Iustin Pop
rsMaybe = maybe rsNoData rsNormal
80 046fe3f5 Iustin Pop
81 046fe3f5 Iustin Pop
-- | Helper for unknown field result.
82 046fe3f5 Iustin Pop
rsUnknown :: ResultEntry
83 046fe3f5 Iustin Pop
rsUnknown = ResultEntry RSUnknown Nothing
84 046fe3f5 Iustin Pop
85 046fe3f5 Iustin Pop
-- | Helper for a missing runtime parameter.
86 046fe3f5 Iustin Pop
missingRuntime :: FieldGetter a b
87 046fe3f5 Iustin Pop
missingRuntime = FieldRuntime (\_ _ -> ResultEntry RSNoData Nothing)
88 046fe3f5 Iustin Pop
89 4393e075 Agata Murawska
-- * Error conversion
90 4393e075 Agata Murawska
91 4393e075 Agata Murawska
-- | Convert RpcError to ResultStatus
92 4393e075 Agata Murawska
rpcErrorToStatus :: RpcError -> ResultStatus
93 4393e075 Agata Murawska
rpcErrorToStatus (OfflineNodeError _) = RSOffline
94 4393e075 Agata Murawska
rpcErrorToStatus _ = RSNoData
95 4393e075 Agata Murawska
96 046fe3f5 Iustin Pop
-- * Common fields
97 046fe3f5 Iustin Pop
98 046fe3f5 Iustin Pop
-- | The list of timestamp fields.
99 046fe3f5 Iustin Pop
timeStampFields :: (TimeStampObject a) => FieldList a b
100 046fe3f5 Iustin Pop
timeStampFields =
101 046fe3f5 Iustin Pop
  [ (FieldDefinition "ctime" "CTime" QFTTimestamp "Creation timestamp",
102 046fe3f5 Iustin Pop
     FieldSimple (rsNormal . cTimeOf))
103 046fe3f5 Iustin Pop
  , (FieldDefinition "mtime" "MTime" QFTTimestamp "Modification timestamp",
104 046fe3f5 Iustin Pop
     FieldSimple (rsNormal . mTimeOf))
105 046fe3f5 Iustin Pop
  ]
106 046fe3f5 Iustin Pop
107 046fe3f5 Iustin Pop
-- | The list of UUID fields.
108 046fe3f5 Iustin Pop
uuidFields :: (UuidObject a) => String -> FieldList a b
109 046fe3f5 Iustin Pop
uuidFields name =
110 046fe3f5 Iustin Pop
  [ (FieldDefinition "uuid" "UUID" QFTText  (name ++ " UUID"),
111 046fe3f5 Iustin Pop
     FieldSimple (rsNormal . uuidOf)) ]
112 046fe3f5 Iustin Pop
113 046fe3f5 Iustin Pop
-- | The list of serial number fields.
114 046fe3f5 Iustin Pop
serialFields :: (SerialNoObject a) => String -> FieldList a b
115 046fe3f5 Iustin Pop
serialFields name =
116 046fe3f5 Iustin Pop
  [ (FieldDefinition "serial_no" "SerialNo" QFTNumber
117 046fe3f5 Iustin Pop
     (name ++ " object serial number, incremented on each modification"),
118 046fe3f5 Iustin Pop
     FieldSimple (rsNormal . serialOf)) ]
119 046fe3f5 Iustin Pop
120 046fe3f5 Iustin Pop
-- | The list of tag fields.
121 046fe3f5 Iustin Pop
tagsFields :: (TagsObject a) => FieldList a b
122 046fe3f5 Iustin Pop
tagsFields =
123 046fe3f5 Iustin Pop
  [ (FieldDefinition "tags" "Tags" QFTOther "Tags",
124 046fe3f5 Iustin Pop
     FieldSimple (rsNormal . tagsOf)) ]
125 046fe3f5 Iustin Pop
126 046fe3f5 Iustin Pop
-- * Generic parameter functions
127 046fe3f5 Iustin Pop
128 046fe3f5 Iustin Pop
-- | Returns a field from a (possibly missing) 'DictObject'. This is
129 046fe3f5 Iustin Pop
-- used by parameter dictionaries, usually. Note that we have two
130 046fe3f5 Iustin Pop
-- levels of maybe: the top level dict might be missing, or one key in
131 046fe3f5 Iustin Pop
-- the dictionary might be.
132 046fe3f5 Iustin Pop
dictFieldGetter :: (DictObject a) => String -> Maybe a -> ResultEntry
133 046fe3f5 Iustin Pop
dictFieldGetter k = maybe rsNoData (rsMaybe . lookup k . toDict)
134 046fe3f5 Iustin Pop
135 046fe3f5 Iustin Pop
-- | Build an optimised lookup map from a Python _PARAMETER_TYPES
136 046fe3f5 Iustin Pop
-- association list.
137 046fe3f5 Iustin Pop
buildQFTLookup :: [(String, String)] -> Map.Map String FieldType
138 046fe3f5 Iustin Pop
buildQFTLookup =
139 046fe3f5 Iustin Pop
  Map.fromList .
140 046fe3f5 Iustin Pop
  map (\(k, v) -> (k, maybe QFTOther vTypeToQFT (vTypeFromRaw v)))
141 046fe3f5 Iustin Pop
142 046fe3f5 Iustin Pop
-- | Ndparams optimised lookup map.
143 046fe3f5 Iustin Pop
ndParamTypes :: Map.Map String FieldType
144 046fe3f5 Iustin Pop
ndParamTypes = buildQFTLookup C.ndsParameterTypes
145 046fe3f5 Iustin Pop
146 046fe3f5 Iustin Pop
-- | Ndparams title map.
147 046fe3f5 Iustin Pop
ndParamTitles :: Map.Map String FieldTitle
148 046fe3f5 Iustin Pop
ndParamTitles = Map.fromList C.ndsParameterTitles
149 046fe3f5 Iustin Pop
150 046fe3f5 Iustin Pop
-- | Ndparam getter builder: given a field, it returns a FieldConfig
151 046fe3f5 Iustin Pop
-- getter, that is a function that takes the config and the object and
152 046fe3f5 Iustin Pop
-- returns the Ndparam field specified when the getter was built.
153 046fe3f5 Iustin Pop
ndParamGetter :: (NdParamObject a) =>
154 046fe3f5 Iustin Pop
                 String -- ^ The field we're building the getter for
155 046fe3f5 Iustin Pop
              -> ConfigData -> a -> ResultEntry
156 046fe3f5 Iustin Pop
ndParamGetter field config =
157 046fe3f5 Iustin Pop
  dictFieldGetter field . getNdParamsOf config
158 046fe3f5 Iustin Pop
159 046fe3f5 Iustin Pop
-- | Builds the ndparam fields for an object.
160 046fe3f5 Iustin Pop
buildNdParamField :: (NdParamObject a) => String -> FieldData a b
161 046fe3f5 Iustin Pop
buildNdParamField field =
162 046fe3f5 Iustin Pop
  let full_name = "ndp/" ++ field
163 046fe3f5 Iustin Pop
      title = fromMaybe field $ field `Map.lookup` ndParamTitles
164 046fe3f5 Iustin Pop
      qft = fromMaybe QFTOther $ field `Map.lookup` ndParamTypes
165 046fe3f5 Iustin Pop
      desc = "The \"" ++ field ++ "\" node parameter"
166 046fe3f5 Iustin Pop
  in (FieldDefinition full_name title qft desc,
167 046fe3f5 Iustin Pop
      FieldConfig (ndParamGetter field))