Statistics
| Branch: | Tag: | Revision:

root / src / Ganeti / Query / Common.hs @ 9c0a27d0

History | View | Annotate | Download (6.1 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 9c0a27d0 Iustin Pop
Copyright (C) 2012, 2013 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 5227de56 Iustin Pop
  , rsUnavail
29 046fe3f5 Iustin Pop
  , rsNormal
30 a64cc96b Helga Velroyen
  , rsMaybeNoData
31 a64cc96b Helga Velroyen
  , rsMaybeUnavail
32 046fe3f5 Iustin Pop
  , rsUnknown
33 046fe3f5 Iustin Pop
  , missingRuntime
34 4393e075 Agata Murawska
  , rpcErrorToStatus
35 046fe3f5 Iustin Pop
  , timeStampFields
36 046fe3f5 Iustin Pop
  , uuidFields
37 046fe3f5 Iustin Pop
  , serialFields
38 046fe3f5 Iustin Pop
  , tagsFields
39 046fe3f5 Iustin Pop
  , dictFieldGetter
40 046fe3f5 Iustin Pop
  , buildQFTLookup
41 046fe3f5 Iustin Pop
  , buildNdParamField
42 046fe3f5 Iustin Pop
  ) where
43 046fe3f5 Iustin Pop
44 046fe3f5 Iustin Pop
import qualified Data.Map as Map
45 046fe3f5 Iustin Pop
import Data.Maybe (fromMaybe)
46 046fe3f5 Iustin Pop
import Text.JSON (JSON, showJSON)
47 046fe3f5 Iustin Pop
48 046fe3f5 Iustin Pop
import qualified Ganeti.Constants as C
49 046fe3f5 Iustin Pop
import Ganeti.Config
50 046fe3f5 Iustin Pop
import Ganeti.Objects
51 4393e075 Agata Murawska
import Ganeti.Rpc
52 4cab6703 Iustin Pop
import Ganeti.Query.Language
53 046fe3f5 Iustin Pop
import Ganeti.Query.Types
54 046fe3f5 Iustin Pop
55 046fe3f5 Iustin Pop
-- * Generic functions
56 046fe3f5 Iustin Pop
57 046fe3f5 Iustin Pop
-- | Conversion from 'VType' to 'FieldType'.
58 046fe3f5 Iustin Pop
vTypeToQFT :: VType -> FieldType
59 046fe3f5 Iustin Pop
vTypeToQFT VTypeString      = QFTOther
60 046fe3f5 Iustin Pop
vTypeToQFT VTypeMaybeString = QFTOther
61 046fe3f5 Iustin Pop
vTypeToQFT VTypeBool        = QFTBool
62 046fe3f5 Iustin Pop
vTypeToQFT VTypeSize        = QFTUnit
63 046fe3f5 Iustin Pop
vTypeToQFT VTypeInt         = QFTNumber
64 046fe3f5 Iustin Pop
65 046fe3f5 Iustin Pop
-- * Result helpers
66 046fe3f5 Iustin Pop
67 046fe3f5 Iustin Pop
-- | Helper for a result with no data.
68 046fe3f5 Iustin Pop
rsNoData :: ResultEntry
69 046fe3f5 Iustin Pop
rsNoData = ResultEntry RSNoData Nothing
70 046fe3f5 Iustin Pop
71 5227de56 Iustin Pop
-- | Helper for result for an entity which supports no such field.
72 5227de56 Iustin Pop
rsUnavail :: ResultEntry
73 5227de56 Iustin Pop
rsUnavail = ResultEntry RSUnavail Nothing
74 5227de56 Iustin Pop
75 046fe3f5 Iustin Pop
-- | Helper to declare a normal result.
76 046fe3f5 Iustin Pop
rsNormal :: (JSON a) => a -> ResultEntry
77 046fe3f5 Iustin Pop
rsNormal a = ResultEntry RSNormal $ Just (showJSON a)
78 046fe3f5 Iustin Pop
79 046fe3f5 Iustin Pop
-- | Helper to declare a result from a 'Maybe' (the item might be
80 046fe3f5 Iustin Pop
-- missing, in which case we return no data). Note that there's some
81 046fe3f5 Iustin Pop
-- ambiguity here: in some cases, we mean 'RSNoData', but in other
82 046fe3f5 Iustin Pop
-- 'RSUnavail'; this is easy to solve in simple cases, but not in
83 a64cc96b Helga Velroyen
-- nested dicts. If you want to return 'RSUnavail' in case of 'Nothing'
84 a64cc96b Helga Velroyen
-- use the function 'rsMaybeUnavail'.
85 a64cc96b Helga Velroyen
rsMaybeNoData :: (JSON a) => Maybe a -> ResultEntry
86 a64cc96b Helga Velroyen
rsMaybeNoData = maybe rsNoData rsNormal
87 a64cc96b Helga Velroyen
88 a64cc96b Helga Velroyen
-- | Helper to declare a result from a 'Maybe'. This version returns
89 a64cc96b Helga Velroyen
-- a 'RSUnavail' in case of 'Nothing'. It should be used for optional
90 a64cc96b Helga Velroyen
-- fields that are not set. For cases where 'Nothing' means that there
91 a64cc96b Helga Velroyen
-- was an error, consider using 'rsMaybe' instead.
92 a64cc96b Helga Velroyen
rsMaybeUnavail :: (JSON a) => Maybe a -> ResultEntry
93 a64cc96b Helga Velroyen
rsMaybeUnavail = maybe rsUnavail rsNormal
94 046fe3f5 Iustin Pop
95 046fe3f5 Iustin Pop
-- | Helper for unknown field result.
96 046fe3f5 Iustin Pop
rsUnknown :: ResultEntry
97 046fe3f5 Iustin Pop
rsUnknown = ResultEntry RSUnknown Nothing
98 046fe3f5 Iustin Pop
99 046fe3f5 Iustin Pop
-- | Helper for a missing runtime parameter.
100 046fe3f5 Iustin Pop
missingRuntime :: FieldGetter a b
101 046fe3f5 Iustin Pop
missingRuntime = FieldRuntime (\_ _ -> ResultEntry RSNoData Nothing)
102 046fe3f5 Iustin Pop
103 4393e075 Agata Murawska
-- * Error conversion
104 4393e075 Agata Murawska
105 4393e075 Agata Murawska
-- | Convert RpcError to ResultStatus
106 4393e075 Agata Murawska
rpcErrorToStatus :: RpcError -> ResultStatus
107 9c0a27d0 Iustin Pop
rpcErrorToStatus OfflineNodeError = RSOffline
108 4393e075 Agata Murawska
rpcErrorToStatus _ = RSNoData
109 4393e075 Agata Murawska
110 046fe3f5 Iustin Pop
-- * Common fields
111 046fe3f5 Iustin Pop
112 046fe3f5 Iustin Pop
-- | The list of timestamp fields.
113 046fe3f5 Iustin Pop
timeStampFields :: (TimeStampObject a) => FieldList a b
114 046fe3f5 Iustin Pop
timeStampFields =
115 046fe3f5 Iustin Pop
  [ (FieldDefinition "ctime" "CTime" QFTTimestamp "Creation timestamp",
116 f94a9680 Iustin Pop
     FieldSimple (rsNormal . cTimeOf), QffNormal)
117 046fe3f5 Iustin Pop
  , (FieldDefinition "mtime" "MTime" QFTTimestamp "Modification timestamp",
118 f94a9680 Iustin Pop
     FieldSimple (rsNormal . mTimeOf), QffNormal)
119 046fe3f5 Iustin Pop
  ]
120 046fe3f5 Iustin Pop
121 046fe3f5 Iustin Pop
-- | The list of UUID fields.
122 046fe3f5 Iustin Pop
uuidFields :: (UuidObject a) => String -> FieldList a b
123 046fe3f5 Iustin Pop
uuidFields name =
124 046fe3f5 Iustin Pop
  [ (FieldDefinition "uuid" "UUID" QFTText  (name ++ " UUID"),
125 f94a9680 Iustin Pop
     FieldSimple (rsNormal . uuidOf), QffNormal) ]
126 046fe3f5 Iustin Pop
127 046fe3f5 Iustin Pop
-- | The list of serial number fields.
128 046fe3f5 Iustin Pop
serialFields :: (SerialNoObject a) => String -> FieldList a b
129 046fe3f5 Iustin Pop
serialFields name =
130 046fe3f5 Iustin Pop
  [ (FieldDefinition "serial_no" "SerialNo" QFTNumber
131 046fe3f5 Iustin Pop
     (name ++ " object serial number, incremented on each modification"),
132 f94a9680 Iustin Pop
     FieldSimple (rsNormal . serialOf), QffNormal) ]
133 046fe3f5 Iustin Pop
134 046fe3f5 Iustin Pop
-- | The list of tag fields.
135 046fe3f5 Iustin Pop
tagsFields :: (TagsObject a) => FieldList a b
136 046fe3f5 Iustin Pop
tagsFields =
137 046fe3f5 Iustin Pop
  [ (FieldDefinition "tags" "Tags" QFTOther "Tags",
138 f94a9680 Iustin Pop
     FieldSimple (rsNormal . tagsOf), QffNormal) ]
139 046fe3f5 Iustin Pop
140 046fe3f5 Iustin Pop
-- * Generic parameter functions
141 046fe3f5 Iustin Pop
142 046fe3f5 Iustin Pop
-- | Returns a field from a (possibly missing) 'DictObject'. This is
143 046fe3f5 Iustin Pop
-- used by parameter dictionaries, usually. Note that we have two
144 046fe3f5 Iustin Pop
-- levels of maybe: the top level dict might be missing, or one key in
145 046fe3f5 Iustin Pop
-- the dictionary might be.
146 046fe3f5 Iustin Pop
dictFieldGetter :: (DictObject a) => String -> Maybe a -> ResultEntry
147 a64cc96b Helga Velroyen
dictFieldGetter k = maybe rsNoData (rsMaybeNoData . lookup k . toDict)
148 046fe3f5 Iustin Pop
149 046fe3f5 Iustin Pop
-- | Build an optimised lookup map from a Python _PARAMETER_TYPES
150 046fe3f5 Iustin Pop
-- association list.
151 046fe3f5 Iustin Pop
buildQFTLookup :: [(String, String)] -> Map.Map String FieldType
152 046fe3f5 Iustin Pop
buildQFTLookup =
153 046fe3f5 Iustin Pop
  Map.fromList .
154 046fe3f5 Iustin Pop
  map (\(k, v) -> (k, maybe QFTOther vTypeToQFT (vTypeFromRaw v)))
155 046fe3f5 Iustin Pop
156 046fe3f5 Iustin Pop
-- | Ndparams optimised lookup map.
157 046fe3f5 Iustin Pop
ndParamTypes :: Map.Map String FieldType
158 046fe3f5 Iustin Pop
ndParamTypes = buildQFTLookup C.ndsParameterTypes
159 046fe3f5 Iustin Pop
160 046fe3f5 Iustin Pop
-- | Ndparams title map.
161 046fe3f5 Iustin Pop
ndParamTitles :: Map.Map String FieldTitle
162 046fe3f5 Iustin Pop
ndParamTitles = Map.fromList C.ndsParameterTitles
163 046fe3f5 Iustin Pop
164 046fe3f5 Iustin Pop
-- | Ndparam getter builder: given a field, it returns a FieldConfig
165 046fe3f5 Iustin Pop
-- getter, that is a function that takes the config and the object and
166 046fe3f5 Iustin Pop
-- returns the Ndparam field specified when the getter was built.
167 046fe3f5 Iustin Pop
ndParamGetter :: (NdParamObject a) =>
168 046fe3f5 Iustin Pop
                 String -- ^ The field we're building the getter for
169 046fe3f5 Iustin Pop
              -> ConfigData -> a -> ResultEntry
170 046fe3f5 Iustin Pop
ndParamGetter field config =
171 046fe3f5 Iustin Pop
  dictFieldGetter field . getNdParamsOf config
172 046fe3f5 Iustin Pop
173 046fe3f5 Iustin Pop
-- | Builds the ndparam fields for an object.
174 046fe3f5 Iustin Pop
buildNdParamField :: (NdParamObject a) => String -> FieldData a b
175 046fe3f5 Iustin Pop
buildNdParamField field =
176 046fe3f5 Iustin Pop
  let full_name = "ndp/" ++ field
177 046fe3f5 Iustin Pop
      title = fromMaybe field $ field `Map.lookup` ndParamTitles
178 046fe3f5 Iustin Pop
      qft = fromMaybe QFTOther $ field `Map.lookup` ndParamTypes
179 046fe3f5 Iustin Pop
      desc = "The \"" ++ field ++ "\" node parameter"
180 046fe3f5 Iustin Pop
  in (FieldDefinition full_name title qft desc,
181 f94a9680 Iustin Pop
      FieldConfig (ndParamGetter field), QffNormal)