981790073a4786b06c6b30045804342d2412f911
[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
296 -- * IPolicy definitions
297
298 $(buildParam "ISpec" "ispec"
299 [ simpleField ConstantUtils.ispecMemSize [t| Int |]
300 , simpleField ConstantUtils.ispecDiskSize [t| Int |]
301 , simpleField ConstantUtils.ispecDiskCount [t| Int |]
302 , simpleField ConstantUtils.ispecCpuCount [t| Int |]
303 , simpleField ConstantUtils.ispecNicCount [t| Int |]
304 , simpleField ConstantUtils.ispecSpindleUse [t| Int |]
305 ])
306
307 $(buildObject "MinMaxISpecs" "mmis"
308 [ renameField "MinSpec" $ simpleField "min" [t| FilledISpecParams |]
309 , renameField "MaxSpec" $ simpleField "max" [t| FilledISpecParams |]
310 ])
311
312 -- | Custom partial ipolicy. This is not built via buildParam since it
313 -- has a special 2-level inheritance mode.
314 $(buildObject "PartialIPolicy" "ipolicy"
315 [ optionalField . renameField "MinMaxISpecsP" $
316 simpleField ConstantUtils.ispecsMinmax [t| [MinMaxISpecs] |]
317 , optionalField . renameField "StdSpecP" $
318 simpleField "std" [t| PartialISpecParams |]
319 , optionalField . renameField "SpindleRatioP" $
320 simpleField "spindle-ratio" [t| Double |]
321 , optionalField . renameField "VcpuRatioP" $
322 simpleField "vcpu-ratio" [t| Double |]
323 , optionalField . renameField "DiskTemplatesP" $
324 simpleField "disk-templates" [t| [DiskTemplate] |]
325 ])
326
327 -- | Custom filled ipolicy. This is not built via buildParam since it
328 -- has a special 2-level inheritance mode.
329 $(buildObject "FilledIPolicy" "ipolicy"
330 [ renameField "MinMaxISpecs" $
331 simpleField ConstantUtils.ispecsMinmax [t| [MinMaxISpecs] |]
332 , renameField "StdSpec" $ simpleField "std" [t| FilledISpecParams |]
333 , simpleField "spindle-ratio" [t| Double |]
334 , simpleField "vcpu-ratio" [t| Double |]
335 , simpleField "disk-templates" [t| [DiskTemplate] |]
336 ])
337
338 -- | Custom filler for the ipolicy types.
339 instance PartialParams FilledIPolicy PartialIPolicy where
340 fillParams
341 (FilledIPolicy { ipolicyMinMaxISpecs = fminmax
342 , ipolicyStdSpec = fstd
343 , ipolicySpindleRatio = fspindleRatio
344 , ipolicyVcpuRatio = fvcpuRatio
345 , ipolicyDiskTemplates = fdiskTemplates})
346 (PartialIPolicy { ipolicyMinMaxISpecsP = pminmax
347 , ipolicyStdSpecP = pstd
348 , ipolicySpindleRatioP = pspindleRatio
349 , ipolicyVcpuRatioP = pvcpuRatio
350 , ipolicyDiskTemplatesP = pdiskTemplates}) =
351 FilledIPolicy
352 { ipolicyMinMaxISpecs = fromMaybe fminmax pminmax
353 , ipolicyStdSpec = maybe fstd (fillParams fstd) pstd
354 , ipolicySpindleRatio = fromMaybe fspindleRatio pspindleRatio
355 , ipolicyVcpuRatio = fromMaybe fvcpuRatio pvcpuRatio
356 , ipolicyDiskTemplates = fromMaybe fdiskTemplates
357 pdiskTemplates
358 }
359 toPartial (FilledIPolicy { ipolicyMinMaxISpecs = fminmax
360 , ipolicyStdSpec = fstd
361 , ipolicySpindleRatio = fspindleRatio
362 , ipolicyVcpuRatio = fvcpuRatio
363 , ipolicyDiskTemplates = fdiskTemplates}) =
364 PartialIPolicy
365 { ipolicyMinMaxISpecsP = Just fminmax
366 , ipolicyStdSpecP = Just $ toPartial fstd
367 , ipolicySpindleRatioP = Just fspindleRatio
368 , ipolicyVcpuRatioP = Just fvcpuRatio
369 , ipolicyDiskTemplatesP = Just fdiskTemplates
370 }
371 toFilled (PartialIPolicy { ipolicyMinMaxISpecsP = pminmax
372 , ipolicyStdSpecP = pstd
373 , ipolicySpindleRatioP = pspindleRatio
374 , ipolicyVcpuRatioP = pvcpuRatio
375 , ipolicyDiskTemplatesP = pdiskTemplates}) =
376 FilledIPolicy <$> pminmax <*> (toFilled =<< pstd) <*> pspindleRatio
377 <*> pvcpuRatio <*> pdiskTemplates
378
379 -- * Node definitions
380
381 $(buildParam "ND" "ndp"
382 [ simpleField "oob_program" [t| String |]
383 , simpleField "spindle_count" [t| Int |]
384 , simpleField "exclusive_storage" [t| Bool |]
385 , simpleField "ovs" [t| Bool |]
386 , simpleField "ovs_name" [t| String |]
387 , simpleField "ovs_link" [t| String |]
388 , simpleField "ssh_port" [t| Int |]
389 , simpleField "cpu_speed" [t| Double |]
390 ])
391
392 -- | Disk state parameters.
393 --
394 -- As according to the documentation this option is unused by Ganeti,
395 -- the content is just a 'JSValue'.
396 type DiskState = Container JSValue
397
398 -- | Hypervisor state parameters.
399 --
400 -- As according to the documentation this option is unused by Ganeti,
401 -- the content is just a 'JSValue'.
402 type HypervisorState = Container JSValue
403
404 $(buildObject "Node" "node" $
405 [ simpleField "name" [t| String |]
406 , simpleField "primary_ip" [t| String |]
407 , simpleField "secondary_ip" [t| String |]
408 , simpleField "master_candidate" [t| Bool |]
409 , simpleField "offline" [t| Bool |]
410 , simpleField "drained" [t| Bool |]
411 , simpleField "group" [t| String |]
412 , simpleField "master_capable" [t| Bool |]
413 , simpleField "vm_capable" [t| Bool |]
414 , simpleField "ndparams" [t| PartialNDParams |]
415 , simpleField "powered" [t| Bool |]
416 , notSerializeDefaultField [| emptyContainer |] $
417 simpleField "hv_state_static" [t| HypervisorState |]
418 , notSerializeDefaultField [| emptyContainer |] $
419 simpleField "disk_state_static" [t| DiskState |]
420 ]
421 ++ timeStampFields
422 ++ uuidFields
423 ++ serialFields
424 ++ tagsFields)
425
426 instance TimeStampObject Node where
427 cTimeOf = nodeCtime
428 mTimeOf = nodeMtime
429
430 instance UuidObject Node where
431 uuidOf = nodeUuid
432
433 instance SerialNoObject Node where
434 serialOf = nodeSerial
435
436 instance TagsObject Node where
437 tagsOf = nodeTags
438
439 -- * NodeGroup definitions
440
441 -- | The cluster/group disk parameters type.
442 type GroupDiskParams = Container DiskParams
443
444 -- | A mapping from network UUIDs to nic params of the networks.
445 type Networks = Container PartialNicParams
446
447 $(buildObject "NodeGroup" "group" $
448 [ simpleField "name" [t| String |]
449 , defaultField [| [] |] $ simpleField "members" [t| [String] |]
450 , simpleField "ndparams" [t| PartialNDParams |]
451 , simpleField "alloc_policy" [t| AllocPolicy |]
452 , simpleField "ipolicy" [t| PartialIPolicy |]
453 , simpleField "diskparams" [t| GroupDiskParams |]
454 , simpleField "networks" [t| Networks |]
455 , notSerializeDefaultField [| emptyContainer |] $
456 simpleField "hv_state_static" [t| HypervisorState |]
457 , notSerializeDefaultField [| emptyContainer |] $
458 simpleField "disk_state_static" [t| DiskState |]
459 ]
460 ++ timeStampFields
461 ++ uuidFields
462 ++ serialFields
463 ++ tagsFields)
464
465 instance TimeStampObject NodeGroup where
466 cTimeOf = groupCtime
467 mTimeOf = groupMtime
468
469 instance UuidObject NodeGroup where
470 uuidOf = groupUuid
471
472 instance SerialNoObject NodeGroup where
473 serialOf = groupSerial
474
475 instance TagsObject NodeGroup where
476 tagsOf = groupTags
477
478 -- * Job scheduler filtering definitions
479
480 -- | Actions that can be performed when a filter matches.
481 data FilterAction
482 = Accept
483 | Pause
484 | Reject
485 | Continue
486 | RateLimit Int
487 deriving (Eq, Ord, Show)
488
489 instance JSON FilterAction where
490 showJSON fa = case fa of
491 Accept -> JSString (toJSString "ACCEPT")
492 Pause -> JSString (toJSString "PAUSE")
493 Reject -> JSString (toJSString "REJECT")
494 Continue -> JSString (toJSString "CONTINUE")
495 RateLimit n -> JSArray [ JSString (toJSString "RATE_LIMIT")
496 , JSRational False (fromIntegral n)
497 ]
498 readJSON v = case v of
499 -- `FilterAction`s are case-sensitive.
500 JSString s | fromJSString s == "ACCEPT" -> return Accept
501 JSString s | fromJSString s == "PAUSE" -> return Pause
502 JSString s | fromJSString s == "REJECT" -> return Reject
503 JSString s | fromJSString s == "CONTINUE" -> return Continue
504 JSArray (JSString s : rest) | fromJSString s == "RATE_LIMIT" ->
505 case rest of
506 [JSRational False n] | denominator n == 1 && numerator n > 0 ->
507 return . RateLimit . fromIntegral $ numerator n
508 _ -> fail "RATE_LIMIT argument must be a positive integer"
509 x -> fail $ "malformed FilterAction JSON: " ++ J.showJSValue x ""
510
511
512 data FilterPredicate
513 = FPJobId (Filter FilterField)
514 | FPOpCode (Filter FilterField)
515 | FPReason (Filter FilterField)
516 deriving (Eq, Ord, Show)
517
518
519 instance JSON FilterPredicate where
520 showJSON fp = case fp of
521 FPJobId expr -> JSArray [string "jobid", showJSON expr]
522 FPOpCode expr -> JSArray [string "opcode", showJSON expr]
523 FPReason expr -> JSArray [string "reason", showJSON expr]
524 where
525 string = JSString . toJSString
526
527 readJSON v = case v of
528 -- Predicate names are case-sensitive.
529 JSArray [JSString name, expr]
530 | name == toJSString "jobid" -> FPJobId <$> readJSON expr
531 | name == toJSString "opcode" -> FPOpCode <$> readJSON expr
532 | name == toJSString "reason" -> FPReason <$> readJSON expr
533 JSArray (JSString name:params) ->
534 fail $ "malformed FilterPredicate: bad parameter list for\
535 \ '" ++ fromJSString name ++ "' predicate: "
536 ++ J.showJSArray params ""
537 _ -> fail "malformed FilterPredicate: must be a list with the first\
538 \ entry being a string describing the predicate type"
539
540
541 $(buildObject "FilterRule" "fr" $
542 [ simpleField "watermark" [t| JobId |]
543 , simpleField "priority" [t| NonNegative Int |]
544 , simpleField "predicates" [t| [FilterPredicate] |]
545 , simpleField "action" [t| FilterAction |]
546 , simpleField "reason_trail" [t| ReasonTrail |]
547 ]
548 ++ uuidFields)
549
550 instance UuidObject FilterRule where
551 uuidOf = frUuid
552
553
554 -- | Order in which filter rules are evaluated, according to
555 -- `doc/design-optables.rst`.
556 -- For `FilterRule` fields not specified as important for the order,
557 -- we choose an arbitrary ordering effect (after the ones from the spec).
558 --
559 -- The `Ord` instance for `FilterRule` agrees with this function.
560 -- Yet it is recommended to use this function instead of `compare` to be
561 -- explicit that the spec order is used.
562 filterRuleOrder :: FilterRule -> FilterRule -> Ordering
563 filterRuleOrder = compare
564
565
566 instance Ord FilterRule where
567 -- It is important that the Ord instance respects the ordering given in
568 -- `doc/design-optables.rst` for the fields defined in there. The other
569 -- fields may be ordered arbitrarily.
570 -- Use `filterRuleOrder` when relying on the spec order.
571 compare =
572 comparing $ \(FilterRule watermark prio predicates action reason uuid) ->
573 ( prio, watermark, uuid -- spec part
574 , predicates, action, reason -- arbitrary part
575 )
576
577
578 -- | IP family type
579 $(declareIADT "IpFamily"
580 [ ("IpFamilyV4", 'AutoConf.pyAfInet4)
581 , ("IpFamilyV6", 'AutoConf.pyAfInet6)
582 ])
583 $(makeJSONInstance ''IpFamily)
584
585 -- | Conversion from IP family to IP version. This is needed because
586 -- Python uses both, depending on context.
587 ipFamilyToVersion :: IpFamily -> Int
588 ipFamilyToVersion IpFamilyV4 = C.ip4Version
589 ipFamilyToVersion IpFamilyV6 = C.ip6Version
590
591 -- | Cluster HvParams (hvtype to hvparams mapping).
592 type ClusterHvParams = GenericContainer Hypervisor HvParams
593
594 -- | Cluster Os-HvParams (os to hvparams mapping).
595 type OsHvParams = Container ClusterHvParams
596
597 -- | Cluser BeParams.
598 type ClusterBeParams = Container FilledBeParams
599
600 -- | Cluster OsParams.
601 type ClusterOsParams = Container OsParams
602 type ClusterOsParamsPrivate = Container (Private OsParams)
603
604 -- | Cluster NicParams.
605 type ClusterNicParams = Container FilledNicParams
606
607 -- | A low-high UID ranges.
608 type UidRange = (Int, Int)
609
610 formatUidRange :: UidRange -> String
611 formatUidRange (lower, higher)
612 | lower == higher = show lower
613 | otherwise = show lower ++ "-" ++ show higher
614
615 -- | Cluster UID Pool, list (low, high) UID ranges.
616 type UidPool = [UidRange]
617
618 -- | The iallocator parameters type.
619 type IAllocatorParams = Container JSValue
620
621 -- | The master candidate client certificate digests
622 type CandidateCertificates = Container String
623
624 -- * Cluster definitions
625 $(buildObject "Cluster" "cluster" $
626 [ simpleField "rsahostkeypub" [t| String |]
627 , optionalField $
628 simpleField "dsahostkeypub" [t| String |]
629 , simpleField "highest_used_port" [t| Int |]
630 , simpleField "tcpudp_port_pool" [t| [Int] |]
631 , simpleField "mac_prefix" [t| String |]
632 , optionalField $
633 simpleField "volume_group_name" [t| String |]
634 , simpleField "reserved_lvs" [t| [String] |]
635 , optionalField $
636 simpleField "drbd_usermode_helper" [t| String |]
637 , simpleField "master_node" [t| String |]
638 , simpleField "master_ip" [t| String |]
639 , simpleField "master_netdev" [t| String |]
640 , simpleField "master_netmask" [t| Int |]
641 , simpleField "use_external_mip_script" [t| Bool |]
642 , simpleField "cluster_name" [t| String |]
643 , simpleField "file_storage_dir" [t| String |]
644 , simpleField "shared_file_storage_dir" [t| String |]
645 , simpleField "gluster_storage_dir" [t| String |]
646 , simpleField "enabled_hypervisors" [t| [Hypervisor] |]
647 , simpleField "hvparams" [t| ClusterHvParams |]
648 , simpleField "os_hvp" [t| OsHvParams |]
649 , simpleField "beparams" [t| ClusterBeParams |]
650 , simpleField "osparams" [t| ClusterOsParams |]
651 , simpleField "osparams_private_cluster" [t| ClusterOsParamsPrivate |]
652 , simpleField "nicparams" [t| ClusterNicParams |]
653 , simpleField "ndparams" [t| FilledNDParams |]
654 , simpleField "diskparams" [t| GroupDiskParams |]
655 , simpleField "candidate_pool_size" [t| Int |]
656 , simpleField "modify_etc_hosts" [t| Bool |]
657 , simpleField "modify_ssh_setup" [t| Bool |]
658 , simpleField "maintain_node_health" [t| Bool |]
659 , simpleField "uid_pool" [t| UidPool |]
660 , simpleField "default_iallocator" [t| String |]
661 , simpleField "default_iallocator_params" [t| IAllocatorParams |]
662 , simpleField "hidden_os" [t| [String] |]
663 , simpleField "blacklisted_os" [t| [String] |]
664 , simpleField "primary_ip_family" [t| IpFamily |]
665 , simpleField "prealloc_wipe_disks" [t| Bool |]
666 , simpleField "ipolicy" [t| FilledIPolicy |]
667 , defaultField [| emptyContainer |] $
668 simpleField "hv_state_static" [t| HypervisorState |]
669 , defaultField [| emptyContainer |] $
670 simpleField "disk_state_static" [t| DiskState |]
671 , simpleField "enabled_disk_templates" [t| [DiskTemplate] |]
672 , simpleField "candidate_certs" [t| CandidateCertificates |]
673 , simpleField "max_running_jobs" [t| Int |]
674 , simpleField "max_tracked_jobs" [t| Int |]
675 , simpleField "install_image" [t| String |]
676 , simpleField "instance_communication_network" [t| String |]
677 , simpleField "zeroing_image" [t| String |]
678 , simpleField "compression_tools" [t| [String] |]
679 , simpleField "enabled_user_shutdown" [t| Bool |]
680 , simpleField "data_collectors" [t| Container DataCollectorConfig |]
681 ]
682 ++ timeStampFields
683 ++ uuidFields
684 ++ serialFields
685 ++ tagsFields)
686
687 instance TimeStampObject Cluster where
688 cTimeOf = clusterCtime
689 mTimeOf = clusterMtime
690
691 instance UuidObject Cluster where
692 uuidOf = clusterUuid
693
694 instance SerialNoObject Cluster where
695 serialOf = clusterSerial
696
697 instance TagsObject Cluster where
698 tagsOf = clusterTags
699
700 -- * ConfigData definitions
701
702 $(buildObject "ConfigData" "config" $
703 -- timeStampFields ++
704 [ simpleField "version" [t| Int |]
705 , simpleField "cluster" [t| Cluster |]
706 , simpleField "nodes" [t| Container Node |]
707 , simpleField "nodegroups" [t| Container NodeGroup |]
708 , simpleField "instances" [t| Container Instance |]
709 , simpleField "networks" [t| Container Network |]
710 , simpleField "disks" [t| Container Disk |]
711 , simpleField "filters" [t| Container FilterRule |]
712 ]
713 ++ timeStampFields
714 ++ serialFields)
715
716 instance SerialNoObject ConfigData where
717 serialOf = configSerial
718
719 instance TimeStampObject ConfigData where
720 cTimeOf = configCtime
721 mTimeOf = configMtime
722
723 -- * Master network parameters
724
725 $(buildObject "MasterNetworkParameters" "masterNetworkParameters"
726 [ simpleField "uuid" [t| String |]
727 , simpleField "ip" [t| String |]
728 , simpleField "netmask" [t| Int |]
729 , simpleField "netdev" [t| String |]
730 , simpleField "ip_family" [t| IpFamily |]
731 ])
732