Revision cafa5b70

b/lib/cmdlib.py
57 57
from ganeti import query
58 58
from ganeti import qlang
59 59
from ganeti import opcodes
60
from ganeti import network
60 61

  
61 62
import ganeti.masterd.instance # pylint: disable-msg=W0611
62 63

  
......
11873 11874
    return result
11874 11875

  
11875 11876

  
11877
# Network LUs
11878
class LUNetworkAdd(LogicalUnit):
11879
  """Logical unit for creating node groups.
11880

  
11881
  """
11882
  HPATH = "network-add"
11883
  HTYPE = constants.HTYPE_NETWORK
11884
  REQ_BGL = False
11885

  
11886
  def ExpandNames(self):
11887
    self.needed_locks = {
11888
      locking.LEVEL_NODE: locking.ALL_SET,
11889
    }
11890
    self.share_locks[locking.LEVEL_NODE] = 1
11891

  
11892
  def CheckPrereq(self):
11893
    """Check prerequisites.
11894

  
11895
    This checks that the given group name is not an existing node group
11896
    already.
11897

  
11898
    """
11899
    try:
11900
      uuid = self.cfg.LookupNetwork(self.op.network_name)
11901
    except errors.OpPrereqError:
11902
      uuid = None
11903

  
11904
    if uuid is not None:
11905
      raise errors.OpPrereqError("Network '%s' already defined" %
11906
                                 self.op.network, errors.ECODE_EXISTS)
11907

  
11908
  def BuildHooksEnv(self):
11909
    """Build hooks env.
11910

  
11911
    """
11912
    env = {
11913
      "NETWORK_NAME": self.op.network_name,
11914
      "NETWORK_SUBNET": self.op.network,
11915
      "NETWORK_GATEWAY": self.op.gateway,
11916
      }
11917
    mn = self.cfg.GetMasterNode()
11918
    return env, [mn], [mn]
11919

  
11920
  def Exec(self, feedback_fn):
11921
    """Add the ip pool to the cluster.
11922

  
11923
    """
11924
    #FIXME: error handling
11925
    nobj = objects.Network(name=self.op.network_name,
11926
                           network=self.op.network,
11927
                           gateway=self.op.gateway,
11928
                           family=4)
11929

  
11930
    # Initialize the associated address pool
11931
    pool = network.AddressPool.InitializeNetwork(nobj)
11932

  
11933
    # Check if we need to reserve the nodes and the cluster master IP
11934
    # These may not be allocated to any instances in routed mode, as
11935
    # they wouldn't function anyway.
11936
    for node in self.cfg.GetAllNodesInfo().values():
11937
      for ip in [node.primary_ip, node.secondary_ip]:
11938
        try:
11939
          pool.Reserve(ip)
11940
          self.LogInfo("Reserved node %s's IP (%s)", node.name, ip)
11941

  
11942
        except errors.AddressPoolError:
11943
          pass
11944

  
11945
    master_ip = self.cfg.GetClusterInfo().master_ip
11946
    try:
11947
      pool.Reserve(master_ip)
11948
      self.LogInfo("Reserved cluster master IP (%s)", master_ip)
11949
    except errors.AddressPoolError:
11950
      pass
11951

  
11952
    if self.op.reserved_ips:
11953
      for ip in self.op.reserved_ips:
11954
        pool.Reserve(ip, external=True)
11955

  
11956
    self.cfg.AddNetwork(nobj, self.proc.GetECId())
11957

  
11958

  
11959
class _NetworkQuery(_QueryBase):
11960
  FIELDS = query.NETWORK_FIELDS
11961

  
11962
  def ExpandNames(self, lu):
11963
    lu.needed_locks = {}
11964

  
11965
    self._all_networks = lu.cfg.GetAllNetworksInfo()
11966
    name_to_uuid = dict((n.name, n.uuid) for n in self._all_networks.values())
11967

  
11968
    if not self.names:
11969
      self.wanted = [name_to_uuid[name]
11970
                     for name in utils.NiceSort(name_to_uuid.keys())]
11971
    else:
11972
      # Accept names to be either names or UUIDs.
11973
      missing = []
11974
      self.wanted = []
11975
      all_uuid = frozenset(self._all_networks.keys())
11976

  
11977
      for name in self.names:
11978
        if name in all_uuid:
11979
          self.wanted.append(name)
11980
        elif name in name_to_uuid:
11981
          self.wanted.append(name_to_uuid[name])
11982
        else:
11983
          missing.append(name)
11984

  
11985
      if missing:
11986
        raise errors.OpPrereqError("Some networks do not exist: %s" % missing,
11987
                                   errors.ECODE_NOENT)
11988

  
11989
  def DeclareLocks(self, lu, level):
11990
    pass
11991

  
11992
  def _GetQueryData(self, lu):
11993
    """Computes the list of networks and their attributes.
11994

  
11995
    """
11996
    do_instances = query.NETQ_INST in self.requested_data
11997
    do_groups = do_instances or (query.NETQ_GROUP in self.requested_data)
11998
    do_stats = query.NETQ_STATS in self.requested_data
11999

  
12000
    network_to_groups = None
12001
    network_to_instances = None
12002
    stats = None
12003

  
12004
    # For NETQ_GROUP, we need to map network->[groups]
12005
    if do_groups:
12006
      all_groups = lu.cfg.GetAllNodeGroupsInfo()
12007
      network_to_groups = dict((uuid, []) for uuid in self.wanted)
12008

  
12009
      if do_instances:
12010
        all_instances = lu.cfg.GetAllInstancesInfo()
12011
        all_nodes = lu.cfg.GetAllNodesInfo()
12012
        network_to_instances = dict((uuid, []) for uuid in self.wanted)
12013

  
12014
      for group in all_groups.values():
12015
        if do_instances:
12016
          group_nodes = [node.name for node in all_nodes.values() if
12017
                         node.group == group.uuid]
12018
          group_instances = [instance for instance in all_instances.values()
12019
                             if instance.primary_node in group_nodes]
12020

  
12021
        for uuid, link in group.networks.items():
12022
          if uuid in network_to_groups:
12023
            network_to_groups[uuid].append(":".join((group.name, link)))
12024

  
12025
            if do_instances:
12026
              for instance in group_instances:
12027
                for nic in instance.nics:
12028
                  if nic.nicparams.get(constants.NIC_LINK, None) == link:
12029
                    network_to_instances[uuid].append(instance.name)
12030
                    break
12031

  
12032
    if do_stats:
12033
      stats = {}
12034
      for uuid, net in self._all_networks.items():
12035
        if uuid in self.wanted:
12036
          pool = network.AddressPool(net)
12037
          stats[uuid] = {
12038
            "free_count": pool.GetFreeCount(),
12039
            "reserved_count": pool.GetReservedCount(),
12040
            "map": pool.GetMap(),
12041
            }
12042

  
12043
    return query.NetworkQueryData([self._all_networks[uuid]
12044
                                   for uuid in self.wanted],
12045
                                   network_to_groups,
12046
                                   network_to_instances,
12047
                                   stats)
12048

  
12049

  
12050
class LUNetworkQuery(NoHooksLU):
12051
  """Logical unit for querying node groups.
12052

  
12053
  """
12054
  REQ_BGL = False
12055

  
12056
  def CheckArguments(self):
12057
    self.nq = _NetworkQuery(self.op.names, self.op.output_fields, False)
12058

  
12059
  def ExpandNames(self):
12060
    self.nq.ExpandNames(self)
12061

  
12062
  def Exec(self, feedback_fn):
12063
    return self.nq.OldStyleQuery(self)
12064

  
12065

  
11876 12066
#: Query type implementations
11877 12067
_QUERY_IMPL = {
11878 12068
  constants.QR_INSTANCE: _InstanceQuery,
11879 12069
  constants.QR_NODE: _NodeQuery,
11880 12070
  constants.QR_GROUP: _GroupQuery,
12071
  constants.QR_NETWORK: _NetworkQuery,
11881 12072
  }
11882 12073

  
11883 12074

  
b/lib/constants.py
314 314
HTYPE_NODE = "NODE"
315 315
HTYPE_GROUP = "GROUP"
316 316
HTYPE_INSTANCE = "INSTANCE"
317
HTYPE_NETWORK = "NETWORK"
317 318

  
318 319
HKR_SKIP = 0
319 320
HKR_FAIL = 1
......
1014 1015
QR_NODE = "node"
1015 1016
QR_LOCK = "lock"
1016 1017
QR_GROUP = "group"
1018
QR_NETWORK = "network"
1017 1019

  
1018 1020
#: List of resources which can be queried using L{opcodes.OpQuery}
1019
QR_OP_QUERY = frozenset([QR_INSTANCE, QR_NODE, QR_GROUP])
1021
QR_OP_QUERY = frozenset([QR_INSTANCE, QR_NODE, QR_GROUP, QR_NETWORK])
1020 1022

  
1021 1023
#: List of resources which can be queried using Local UniX Interface
1022 1024
QR_OP_LUXI = QR_OP_QUERY.union([

Also available in: Unified diff