Statistics
| Branch: | Tag: | Revision:

root / lib / cmdlib / network.py @ 32449822

History | View | Annotate | Download (22.6 kB)

1 37dc17e3 Thomas Thrainer
#
2 37dc17e3 Thomas Thrainer
#
3 37dc17e3 Thomas Thrainer
4 37dc17e3 Thomas Thrainer
# Copyright (C) 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013 Google Inc.
5 37dc17e3 Thomas Thrainer
#
6 37dc17e3 Thomas Thrainer
# This program is free software; you can redistribute it and/or modify
7 37dc17e3 Thomas Thrainer
# it under the terms of the GNU General Public License as published by
8 37dc17e3 Thomas Thrainer
# the Free Software Foundation; either version 2 of the License, or
9 37dc17e3 Thomas Thrainer
# (at your option) any later version.
10 37dc17e3 Thomas Thrainer
#
11 37dc17e3 Thomas Thrainer
# This program is distributed in the hope that it will be useful, but
12 37dc17e3 Thomas Thrainer
# WITHOUT ANY WARRANTY; without even the implied warranty of
13 37dc17e3 Thomas Thrainer
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14 37dc17e3 Thomas Thrainer
# General Public License for more details.
15 37dc17e3 Thomas Thrainer
#
16 37dc17e3 Thomas Thrainer
# You should have received a copy of the GNU General Public License
17 37dc17e3 Thomas Thrainer
# along with this program; if not, write to the Free Software
18 37dc17e3 Thomas Thrainer
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
19 37dc17e3 Thomas Thrainer
# 02110-1301, USA.
20 37dc17e3 Thomas Thrainer
21 37dc17e3 Thomas Thrainer
22 37dc17e3 Thomas Thrainer
"""Logical units dealing with networks."""
23 37dc17e3 Thomas Thrainer
24 37dc17e3 Thomas Thrainer
from ganeti import constants
25 37dc17e3 Thomas Thrainer
from ganeti import errors
26 37dc17e3 Thomas Thrainer
from ganeti import locking
27 37dc17e3 Thomas Thrainer
from ganeti import network
28 37dc17e3 Thomas Thrainer
from ganeti import objects
29 37dc17e3 Thomas Thrainer
from ganeti import qlang
30 37dc17e3 Thomas Thrainer
from ganeti import query
31 37dc17e3 Thomas Thrainer
from ganeti import utils
32 5eacbcae Thomas Thrainer
from ganeti.cmdlib.base import LogicalUnit, NoHooksLU, QueryBase
33 5eacbcae Thomas Thrainer
from ganeti.cmdlib.common import ShareAll, CheckNodeGroupInstances
34 37dc17e3 Thomas Thrainer
35 37dc17e3 Thomas Thrainer
36 37dc17e3 Thomas Thrainer
def _BuildNetworkHookEnv(name, subnet, gateway, network6, gateway6,
37 37dc17e3 Thomas Thrainer
                         mac_prefix, tags):
38 37dc17e3 Thomas Thrainer
  """Builds network related env variables for hooks
39 37dc17e3 Thomas Thrainer

40 37dc17e3 Thomas Thrainer
  This builds the hook environment from individual variables.
41 37dc17e3 Thomas Thrainer

42 37dc17e3 Thomas Thrainer
  @type name: string
43 37dc17e3 Thomas Thrainer
  @param name: the name of the network
44 37dc17e3 Thomas Thrainer
  @type subnet: string
45 37dc17e3 Thomas Thrainer
  @param subnet: the ipv4 subnet
46 37dc17e3 Thomas Thrainer
  @type gateway: string
47 37dc17e3 Thomas Thrainer
  @param gateway: the ipv4 gateway
48 37dc17e3 Thomas Thrainer
  @type network6: string
49 37dc17e3 Thomas Thrainer
  @param network6: the ipv6 subnet
50 37dc17e3 Thomas Thrainer
  @type gateway6: string
51 37dc17e3 Thomas Thrainer
  @param gateway6: the ipv6 gateway
52 37dc17e3 Thomas Thrainer
  @type mac_prefix: string
53 37dc17e3 Thomas Thrainer
  @param mac_prefix: the mac_prefix
54 37dc17e3 Thomas Thrainer
  @type tags: list
55 37dc17e3 Thomas Thrainer
  @param tags: the tags of the network
56 37dc17e3 Thomas Thrainer

57 37dc17e3 Thomas Thrainer
  """
58 37dc17e3 Thomas Thrainer
  env = {}
59 37dc17e3 Thomas Thrainer
  if name:
60 37dc17e3 Thomas Thrainer
    env["NETWORK_NAME"] = name
61 37dc17e3 Thomas Thrainer
  if subnet:
62 37dc17e3 Thomas Thrainer
    env["NETWORK_SUBNET"] = subnet
63 37dc17e3 Thomas Thrainer
  if gateway:
64 37dc17e3 Thomas Thrainer
    env["NETWORK_GATEWAY"] = gateway
65 37dc17e3 Thomas Thrainer
  if network6:
66 37dc17e3 Thomas Thrainer
    env["NETWORK_SUBNET6"] = network6
67 37dc17e3 Thomas Thrainer
  if gateway6:
68 37dc17e3 Thomas Thrainer
    env["NETWORK_GATEWAY6"] = gateway6
69 37dc17e3 Thomas Thrainer
  if mac_prefix:
70 37dc17e3 Thomas Thrainer
    env["NETWORK_MAC_PREFIX"] = mac_prefix
71 37dc17e3 Thomas Thrainer
  if tags:
72 37dc17e3 Thomas Thrainer
    env["NETWORK_TAGS"] = " ".join(tags)
73 37dc17e3 Thomas Thrainer
74 37dc17e3 Thomas Thrainer
  return env
75 37dc17e3 Thomas Thrainer
76 37dc17e3 Thomas Thrainer
77 37dc17e3 Thomas Thrainer
class LUNetworkAdd(LogicalUnit):
78 37dc17e3 Thomas Thrainer
  """Logical unit for creating networks.
79 37dc17e3 Thomas Thrainer

80 37dc17e3 Thomas Thrainer
  """
81 37dc17e3 Thomas Thrainer
  HPATH = "network-add"
82 37dc17e3 Thomas Thrainer
  HTYPE = constants.HTYPE_NETWORK
83 37dc17e3 Thomas Thrainer
  REQ_BGL = False
84 37dc17e3 Thomas Thrainer
85 37dc17e3 Thomas Thrainer
  def BuildHooksNodes(self):
86 37dc17e3 Thomas Thrainer
    """Build hooks nodes.
87 37dc17e3 Thomas Thrainer

88 37dc17e3 Thomas Thrainer
    """
89 37dc17e3 Thomas Thrainer
    mn = self.cfg.GetMasterNode()
90 37dc17e3 Thomas Thrainer
    return ([mn], [mn])
91 37dc17e3 Thomas Thrainer
92 37dc17e3 Thomas Thrainer
  def CheckArguments(self):
93 37dc17e3 Thomas Thrainer
    if self.op.mac_prefix:
94 37dc17e3 Thomas Thrainer
      self.op.mac_prefix = \
95 37dc17e3 Thomas Thrainer
        utils.NormalizeAndValidateThreeOctetMacPrefix(self.op.mac_prefix)
96 37dc17e3 Thomas Thrainer
97 37dc17e3 Thomas Thrainer
  def ExpandNames(self):
98 37dc17e3 Thomas Thrainer
    self.network_uuid = self.cfg.GenerateUniqueID(self.proc.GetECId())
99 37dc17e3 Thomas Thrainer
100 37dc17e3 Thomas Thrainer
    if self.op.conflicts_check:
101 37dc17e3 Thomas Thrainer
      self.share_locks[locking.LEVEL_NODE] = 1
102 37dc17e3 Thomas Thrainer
      self.share_locks[locking.LEVEL_NODE_ALLOC] = 1
103 37dc17e3 Thomas Thrainer
      self.needed_locks = {
104 37dc17e3 Thomas Thrainer
        locking.LEVEL_NODE: locking.ALL_SET,
105 37dc17e3 Thomas Thrainer
        locking.LEVEL_NODE_ALLOC: locking.ALL_SET,
106 37dc17e3 Thomas Thrainer
        }
107 37dc17e3 Thomas Thrainer
    else:
108 37dc17e3 Thomas Thrainer
      self.needed_locks = {}
109 37dc17e3 Thomas Thrainer
110 37dc17e3 Thomas Thrainer
    self.add_locks[locking.LEVEL_NETWORK] = self.network_uuid
111 37dc17e3 Thomas Thrainer
112 37dc17e3 Thomas Thrainer
  def CheckPrereq(self):
113 37dc17e3 Thomas Thrainer
    if self.op.network is None:
114 37dc17e3 Thomas Thrainer
      raise errors.OpPrereqError("Network must be given",
115 37dc17e3 Thomas Thrainer
                                 errors.ECODE_INVAL)
116 37dc17e3 Thomas Thrainer
117 37dc17e3 Thomas Thrainer
    try:
118 37dc17e3 Thomas Thrainer
      existing_uuid = self.cfg.LookupNetwork(self.op.network_name)
119 37dc17e3 Thomas Thrainer
    except errors.OpPrereqError:
120 37dc17e3 Thomas Thrainer
      pass
121 37dc17e3 Thomas Thrainer
    else:
122 37dc17e3 Thomas Thrainer
      raise errors.OpPrereqError("Desired network name '%s' already exists as a"
123 37dc17e3 Thomas Thrainer
                                 " network (UUID: %s)" %
124 37dc17e3 Thomas Thrainer
                                 (self.op.network_name, existing_uuid),
125 37dc17e3 Thomas Thrainer
                                 errors.ECODE_EXISTS)
126 37dc17e3 Thomas Thrainer
127 37dc17e3 Thomas Thrainer
    # Check tag validity
128 37dc17e3 Thomas Thrainer
    for tag in self.op.tags:
129 37dc17e3 Thomas Thrainer
      objects.TaggableObject.ValidateTag(tag)
130 37dc17e3 Thomas Thrainer
131 37dc17e3 Thomas Thrainer
  def BuildHooksEnv(self):
132 37dc17e3 Thomas Thrainer
    """Build hooks env.
133 37dc17e3 Thomas Thrainer

134 37dc17e3 Thomas Thrainer
    """
135 37dc17e3 Thomas Thrainer
    args = {
136 37dc17e3 Thomas Thrainer
      "name": self.op.network_name,
137 37dc17e3 Thomas Thrainer
      "subnet": self.op.network,
138 37dc17e3 Thomas Thrainer
      "gateway": self.op.gateway,
139 37dc17e3 Thomas Thrainer
      "network6": self.op.network6,
140 37dc17e3 Thomas Thrainer
      "gateway6": self.op.gateway6,
141 37dc17e3 Thomas Thrainer
      "mac_prefix": self.op.mac_prefix,
142 37dc17e3 Thomas Thrainer
      "tags": self.op.tags,
143 37dc17e3 Thomas Thrainer
      }
144 37dc17e3 Thomas Thrainer
    return _BuildNetworkHookEnv(**args) # pylint: disable=W0142
145 37dc17e3 Thomas Thrainer
146 37dc17e3 Thomas Thrainer
  def Exec(self, feedback_fn):
147 37dc17e3 Thomas Thrainer
    """Add the ip pool to the cluster.
148 37dc17e3 Thomas Thrainer

149 37dc17e3 Thomas Thrainer
    """
150 37dc17e3 Thomas Thrainer
    nobj = objects.Network(name=self.op.network_name,
151 37dc17e3 Thomas Thrainer
                           network=self.op.network,
152 37dc17e3 Thomas Thrainer
                           gateway=self.op.gateway,
153 37dc17e3 Thomas Thrainer
                           network6=self.op.network6,
154 37dc17e3 Thomas Thrainer
                           gateway6=self.op.gateway6,
155 37dc17e3 Thomas Thrainer
                           mac_prefix=self.op.mac_prefix,
156 37dc17e3 Thomas Thrainer
                           uuid=self.network_uuid)
157 37dc17e3 Thomas Thrainer
    # Initialize the associated address pool
158 37dc17e3 Thomas Thrainer
    try:
159 37dc17e3 Thomas Thrainer
      pool = network.AddressPool.InitializeNetwork(nobj)
160 37dc17e3 Thomas Thrainer
    except errors.AddressPoolError, err:
161 37dc17e3 Thomas Thrainer
      raise errors.OpExecError("Cannot create IP address pool for network"
162 37dc17e3 Thomas Thrainer
                               " '%s': %s" % (self.op.network_name, err))
163 37dc17e3 Thomas Thrainer
164 37dc17e3 Thomas Thrainer
    # Check if we need to reserve the nodes and the cluster master IP
165 37dc17e3 Thomas Thrainer
    # These may not be allocated to any instances in routed mode, as
166 37dc17e3 Thomas Thrainer
    # they wouldn't function anyway.
167 37dc17e3 Thomas Thrainer
    if self.op.conflicts_check:
168 37dc17e3 Thomas Thrainer
      for node in self.cfg.GetAllNodesInfo().values():
169 37dc17e3 Thomas Thrainer
        for ip in [node.primary_ip, node.secondary_ip]:
170 37dc17e3 Thomas Thrainer
          try:
171 37dc17e3 Thomas Thrainer
            if pool.Contains(ip):
172 37dc17e3 Thomas Thrainer
              pool.Reserve(ip)
173 37dc17e3 Thomas Thrainer
              self.LogInfo("Reserved IP address of node '%s' (%s)",
174 37dc17e3 Thomas Thrainer
                           node.name, ip)
175 37dc17e3 Thomas Thrainer
          except errors.AddressPoolError, err:
176 37dc17e3 Thomas Thrainer
            self.LogWarning("Cannot reserve IP address '%s' of node '%s': %s",
177 37dc17e3 Thomas Thrainer
                            ip, node.name, err)
178 37dc17e3 Thomas Thrainer
179 37dc17e3 Thomas Thrainer
      master_ip = self.cfg.GetClusterInfo().master_ip
180 37dc17e3 Thomas Thrainer
      try:
181 37dc17e3 Thomas Thrainer
        if pool.Contains(master_ip):
182 37dc17e3 Thomas Thrainer
          pool.Reserve(master_ip)
183 37dc17e3 Thomas Thrainer
          self.LogInfo("Reserved cluster master IP address (%s)", master_ip)
184 37dc17e3 Thomas Thrainer
      except errors.AddressPoolError, err:
185 37dc17e3 Thomas Thrainer
        self.LogWarning("Cannot reserve cluster master IP address (%s): %s",
186 37dc17e3 Thomas Thrainer
                        master_ip, err)
187 37dc17e3 Thomas Thrainer
188 37dc17e3 Thomas Thrainer
    if self.op.add_reserved_ips:
189 37dc17e3 Thomas Thrainer
      for ip in self.op.add_reserved_ips:
190 37dc17e3 Thomas Thrainer
        try:
191 37dc17e3 Thomas Thrainer
          pool.Reserve(ip, external=True)
192 37dc17e3 Thomas Thrainer
        except errors.AddressPoolError, err:
193 37dc17e3 Thomas Thrainer
          raise errors.OpExecError("Cannot reserve IP address '%s': %s" %
194 37dc17e3 Thomas Thrainer
                                   (ip, err))
195 37dc17e3 Thomas Thrainer
196 37dc17e3 Thomas Thrainer
    if self.op.tags:
197 37dc17e3 Thomas Thrainer
      for tag in self.op.tags:
198 37dc17e3 Thomas Thrainer
        nobj.AddTag(tag)
199 37dc17e3 Thomas Thrainer
200 37dc17e3 Thomas Thrainer
    self.cfg.AddNetwork(nobj, self.proc.GetECId(), check_uuid=False)
201 37dc17e3 Thomas Thrainer
    del self.remove_locks[locking.LEVEL_NETWORK]
202 37dc17e3 Thomas Thrainer
203 37dc17e3 Thomas Thrainer
204 37dc17e3 Thomas Thrainer
class LUNetworkRemove(LogicalUnit):
205 37dc17e3 Thomas Thrainer
  HPATH = "network-remove"
206 37dc17e3 Thomas Thrainer
  HTYPE = constants.HTYPE_NETWORK
207 37dc17e3 Thomas Thrainer
  REQ_BGL = False
208 37dc17e3 Thomas Thrainer
209 37dc17e3 Thomas Thrainer
  def ExpandNames(self):
210 37dc17e3 Thomas Thrainer
    self.network_uuid = self.cfg.LookupNetwork(self.op.network_name)
211 37dc17e3 Thomas Thrainer
212 37dc17e3 Thomas Thrainer
    self.share_locks[locking.LEVEL_NODEGROUP] = 1
213 37dc17e3 Thomas Thrainer
    self.needed_locks = {
214 37dc17e3 Thomas Thrainer
      locking.LEVEL_NETWORK: [self.network_uuid],
215 37dc17e3 Thomas Thrainer
      locking.LEVEL_NODEGROUP: locking.ALL_SET,
216 37dc17e3 Thomas Thrainer
      }
217 37dc17e3 Thomas Thrainer
218 37dc17e3 Thomas Thrainer
  def CheckPrereq(self):
219 37dc17e3 Thomas Thrainer
    """Check prerequisites.
220 37dc17e3 Thomas Thrainer

221 37dc17e3 Thomas Thrainer
    This checks that the given network name exists as a network, that is
222 37dc17e3 Thomas Thrainer
    empty (i.e., contains no nodes), and that is not the last group of the
223 37dc17e3 Thomas Thrainer
    cluster.
224 37dc17e3 Thomas Thrainer

225 37dc17e3 Thomas Thrainer
    """
226 37dc17e3 Thomas Thrainer
    # Verify that the network is not conncted.
227 37dc17e3 Thomas Thrainer
    node_groups = [group.name
228 37dc17e3 Thomas Thrainer
                   for group in self.cfg.GetAllNodeGroupsInfo().values()
229 37dc17e3 Thomas Thrainer
                   if self.network_uuid in group.networks]
230 37dc17e3 Thomas Thrainer
231 37dc17e3 Thomas Thrainer
    if node_groups:
232 37dc17e3 Thomas Thrainer
      self.LogWarning("Network '%s' is connected to the following"
233 37dc17e3 Thomas Thrainer
                      " node groups: %s" %
234 37dc17e3 Thomas Thrainer
                      (self.op.network_name,
235 37dc17e3 Thomas Thrainer
                       utils.CommaJoin(utils.NiceSort(node_groups))))
236 37dc17e3 Thomas Thrainer
      raise errors.OpPrereqError("Network still connected", errors.ECODE_STATE)
237 37dc17e3 Thomas Thrainer
238 37dc17e3 Thomas Thrainer
  def BuildHooksEnv(self):
239 37dc17e3 Thomas Thrainer
    """Build hooks env.
240 37dc17e3 Thomas Thrainer

241 37dc17e3 Thomas Thrainer
    """
242 37dc17e3 Thomas Thrainer
    return {
243 37dc17e3 Thomas Thrainer
      "NETWORK_NAME": self.op.network_name,
244 37dc17e3 Thomas Thrainer
      }
245 37dc17e3 Thomas Thrainer
246 37dc17e3 Thomas Thrainer
  def BuildHooksNodes(self):
247 37dc17e3 Thomas Thrainer
    """Build hooks nodes.
248 37dc17e3 Thomas Thrainer

249 37dc17e3 Thomas Thrainer
    """
250 37dc17e3 Thomas Thrainer
    mn = self.cfg.GetMasterNode()
251 37dc17e3 Thomas Thrainer
    return ([mn], [mn])
252 37dc17e3 Thomas Thrainer
253 37dc17e3 Thomas Thrainer
  def Exec(self, feedback_fn):
254 37dc17e3 Thomas Thrainer
    """Remove the network.
255 37dc17e3 Thomas Thrainer

256 37dc17e3 Thomas Thrainer
    """
257 37dc17e3 Thomas Thrainer
    try:
258 37dc17e3 Thomas Thrainer
      self.cfg.RemoveNetwork(self.network_uuid)
259 37dc17e3 Thomas Thrainer
    except errors.ConfigurationError:
260 37dc17e3 Thomas Thrainer
      raise errors.OpExecError("Network '%s' with UUID %s disappeared" %
261 37dc17e3 Thomas Thrainer
                               (self.op.network_name, self.network_uuid))
262 37dc17e3 Thomas Thrainer
263 37dc17e3 Thomas Thrainer
264 37dc17e3 Thomas Thrainer
class LUNetworkSetParams(LogicalUnit):
265 37dc17e3 Thomas Thrainer
  """Modifies the parameters of a network.
266 37dc17e3 Thomas Thrainer

267 37dc17e3 Thomas Thrainer
  """
268 37dc17e3 Thomas Thrainer
  HPATH = "network-modify"
269 37dc17e3 Thomas Thrainer
  HTYPE = constants.HTYPE_NETWORK
270 37dc17e3 Thomas Thrainer
  REQ_BGL = False
271 37dc17e3 Thomas Thrainer
272 37dc17e3 Thomas Thrainer
  def CheckArguments(self):
273 37dc17e3 Thomas Thrainer
    if (self.op.gateway and
274 37dc17e3 Thomas Thrainer
        (self.op.add_reserved_ips or self.op.remove_reserved_ips)):
275 37dc17e3 Thomas Thrainer
      raise errors.OpPrereqError("Cannot modify gateway and reserved ips"
276 37dc17e3 Thomas Thrainer
                                 " at once", errors.ECODE_INVAL)
277 37dc17e3 Thomas Thrainer
278 37dc17e3 Thomas Thrainer
  def ExpandNames(self):
279 37dc17e3 Thomas Thrainer
    self.network_uuid = self.cfg.LookupNetwork(self.op.network_name)
280 37dc17e3 Thomas Thrainer
281 37dc17e3 Thomas Thrainer
    self.needed_locks = {
282 37dc17e3 Thomas Thrainer
      locking.LEVEL_NETWORK: [self.network_uuid],
283 37dc17e3 Thomas Thrainer
      }
284 37dc17e3 Thomas Thrainer
285 37dc17e3 Thomas Thrainer
  def CheckPrereq(self):
286 37dc17e3 Thomas Thrainer
    """Check prerequisites.
287 37dc17e3 Thomas Thrainer

288 37dc17e3 Thomas Thrainer
    """
289 37dc17e3 Thomas Thrainer
    self.network = self.cfg.GetNetwork(self.network_uuid)
290 37dc17e3 Thomas Thrainer
    self.gateway = self.network.gateway
291 37dc17e3 Thomas Thrainer
    self.mac_prefix = self.network.mac_prefix
292 37dc17e3 Thomas Thrainer
    self.network6 = self.network.network6
293 37dc17e3 Thomas Thrainer
    self.gateway6 = self.network.gateway6
294 37dc17e3 Thomas Thrainer
    self.tags = self.network.tags
295 37dc17e3 Thomas Thrainer
296 37dc17e3 Thomas Thrainer
    self.pool = network.AddressPool(self.network)
297 37dc17e3 Thomas Thrainer
298 37dc17e3 Thomas Thrainer
    if self.op.gateway:
299 37dc17e3 Thomas Thrainer
      if self.op.gateway == constants.VALUE_NONE:
300 37dc17e3 Thomas Thrainer
        self.gateway = None
301 37dc17e3 Thomas Thrainer
      else:
302 37dc17e3 Thomas Thrainer
        self.gateway = self.op.gateway
303 37dc17e3 Thomas Thrainer
        if self.pool.IsReserved(self.gateway):
304 37dc17e3 Thomas Thrainer
          raise errors.OpPrereqError("Gateway IP address '%s' is already"
305 37dc17e3 Thomas Thrainer
                                     " reserved" % self.gateway,
306 37dc17e3 Thomas Thrainer
                                     errors.ECODE_STATE)
307 37dc17e3 Thomas Thrainer
308 37dc17e3 Thomas Thrainer
    if self.op.mac_prefix:
309 37dc17e3 Thomas Thrainer
      if self.op.mac_prefix == constants.VALUE_NONE:
310 37dc17e3 Thomas Thrainer
        self.mac_prefix = None
311 37dc17e3 Thomas Thrainer
      else:
312 37dc17e3 Thomas Thrainer
        self.mac_prefix = \
313 37dc17e3 Thomas Thrainer
          utils.NormalizeAndValidateThreeOctetMacPrefix(self.op.mac_prefix)
314 37dc17e3 Thomas Thrainer
315 37dc17e3 Thomas Thrainer
    if self.op.gateway6:
316 37dc17e3 Thomas Thrainer
      if self.op.gateway6 == constants.VALUE_NONE:
317 37dc17e3 Thomas Thrainer
        self.gateway6 = None
318 37dc17e3 Thomas Thrainer
      else:
319 37dc17e3 Thomas Thrainer
        self.gateway6 = self.op.gateway6
320 37dc17e3 Thomas Thrainer
321 37dc17e3 Thomas Thrainer
    if self.op.network6:
322 37dc17e3 Thomas Thrainer
      if self.op.network6 == constants.VALUE_NONE:
323 37dc17e3 Thomas Thrainer
        self.network6 = None
324 37dc17e3 Thomas Thrainer
      else:
325 37dc17e3 Thomas Thrainer
        self.network6 = self.op.network6
326 37dc17e3 Thomas Thrainer
327 37dc17e3 Thomas Thrainer
  def BuildHooksEnv(self):
328 37dc17e3 Thomas Thrainer
    """Build hooks env.
329 37dc17e3 Thomas Thrainer

330 37dc17e3 Thomas Thrainer
    """
331 37dc17e3 Thomas Thrainer
    args = {
332 37dc17e3 Thomas Thrainer
      "name": self.op.network_name,
333 37dc17e3 Thomas Thrainer
      "subnet": self.network.network,
334 37dc17e3 Thomas Thrainer
      "gateway": self.gateway,
335 37dc17e3 Thomas Thrainer
      "network6": self.network6,
336 37dc17e3 Thomas Thrainer
      "gateway6": self.gateway6,
337 37dc17e3 Thomas Thrainer
      "mac_prefix": self.mac_prefix,
338 37dc17e3 Thomas Thrainer
      "tags": self.tags,
339 37dc17e3 Thomas Thrainer
      }
340 37dc17e3 Thomas Thrainer
    return _BuildNetworkHookEnv(**args) # pylint: disable=W0142
341 37dc17e3 Thomas Thrainer
342 37dc17e3 Thomas Thrainer
  def BuildHooksNodes(self):
343 37dc17e3 Thomas Thrainer
    """Build hooks nodes.
344 37dc17e3 Thomas Thrainer

345 37dc17e3 Thomas Thrainer
    """
346 37dc17e3 Thomas Thrainer
    mn = self.cfg.GetMasterNode()
347 37dc17e3 Thomas Thrainer
    return ([mn], [mn])
348 37dc17e3 Thomas Thrainer
349 37dc17e3 Thomas Thrainer
  def Exec(self, feedback_fn):
350 37dc17e3 Thomas Thrainer
    """Modifies the network.
351 37dc17e3 Thomas Thrainer

352 37dc17e3 Thomas Thrainer
    """
353 37dc17e3 Thomas Thrainer
    #TODO: reserve/release via temporary reservation manager
354 37dc17e3 Thomas Thrainer
    #      extend cfg.ReserveIp/ReleaseIp with the external flag
355 37dc17e3 Thomas Thrainer
    if self.op.gateway:
356 37dc17e3 Thomas Thrainer
      if self.gateway == self.network.gateway:
357 37dc17e3 Thomas Thrainer
        self.LogWarning("Gateway is already %s", self.gateway)
358 37dc17e3 Thomas Thrainer
      else:
359 37dc17e3 Thomas Thrainer
        if self.gateway:
360 37dc17e3 Thomas Thrainer
          self.pool.Reserve(self.gateway, external=True)
361 37dc17e3 Thomas Thrainer
        if self.network.gateway:
362 37dc17e3 Thomas Thrainer
          self.pool.Release(self.network.gateway, external=True)
363 37dc17e3 Thomas Thrainer
        self.network.gateway = self.gateway
364 37dc17e3 Thomas Thrainer
365 37dc17e3 Thomas Thrainer
    if self.op.add_reserved_ips:
366 37dc17e3 Thomas Thrainer
      for ip in self.op.add_reserved_ips:
367 37dc17e3 Thomas Thrainer
        try:
368 37dc17e3 Thomas Thrainer
          if self.pool.IsReserved(ip):
369 37dc17e3 Thomas Thrainer
            self.LogWarning("IP address %s is already reserved", ip)
370 37dc17e3 Thomas Thrainer
          else:
371 37dc17e3 Thomas Thrainer
            self.pool.Reserve(ip, external=True)
372 37dc17e3 Thomas Thrainer
        except errors.AddressPoolError, err:
373 37dc17e3 Thomas Thrainer
          self.LogWarning("Cannot reserve IP address %s: %s", ip, err)
374 37dc17e3 Thomas Thrainer
375 37dc17e3 Thomas Thrainer
    if self.op.remove_reserved_ips:
376 37dc17e3 Thomas Thrainer
      for ip in self.op.remove_reserved_ips:
377 37dc17e3 Thomas Thrainer
        if ip == self.network.gateway:
378 37dc17e3 Thomas Thrainer
          self.LogWarning("Cannot unreserve Gateway's IP")
379 37dc17e3 Thomas Thrainer
          continue
380 37dc17e3 Thomas Thrainer
        try:
381 37dc17e3 Thomas Thrainer
          if not self.pool.IsReserved(ip):
382 37dc17e3 Thomas Thrainer
            self.LogWarning("IP address %s is already unreserved", ip)
383 37dc17e3 Thomas Thrainer
          else:
384 37dc17e3 Thomas Thrainer
            self.pool.Release(ip, external=True)
385 37dc17e3 Thomas Thrainer
        except errors.AddressPoolError, err:
386 37dc17e3 Thomas Thrainer
          self.LogWarning("Cannot release IP address %s: %s", ip, err)
387 37dc17e3 Thomas Thrainer
388 37dc17e3 Thomas Thrainer
    if self.op.mac_prefix:
389 37dc17e3 Thomas Thrainer
      self.network.mac_prefix = self.mac_prefix
390 37dc17e3 Thomas Thrainer
391 37dc17e3 Thomas Thrainer
    if self.op.network6:
392 37dc17e3 Thomas Thrainer
      self.network.network6 = self.network6
393 37dc17e3 Thomas Thrainer
394 37dc17e3 Thomas Thrainer
    if self.op.gateway6:
395 37dc17e3 Thomas Thrainer
      self.network.gateway6 = self.gateway6
396 37dc17e3 Thomas Thrainer
397 37dc17e3 Thomas Thrainer
    self.pool.Validate()
398 37dc17e3 Thomas Thrainer
399 37dc17e3 Thomas Thrainer
    self.cfg.Update(self.network, feedback_fn)
400 37dc17e3 Thomas Thrainer
401 37dc17e3 Thomas Thrainer
402 5eacbcae Thomas Thrainer
class NetworkQuery(QueryBase):
403 37dc17e3 Thomas Thrainer
  FIELDS = query.NETWORK_FIELDS
404 37dc17e3 Thomas Thrainer
405 37dc17e3 Thomas Thrainer
  def ExpandNames(self, lu):
406 37dc17e3 Thomas Thrainer
    lu.needed_locks = {}
407 5eacbcae Thomas Thrainer
    lu.share_locks = ShareAll()
408 37dc17e3 Thomas Thrainer
409 37dc17e3 Thomas Thrainer
    self.do_locking = self.use_locking
410 37dc17e3 Thomas Thrainer
411 37dc17e3 Thomas Thrainer
    all_networks = lu.cfg.GetAllNetworksInfo()
412 37dc17e3 Thomas Thrainer
    name_to_uuid = dict((n.name, n.uuid) for n in all_networks.values())
413 37dc17e3 Thomas Thrainer
414 37dc17e3 Thomas Thrainer
    if self.names:
415 37dc17e3 Thomas Thrainer
      missing = []
416 37dc17e3 Thomas Thrainer
      self.wanted = []
417 37dc17e3 Thomas Thrainer
418 37dc17e3 Thomas Thrainer
      for name in self.names:
419 37dc17e3 Thomas Thrainer
        if name in name_to_uuid:
420 37dc17e3 Thomas Thrainer
          self.wanted.append(name_to_uuid[name])
421 37dc17e3 Thomas Thrainer
        else:
422 37dc17e3 Thomas Thrainer
          missing.append(name)
423 37dc17e3 Thomas Thrainer
424 37dc17e3 Thomas Thrainer
      if missing:
425 37dc17e3 Thomas Thrainer
        raise errors.OpPrereqError("Some networks do not exist: %s" % missing,
426 37dc17e3 Thomas Thrainer
                                   errors.ECODE_NOENT)
427 37dc17e3 Thomas Thrainer
    else:
428 37dc17e3 Thomas Thrainer
      self.wanted = locking.ALL_SET
429 37dc17e3 Thomas Thrainer
430 37dc17e3 Thomas Thrainer
    if self.do_locking:
431 37dc17e3 Thomas Thrainer
      lu.needed_locks[locking.LEVEL_NETWORK] = self.wanted
432 37dc17e3 Thomas Thrainer
      if query.NETQ_INST in self.requested_data:
433 37dc17e3 Thomas Thrainer
        lu.needed_locks[locking.LEVEL_INSTANCE] = locking.ALL_SET
434 37dc17e3 Thomas Thrainer
      if query.NETQ_GROUP in self.requested_data:
435 37dc17e3 Thomas Thrainer
        lu.needed_locks[locking.LEVEL_NODEGROUP] = locking.ALL_SET
436 37dc17e3 Thomas Thrainer
437 37dc17e3 Thomas Thrainer
  def DeclareLocks(self, lu, level):
438 37dc17e3 Thomas Thrainer
    pass
439 37dc17e3 Thomas Thrainer
440 37dc17e3 Thomas Thrainer
  def _GetQueryData(self, lu):
441 37dc17e3 Thomas Thrainer
    """Computes the list of networks and their attributes.
442 37dc17e3 Thomas Thrainer

443 37dc17e3 Thomas Thrainer
    """
444 37dc17e3 Thomas Thrainer
    all_networks = lu.cfg.GetAllNetworksInfo()
445 37dc17e3 Thomas Thrainer
446 37dc17e3 Thomas Thrainer
    network_uuids = self._GetNames(lu, all_networks.keys(),
447 37dc17e3 Thomas Thrainer
                                   locking.LEVEL_NETWORK)
448 37dc17e3 Thomas Thrainer
449 37dc17e3 Thomas Thrainer
    do_instances = query.NETQ_INST in self.requested_data
450 37dc17e3 Thomas Thrainer
    do_groups = query.NETQ_GROUP in self.requested_data
451 37dc17e3 Thomas Thrainer
452 37dc17e3 Thomas Thrainer
    network_to_instances = None
453 37dc17e3 Thomas Thrainer
    network_to_groups = None
454 37dc17e3 Thomas Thrainer
455 37dc17e3 Thomas Thrainer
    # For NETQ_GROUP, we need to map network->[groups]
456 37dc17e3 Thomas Thrainer
    if do_groups:
457 37dc17e3 Thomas Thrainer
      all_groups = lu.cfg.GetAllNodeGroupsInfo()
458 37dc17e3 Thomas Thrainer
      network_to_groups = dict((uuid, []) for uuid in network_uuids)
459 37dc17e3 Thomas Thrainer
      for _, group in all_groups.iteritems():
460 37dc17e3 Thomas Thrainer
        for net_uuid in network_uuids:
461 37dc17e3 Thomas Thrainer
          netparams = group.networks.get(net_uuid, None)
462 37dc17e3 Thomas Thrainer
          if netparams:
463 37dc17e3 Thomas Thrainer
            info = (group.name, netparams[constants.NIC_MODE],
464 37dc17e3 Thomas Thrainer
                    netparams[constants.NIC_LINK])
465 37dc17e3 Thomas Thrainer
466 37dc17e3 Thomas Thrainer
            network_to_groups[net_uuid].append(info)
467 37dc17e3 Thomas Thrainer
468 37dc17e3 Thomas Thrainer
    if do_instances:
469 37dc17e3 Thomas Thrainer
      all_instances = lu.cfg.GetAllInstancesInfo()
470 37dc17e3 Thomas Thrainer
      network_to_instances = dict((uuid, []) for uuid in network_uuids)
471 37dc17e3 Thomas Thrainer
      for instance in all_instances.values():
472 37dc17e3 Thomas Thrainer
        for nic in instance.nics:
473 37dc17e3 Thomas Thrainer
          if nic.network in network_uuids:
474 da4a52a3 Thomas Thrainer
            network_to_instances[nic.network].append(instance.uuid)
475 37dc17e3 Thomas Thrainer
            break
476 37dc17e3 Thomas Thrainer
477 37dc17e3 Thomas Thrainer
    if query.NETQ_STATS in self.requested_data:
478 37dc17e3 Thomas Thrainer
      stats = \
479 37dc17e3 Thomas Thrainer
        dict((uuid,
480 37dc17e3 Thomas Thrainer
              self._GetStats(network.AddressPool(all_networks[uuid])))
481 37dc17e3 Thomas Thrainer
             for uuid in network_uuids)
482 37dc17e3 Thomas Thrainer
    else:
483 37dc17e3 Thomas Thrainer
      stats = None
484 37dc17e3 Thomas Thrainer
485 37dc17e3 Thomas Thrainer
    return query.NetworkQueryData([all_networks[uuid]
486 37dc17e3 Thomas Thrainer
                                   for uuid in network_uuids],
487 37dc17e3 Thomas Thrainer
                                   network_to_groups,
488 37dc17e3 Thomas Thrainer
                                   network_to_instances,
489 37dc17e3 Thomas Thrainer
                                   stats)
490 37dc17e3 Thomas Thrainer
491 37dc17e3 Thomas Thrainer
  @staticmethod
492 37dc17e3 Thomas Thrainer
  def _GetStats(pool):
493 37dc17e3 Thomas Thrainer
    """Returns statistics for a network address pool.
494 37dc17e3 Thomas Thrainer

495 37dc17e3 Thomas Thrainer
    """
496 37dc17e3 Thomas Thrainer
    return {
497 37dc17e3 Thomas Thrainer
      "free_count": pool.GetFreeCount(),
498 37dc17e3 Thomas Thrainer
      "reserved_count": pool.GetReservedCount(),
499 37dc17e3 Thomas Thrainer
      "map": pool.GetMap(),
500 37dc17e3 Thomas Thrainer
      "external_reservations":
501 37dc17e3 Thomas Thrainer
        utils.CommaJoin(pool.GetExternalReservations()),
502 37dc17e3 Thomas Thrainer
      }
503 37dc17e3 Thomas Thrainer
504 37dc17e3 Thomas Thrainer
505 37dc17e3 Thomas Thrainer
class LUNetworkQuery(NoHooksLU):
506 37dc17e3 Thomas Thrainer
  """Logical unit for querying networks.
507 37dc17e3 Thomas Thrainer

508 37dc17e3 Thomas Thrainer
  """
509 37dc17e3 Thomas Thrainer
  REQ_BGL = False
510 37dc17e3 Thomas Thrainer
511 37dc17e3 Thomas Thrainer
  def CheckArguments(self):
512 5eacbcae Thomas Thrainer
    self.nq = NetworkQuery(qlang.MakeSimpleFilter("name", self.op.names),
513 37dc17e3 Thomas Thrainer
                            self.op.output_fields, self.op.use_locking)
514 37dc17e3 Thomas Thrainer
515 37dc17e3 Thomas Thrainer
  def ExpandNames(self):
516 37dc17e3 Thomas Thrainer
    self.nq.ExpandNames(self)
517 37dc17e3 Thomas Thrainer
518 37dc17e3 Thomas Thrainer
  def Exec(self, feedback_fn):
519 37dc17e3 Thomas Thrainer
    return self.nq.OldStyleQuery(self)
520 37dc17e3 Thomas Thrainer
521 37dc17e3 Thomas Thrainer
522 37dc17e3 Thomas Thrainer
def _FmtNetworkConflict(details):
523 37dc17e3 Thomas Thrainer
  """Utility for L{_NetworkConflictCheck}.
524 37dc17e3 Thomas Thrainer

525 37dc17e3 Thomas Thrainer
  """
526 37dc17e3 Thomas Thrainer
  return utils.CommaJoin("nic%s/%s" % (idx, ipaddr)
527 37dc17e3 Thomas Thrainer
                         for (idx, ipaddr) in details)
528 37dc17e3 Thomas Thrainer
529 37dc17e3 Thomas Thrainer
530 37dc17e3 Thomas Thrainer
def _NetworkConflictCheck(lu, check_fn, action, instances):
531 37dc17e3 Thomas Thrainer
  """Checks for network interface conflicts with a network.
532 37dc17e3 Thomas Thrainer

533 37dc17e3 Thomas Thrainer
  @type lu: L{LogicalUnit}
534 37dc17e3 Thomas Thrainer
  @type check_fn: callable receiving one parameter (L{objects.NIC}) and
535 37dc17e3 Thomas Thrainer
    returning boolean
536 37dc17e3 Thomas Thrainer
  @param check_fn: Function checking for conflict
537 37dc17e3 Thomas Thrainer
  @type action: string
538 37dc17e3 Thomas Thrainer
  @param action: Part of error message (see code)
539 3fe41221 Klaus Aehlig
  @param instances: the instances to check
540 3fe41221 Klaus Aehlig
  @type instances: list of instance objects
541 37dc17e3 Thomas Thrainer
  @raise errors.OpPrereqError: If conflicting IP addresses are found.
542 37dc17e3 Thomas Thrainer

543 37dc17e3 Thomas Thrainer
  """
544 37dc17e3 Thomas Thrainer
  conflicts = []
545 37dc17e3 Thomas Thrainer
546 da4a52a3 Thomas Thrainer
  for instance in instances:
547 37dc17e3 Thomas Thrainer
    instconflicts = [(idx, nic.ip)
548 37dc17e3 Thomas Thrainer
                     for (idx, nic) in enumerate(instance.nics)
549 37dc17e3 Thomas Thrainer
                     if check_fn(nic)]
550 37dc17e3 Thomas Thrainer
551 37dc17e3 Thomas Thrainer
    if instconflicts:
552 37dc17e3 Thomas Thrainer
      conflicts.append((instance.name, instconflicts))
553 37dc17e3 Thomas Thrainer
554 37dc17e3 Thomas Thrainer
  if conflicts:
555 37dc17e3 Thomas Thrainer
    lu.LogWarning("IP addresses from network '%s', which is about to %s"
556 37dc17e3 Thomas Thrainer
                  " node group '%s', are in use: %s" %
557 37dc17e3 Thomas Thrainer
                  (lu.network_name, action, lu.group.name,
558 37dc17e3 Thomas Thrainer
                   utils.CommaJoin(("%s: %s" %
559 37dc17e3 Thomas Thrainer
                                    (name, _FmtNetworkConflict(details)))
560 37dc17e3 Thomas Thrainer
                                   for (name, details) in conflicts)))
561 37dc17e3 Thomas Thrainer
562 37dc17e3 Thomas Thrainer
    raise errors.OpPrereqError("Conflicting IP addresses found; "
563 37dc17e3 Thomas Thrainer
                               " remove/modify the corresponding network"
564 37dc17e3 Thomas Thrainer
                               " interfaces", errors.ECODE_STATE)
565 37dc17e3 Thomas Thrainer
566 37dc17e3 Thomas Thrainer
567 37dc17e3 Thomas Thrainer
class LUNetworkConnect(LogicalUnit):
568 37dc17e3 Thomas Thrainer
  """Connect a network to a nodegroup
569 37dc17e3 Thomas Thrainer

570 37dc17e3 Thomas Thrainer
  """
571 37dc17e3 Thomas Thrainer
  HPATH = "network-connect"
572 37dc17e3 Thomas Thrainer
  HTYPE = constants.HTYPE_NETWORK
573 37dc17e3 Thomas Thrainer
  REQ_BGL = False
574 37dc17e3 Thomas Thrainer
575 37dc17e3 Thomas Thrainer
  def ExpandNames(self):
576 37dc17e3 Thomas Thrainer
    self.network_name = self.op.network_name
577 37dc17e3 Thomas Thrainer
    self.group_name = self.op.group_name
578 37dc17e3 Thomas Thrainer
    self.network_mode = self.op.network_mode
579 37dc17e3 Thomas Thrainer
    self.network_link = self.op.network_link
580 37dc17e3 Thomas Thrainer
581 37dc17e3 Thomas Thrainer
    self.network_uuid = self.cfg.LookupNetwork(self.network_name)
582 37dc17e3 Thomas Thrainer
    self.group_uuid = self.cfg.LookupNodeGroup(self.group_name)
583 37dc17e3 Thomas Thrainer
584 37dc17e3 Thomas Thrainer
    self.needed_locks = {
585 37dc17e3 Thomas Thrainer
      locking.LEVEL_INSTANCE: [],
586 37dc17e3 Thomas Thrainer
      locking.LEVEL_NODEGROUP: [self.group_uuid],
587 37dc17e3 Thomas Thrainer
      }
588 37dc17e3 Thomas Thrainer
    self.share_locks[locking.LEVEL_INSTANCE] = 1
589 37dc17e3 Thomas Thrainer
590 37dc17e3 Thomas Thrainer
    if self.op.conflicts_check:
591 37dc17e3 Thomas Thrainer
      self.needed_locks[locking.LEVEL_NETWORK] = [self.network_uuid]
592 37dc17e3 Thomas Thrainer
      self.share_locks[locking.LEVEL_NETWORK] = 1
593 37dc17e3 Thomas Thrainer
594 37dc17e3 Thomas Thrainer
  def DeclareLocks(self, level):
595 37dc17e3 Thomas Thrainer
    if level == locking.LEVEL_INSTANCE:
596 37dc17e3 Thomas Thrainer
      assert not self.needed_locks[locking.LEVEL_INSTANCE]
597 37dc17e3 Thomas Thrainer
598 37dc17e3 Thomas Thrainer
      # Lock instances optimistically, needs verification once group lock has
599 37dc17e3 Thomas Thrainer
      # been acquired
600 37dc17e3 Thomas Thrainer
      if self.op.conflicts_check:
601 37dc17e3 Thomas Thrainer
        self.needed_locks[locking.LEVEL_INSTANCE] = \
602 da4a52a3 Thomas Thrainer
          self.cfg.GetInstanceNames(
603 da4a52a3 Thomas Thrainer
            self.cfg.GetNodeGroupInstances(self.group_uuid))
604 37dc17e3 Thomas Thrainer
605 37dc17e3 Thomas Thrainer
  def BuildHooksEnv(self):
606 37dc17e3 Thomas Thrainer
    ret = {
607 37dc17e3 Thomas Thrainer
      "GROUP_NAME": self.group_name,
608 37dc17e3 Thomas Thrainer
      "GROUP_NETWORK_MODE": self.network_mode,
609 37dc17e3 Thomas Thrainer
      "GROUP_NETWORK_LINK": self.network_link,
610 37dc17e3 Thomas Thrainer
      }
611 37dc17e3 Thomas Thrainer
    return ret
612 37dc17e3 Thomas Thrainer
613 37dc17e3 Thomas Thrainer
  def BuildHooksNodes(self):
614 1c3231aa Thomas Thrainer
    node_uuids = self.cfg.GetNodeGroup(self.group_uuid).members
615 1c3231aa Thomas Thrainer
    return (node_uuids, node_uuids)
616 37dc17e3 Thomas Thrainer
617 37dc17e3 Thomas Thrainer
  def CheckPrereq(self):
618 37dc17e3 Thomas Thrainer
    owned_groups = frozenset(self.owned_locks(locking.LEVEL_NODEGROUP))
619 37dc17e3 Thomas Thrainer
620 37dc17e3 Thomas Thrainer
    assert self.group_uuid in owned_groups
621 37dc17e3 Thomas Thrainer
622 37dc17e3 Thomas Thrainer
    # Check if locked instances are still correct
623 da4a52a3 Thomas Thrainer
    owned_instance_names = frozenset(self.owned_locks(locking.LEVEL_INSTANCE))
624 37dc17e3 Thomas Thrainer
    if self.op.conflicts_check:
625 da4a52a3 Thomas Thrainer
      CheckNodeGroupInstances(self.cfg, self.group_uuid, owned_instance_names)
626 37dc17e3 Thomas Thrainer
627 37dc17e3 Thomas Thrainer
    self.netparams = {
628 37dc17e3 Thomas Thrainer
      constants.NIC_MODE: self.network_mode,
629 37dc17e3 Thomas Thrainer
      constants.NIC_LINK: self.network_link,
630 37dc17e3 Thomas Thrainer
      }
631 37dc17e3 Thomas Thrainer
    objects.NIC.CheckParameterSyntax(self.netparams)
632 37dc17e3 Thomas Thrainer
633 37dc17e3 Thomas Thrainer
    self.group = self.cfg.GetNodeGroup(self.group_uuid)
634 37dc17e3 Thomas Thrainer
    #if self.network_mode == constants.NIC_MODE_BRIDGED:
635 37dc17e3 Thomas Thrainer
    #  _CheckNodeGroupBridgesExist(self, self.network_link, self.group_uuid)
636 37dc17e3 Thomas Thrainer
    self.connected = False
637 37dc17e3 Thomas Thrainer
    if self.network_uuid in self.group.networks:
638 37dc17e3 Thomas Thrainer
      self.LogWarning("Network '%s' is already mapped to group '%s'" %
639 37dc17e3 Thomas Thrainer
                      (self.network_name, self.group.name))
640 37dc17e3 Thomas Thrainer
      self.connected = True
641 37dc17e3 Thomas Thrainer
642 37dc17e3 Thomas Thrainer
    # check only if not already connected
643 37dc17e3 Thomas Thrainer
    elif self.op.conflicts_check:
644 37dc17e3 Thomas Thrainer
      pool = network.AddressPool(self.cfg.GetNetwork(self.network_uuid))
645 37dc17e3 Thomas Thrainer
646 da4a52a3 Thomas Thrainer
      _NetworkConflictCheck(
647 da4a52a3 Thomas Thrainer
        self, lambda nic: pool.Contains(nic.ip), "connect to",
648 3fe41221 Klaus Aehlig
        [instance_info for (_, instance_info) in
649 3fe41221 Klaus Aehlig
         self.cfg.GetMultiInstanceInfoByName(owned_instance_names)])
650 37dc17e3 Thomas Thrainer
651 37dc17e3 Thomas Thrainer
  def Exec(self, feedback_fn):
652 37dc17e3 Thomas Thrainer
    # Connect the network and update the group only if not already connected
653 37dc17e3 Thomas Thrainer
    if not self.connected:
654 37dc17e3 Thomas Thrainer
      self.group.networks[self.network_uuid] = self.netparams
655 37dc17e3 Thomas Thrainer
      self.cfg.Update(self.group, feedback_fn)
656 37dc17e3 Thomas Thrainer
657 37dc17e3 Thomas Thrainer
658 37dc17e3 Thomas Thrainer
class LUNetworkDisconnect(LogicalUnit):
659 37dc17e3 Thomas Thrainer
  """Disconnect a network to a nodegroup
660 37dc17e3 Thomas Thrainer

661 37dc17e3 Thomas Thrainer
  """
662 37dc17e3 Thomas Thrainer
  HPATH = "network-disconnect"
663 37dc17e3 Thomas Thrainer
  HTYPE = constants.HTYPE_NETWORK
664 37dc17e3 Thomas Thrainer
  REQ_BGL = False
665 37dc17e3 Thomas Thrainer
666 37dc17e3 Thomas Thrainer
  def ExpandNames(self):
667 37dc17e3 Thomas Thrainer
    self.network_name = self.op.network_name
668 37dc17e3 Thomas Thrainer
    self.group_name = self.op.group_name
669 37dc17e3 Thomas Thrainer
670 37dc17e3 Thomas Thrainer
    self.network_uuid = self.cfg.LookupNetwork(self.network_name)
671 37dc17e3 Thomas Thrainer
    self.group_uuid = self.cfg.LookupNodeGroup(self.group_name)
672 37dc17e3 Thomas Thrainer
673 37dc17e3 Thomas Thrainer
    self.needed_locks = {
674 37dc17e3 Thomas Thrainer
      locking.LEVEL_INSTANCE: [],
675 37dc17e3 Thomas Thrainer
      locking.LEVEL_NODEGROUP: [self.group_uuid],
676 37dc17e3 Thomas Thrainer
      }
677 37dc17e3 Thomas Thrainer
    self.share_locks[locking.LEVEL_INSTANCE] = 1
678 37dc17e3 Thomas Thrainer
679 37dc17e3 Thomas Thrainer
  def DeclareLocks(self, level):
680 37dc17e3 Thomas Thrainer
    if level == locking.LEVEL_INSTANCE:
681 37dc17e3 Thomas Thrainer
      assert not self.needed_locks[locking.LEVEL_INSTANCE]
682 37dc17e3 Thomas Thrainer
683 37dc17e3 Thomas Thrainer
      # Lock instances optimistically, needs verification once group lock has
684 37dc17e3 Thomas Thrainer
      # been acquired
685 37dc17e3 Thomas Thrainer
      self.needed_locks[locking.LEVEL_INSTANCE] = \
686 da4a52a3 Thomas Thrainer
        self.cfg.GetInstanceNames(
687 da4a52a3 Thomas Thrainer
          self.cfg.GetNodeGroupInstances(self.group_uuid))
688 37dc17e3 Thomas Thrainer
689 37dc17e3 Thomas Thrainer
  def BuildHooksEnv(self):
690 37dc17e3 Thomas Thrainer
    ret = {
691 37dc17e3 Thomas Thrainer
      "GROUP_NAME": self.group_name,
692 37dc17e3 Thomas Thrainer
      }
693 37dc17e3 Thomas Thrainer
    return ret
694 37dc17e3 Thomas Thrainer
695 37dc17e3 Thomas Thrainer
  def BuildHooksNodes(self):
696 37dc17e3 Thomas Thrainer
    nodes = self.cfg.GetNodeGroup(self.group_uuid).members
697 37dc17e3 Thomas Thrainer
    return (nodes, nodes)
698 37dc17e3 Thomas Thrainer
699 37dc17e3 Thomas Thrainer
  def CheckPrereq(self):
700 37dc17e3 Thomas Thrainer
    owned_groups = frozenset(self.owned_locks(locking.LEVEL_NODEGROUP))
701 37dc17e3 Thomas Thrainer
702 37dc17e3 Thomas Thrainer
    assert self.group_uuid in owned_groups
703 37dc17e3 Thomas Thrainer
704 37dc17e3 Thomas Thrainer
    # Check if locked instances are still correct
705 37dc17e3 Thomas Thrainer
    owned_instances = frozenset(self.owned_locks(locking.LEVEL_INSTANCE))
706 5eacbcae Thomas Thrainer
    CheckNodeGroupInstances(self.cfg, self.group_uuid, owned_instances)
707 37dc17e3 Thomas Thrainer
708 37dc17e3 Thomas Thrainer
    self.group = self.cfg.GetNodeGroup(self.group_uuid)
709 37dc17e3 Thomas Thrainer
    self.connected = True
710 37dc17e3 Thomas Thrainer
    if self.network_uuid not in self.group.networks:
711 37dc17e3 Thomas Thrainer
      self.LogWarning("Network '%s' is not mapped to group '%s'",
712 37dc17e3 Thomas Thrainer
                      self.network_name, self.group.name)
713 37dc17e3 Thomas Thrainer
      self.connected = False
714 37dc17e3 Thomas Thrainer
715 37dc17e3 Thomas Thrainer
    # We need this check only if network is not already connected
716 37dc17e3 Thomas Thrainer
    else:
717 da4a52a3 Thomas Thrainer
      _NetworkConflictCheck(
718 da4a52a3 Thomas Thrainer
        self, lambda nic: nic.network == self.network_uuid, "disconnect from",
719 32449822 Dimitris Aragiorgis
        [instance_info for (_, instance_info) in
720 32449822 Dimitris Aragiorgis
        self.cfg.GetMultiInstanceInfoByName(owned_instances)])
721 37dc17e3 Thomas Thrainer
722 37dc17e3 Thomas Thrainer
  def Exec(self, feedback_fn):
723 37dc17e3 Thomas Thrainer
    # Disconnect the network and update the group only if network is connected
724 37dc17e3 Thomas Thrainer
    if self.connected:
725 37dc17e3 Thomas Thrainer
      del self.group.networks[self.network_uuid]
726 37dc17e3 Thomas Thrainer
      self.cfg.Update(self.group, feedback_fn)