Statistics
| Branch: | Tag: | Revision:

root / src / Ganeti / Query / Network.hs @ e817723c

History | View | Annotate | Download (6.9 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
  , fieldsMap
31
  ) where
32

    
33
-- FIXME: everything except fieldsMap
34
-- is only exported for testing.
35

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

    
40
import Ganeti.JSON
41
import Ganeti.Network
42
import Ganeti.Objects
43
import Ganeti.Query.Language
44
import Ganeti.Query.Common
45
import Ganeti.Query.Types
46
import Ganeti.Types
47

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

    
95
-- | The group fields map.
96
fieldsMap :: FieldMap Network NoDataRuntime
97
fieldsMap =
98
  Map.fromList $ map (\v@(f, _, _) -> (fdefName f, v)) networkFields
99

    
100
-- TODO: the following fields are not implemented yet: external_reservations
101

    
102
-- | Given a network's UUID, this function lists all connections from
103
-- the network to nodegroups including the respective mode and links.
104
getGroupConnections :: ConfigData -> String -> [(String, String, String)]
105
getGroupConnections cfg network_uuid =
106
  mapMaybe (getGroupConnection network_uuid)
107
  ((Map.elems . fromContainer . configNodegroups) cfg)
108

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

    
121
-- | Retrieves the network's mode and formats it human-readable,
122
-- also in case it is not available.
123
getNicMode :: PartialNicParams -> String
124
getNicMode nic_params =
125
  maybe "-" nICModeToRaw $ nicpModeP nic_params
126

    
127
-- | Retrieves the network's link and formats it human-readable, also in
128
-- case it it not available.
129
getNicLink :: PartialNicParams -> String
130
getNicLink nic_params = fromMaybe "-" (nicpLinkP nic_params)
131

    
132
-- | Retrieves the network's instances' names.
133
getInstances :: ConfigData -> String -> [String]
134
getInstances cfg network_uuid =
135
  map instName (filter (instIsConnected cfg network_uuid)
136
    ((Map.elems . fromContainer . configInstances) cfg))
137

    
138
-- | Helper function that checks if an instance is linked to the given network.
139
instIsConnected :: ConfigData -> String -> Instance -> Bool
140
instIsConnected cfg network_uuid inst =
141
  network_uuid `elem` mapMaybe (getNetworkUuid cfg)
142
    (mapMaybe nicNetwork (instNics inst))
143

    
144
-- | Helper function to look up a network's UUID by its name
145
getNetworkUuid :: ConfigData -> String -> Maybe String
146
getNetworkUuid cfg name =
147
  let net = find (\n -> name == fromNonEmpty (networkName n))
148
               ((Map.elems . fromContainer . configNetworks) cfg)
149
  in fmap networkUuid net
150

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

    
169
-- | Computes the external reservations as string for a network.
170
getExtReservationsString :: Network -> ResultEntry
171
getExtReservationsString net =
172
  let addrs = getReservations (networkNetwork net)
173
              (fromMaybe "" $ networkExtReservations net)
174
  in rsNormal . intercalate ", " $ map show addrs