Revision 34a51ae9

b/lib/cmdlib.py
40 40
import shutil
41 41
import itertools
42 42
import operator
43
import ipaddr
43 44

  
44 45
from ganeti import ssh
45 46
from ganeti import utils
......
60 61
from ganeti import ht
61 62
from ganeti import rpc
62 63
from ganeti import runtime
64
from ganeti import network
63 65

  
64 66
import ganeti.masterd.instance # pylint: disable=W0611
65 67

  
......
15342 15344

  
15343 15345
# Network LUs
15344 15346
class LUNetworkAdd(LogicalUnit):
15345
  pass
15347
  """Logical unit for creating node groups.
15348

  
15349
  """
15350
  HPATH = "network-add"
15351
  HTYPE = constants.HTYPE_NETWORK
15352
  REQ_BGL = False
15353

  
15354
  def BuildHooksNodes(self):
15355
    """Build hooks nodes.
15356

  
15357
    """
15358
    mn = self.cfg.GetMasterNode()
15359
    return ([mn], [mn])
15360

  
15361
  def ExpandNames(self):
15362
    self.needed_locks = {
15363
      locking.LEVEL_NODE: locking.ALL_SET,
15364
    }
15365
    self.share_locks[locking.LEVEL_NODE] = 1
15366

  
15367
  def CheckPrereq(self):
15368
    """Check prerequisites.
15369

  
15370
    This checks that the given group name is not an existing node group
15371
    already.
15372

  
15373
    """
15374
    if self.op.network is None:
15375
      raise errors.OpPrereqError("Network must be given",
15376
                                 errors.ECODE_INVAL)
15377

  
15378
    uuid = self.cfg.LookupNetwork(self.op.network_name)
15379

  
15380
    if uuid:
15381
      raise errors.OpPrereqError("Network '%s' already defined" %
15382
                                 self.op.network, errors.ECODE_EXISTS)
15383

  
15384
    if (self.op.network_type and
15385
        self.op.network_type not in constants.NETWORK_VALID_TYPES):
15386
      raise errors.OpPrereqError("Invalid network type", errors.ECODE_INVAL)
15387

  
15388
    self.mac_prefix = None
15389
    if self.op.mac_prefix:
15390
      if self.op.mac_prefix == constants.VALUE_NONE:
15391
        self.mac_prefix = None
15392
      else:
15393
        self.mac_prefix = self.op.mac_prefix
15394

  
15395
    if self.op.network6:
15396
      ipaddr.IPv6Network(self.op.network6)
15397

  
15398
    if self.op.gateway6:
15399
      ipaddr.IPv6Address(self.op.gateway6)
15400

  
15401
  def BuildHooksEnv(self):
15402
    """Build hooks env.
15403

  
15404
    """
15405
    env = {
15406
      "NETWORK_NAME": self.op.network_name,
15407
      "NETWORK_SUBNET": self.op.network,
15408
      "NETWORK_GATEWAY": self.op.gateway,
15409
      "NETWORK_SUBNET6": self.op.network6,
15410
      "NETWORK_GATEWAY6": self.op.gateway6,
15411
      "NETWORK_MAC_PREFIX": self.mac_prefix,
15412
      "NETWORK_TYPE": self.op.network_type,
15413
      }
15414
    return env
15415

  
15416
  def Exec(self, feedback_fn):
15417
    """Add the ip pool to the cluster.
15418

  
15419
    """
15420
    nobj = objects.Network(name=self.op.network_name,
15421
                           network=self.op.network,
15422
                           gateway=self.op.gateway,
15423
                           network6=self.op.network6,
15424
                           gateway6=self.op.gateway6,
15425
                           mac_prefix=self.mac_prefix,
15426
                           network_type=self.op.network_type,
15427
                           family=4)
15428
    # Initialize the associated address pool
15429
    try:
15430
      pool = network.AddressPool.InitializeNetwork(nobj)
15431
    except:
15432
      raise errors.OpExecError("Cannot create IP pool for this network",
15433
                               errors.ECODE_INVAL)
15434

  
15435
    # Check if we need to reserve the nodes and the cluster master IP
15436
    # These may not be allocated to any instances in routed mode, as
15437
    # they wouldn't function anyway.
15438
    for node in self.cfg.GetAllNodesInfo().values():
15439
      for ip in [node.primary_ip, node.secondary_ip]:
15440
        try:
15441
          pool.Reserve(ip)
15442
          self.LogInfo("Reserved node %s's IP (%s)", node.name, ip)
15443

  
15444
        except errors.AddressPoolError:
15445
          pass
15446

  
15447
    master_ip = self.cfg.GetClusterInfo().master_ip
15448
    try:
15449
      pool.Reserve(master_ip)
15450
      self.LogInfo("Reserved cluster master IP (%s)", master_ip)
15451
    except errors.AddressPoolError:
15452
      pass
15453

  
15454
    if self.op.reserved_ips:
15455
      for ip in self.op.reserved_ips:
15456
        try:
15457
          pool.Reserve(ip, external=True)
15458
        except:
15459
          raise errors.OpExecError("Cannot reserve IP %s " % ip,
15460
                                   errors.ECODE_INVAL)
15461

  
15462
    self.cfg.AddNetwork(nobj, self.proc.GetECId())
15346 15463

  
15347 15464
class LUNetworkRemove(LogicalUnit):
15348
  pass
15465
  HPATH = "network-remove"
15466
  HTYPE = constants.HTYPE_NETWORK
15467
  REQ_BGL = False
15468

  
15469
  def ExpandNames(self):
15470
    self.network_uuid = self.cfg.LookupNetwork(self.op.network_name)
15471

  
15472
    self.needed_locks = {
15473
      locking.LEVEL_NODE: locking.ALL_SET,
15474
      }
15475
    self.share_locks[locking.LEVEL_NODE] = 1
15476

  
15477
  def CheckPrereq(self):
15478
    """Check prerequisites.
15479

  
15480
    This checks that the given network name exists as a network, that is
15481
    empty (i.e., contains no nodes), and that is not the last group of the
15482
    cluster.
15483

  
15484
    """
15485
    if not self.network_uuid:
15486
      raise errors.OpPrereqError("Network %s not found" % self.op.network_name,
15487
                                 errors.ECODE_INVAL)
15488

  
15489
    # Verify that the network is not conncted.
15490
    node_groups = [group.name
15491
                   for group in self.cfg.GetAllNodeGroupsInfo().values()
15492
                   for network in group.networks.keys()
15493
                   if network == self.network_uuid]
15494

  
15495
    if node_groups:
15496
      self.LogWarning("Nework '%s' is connected to the following"
15497
                      " node groups: %s" % (self.op.network_name,
15498
                      utils.CommaJoin(utils.NiceSort(node_groups))))
15499
      raise errors.OpPrereqError("Network still connected",
15500
                                 errors.ECODE_STATE)
15501

  
15502
  def BuildHooksEnv(self):
15503
    """Build hooks env.
15504

  
15505
    """
15506
    return {
15507
      "NETWORK_NAME": self.op.network_name,
15508
      }
15509

  
15510
  def BuildHooksNodes(self):
15511
    """Build hooks nodes.
15512

  
15513
    """
15514
    mn = self.cfg.GetMasterNode()
15515
    return ([mn], [mn])
15516

  
15517
  def Exec(self, feedback_fn):
15518
    """Remove the network.
15519

  
15520
    """
15521
    try:
15522
      self.cfg.RemoveNetwork(self.network_uuid)
15523
    except errors.ConfigurationError:
15524
      raise errors.OpExecError("Network '%s' with UUID %s disappeared" %
15525
                               (self.op.network_name, self.network_uuid))
15526

  
15349 15527

  
15350 15528
class LUNetworkSetParams(LogicalUnit):
15351 15529
  pass
b/lib/config.py
50 50
from ganeti import uidpool
51 51
from ganeti import netutils
52 52
from ganeti import runtime
53
from ganeti import network
53 54

  
54 55

  
55 56
_config_lock = locking.SharedLock("ConfigWriter")
......
2093 2094
    nodegroups = ["%s %s" % (nodegroup.uuid, nodegroup.name) for nodegroup in
2094 2095
                  self._config_data.nodegroups.values()]
2095 2096
    nodegroups_data = fn(utils.NiceSort(nodegroups))
2097
    networks = ["%s %s" % (net.uuid, net.name) for net in
2098
                self._config_data.networks.values()]
2099
    networks_data = fn(utils.NiceSort(networks))
2096 2100

  
2097 2101
    ssconf_values = {
2098 2102
      constants.SS_CLUSTER_NAME: cluster.cluster_name,
......
2117 2121
      constants.SS_MAINTAIN_NODE_HEALTH: str(cluster.maintain_node_health),
2118 2122
      constants.SS_UID_POOL: uid_pool,
2119 2123
      constants.SS_NODEGROUPS: nodegroups_data,
2124
      constants.SS_NETWORKS: networks_data,
2120 2125
      }
2121 2126
    bad_values = [(k, v) for k, v in ssconf_values.items()
2122 2127
                  if not isinstance(v, (str, basestring))]
......
2244 2249
    """
2245 2250
    for rm in self._all_rms:
2246 2251
      rm.DropECReservations(ec_id)
2252

  
2253
  @locking.ssynchronized(_config_lock)
2254
  def AddNetwork(self, net, ec_id):
2255
    """Add a network to the configuration.
2256

  
2257
    @type net: L{objects.Network}
2258
    @param net: the Network object to add
2259
    @type ec_id: string
2260
    @param ec_id: unique id for the job to use when creating a missing UUID
2261

  
2262
    """
2263
    self._UnlockedAddNetwork(net, ec_id)
2264
    self._WriteConfig()
2265

  
2266
  def _UnlockedAddNetwork(self, net, ec_id):
2267
    """Add a network to the configuration.
2268

  
2269
    """
2270
    logging.info("Adding network %s to configuration", net.name)
2271

  
2272
    self._EnsureUUID(net, ec_id)
2273

  
2274
    existing_uuid = self._UnlockedLookupNetwork(net.name)
2275
    if existing_uuid:
2276
      raise errors.OpPrereqError("Desired network name '%s' already"
2277
                                 " exists as a network (UUID: %s)" %
2278
                                 (net.name, existing_uuid),
2279
                                 errors.ECODE_EXISTS)
2280
    net.serial_no = 1
2281
    self._config_data.networks[net.uuid] = net
2282
    self._config_data.cluster.serial_no += 1
2283

  
2284
  def _UnlockedLookupNetwork(self, target):
2285
    """Lookup a network's UUID.
2286

  
2287
    @type target: string
2288
    @param target: network name or UUID
2289
    @rtype: string
2290
    @return: network UUID
2291
    @raises errors.OpPrereqError: when the target network cannot be found
2292

  
2293
    """
2294
    if target in self._config_data.networks:
2295
      return target
2296
    for net in self._config_data.networks.values():
2297
      if net.name == target:
2298
        return net.uuid
2299
    return None
2300

  
2301
  @locking.ssynchronized(_config_lock, shared=1)
2302
  def LookupNetwork(self, target):
2303
    """Lookup a network's UUID.
2304

  
2305
    This function is just a wrapper over L{_UnlockedLookupNetwork}.
2306

  
2307
    @type target: string
2308
    @param target: network name or UUID
2309
    @rtype: string
2310
    @return: network UUID
2311

  
2312
    """
2313
    return self._UnlockedLookupNetwork(target)
2314

  
2315
  @locking.ssynchronized(_config_lock)
2316
  def RemoveNetwork(self, network_uuid):
2317
    """Remove a network from the configuration.
2318

  
2319
    @type network_uuid: string
2320
    @param network_uuid: the UUID of the network to remove
2321

  
2322
    """
2323
    logging.info("Removing network %s from configuration", network_uuid)
2324

  
2325
    if network_uuid not in self._config_data.networks:
2326
      raise errors.ConfigurationError("Unknown network '%s'" % network_uuid)
2327

  
2328
    del self._config_data.networks[network_uuid]
2329
    self._config_data.cluster.serial_no += 1
2330
    self._WriteConfig()

Also available in: Unified diff