commit 6c6f5e5 (HEAD, master)
Merge: 99f5fa4 becf9d5
Author: Michael Hanselmann <[email protected]>
Date: Tue Feb 12 13:43:12 2013 +0100
Merge branch 'devel-2.7'
* devel-2.7: (23 commits)
QA: Support additional arguments for initialization
qa_utils: Fix order of arguments passed to _AssertRetCode
Improve reporting on errors.AddressPoolError exceptions
Add note about lv-tags rename
Make use of HooksDict() for networks
Remove family and size from network objects
Remove network_type slot (Issue 363)
Moved uniformity check for exclusive_storage flag
"exclusive_storage" cannot be changed on single nodes
Upgrades made on loading the configuration are always saved
Show correct daemon name on Luxi connect errors
Update the security document for Ganeti 2.7
OS environment: add network information
ConfigData: run UpgradeConfig on network objects
Make ParticalNic's network field of type String
Make gnt-os list work with no OSes
Fix OCF files installation in devel/upload
baserlib: Fix two mistakes in docstring
Workaround hlint behaviour with no warnings/errors
Remove use of 'head' and add hlint warning for it
...
Conflicts:
qa/qa_cluster.py: Trivial
qa/qa_node.py: Node attributes
src/Ganeti/Types.hs: Network cleanup
test/hs/Test/Ganeti/Objects.hs: Network cleanup
Signed-off-by: Michael Hanselmann <[email protected]>
diff --cc qa/qa_node.py
index 6081a02,ac7fc90..809f879
--- a/qa/qa_node.py
+++ b/qa/qa_node.py
@@@ -424,4 -421,23 +424,23 @@@ def TestNodeListFields()
def TestNodeListDrbd(node):
"""gnt-node list-drbd"""
- AssertCommand(["gnt-node", "list-drbd", node["primary"]])
+ AssertCommand(["gnt-node", "list-drbd", node.primary])
+
+
+ def _BuildSetESCmd(action, value, node_name):
+ cmd = ["gnt-node"]
+ if action == "add":
+ cmd.extend(["add", "--readd"])
+ else:
+ cmd.append("modify")
+ cmd.extend(["--node-parameters", "exclusive_storage=%s" % value, node_name])
+ return cmd
+
+
+ def TestExclStorSingleNode(node):
+ """gnt-node add/modify cannot change the exclusive_storage flag.
+
+ """
+ for action in ["add", "modify"]:
+ for value in (True, False, "default"):
- AssertCommand(_BuildSetESCmd(action, value, node["primary"]), fail=True)
++ AssertCommand(_BuildSetESCmd(action, value, node.primary), fail=True)
diff --cc src/Ganeti/Query/Network.hs
index e0b5a13,0000000..2d262bf
mode 100644,000000..100644
--- a/src/Ganeti/Query/Network.hs
+++ b/src/Ganeti/Query/Network.hs
@@@ -1,143 -1,0 +1,141 @@@
+{-| Implementation of the Ganeti Query2 node group queries.
+
+ -}
+
+{-
+
+Copyright (C) 2012 Google Inc.
+
+This program is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301, USA.
+
+-}
+
+module Ganeti.Query.Network
+ ( NetworkRuntime(..)
+ , networkFieldsMap
+ ) where
+
+import qualified Data.Map as Map
+import Data.Maybe (fromMaybe, mapMaybe)
+import Data.List (find)
+
+import Ganeti.JSON
+import Ganeti.Network
+import Ganeti.Objects
+import Ganeti.Query.Language
+import Ganeti.Query.Common
+import Ganeti.Query.Types
+import Ganeti.Types
+
+data NetworkRuntime = NetworkRuntime
+
+networkFields :: FieldList Network NetworkRuntime
+networkFields =
+ [ (FieldDefinition "name" "Name" QFTText "Network name",
+ FieldSimple (rsNormal . networkName), QffNormal)
+ , (FieldDefinition "network" "Subnet" QFTText "IPv4 subnet",
+ FieldSimple (rsNormal . networkNetwork), QffNormal)
+ , (FieldDefinition "gateway" "Gateway" QFTOther "IPv4 gateway",
+ FieldSimple (rsMaybeUnavail . networkGateway), QffNormal)
+ , (FieldDefinition "network6" "IPv6Subnet" QFTOther "IPv6 subnet",
+ FieldSimple (rsMaybeUnavail . networkNetwork6), QffNormal)
+ , (FieldDefinition "gateway6" "IPv6Gateway" QFTOther "IPv6 gateway",
+ FieldSimple (rsMaybeUnavail . networkGateway6), QffNormal)
+ , (FieldDefinition "mac_prefix" "MacPrefix" QFTOther "MAC address prefix",
+ FieldSimple (rsMaybeUnavail . networkMacPrefix), QffNormal)
- , (FieldDefinition "network_type" "NetworkType" QFTOther "Network type",
- FieldSimple (rsMaybeUnavail . networkNetworkType), QffNormal)
+ , (FieldDefinition "free_count" "FreeCount" QFTOther "Number of free IPs",
+ FieldSimple (rsMaybeNoData . fmap getFreeCount . createAddressPool),
+ QffNormal)
+ , (FieldDefinition "map" "Map" QFTText "Map of the network's reserved IPs",
+ FieldSimple (rsMaybeNoData . fmap getMap . createAddressPool),
+ QffNormal)
+ , (FieldDefinition "reserved_count" "ReservedCount" QFTOther
+ "Number of reserved IPs",
+ FieldSimple (rsMaybeNoData . fmap getReservedCount . createAddressPool),
+ QffNormal)
+ , (FieldDefinition "group_list" "GroupList" QFTOther "List of node groups",
+ FieldConfig (\cfg -> rsNormal . getGroupConnections cfg . networkUuid),
+ QffNormal)
+ , (FieldDefinition "group_cnt" "GroupCount" QFTOther "Number of node
groups",
+ FieldConfig (\cfg -> rsNormal . length . getGroupConnections cfg
+ . networkUuid), QffNormal)
+ , (FieldDefinition "inst_list" "InstanceList" QFTOther "List of instances",
+ FieldConfig (\cfg -> rsNormal . getInstances cfg . networkUuid),
+ QffNormal)
+ , (FieldDefinition "inst_cnt" "InstanceCount" QFTOther "Number of
instances",
+ FieldConfig (\cfg -> rsNormal . length . getInstances cfg
+ . networkUuid), QffNormal)
+ ] ++
+ uuidFields "Network" ++
+ serialFields "Network" ++
+ tagsFields
+
+-- | The group fields map.
+networkFieldsMap :: FieldMap Network NetworkRuntime
+networkFieldsMap =
+ Map.fromList $ map (\v@(f, _, _) -> (fdefName f, v)) networkFields
+
+-- TODO: the following fields are not implemented yet: external_reservations,
+-- inst_cnt, inst_list
+
+-- | Given a network's UUID, this function lists all connections from
+-- the network to nodegroups including the respective mode and links.
+getGroupConnections :: ConfigData -> String -> [(String, String, String)]
+getGroupConnections cfg network_uuid =
+ mapMaybe (getGroupConnection network_uuid)
+ ((Map.elems . fromContainer . configNodegroups) cfg)
+
+-- | Given a network's UUID and a node group, this function assembles
+-- a tuple of the group's name, the mode and the link by which the
+-- network is connected to the group. Returns 'Nothing' if the network
+-- is not connected to the group.
+getGroupConnection :: String -> NodeGroup -> Maybe (String, String, String)
+getGroupConnection network_uuid group =
+ let networks = fromContainer . groupNetworks $ group
+ in case Map.lookup network_uuid networks of
+ Nothing -> Nothing
+ Just net ->
+ Just (groupName group, getNicMode net, getNicLink net)
+
+-- | Retrieves the network's mode and formats it human-readable,
+-- also in case it is not available.
+getNicMode :: PartialNicParams -> String
+getNicMode nic_params =
+ maybe "-" nICModeToRaw $ nicpModeP nic_params
+
+-- | Retrieves the network's link and formats it human-readable, also in
+-- case it it not available.
+getNicLink :: PartialNicParams -> String
+getNicLink nic_params = fromMaybe "-" (nicpLinkP nic_params)
+
+-- | Retrieves the network's instances' names.
+getInstances :: ConfigData -> String -> [String]
+getInstances cfg network_uuid =
+ map instName (filter (instIsConnected cfg network_uuid)
+ ((Map.elems . fromContainer . configInstances) cfg))
+
+-- | Helper function that checks if an instance is linked to the given
network.
+instIsConnected :: ConfigData -> String -> Instance -> Bool
+instIsConnected cfg network_uuid inst =
+ network_uuid `elem` mapMaybe (getNetworkUuid cfg)
+ (mapMaybe nicNetwork (instNics inst))
+
+-- | Helper function to look up a network's UUID by its name
+getNetworkUuid :: ConfigData -> String -> Maybe String
+getNetworkUuid cfg name =
+ let net = find (\n -> name == fromNonEmpty (networkName n))
+ ((Map.elems . fromContainer . configNetworks) cfg)
+ in fmap networkUuid net
diff --cc src/Ganeti/Types.hs
index 2e3779a,e6c9378..c57ee2d
--- a/src/Ganeti/Types.hs
+++ b/src/Ganeti/Types.hs
@@@ -359,14 -357,7 +357,7 @@@ $(THH.declareSADT "IAllocatorMode
])
$(THH.makeJSONInstance ''IAllocatorMode)
- -- | Network type.
- $(THH.declareSADT "NetworkType"
- [ ("PrivateNetwork", 'C.networkTypePrivate)
- , ("PublicNetwork", 'C.networkTypePublic)
- ])
- $(THH.makeJSONInstance ''NetworkType)
-
--- | Netork mode.
+-- | Network mode.
$(THH.declareSADT "NICMode"
[ ("NMBridged", 'C.nicModeBridged)
, ("NMRouted", 'C.nicModeRouted)
diff --cc test/hs/Test/Ganeti/Objects.hs
index 8182279,65d7659..dc619ec
--- a/test/hs/Test/Ganeti/Objects.hs
+++ b/test/hs/Test/Ganeti/Objects.hs
@@@ -176,18 -172,12 +172,13 @@@ genValidNetwork = d
net6 <- genMaybe genIp6Net
gateway <- genMaybe genIp4AddrStr
gateway6 <- genMaybe genIp6Addr
- size <- genMaybe genJSValue
res <- liftM Just (genBitString $ netmask2NumHosts netmask)
ext_res <- liftM Just (genBitString $ netmask2NumHosts netmask)
+ uuid <- arbitrary
- let n = Network name network_type mac_prefix net_family net net6 gateway
- gateway6 size res ext_res uuid 0 Set.empty
+ let n = Network name mac_prefix net net6 gateway
- gateway6 res ext_res 0 Set.empty
++ gateway6 res ext_res uuid 0 Set.empty
return n
- -- | Generates an arbitrary network type.
- genNetworkType :: Gen NetworkType
- genNetworkType = elements [ PrivateNetwork, PublicNetwork ]
-
-- | Generate an arbitrary string consisting of '0' and '1' of the given
length.
genBitString :: Int -> Gen String
genBitString len = vectorOf len (elements "01")