Merge branch 'stable-2.14' into stable-2.15
[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 qualified Data.ByteString.UTF8 as UTF8
112 import Data.List (foldl', intercalate)
113 import Data.Maybe
114 import qualified Data.Map as Map
115 import Data.Monoid
116 import Data.Ord (comparing)
117 import Data.Ratio (numerator, denominator)
118 import Data.Tuple (swap)
119 import Data.Word
120 import Text.JSON (showJSON, readJSON, JSON, JSValue(..), fromJSString,
121 toJSString)
122 import qualified Text.JSON as J
123
124 import qualified AutoConf
125 import qualified Ganeti.Constants as C
126 import qualified Ganeti.ConstantUtils as ConstantUtils
127 import Ganeti.JSON
128 import Ganeti.Objects.BitArray (BitArray)
129 import Ganeti.Objects.Disk
130 import Ganeti.Objects.Nic
131 import Ganeti.Objects.Instance
132 import Ganeti.Query.Language
133 import Ganeti.PartialParams
134 import Ganeti.Types
135 import Ganeti.THH
136 import Ganeti.THH.Field
137 import Ganeti.Utils (sepSplit, tryRead)
138
139 -- * Generic definitions
140
141 -- | Fills one map with keys from the other map, if not already
142 -- existing. Mirrors objects.py:FillDict.
143 fillDict :: (Ord k) => Map.Map k v -> Map.Map k v -> [k] -> Map.Map k v
144 fillDict defaults custom skip_keys =
145 let updated = Map.union custom defaults
146 in foldl' (flip Map.delete) updated skip_keys
147
148
149 -- * Network definitions
150
151 -- ** Ipv4 types
152
153 data Ip4Address = Ip4Address Word8 Word8 Word8 Word8
154 deriving (Eq, Ord)
155
156 mkIp4Address :: (Word8, Word8, Word8, Word8) -> Ip4Address
157 mkIp4Address (a, b, c, d) = Ip4Address a b c d
158
159 instance Show Ip4Address where
160 show (Ip4Address a b c d) = intercalate "." $ map show [a, b, c, d]
161
162 readIp4Address :: (Applicative m, Monad m) => String -> m Ip4Address
163 readIp4Address s =
164 case sepSplit '.' s of
165 [a, b, c, d] -> Ip4Address <$>
166 tryRead "first octect" a <*>
167 tryRead "second octet" b <*>
168 tryRead "third octet" c <*>
169 tryRead "fourth octet" d
170 _ -> fail $ "Can't parse IPv4 address from string " ++ s
171
172 instance JSON Ip4Address where
173 showJSON = showJSON . show
174 readJSON (JSString s) = readIp4Address (fromJSString s)
175 readJSON v = fail $ "Invalid JSON value " ++ show v ++ " for an IPv4 address"
176
177 -- Converts an address to a list of numbers
178 ip4AddressToList :: Ip4Address -> [Word8]
179 ip4AddressToList (Ip4Address a b c d) = [a, b, c, d]
180
181 -- | Converts an address into its ordinal number.
182 -- This is needed for indexing IP adresses in reservation pools.
183 ip4AddressToNumber :: Ip4Address -> Integer
184 ip4AddressToNumber = foldl (\n i -> 256 * n + toInteger i) 0 . ip4AddressToList
185
186 -- | Converts a number into an address.
187 -- This is needed for indexing IP adresses in reservation pools.
188 ip4AddressFromNumber :: Integer -> Ip4Address
189 ip4AddressFromNumber n =
190 let s = state $ first fromInteger . swap . (`divMod` 256)
191 (d, c, b, a) = evalState ((,,,) <$> s <*> s <*> s <*> s) n
192 in Ip4Address a b c d
193
194 nextIp4Address :: Ip4Address -> Ip4Address
195 nextIp4Address = ip4AddressFromNumber . (+ 1) . ip4AddressToNumber
196
197 -- | Custom type for an IPv4 network.
198 data Ip4Network = Ip4Network { ip4netAddr :: Ip4Address
199 , ip4netMask :: Word8
200 }
201 deriving (Eq)
202
203 mkIp4Network :: Ip4Address -> Word8 -> Ip4Network
204 mkIp4Network = Ip4Network
205
206 instance Show Ip4Network where
207 show (Ip4Network ip netmask) = show ip ++ "/" ++ show netmask
208
209 -- | JSON instance for 'Ip4Network'.
210 instance JSON Ip4Network where
211 showJSON = showJSON . show
212 readJSON (JSString s) =
213 case sepSplit '/' (fromJSString s) of
214 [ip, nm] -> do
215 ip' <- readIp4Address ip
216 nm' <- tryRead "parsing netmask" nm
217 if nm' >= 0 && nm' <= 32
218 then return $ Ip4Network ip' nm'
219 else fail $ "Invalid netmask " ++ show nm' ++ " from string " ++
220 fromJSString s
221 _ -> fail $ "Can't parse IPv4 network from string " ++ fromJSString s
222 readJSON v = fail $ "Invalid JSON value " ++ show v ++ " for an IPv4 network"
223
224 -- ** Address pools
225
226 -- | Currently address pools just wrap a reservation 'BitArray'.
227 --
228 -- In future, 'Network' might be extended to include several address pools
229 -- and address pools might include their own ranges of addresses.
230 newtype AddressPool = AddressPool { apReservations :: BitArray }
231 deriving (Eq, Ord, Show)
232
233 instance JSON AddressPool where
234 showJSON = showJSON . apReservations
235 readJSON = liftM AddressPool . readJSON
236
237 -- ** Ganeti \"network\" config object.
238
239 -- FIXME: Not all types might be correct here, since they
240 -- haven't been exhaustively deduced from the python code yet.
241 --
242 -- FIXME: When parsing, check that the ext_reservations and reservations
243 -- have the same length
244 $(buildObject "Network" "network" $
245 [ simpleField "name" [t| NonEmptyString |]
246 , optionalField $
247 simpleField "mac_prefix" [t| String |]
248 , simpleField "network" [t| Ip4Network |]
249 , optionalField $
250 simpleField "network6" [t| String |]
251 , optionalField $
252 simpleField "gateway" [t| Ip4Address |]
253 , optionalField $
254 simpleField "gateway6" [t| String |]
255 , optionalField $
256 simpleField "reservations" [t| AddressPool |]
257 , optionalField $
258 simpleField "ext_reservations" [t| AddressPool |]
259 ]
260 ++ uuidFields
261 ++ timeStampFields
262 ++ serialFields
263 ++ tagsFields)
264
265 instance SerialNoObject Network where
266 serialOf = networkSerial
267
268 instance TagsObject Network where
269 tagsOf = networkTags
270
271 instance UuidObject Network where
272 uuidOf = UTF8.toString . networkUuid
273
274 instance TimeStampObject Network where
275 cTimeOf = networkCtime
276 mTimeOf = networkMtime
277
278
279 -- * Datacollector definitions
280 type MicroSeconds = Integer
281
282 -- | The configuration regarding a single data collector.
283 $(buildObject "DataCollectorConfig" "dataCollector" [
284 simpleField "active" [t| Bool|],
285 simpleField "interval" [t| MicroSeconds |]
286 ])
287
288 -- | Central default values of the data collector config.
289 instance Monoid DataCollectorConfig where
290 mempty = DataCollectorConfig
291 { dataCollectorActive = True
292 , dataCollectorInterval = 10^(6::Integer) * fromIntegral C.mondTimeInterval
293 }
294 mappend _ a = a
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 = UTF8.toString . 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 = UTF8.toString . 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 = UTF8.toString . 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 = UTF8.toString . 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