Statistics
| Branch: | Tag: | Revision:

root / src / Ganeti / Query / Network.hs @ 11e90588

History | View | Annotate | Download (7.2 kB)

1
{-| Implementation of the Ganeti Query2 node group queries.
2

    
3
 -}
4

    
5
{-
6

    
7
Copyright (C) 2012, 2013 Google Inc.
8

    
9
This program is free software; you can redistribute it and/or modify
10
it under the terms of the GNU General Public License as published by
11
the Free Software Foundation; either version 2 of the License, or
12
(at your option) any later version.
13

    
14
This program is distributed in the hope that it will be useful, but
15
WITHOUT ANY WARRANTY; without even the implied warranty of
16
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
17
General Public License for more details.
18

    
19
You should have received a copy of the GNU General Public License
20
along with this program; if not, write to the Free Software
21
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
22
02110-1301, USA.
23

    
24
-}
25

    
26
module Ganeti.Query.Network
27
  ( getGroupConnection
28
  , getNetworkUuid
29
  , instIsConnected
30
  , Runtime
31
  , fieldsMap
32
  , collectLiveData
33
  ) where
34

    
35
-- FIXME: everything except Runtime(..) and fieldsMap
36
-- is only exported for testing.
37

    
38
import qualified Data.Map as Map
39
import Data.Maybe (fromMaybe, mapMaybe)
40
import Data.List (find, foldl', intercalate)
41

    
42
import Ganeti.JSON
43
import Ganeti.Network
44
import Ganeti.Objects
45
import Ganeti.Query.Language
46
import Ganeti.Query.Common
47
import Ganeti.Query.Types
48
import Ganeti.Types
49
import Ganeti.Utils (b64StringToBitString)
50

    
51
-- | There is no actual runtime.
52
data Runtime = Runtime
53

    
54
networkFields :: FieldList Network Runtime
55
networkFields =
56
  [ (FieldDefinition "name" "Network" QFTText "Name",
57
     FieldSimple (rsNormal . networkName), QffNormal)
58
  , (FieldDefinition "network" "Subnet" QFTText "IPv4 subnet",
59
     FieldSimple (rsNormal . networkNetwork), QffNormal)
60
  , (FieldDefinition "gateway" "Gateway" QFTOther "IPv4 gateway",
61
     FieldSimple (rsMaybeUnavail . networkGateway), QffNormal)
62
  , (FieldDefinition "network6" "IPv6Subnet" QFTOther "IPv6 subnet",
63
     FieldSimple (rsMaybeUnavail . networkNetwork6), QffNormal)
64
  , (FieldDefinition "gateway6" "IPv6Gateway" QFTOther "IPv6 gateway",
65
     FieldSimple (rsMaybeUnavail . networkGateway6), QffNormal)
66
  , (FieldDefinition "mac_prefix" "MacPrefix" QFTOther "MAC address prefix",
67
     FieldSimple (rsMaybeUnavail . networkMacPrefix), QffNormal)
68
  , (FieldDefinition "free_count" "FreeCount" QFTNumber "Number of available\
69
                                                       \ addresses",
70
     FieldSimple (rsMaybeNoData . fmap getFreeCount . createAddressPool),
71
     QffNormal)
72
  , (FieldDefinition "map" "Map" QFTText "Actual mapping",
73
     FieldSimple (rsMaybeNoData . fmap getMap . createAddressPool),
74
     QffNormal)
75
  , (FieldDefinition "reserved_count" "ReservedCount" QFTNumber
76
       "Number of reserved addresses",
77
     FieldSimple (rsMaybeNoData . fmap getReservedCount . createAddressPool),
78
     QffNormal)
79
  , (FieldDefinition "group_list" "GroupList" QFTOther
80
       "List of nodegroups (group name, NIC mode, NIC link)",
81
     FieldConfig (\cfg -> rsNormal . getGroupConnections cfg . networkUuid),
82
     QffNormal)
83
  , (FieldDefinition "group_cnt" "NodeGroups" QFTNumber "Number of nodegroups",
84
     FieldConfig (\cfg -> rsNormal . length . getGroupConnections cfg
85
       . networkUuid), QffNormal)
86
  , (FieldDefinition "inst_list" "InstanceList" QFTOther "List of instances",
87
     FieldConfig (\cfg -> rsNormal . getInstances cfg . networkUuid),
88
     QffNormal)
89
  , (FieldDefinition "inst_cnt" "Instances" QFTNumber "Number of instances",
90
     FieldConfig (\cfg -> rsNormal . length . getInstances cfg
91
       . networkUuid), QffNormal)
92
  , (FieldDefinition "external_reservations" "ExternalReservations" QFTText
93
     "External reservations",
94
     FieldSimple getExtReservationsString, QffNormal)
95
  ] ++
96
  timeStampFields ++
97
  uuidFields "Network" ++
98
  serialFields "Network" ++
99
  tagsFields
100

    
101
-- | The group fields map.
102
fieldsMap :: FieldMap Network Runtime
103
fieldsMap =
104
  Map.fromList $ map (\v@(f, _, _) -> (fdefName f, v)) networkFields
105

    
106
-- TODO: the following fields are not implemented yet: external_reservations
107

    
108
-- | Given a network's UUID, this function lists all connections from
109
-- the network to nodegroups including the respective mode and links.
110
getGroupConnections :: ConfigData -> String -> [(String, String, String)]
111
getGroupConnections cfg network_uuid =
112
  mapMaybe (getGroupConnection network_uuid)
113
  ((Map.elems . fromContainer . configNodegroups) cfg)
114

    
115
-- | Given a network's UUID and a node group, this function assembles
116
-- a tuple of the group's name, the mode and the link by which the
117
-- network is connected to the group. Returns 'Nothing' if the network
118
-- is not connected to the group.
119
getGroupConnection :: String -> NodeGroup -> Maybe (String, String, String)
120
getGroupConnection network_uuid group =
121
  let networks = fromContainer . groupNetworks $ group
122
  in case Map.lookup network_uuid networks of
123
    Nothing -> Nothing
124
    Just net ->
125
      Just (groupName group, getNicMode net, getNicLink net)
126

    
127
-- | Retrieves the network's mode and formats it human-readable,
128
-- also in case it is not available.
129
getNicMode :: PartialNicParams -> String
130
getNicMode nic_params =
131
  maybe "-" nICModeToRaw $ nicpModeP nic_params
132

    
133
-- | Retrieves the network's link and formats it human-readable, also in
134
-- case it it not available.
135
getNicLink :: PartialNicParams -> String
136
getNicLink nic_params = fromMaybe "-" (nicpLinkP nic_params)
137

    
138
-- | Retrieves the network's instances' names.
139
getInstances :: ConfigData -> String -> [String]
140
getInstances cfg network_uuid =
141
  map instName (filter (instIsConnected cfg network_uuid)
142
    ((Map.elems . fromContainer . configInstances) cfg))
143

    
144
-- | Helper function that checks if an instance is linked to the given network.
145
instIsConnected :: ConfigData -> String -> Instance -> Bool
146
instIsConnected cfg network_uuid inst =
147
  network_uuid `elem` mapMaybe (getNetworkUuid cfg)
148
    (mapMaybe nicNetwork (instNics inst))
149

    
150
-- | Helper function to look up a network's UUID by its name
151
getNetworkUuid :: ConfigData -> String -> Maybe String
152
getNetworkUuid cfg name =
153
  let net = find (\n -> name == fromNonEmpty (networkName n))
154
               ((Map.elems . fromContainer . configNetworks) cfg)
155
  in fmap networkUuid net
156

    
157
-- | Computes the reservations list for a network.
158
--
159
-- This doesn't use the netmask for validation of the length, instead
160
-- simply iterating over the reservations string.
161
getReservations :: Ip4Network -> String -> [Ip4Address]
162
getReservations (Ip4Network net _) =
163
  reverse .
164
  fst .
165
  foldl' (\(accu, addr) c ->
166
            let addr' = nextIp4Address addr
167
                accu' = case c of
168
                          '1' -> addr:accu
169
                          '0' -> accu
170
                          _ -> -- FIXME: the reservations string
171
                               -- should be a proper type
172
                               accu
173
            in (accu', addr')) ([], net)
174

    
175
-- | Computes the external reservations as string for a network.
176
getExtReservationsString :: Network -> ResultEntry
177
getExtReservationsString net =
178
  let addrs = getReservations (networkNetwork net)
179
              (b64StringToBitString $ fromMaybe "" $ networkExtReservations net)
180
  in rsNormal . intercalate ", " $ map show addrs
181

    
182
-- | Dummy function for collecting live data (which networks don't have).
183
collectLiveData :: Bool -> ConfigData -> [Network] -> IO [(Network, Runtime)]
184
collectLiveData _ _ = return . map (\n -> (n, Runtime))