Merge branch 'stable-2.13' into stable-2.14
[ganeti-github.git] / src / Ganeti / Objects.hs
1 {-# LANGUAGE TemplateHaskell, FunctionalDependencies #-}
2
3 {-| Implementation of the Ganeti config objects.
4
5 -}
6
7 {-
8
9 Copyright (C) 2011, 2012, 2013, 2014 Google Inc.
10 All rights reserved.
11
12 Redistribution and use in source and binary forms, with or without
13 modification, are permitted provided that the following conditions are
14 met:
15
16 1. Redistributions of source code must retain the above copyright notice,
17 this list of conditions and the following disclaimer.
18
19 2. Redistributions in binary form must reproduce the above copyright
20 notice, this list of conditions and the following disclaimer in the
21 documentation and/or other materials provided with the distribution.
22
23 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
24 IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
25 TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
26 PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
27 CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
28 EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
29 PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
30 PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
31 LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
32 NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
33 SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
34
35 -}
36
37 module Ganeti.Objects
38 ( HvParams
39 , OsParams
40 , OsParamsPrivate
41 , PartialNicParams(..)
42 , FilledNicParams(..)
43 , allNicParamFields
44 , PartialNic(..)
45 , FileDriver(..)
46 , DataCollectorConfig(..)
47 , DiskTemplate(..)
48 , PartialBeParams(..)
49 , FilledBeParams(..)
50 , PartialNDParams(..)
51 , FilledNDParams(..)
52 , allNDParamFields
53 , Node(..)
54 , AllocPolicy(..)
55 , FilledISpecParams(..)
56 , PartialISpecParams(..)
57 , allISpecParamFields
58 , MinMaxISpecs(..)
59 , FilledIPolicy(..)
60 , PartialIPolicy(..)
61 , GroupDiskParams
62 , NodeGroup(..)
63 , FilterAction(..)
64 , FilterPredicate(..)
65 , FilterRule(..)
66 , filterRuleOrder
67 , IpFamily(..)
68 , ipFamilyToRaw
69 , ipFamilyToVersion
70 , fillDict
71 , ClusterHvParams
72 , OsHvParams
73 , ClusterBeParams
74 , ClusterOsParams
75 , ClusterOsParamsPrivate
76 , ClusterNicParams
77 , UidPool
78 , formatUidRange
79 , UidRange
80 , Cluster(..)
81 , ConfigData(..)
82 , TimeStampObject(..) -- re-exported from Types
83 , UuidObject(..) -- re-exported from Types
84 , SerialNoObject(..) -- re-exported from Types
85 , TagsObject(..) -- re-exported from Types
86 , DictObject(..) -- re-exported from THH
87 , TagSet -- re-exported from THH
88 , Network(..)
89 , AddressPool(..)
90 , Ip4Address()
91 , mkIp4Address
92 , Ip4Network()
93 , mkIp4Network
94 , ip4netAddr
95 , ip4netMask
96 , readIp4Address
97 , ip4AddressToList
98 , ip4AddressToNumber
99 , ip4AddressFromNumber
100 , nextIp4Address
101 , IAllocatorParams
102 , MasterNetworkParameters(..)
103 , module Ganeti.PartialParams
104 , module Ganeti.Objects.Disk
105 , module Ganeti.Objects.Instance
106 ) where
107
108 import Control.Applicative
109 import Control.Arrow (first)
110 import Control.Monad.State
111 import Data.List (foldl', intercalate)
112 import Data.Maybe
113 import qualified Data.Map as Map
114 import Data.Monoid
115 import Data.Ord (comparing)
116 import Data.Ratio (numerator, denominator)
117 import Data.Tuple (swap)
118 import Data.Word
119 import Text.JSON (showJSON, readJSON, JSON, JSValue(..), fromJSString,
120 toJSString)
121 import qualified Text.JSON as J
122
123 import qualified AutoConf
124 import qualified Ganeti.Constants as C
125 import qualified Ganeti.ConstantUtils as ConstantUtils
126 import Ganeti.JSON
127 import Ganeti.Objects.BitArray (BitArray)
128 import Ganeti.Objects.Disk
129 import Ganeti.Objects.Nic
130 import Ganeti.Objects.Instance
131 import Ganeti.Query.Language
132 import Ganeti.PartialParams
133 import Ganeti.Types
134 import Ganeti.THH
135 import Ganeti.THH.Field
136 import Ganeti.Utils (sepSplit, tryRead)
137
138 -- * Generic definitions
139
140 -- | Fills one map with keys from the other map, if not already
141 -- existing. Mirrors objects.py:FillDict.
142 fillDict :: (Ord k) => Map.Map k v -> Map.Map k v -> [k] -> Map.Map k v
143 fillDict defaults custom skip_keys =
144 let updated = Map.union custom defaults
145 in foldl' (flip Map.delete) updated skip_keys
146
147
148 -- * Network definitions
149
150 -- ** Ipv4 types
151
152 data Ip4Address = Ip4Address Word8 Word8 Word8 Word8
153 deriving (Eq, Ord)
154
155 mkIp4Address :: (Word8, Word8, Word8, Word8) -> Ip4Address
156 mkIp4Address (a, b, c, d) = Ip4Address a b c d
157
158 instance Show Ip4Address where
159 show (Ip4Address a b c d) = intercalate "." $ map show [a, b, c, d]
160
161 readIp4Address :: (Applicative m, Monad m) => String -> m Ip4Address
162 readIp4Address s =
163 case sepSplit '.' s of
164 [a, b, c, d] -> Ip4Address <$>
165 tryRead "first octect" a <*>
166 tryRead "second octet" b <*>
167 tryRead "third octet" c <*>
168 tryRead "fourth octet" d
169 _ -> fail $ "Can't parse IPv4 address from string " ++ s
170
171 instance JSON Ip4Address where
172 showJSON = showJSON . show
173 readJSON (JSString s) = readIp4Address (fromJSString s)
174 readJSON v = fail $ "Invalid JSON value " ++ show v ++ " for an IPv4 address"
175
176 -- Converts an address to a list of numbers
177 ip4AddressToList :: Ip4Address -> [Word8]
178 ip4AddressToList (Ip4Address a b c d) = [a, b, c, d]
179
180 -- | Converts an address into its ordinal number.
181 -- This is needed for indexing IP adresses in reservation pools.
182 ip4AddressToNumber :: Ip4Address -> Integer
183 ip4AddressToNumber = foldl (\n i -> 256 * n + toInteger i) 0 . ip4AddressToList
184
185 -- | Converts a number into an address.
186 -- This is needed for indexing IP adresses in reservation pools.
187 ip4AddressFromNumber :: Integer -> Ip4Address
188 ip4AddressFromNumber n =
189 let s = state $ first fromInteger . swap . (`divMod` 256)
190 (d, c, b, a) = evalState ((,,,) <$> s <*> s <*> s <*> s) n
191 in Ip4Address a b c d
192
193 nextIp4Address :: Ip4Address -> Ip4Address
194 nextIp4Address = ip4AddressFromNumber . (+ 1) . ip4AddressToNumber
195
196 -- | Custom type for an IPv4 network.
197 data Ip4Network = Ip4Network { ip4netAddr :: Ip4Address
198 , ip4netMask :: Word8
199 }
200 deriving (Eq)
201
202 mkIp4Network :: Ip4Address -> Word8 -> Ip4Network
203 mkIp4Network = Ip4Network
204
205 instance Show Ip4Network where
206 show (Ip4Network ip netmask) = show ip ++ "/" ++ show netmask
207
208 -- | JSON instance for 'Ip4Network'.
209 instance JSON Ip4Network where
210 showJSON = showJSON . show
211 readJSON (JSString s) =
212 case sepSplit '/' (fromJSString s) of
213 [ip, nm] -> do
214 ip' <- readIp4Address ip
215 nm' <- tryRead "parsing netmask" nm
216 if nm' >= 0 && nm' <= 32
217 then return $ Ip4Network ip' nm'
218 else fail $ "Invalid netmask " ++ show nm' ++ " from string " ++
219 fromJSString s
220 _ -> fail $ "Can't parse IPv4 network from string " ++ fromJSString s
221 readJSON v = fail $ "Invalid JSON value " ++ show v ++ " for an IPv4 network"
222
223 -- ** Address pools
224
225 -- | Currently address pools just wrap a reservation 'BitArray'.
226 --
227 -- In future, 'Network' might be extended to include several address pools
228 -- and address pools might include their own ranges of addresses.
229 newtype AddressPool = AddressPool { apReservations :: BitArray }
230 deriving (Eq, Ord, Show)
231
232 instance JSON AddressPool where
233 showJSON = showJSON . apReservations
234 readJSON = liftM AddressPool . readJSON
235
236 -- ** Ganeti \"network\" config object.
237
238 -- FIXME: Not all types might be correct here, since they
239 -- haven't been exhaustively deduced from the python code yet.
240 --
241 -- FIXME: When parsing, check that the ext_reservations and reservations
242 -- have the same length
243 $(buildObject "Network" "network" $
244 [ simpleField "name" [t| NonEmptyString |]
245 , optionalField $
246 simpleField "mac_prefix" [t| String |]
247 , simpleField "network" [t| Ip4Network |]
248 , optionalField $
249 simpleField "network6" [t| String |]
250 , optionalField $
251 simpleField "gateway" [t| Ip4Address |]
252 , optionalField $
253 simpleField "gateway6" [t| String |]
254 , optionalField $
255 simpleField "reservations" [t| AddressPool |]
256 , optionalField $
257 simpleField "ext_reservations" [t| AddressPool |]
258 ]
259 ++ uuidFields
260 ++ timeStampFields
261 ++ serialFields
262 ++ tagsFields)
263
264 instance SerialNoObject Network where
265 serialOf = networkSerial
266
267 instance TagsObject Network where
268 tagsOf = networkTags
269
270 instance UuidObject Network where
271 uuidOf = networkUuid
272
273 instance TimeStampObject Network where
274 cTimeOf = networkCtime
275 mTimeOf = networkMtime
276
277
278 -- * Datacollector definitions
279 type MicroSeconds = Integer
280
281 -- | The configuration regarding a single data collector.
282 $(buildObject "DataCollectorConfig" "dataCollector" [
283 simpleField "active" [t| Bool|],
284 simpleField "interval" [t| MicroSeconds |]
285 ])
286
287 -- | Central default values of the data collector config.
288 instance Monoid DataCollectorConfig where
289 mempty = DataCollectorConfig
290 { dataCollectorActive = True
291 , dataCollectorInterval = 10^(6::Integer) * fromIntegral C.mondTimeInterval
292 }
293 mappend _ a = a
294
295 -- * IPolicy definitions
296
297 $(buildParam "ISpec" "ispec"
298 [ simpleField ConstantUtils.ispecMemSize [t| Int |]
299 , simpleField ConstantUtils.ispecDiskSize [t| Int |]
300 , simpleField ConstantUtils.ispecDiskCount [t| Int |]
301 , simpleField ConstantUtils.ispecCpuCount [t| Int |]
302 , simpleField ConstantUtils.ispecNicCount [t| Int |]
303 , simpleField ConstantUtils.ispecSpindleUse [t| Int |]
304 ])
305
306 $(buildObject "MinMaxISpecs" "mmis"
307 [ renameField "MinSpec" $ simpleField "min" [t| FilledISpecParams |]
308 , renameField "MaxSpec" $ simpleField "max" [t| FilledISpecParams |]
309 ])
310
311 -- | Custom partial ipolicy. This is not built via buildParam since it
312 -- has a special 2-level inheritance mode.
313 $(buildObject "PartialIPolicy" "ipolicy"
314 [ optionalField . renameField "MinMaxISpecsP" $
315 simpleField ConstantUtils.ispecsMinmax [t| [MinMaxISpecs] |]
316 , optionalField . renameField "StdSpecP" $
317 simpleField "std" [t| PartialISpecParams |]
318 , optionalField . renameField "SpindleRatioP" $
319 simpleField "spindle-ratio" [t| Double |]
320 , optionalField . renameField "VcpuRatioP" $
321 simpleField "vcpu-ratio" [t| Double |]
322 , optionalField . renameField "DiskTemplatesP" $
323 simpleField "disk-templates" [t| [DiskTemplate] |]
324 ])
325
326 -- | Custom filled ipolicy. This is not built via buildParam since it
327 -- has a special 2-level inheritance mode.
328 $(buildObject "FilledIPolicy" "ipolicy"
329 [ renameField "MinMaxISpecs" $
330 simpleField ConstantUtils.ispecsMinmax [t| [MinMaxISpecs] |]
331 , renameField "StdSpec" $ simpleField "std" [t| FilledISpecParams |]
332 , simpleField "spindle-ratio" [t| Double |]
333 , simpleField "vcpu-ratio" [t| Double |]
334 , simpleField "disk-templates" [t| [DiskTemplate] |]
335 ])
336
337 -- | Custom filler for the ipolicy types.
338 instance PartialParams FilledIPolicy PartialIPolicy where
339 fillParams
340 (FilledIPolicy { ipolicyMinMaxISpecs = fminmax
341 , ipolicyStdSpec = fstd
342 , ipolicySpindleRatio = fspindleRatio
343 , ipolicyVcpuRatio = fvcpuRatio
344 , ipolicyDiskTemplates = fdiskTemplates})
345 (PartialIPolicy { ipolicyMinMaxISpecsP = pminmax
346 , ipolicyStdSpecP = pstd
347 , ipolicySpindleRatioP = pspindleRatio
348 , ipolicyVcpuRatioP = pvcpuRatio
349 , ipolicyDiskTemplatesP = pdiskTemplates}) =
350 FilledIPolicy
351 { ipolicyMinMaxISpecs = fromMaybe fminmax pminmax
352 , ipolicyStdSpec = maybe fstd (fillParams fstd) pstd
353 , ipolicySpindleRatio = fromMaybe fspindleRatio pspindleRatio
354 , ipolicyVcpuRatio = fromMaybe fvcpuRatio pvcpuRatio
355 , ipolicyDiskTemplates = fromMaybe fdiskTemplates
356 pdiskTemplates
357 }
358 toPartial (FilledIPolicy { ipolicyMinMaxISpecs = fminmax
359 , ipolicyStdSpec = fstd
360 , ipolicySpindleRatio = fspindleRatio
361 , ipolicyVcpuRatio = fvcpuRatio
362 , ipolicyDiskTemplates = fdiskTemplates}) =
363 PartialIPolicy
364 { ipolicyMinMaxISpecsP = Just fminmax
365 , ipolicyStdSpecP = Just $ toPartial fstd
366 , ipolicySpindleRatioP = Just fspindleRatio
367 , ipolicyVcpuRatioP = Just fvcpuRatio
368 , ipolicyDiskTemplatesP = Just fdiskTemplates
369 }
370 toFilled (PartialIPolicy { ipolicyMinMaxISpecsP = pminmax
371 , ipolicyStdSpecP = pstd
372 , ipolicySpindleRatioP = pspindleRatio
373 , ipolicyVcpuRatioP = pvcpuRatio
374 , ipolicyDiskTemplatesP = pdiskTemplates}) =
375 FilledIPolicy <$> pminmax <*> (toFilled =<< pstd) <*> pspindleRatio
376 <*> pvcpuRatio <*> pdiskTemplates
377
378 -- * Node definitions
379
380 $(buildParam "ND" "ndp"
381 [ simpleField "oob_program" [t| String |]
382 , simpleField "spindle_count" [t| Int |]
383 , simpleField "exclusive_storage" [t| Bool |]
384 , simpleField "ovs" [t| Bool |]
385 , simpleField "ovs_name" [t| String |]
386 , simpleField "ovs_link" [t| String |]
387 , simpleField "ssh_port" [t| Int |]
388 , simpleField "cpu_speed" [t| Double |]
389 ])
390
391 -- | Disk state parameters.
392 --
393 -- As according to the documentation this option is unused by Ganeti,
394 -- the content is just a 'JSValue'.
395 type DiskState = Container JSValue
396
397 -- | Hypervisor state parameters.
398 --
399 -- As according to the documentation this option is unused by Ganeti,
400 -- the content is just a 'JSValue'.
401 type HypervisorState = Container JSValue
402
403 $(buildObject "Node" "node" $
404 [ simpleField "name" [t| String |]
405 , simpleField "primary_ip" [t| String |]
406 , simpleField "secondary_ip" [t| String |]
407 , simpleField "master_candidate" [t| Bool |]
408 , simpleField "offline" [t| Bool |]
409 , simpleField "drained" [t| Bool |]
410 , simpleField "group" [t| String |]
411 , simpleField "master_capable" [t| Bool |]
412 , simpleField "vm_capable" [t| Bool |]
413 , simpleField "ndparams" [t| PartialNDParams |]
414 , simpleField "powered" [t| Bool |]
415 , notSerializeDefaultField [| emptyContainer |] $
416 simpleField "hv_state_static" [t| HypervisorState |]
417 , notSerializeDefaultField [| emptyContainer |] $
418 simpleField "disk_state_static" [t| DiskState |]
419 ]
420 ++ timeStampFields
421 ++ uuidFields
422 ++ serialFields
423 ++ tagsFields)
424
425 instance TimeStampObject Node where
426 cTimeOf = nodeCtime
427 mTimeOf = nodeMtime
428
429 instance UuidObject Node where
430 uuidOf = nodeUuid
431
432 instance SerialNoObject Node where
433 serialOf = nodeSerial
434
435 instance TagsObject Node where
436 tagsOf = nodeTags
437
438 -- * NodeGroup definitions
439
440 -- | The cluster/group disk parameters type.
441 type GroupDiskParams = Container DiskParams
442
443 -- | A mapping from network UUIDs to nic params of the networks.
444 type Networks = Container PartialNicParams
445
446 $(buildObject "NodeGroup" "group" $
447 [ simpleField "name" [t| String |]
448 , defaultField [| [] |] $ simpleField "members" [t| [String] |]
449 , simpleField "ndparams" [t| PartialNDParams |]
450 , simpleField "alloc_policy" [t| AllocPolicy |]
451 , simpleField "ipolicy" [t| PartialIPolicy |]
452 , simpleField "diskparams" [t| GroupDiskParams |]
453 , simpleField "networks" [t| Networks |]
454 , notSerializeDefaultField [| emptyContainer |] $
455 simpleField "hv_state_static" [t| HypervisorState |]
456 , notSerializeDefaultField [| emptyContainer |] $
457 simpleField "disk_state_static" [t| DiskState |]
458 ]
459 ++ timeStampFields
460 ++ uuidFields
461 ++ serialFields
462 ++ tagsFields)
463
464 instance TimeStampObject NodeGroup where
465 cTimeOf = groupCtime
466 mTimeOf = groupMtime
467
468 instance UuidObject NodeGroup where
469 uuidOf = groupUuid
470
471 instance SerialNoObject NodeGroup where
472 serialOf = groupSerial
473
474 instance TagsObject NodeGroup where
475 tagsOf = groupTags
476
477 -- * Job scheduler filtering definitions
478
479 -- | Actions that can be performed when a filter matches.
480 data FilterAction
481 = Accept
482 | Pause
483 | Reject
484 | Continue
485 | RateLimit Int
486 deriving (Eq, Ord, Show)
487
488 instance JSON FilterAction where
489 showJSON fa = case fa of
490 Accept -> JSString (toJSString "ACCEPT")
491 Pause -> JSString (toJSString "PAUSE")
492 Reject -> JSString (toJSString "REJECT")
493 Continue -> JSString (toJSString "CONTINUE")
494 RateLimit n -> JSArray [ JSString (toJSString "RATE_LIMIT")
495 , JSRational False (fromIntegral n)
496 ]
497 readJSON v = case v of
498 -- `FilterAction`s are case-sensitive.
499 JSString s | fromJSString s == "ACCEPT" -> return Accept
500 JSString s | fromJSString s == "PAUSE" -> return Pause
501 JSString s | fromJSString s == "REJECT" -> return Reject
502 JSString s | fromJSString s == "CONTINUE" -> return Continue
503 JSArray (JSString s : rest) | fromJSString s == "RATE_LIMIT" ->
504 case rest of
505 [JSRational False n] | denominator n == 1 && numerator n > 0 ->
506 return . RateLimit . fromIntegral $ numerator n
507 _ -> fail "RATE_LIMIT argument must be a positive integer"
508 x -> fail $ "malformed FilterAction JSON: " ++ J.showJSValue x ""
509
510
511 data FilterPredicate
512 = FPJobId (Filter FilterField)
513 | FPOpCode (Filter FilterField)
514 | FPReason (Filter FilterField)
515 deriving (Eq, Ord, Show)
516
517
518 instance JSON FilterPredicate where
519 showJSON fp = case fp of
520 FPJobId expr -> JSArray [string "jobid", showJSON expr]
521 FPOpCode expr -> JSArray [string "opcode", showJSON expr]
522 FPReason expr -> JSArray [string "reason", showJSON expr]
523 where
524 string = JSString . toJSString
525
526 readJSON v = case v of
527 -- Predicate names are case-sensitive.
528 JSArray [JSString name, expr]
529 | name == toJSString "jobid" -> FPJobId <$> readJSON expr
530 | name == toJSString "opcode" -> FPOpCode <$> readJSON expr
531 | name == toJSString "reason" -> FPReason <$> readJSON expr
532 JSArray (JSString name:params) ->
533 fail $ "malformed FilterPredicate: bad parameter list for\
534 \ '" ++ fromJSString name ++ "' predicate: "
535 ++ J.showJSArray params ""
536 _ -> fail "malformed FilterPredicate: must be a list with the first\
537 \ entry being a string describing the predicate type"
538
539
540 $(buildObject "FilterRule" "fr" $
541 [ simpleField "watermark" [t| JobId |]
542 , simpleField "priority" [t| NonNegative Int |]
543 , simpleField "predicates" [t| [FilterPredicate] |]
544 , simpleField "action" [t| FilterAction |]
545 , simpleField "reason_trail" [t| ReasonTrail |]
546 ]
547 ++ uuidFields)
548
549 instance UuidObject FilterRule where
550 uuidOf = frUuid
551
552
553 -- | Order in which filter rules are evaluated, according to
554 -- `doc/design-optables.rst`.
555 -- For `FilterRule` fields not specified as important for the order,
556 -- we choose an arbitrary ordering effect (after the ones from the spec).
557 --
558 -- The `Ord` instance for `FilterRule` agrees with this function.
559 -- Yet it is recommended to use this function instead of `compare` to be
560 -- explicit that the spec order is used.
561 filterRuleOrder :: FilterRule -> FilterRule -> Ordering
562 filterRuleOrder = compare
563
564
565 instance Ord FilterRule where
566 -- It is important that the Ord instance respects the ordering given in
567 -- `doc/design-optables.rst` for the fields defined in there. The other
568 -- fields may be ordered arbitrarily.
569 -- Use `filterRuleOrder` when relying on the spec order.
570 compare =
571 comparing $ \(FilterRule watermark prio predicates action reason uuid) ->
572 ( prio, watermark, uuid -- spec part
573 , predicates, action, reason -- arbitrary part
574 )
575
576
577 -- | IP family type
578 $(declareIADT "IpFamily"
579 [ ("IpFamilyV4", 'AutoConf.pyAfInet4)
580 , ("IpFamilyV6", 'AutoConf.pyAfInet6)
581 ])
582 $(makeJSONInstance ''IpFamily)
583
584 -- | Conversion from IP family to IP version. This is needed because
585 -- Python uses both, depending on context.
586 ipFamilyToVersion :: IpFamily -> Int
587 ipFamilyToVersion IpFamilyV4 = C.ip4Version
588 ipFamilyToVersion IpFamilyV6 = C.ip6Version
589
590 -- | Cluster HvParams (hvtype to hvparams mapping).
591 type ClusterHvParams = GenericContainer Hypervisor HvParams
592
593 -- | Cluster Os-HvParams (os to hvparams mapping).
594 type OsHvParams = Container ClusterHvParams
595
596 -- | Cluser BeParams.
597 type ClusterBeParams = Container FilledBeParams
598
599 -- | Cluster OsParams.
600 type ClusterOsParams = Container OsParams
601 type ClusterOsParamsPrivate = Container (Private OsParams)
602
603 -- | Cluster NicParams.
604 type ClusterNicParams = Container FilledNicParams
605
606 -- | A low-high UID ranges.
607 type UidRange = (Int, Int)
608
609 formatUidRange :: UidRange -> String
610 formatUidRange (lower, higher)
611 | lower == higher = show lower
612 | otherwise = show lower ++ "-" ++ show higher
613
614 -- | Cluster UID Pool, list (low, high) UID ranges.
615 type UidPool = [UidRange]
616
617 -- | The iallocator parameters type.
618 type IAllocatorParams = Container JSValue
619
620 -- | The master candidate client certificate digests
621 type CandidateCertificates = Container String
622
623 -- * Cluster definitions
624 $(buildObject "Cluster" "cluster" $
625 [ simpleField "rsahostkeypub" [t| String |]
626 , optionalField $
627 simpleField "dsahostkeypub" [t| String |]
628 , simpleField "highest_used_port" [t| Int |]
629 , simpleField "tcpudp_port_pool" [t| [Int] |]
630 , simpleField "mac_prefix" [t| String |]
631 , optionalField $
632 simpleField "volume_group_name" [t| String |]
633 , simpleField "reserved_lvs" [t| [String] |]
634 , optionalField $
635 simpleField "drbd_usermode_helper" [t| String |]
636 , simpleField "master_node" [t| String |]
637 , simpleField "master_ip" [t| String |]
638 , simpleField "master_netdev" [t| String |]
639 , simpleField "master_netmask" [t| Int |]
640 , simpleField "use_external_mip_script" [t| Bool |]
641 , simpleField "cluster_name" [t| String |]
642 , simpleField "file_storage_dir" [t| String |]
643 , simpleField "shared_file_storage_dir" [t| String |]
644 , simpleField "gluster_storage_dir" [t| String |]
645 , simpleField "enabled_hypervisors" [t| [Hypervisor] |]
646 , simpleField "hvparams" [t| ClusterHvParams |]
647 , simpleField "os_hvp" [t| OsHvParams |]
648 , simpleField "beparams" [t| ClusterBeParams |]
649 , simpleField "osparams" [t| ClusterOsParams |]
650 , simpleField "osparams_private_cluster" [t| ClusterOsParamsPrivate |]
651 , simpleField "nicparams" [t| ClusterNicParams |]
652 , simpleField "ndparams" [t| FilledNDParams |]
653 , simpleField "diskparams" [t| GroupDiskParams |]
654 , simpleField "candidate_pool_size" [t| Int |]
655 , simpleField "modify_etc_hosts" [t| Bool |]
656 , simpleField "modify_ssh_setup" [t| Bool |]
657 , simpleField "maintain_node_health" [t| Bool |]
658 , simpleField "uid_pool" [t| UidPool |]
659 , simpleField "default_iallocator" [t| String |]
660 , simpleField "default_iallocator_params" [t| IAllocatorParams |]
661 , simpleField "hidden_os" [t| [String] |]
662 , simpleField "blacklisted_os" [t| [String] |]
663 , simpleField "primary_ip_family" [t| IpFamily |]
664 , simpleField "prealloc_wipe_disks" [t| Bool |]
665 , simpleField "ipolicy" [t| FilledIPolicy |]
666 , defaultField [| emptyContainer |] $
667 simpleField "hv_state_static" [t| HypervisorState |]
668 , defaultField [| emptyContainer |] $
669 simpleField "disk_state_static" [t| DiskState |]
670 , simpleField "enabled_disk_templates" [t| [DiskTemplate] |]
671 , simpleField "candidate_certs" [t| CandidateCertificates |]
672 , simpleField "max_running_jobs" [t| Int |]
673 , simpleField "max_tracked_jobs" [t| Int |]
674 , simpleField "install_image" [t| String |]
675 , simpleField "instance_communication_network" [t| String |]
676 , simpleField "zeroing_image" [t| String |]
677 , simpleField "compression_tools" [t| [String] |]
678 , simpleField "enabled_user_shutdown" [t| Bool |]
679 , simpleField "data_collectors" [t| Container DataCollectorConfig |]
680 ]
681 ++ timeStampFields
682 ++ uuidFields
683 ++ serialFields
684 ++ tagsFields)
685
686 instance TimeStampObject Cluster where
687 cTimeOf = clusterCtime
688 mTimeOf = clusterMtime
689
690 instance UuidObject Cluster where
691 uuidOf = clusterUuid
692
693 instance SerialNoObject Cluster where
694 serialOf = clusterSerial
695
696 instance TagsObject Cluster where
697 tagsOf = clusterTags
698
699 -- * ConfigData definitions
700
701 $(buildObject "ConfigData" "config" $
702 -- timeStampFields ++
703 [ simpleField "version" [t| Int |]
704 , simpleField "cluster" [t| Cluster |]
705 , simpleField "nodes" [t| Container Node |]
706 , simpleField "nodegroups" [t| Container NodeGroup |]
707 , simpleField "instances" [t| Container Instance |]
708 , simpleField "networks" [t| Container Network |]
709 , simpleField "disks" [t| Container Disk |]
710 , simpleField "filters" [t| Container FilterRule |]
711 ]
712 ++ timeStampFields
713 ++ serialFields)
714
715 instance SerialNoObject ConfigData where
716 serialOf = configSerial
717
718 instance TimeStampObject ConfigData where
719 cTimeOf = configCtime
720 mTimeOf = configMtime
721
722 -- * Master network parameters
723
724 $(buildObject "MasterNetworkParameters" "masterNetworkParameters"
725 [ simpleField "uuid" [t| String |]
726 , simpleField "ip" [t| String |]
727 , simpleField "netmask" [t| Int |]
728 , simpleField "netdev" [t| String |]
729 , simpleField "ip_family" [t| IpFamily |]
730 ])
731