commit 37dc17e328a32c69bad9d58e072e53505e842ab3
Author: Thomas Thrainer <thomasth@google.com>
Date:   Mon May 13 11:38:08 2013 +0200

    Extract network related logical units from cmdlib
    
    LUNetwork* and associated helper functions are extracted to network.py.
    
    Signed-off-by: Thomas Thrainer <thomasth@google.com>
    Reviewed-by: Bernardo Dal Seno <bdalseno@google.com>

diff --git a/lib/cmdlib/__init__.py b/lib/cmdlib/__init__.py
index c3148af..88aa001 100644
--- a/lib/cmdlib/__init__.py
+++ b/lib/cmdlib/__init__.py
@@ -66,8 +66,11 @@ from ganeti.masterd import iallocator
 from ganeti.cmdlib.base import ResultWithJobs, LogicalUnit, NoHooksLU, \
   Tasklet, _QueryBase
 from ganeti.cmdlib.common import _ExpandInstanceName, _ExpandItemName, \
-  _ExpandNodeName, _ShareAll
+  _ExpandNodeName, _ShareAll, _CheckNodeGroupInstances
 from ganeti.cmdlib.tags import LUTagsGet, LUTagsSearch, LUTagsSet, LUTagsDel
+from ganeti.cmdlib.network import LUNetworkAdd, LUNetworkRemove, \
+  LUNetworkSetParams, _NetworkQuery, LUNetworkQuery, LUNetworkConnect, \
+  LUNetworkDisconnect
 
 import ganeti.masterd.instance # pylint: disable=W0611
 
@@ -153,30 +156,6 @@ def _CheckInstanceNodeGroups(cfg, instance_name, owned_groups,
   return inst_groups
 
 
-def _CheckNodeGroupInstances(cfg, group_uuid, owned_instances):
-  """Checks if the instances in a node group are still correct.
-
-  @type cfg: L{config.ConfigWriter}
-  @param cfg: The cluster configuration
-  @type group_uuid: string
-  @param group_uuid: Node group UUID
-  @type owned_instances: set or frozenset
-  @param owned_instances: List of currently owned instances
-
-  """
-  wanted_instances = cfg.GetNodeGroupInstances(group_uuid)
-  if owned_instances != wanted_instances:
-    raise errors.OpPrereqError("Instances in node group '%s' changed since"
-                               " locks were acquired, wanted '%s', have '%s';"
-                               " retry the operation" %
-                               (group_uuid,
-                                utils.CommaJoin(wanted_instances),
-                                utils.CommaJoin(owned_instances)),
-                               errors.ECODE_STATE)
-
-  return wanted_instances
-
-
 def _SupportsOob(cfg, node):
   """Tells if node supports OOB.
 
@@ -898,47 +877,6 @@ def _ComputeNewInstanceViolations(old_ipolicy, new_ipolicy, instances, cfg):
           _ComputeViolatingInstances(old_ipolicy, instances, cfg))
 
 
-def _BuildNetworkHookEnv(name, subnet, gateway, network6, gateway6,
-                         mac_prefix, tags):
-  """Builds network related env variables for hooks
-
-  This builds the hook environment from individual variables.
-
-  @type name: string
-  @param name: the name of the network
-  @type subnet: string
-  @param subnet: the ipv4 subnet
-  @type gateway: string
-  @param gateway: the ipv4 gateway
-  @type network6: string
-  @param network6: the ipv6 subnet
-  @type gateway6: string
-  @param gateway6: the ipv6 gateway
-  @type mac_prefix: string
-  @param mac_prefix: the mac_prefix
-  @type tags: list
-  @param tags: the tags of the network
-
-  """
-  env = {}
-  if name:
-    env["NETWORK_NAME"] = name
-  if subnet:
-    env["NETWORK_SUBNET"] = subnet
-  if gateway:
-    env["NETWORK_GATEWAY"] = gateway
-  if network6:
-    env["NETWORK_SUBNET6"] = network6
-  if gateway6:
-    env["NETWORK_GATEWAY6"] = gateway6
-  if mac_prefix:
-    env["NETWORK_MAC_PREFIX"] = mac_prefix
-  if tags:
-    env["NETWORK_TAGS"] = " ".join(tags)
-
-  return env
-
-
 def _BuildInstanceHookEnv(name, primary_node, secondary_nodes, os_type, status,
                           minmem, maxmem, vcpus, nics, disk_template, disks,
                           bep, hvp, hypervisor_name, tags):
@@ -15715,650 +15653,6 @@ class LUTestAllocator(NoHooksLU):
     return result
 
 
-class LUNetworkAdd(LogicalUnit):
-  """Logical unit for creating networks.
-
-  """
-  HPATH = "network-add"
-  HTYPE = constants.HTYPE_NETWORK
-  REQ_BGL = False
-
-  def BuildHooksNodes(self):
-    """Build hooks nodes.
-
-    """
-    mn = self.cfg.GetMasterNode()
-    return ([mn], [mn])
-
-  def CheckArguments(self):
-    if self.op.mac_prefix:
-      self.op.mac_prefix = \
-        utils.NormalizeAndValidateThreeOctetMacPrefix(self.op.mac_prefix)
-
-  def ExpandNames(self):
-    self.network_uuid = self.cfg.GenerateUniqueID(self.proc.GetECId())
-
-    if self.op.conflicts_check:
-      self.share_locks[locking.LEVEL_NODE] = 1
-      self.share_locks[locking.LEVEL_NODE_ALLOC] = 1
-      self.needed_locks = {
-        locking.LEVEL_NODE: locking.ALL_SET,
-        locking.LEVEL_NODE_ALLOC: locking.ALL_SET,
-        }
-    else:
-      self.needed_locks = {}
-
-    self.add_locks[locking.LEVEL_NETWORK] = self.network_uuid
-
-  def CheckPrereq(self):
-    if self.op.network is None:
-      raise errors.OpPrereqError("Network must be given",
-                                 errors.ECODE_INVAL)
-
-    try:
-      existing_uuid = self.cfg.LookupNetwork(self.op.network_name)
-    except errors.OpPrereqError:
-      pass
-    else:
-      raise errors.OpPrereqError("Desired network name '%s' already exists as a"
-                                 " network (UUID: %s)" %
-                                 (self.op.network_name, existing_uuid),
-                                 errors.ECODE_EXISTS)
-
-    # Check tag validity
-    for tag in self.op.tags:
-      objects.TaggableObject.ValidateTag(tag)
-
-  def BuildHooksEnv(self):
-    """Build hooks env.
-
-    """
-    args = {
-      "name": self.op.network_name,
-      "subnet": self.op.network,
-      "gateway": self.op.gateway,
-      "network6": self.op.network6,
-      "gateway6": self.op.gateway6,
-      "mac_prefix": self.op.mac_prefix,
-      "tags": self.op.tags,
-      }
-    return _BuildNetworkHookEnv(**args) # pylint: disable=W0142
-
-  def Exec(self, feedback_fn):
-    """Add the ip pool to the cluster.
-
-    """
-    nobj = objects.Network(name=self.op.network_name,
-                           network=self.op.network,
-                           gateway=self.op.gateway,
-                           network6=self.op.network6,
-                           gateway6=self.op.gateway6,
-                           mac_prefix=self.op.mac_prefix,
-                           uuid=self.network_uuid)
-    # Initialize the associated address pool
-    try:
-      pool = network.AddressPool.InitializeNetwork(nobj)
-    except errors.AddressPoolError, err:
-      raise errors.OpExecError("Cannot create IP address pool for network"
-                               " '%s': %s" % (self.op.network_name, err))
-
-    # Check if we need to reserve the nodes and the cluster master IP
-    # These may not be allocated to any instances in routed mode, as
-    # they wouldn't function anyway.
-    if self.op.conflicts_check:
-      for node in self.cfg.GetAllNodesInfo().values():
-        for ip in [node.primary_ip, node.secondary_ip]:
-          try:
-            if pool.Contains(ip):
-              pool.Reserve(ip)
-              self.LogInfo("Reserved IP address of node '%s' (%s)",
-                           node.name, ip)
-          except errors.AddressPoolError, err:
-            self.LogWarning("Cannot reserve IP address '%s' of node '%s': %s",
-                            ip, node.name, err)
-
-      master_ip = self.cfg.GetClusterInfo().master_ip
-      try:
-        if pool.Contains(master_ip):
-          pool.Reserve(master_ip)
-          self.LogInfo("Reserved cluster master IP address (%s)", master_ip)
-      except errors.AddressPoolError, err:
-        self.LogWarning("Cannot reserve cluster master IP address (%s): %s",
-                        master_ip, err)
-
-    if self.op.add_reserved_ips:
-      for ip in self.op.add_reserved_ips:
-        try:
-          pool.Reserve(ip, external=True)
-        except errors.AddressPoolError, err:
-          raise errors.OpExecError("Cannot reserve IP address '%s': %s" %
-                                   (ip, err))
-
-    if self.op.tags:
-      for tag in self.op.tags:
-        nobj.AddTag(tag)
-
-    self.cfg.AddNetwork(nobj, self.proc.GetECId(), check_uuid=False)
-    del self.remove_locks[locking.LEVEL_NETWORK]
-
-
-class LUNetworkRemove(LogicalUnit):
-  HPATH = "network-remove"
-  HTYPE = constants.HTYPE_NETWORK
-  REQ_BGL = False
-
-  def ExpandNames(self):
-    self.network_uuid = self.cfg.LookupNetwork(self.op.network_name)
-
-    self.share_locks[locking.LEVEL_NODEGROUP] = 1
-    self.needed_locks = {
-      locking.LEVEL_NETWORK: [self.network_uuid],
-      locking.LEVEL_NODEGROUP: locking.ALL_SET,
-      }
-
-  def CheckPrereq(self):
-    """Check prerequisites.
-
-    This checks that the given network name exists as a network, that is
-    empty (i.e., contains no nodes), and that is not the last group of the
-    cluster.
-
-    """
-    # Verify that the network is not conncted.
-    node_groups = [group.name
-                   for group in self.cfg.GetAllNodeGroupsInfo().values()
-                   if self.network_uuid in group.networks]
-
-    if node_groups:
-      self.LogWarning("Network '%s' is connected to the following"
-                      " node groups: %s" %
-                      (self.op.network_name,
-                       utils.CommaJoin(utils.NiceSort(node_groups))))
-      raise errors.OpPrereqError("Network still connected", errors.ECODE_STATE)
-
-  def BuildHooksEnv(self):
-    """Build hooks env.
-
-    """
-    return {
-      "NETWORK_NAME": self.op.network_name,
-      }
-
-  def BuildHooksNodes(self):
-    """Build hooks nodes.
-
-    """
-    mn = self.cfg.GetMasterNode()
-    return ([mn], [mn])
-
-  def Exec(self, feedback_fn):
-    """Remove the network.
-
-    """
-    try:
-      self.cfg.RemoveNetwork(self.network_uuid)
-    except errors.ConfigurationError:
-      raise errors.OpExecError("Network '%s' with UUID %s disappeared" %
-                               (self.op.network_name, self.network_uuid))
-
-
-class LUNetworkSetParams(LogicalUnit):
-  """Modifies the parameters of a network.
-
-  """
-  HPATH = "network-modify"
-  HTYPE = constants.HTYPE_NETWORK
-  REQ_BGL = False
-
-  def CheckArguments(self):
-    if (self.op.gateway and
-        (self.op.add_reserved_ips or self.op.remove_reserved_ips)):
-      raise errors.OpPrereqError("Cannot modify gateway and reserved ips"
-                                 " at once", errors.ECODE_INVAL)
-
-  def ExpandNames(self):
-    self.network_uuid = self.cfg.LookupNetwork(self.op.network_name)
-
-    self.needed_locks = {
-      locking.LEVEL_NETWORK: [self.network_uuid],
-      }
-
-  def CheckPrereq(self):
-    """Check prerequisites.
-
-    """
-    self.network = self.cfg.GetNetwork(self.network_uuid)
-    self.gateway = self.network.gateway
-    self.mac_prefix = self.network.mac_prefix
-    self.network6 = self.network.network6
-    self.gateway6 = self.network.gateway6
-    self.tags = self.network.tags
-
-    self.pool = network.AddressPool(self.network)
-
-    if self.op.gateway:
-      if self.op.gateway == constants.VALUE_NONE:
-        self.gateway = None
-      else:
-        self.gateway = self.op.gateway
-        if self.pool.IsReserved(self.gateway):
-          raise errors.OpPrereqError("Gateway IP address '%s' is already"
-                                     " reserved" % self.gateway,
-                                     errors.ECODE_STATE)
-
-    if self.op.mac_prefix:
-      if self.op.mac_prefix == constants.VALUE_NONE:
-        self.mac_prefix = None
-      else:
-        self.mac_prefix = \
-          utils.NormalizeAndValidateThreeOctetMacPrefix(self.op.mac_prefix)
-
-    if self.op.gateway6:
-      if self.op.gateway6 == constants.VALUE_NONE:
-        self.gateway6 = None
-      else:
-        self.gateway6 = self.op.gateway6
-
-    if self.op.network6:
-      if self.op.network6 == constants.VALUE_NONE:
-        self.network6 = None
-      else:
-        self.network6 = self.op.network6
-
-  def BuildHooksEnv(self):
-    """Build hooks env.
-
-    """
-    args = {
-      "name": self.op.network_name,
-      "subnet": self.network.network,
-      "gateway": self.gateway,
-      "network6": self.network6,
-      "gateway6": self.gateway6,
-      "mac_prefix": self.mac_prefix,
-      "tags": self.tags,
-      }
-    return _BuildNetworkHookEnv(**args) # pylint: disable=W0142
-
-  def BuildHooksNodes(self):
-    """Build hooks nodes.
-
-    """
-    mn = self.cfg.GetMasterNode()
-    return ([mn], [mn])
-
-  def Exec(self, feedback_fn):
-    """Modifies the network.
-
-    """
-    #TODO: reserve/release via temporary reservation manager
-    #      extend cfg.ReserveIp/ReleaseIp with the external flag
-    if self.op.gateway:
-      if self.gateway == self.network.gateway:
-        self.LogWarning("Gateway is already %s", self.gateway)
-      else:
-        if self.gateway:
-          self.pool.Reserve(self.gateway, external=True)
-        if self.network.gateway:
-          self.pool.Release(self.network.gateway, external=True)
-        self.network.gateway = self.gateway
-
-    if self.op.add_reserved_ips:
-      for ip in self.op.add_reserved_ips:
-        try:
-          if self.pool.IsReserved(ip):
-            self.LogWarning("IP address %s is already reserved", ip)
-          else:
-            self.pool.Reserve(ip, external=True)
-        except errors.AddressPoolError, err:
-          self.LogWarning("Cannot reserve IP address %s: %s", ip, err)
-
-    if self.op.remove_reserved_ips:
-      for ip in self.op.remove_reserved_ips:
-        if ip == self.network.gateway:
-          self.LogWarning("Cannot unreserve Gateway's IP")
-          continue
-        try:
-          if not self.pool.IsReserved(ip):
-            self.LogWarning("IP address %s is already unreserved", ip)
-          else:
-            self.pool.Release(ip, external=True)
-        except errors.AddressPoolError, err:
-          self.LogWarning("Cannot release IP address %s: %s", ip, err)
-
-    if self.op.mac_prefix:
-      self.network.mac_prefix = self.mac_prefix
-
-    if self.op.network6:
-      self.network.network6 = self.network6
-
-    if self.op.gateway6:
-      self.network.gateway6 = self.gateway6
-
-    self.pool.Validate()
-
-    self.cfg.Update(self.network, feedback_fn)
-
-
-class _NetworkQuery(_QueryBase):
-  FIELDS = query.NETWORK_FIELDS
-
-  def ExpandNames(self, lu):
-    lu.needed_locks = {}
-    lu.share_locks = _ShareAll()
-
-    self.do_locking = self.use_locking
-
-    all_networks = lu.cfg.GetAllNetworksInfo()
-    name_to_uuid = dict((n.name, n.uuid) for n in all_networks.values())
-
-    if self.names:
-      missing = []
-      self.wanted = []
-
-      for name in self.names:
-        if name in name_to_uuid:
-          self.wanted.append(name_to_uuid[name])
-        else:
-          missing.append(name)
-
-      if missing:
-        raise errors.OpPrereqError("Some networks do not exist: %s" % missing,
-                                   errors.ECODE_NOENT)
-    else:
-      self.wanted = locking.ALL_SET
-
-    if self.do_locking:
-      lu.needed_locks[locking.LEVEL_NETWORK] = self.wanted
-      if query.NETQ_INST in self.requested_data:
-        lu.needed_locks[locking.LEVEL_INSTANCE] = locking.ALL_SET
-      if query.NETQ_GROUP in self.requested_data:
-        lu.needed_locks[locking.LEVEL_NODEGROUP] = locking.ALL_SET
-
-  def DeclareLocks(self, lu, level):
-    pass
-
-  def _GetQueryData(self, lu):
-    """Computes the list of networks and their attributes.
-
-    """
-    all_networks = lu.cfg.GetAllNetworksInfo()
-
-    network_uuids = self._GetNames(lu, all_networks.keys(),
-                                   locking.LEVEL_NETWORK)
-
-    do_instances = query.NETQ_INST in self.requested_data
-    do_groups = query.NETQ_GROUP in self.requested_data
-
-    network_to_instances = None
-    network_to_groups = None
-
-    # For NETQ_GROUP, we need to map network->[groups]
-    if do_groups:
-      all_groups = lu.cfg.GetAllNodeGroupsInfo()
-      network_to_groups = dict((uuid, []) for uuid in network_uuids)
-      for _, group in all_groups.iteritems():
-        for net_uuid in network_uuids:
-          netparams = group.networks.get(net_uuid, None)
-          if netparams:
-            info = (group.name, netparams[constants.NIC_MODE],
-                    netparams[constants.NIC_LINK])
-
-            network_to_groups[net_uuid].append(info)
-
-    if do_instances:
-      all_instances = lu.cfg.GetAllInstancesInfo()
-      network_to_instances = dict((uuid, []) for uuid in network_uuids)
-      for instance in all_instances.values():
-        for nic in instance.nics:
-          if nic.network in network_uuids:
-            network_to_instances[nic.network].append(instance.name)
-            break
-
-    if query.NETQ_STATS in self.requested_data:
-      stats = \
-        dict((uuid,
-              self._GetStats(network.AddressPool(all_networks[uuid])))
-             for uuid in network_uuids)
-    else:
-      stats = None
-
-    return query.NetworkQueryData([all_networks[uuid]
-                                   for uuid in network_uuids],
-                                   network_to_groups,
-                                   network_to_instances,
-                                   stats)
-
-  @staticmethod
-  def _GetStats(pool):
-    """Returns statistics for a network address pool.
-
-    """
-    return {
-      "free_count": pool.GetFreeCount(),
-      "reserved_count": pool.GetReservedCount(),
-      "map": pool.GetMap(),
-      "external_reservations":
-        utils.CommaJoin(pool.GetExternalReservations()),
-      }
-
-
-class LUNetworkQuery(NoHooksLU):
-  """Logical unit for querying networks.
-
-  """
-  REQ_BGL = False
-
-  def CheckArguments(self):
-    self.nq = _NetworkQuery(qlang.MakeSimpleFilter("name", self.op.names),
-                            self.op.output_fields, self.op.use_locking)
-
-  def ExpandNames(self):
-    self.nq.ExpandNames(self)
-
-  def Exec(self, feedback_fn):
-    return self.nq.OldStyleQuery(self)
-
-
-class LUNetworkConnect(LogicalUnit):
-  """Connect a network to a nodegroup
-
-  """
-  HPATH = "network-connect"
-  HTYPE = constants.HTYPE_NETWORK
-  REQ_BGL = False
-
-  def ExpandNames(self):
-    self.network_name = self.op.network_name
-    self.group_name = self.op.group_name
-    self.network_mode = self.op.network_mode
-    self.network_link = self.op.network_link
-
-    self.network_uuid = self.cfg.LookupNetwork(self.network_name)
-    self.group_uuid = self.cfg.LookupNodeGroup(self.group_name)
-
-    self.needed_locks = {
-      locking.LEVEL_INSTANCE: [],
-      locking.LEVEL_NODEGROUP: [self.group_uuid],
-      }
-    self.share_locks[locking.LEVEL_INSTANCE] = 1
-
-    if self.op.conflicts_check:
-      self.needed_locks[locking.LEVEL_NETWORK] = [self.network_uuid]
-      self.share_locks[locking.LEVEL_NETWORK] = 1
-
-  def DeclareLocks(self, level):
-    if level == locking.LEVEL_INSTANCE:
-      assert not self.needed_locks[locking.LEVEL_INSTANCE]
-
-      # Lock instances optimistically, needs verification once group lock has
-      # been acquired
-      if self.op.conflicts_check:
-        self.needed_locks[locking.LEVEL_INSTANCE] = \
-            self.cfg.GetNodeGroupInstances(self.group_uuid)
-
-  def BuildHooksEnv(self):
-    ret = {
-      "GROUP_NAME": self.group_name,
-      "GROUP_NETWORK_MODE": self.network_mode,
-      "GROUP_NETWORK_LINK": self.network_link,
-      }
-    return ret
-
-  def BuildHooksNodes(self):
-    nodes = self.cfg.GetNodeGroup(self.group_uuid).members
-    return (nodes, nodes)
-
-  def CheckPrereq(self):
-    owned_groups = frozenset(self.owned_locks(locking.LEVEL_NODEGROUP))
-
-    assert self.group_uuid in owned_groups
-
-    # Check if locked instances are still correct
-    owned_instances = frozenset(self.owned_locks(locking.LEVEL_INSTANCE))
-    if self.op.conflicts_check:
-      _CheckNodeGroupInstances(self.cfg, self.group_uuid, owned_instances)
-
-    self.netparams = {
-      constants.NIC_MODE: self.network_mode,
-      constants.NIC_LINK: self.network_link,
-      }
-    objects.NIC.CheckParameterSyntax(self.netparams)
-
-    self.group = self.cfg.GetNodeGroup(self.group_uuid)
-    #if self.network_mode == constants.NIC_MODE_BRIDGED:
-    #  _CheckNodeGroupBridgesExist(self, self.network_link, self.group_uuid)
-    self.connected = False
-    if self.network_uuid in self.group.networks:
-      self.LogWarning("Network '%s' is already mapped to group '%s'" %
-                      (self.network_name, self.group.name))
-      self.connected = True
-
-    # check only if not already connected
-    elif self.op.conflicts_check:
-      pool = network.AddressPool(self.cfg.GetNetwork(self.network_uuid))
-
-      _NetworkConflictCheck(self, lambda nic: pool.Contains(nic.ip),
-                            "connect to", owned_instances)
-
-  def Exec(self, feedback_fn):
-    # Connect the network and update the group only if not already connected
-    if not self.connected:
-      self.group.networks[self.network_uuid] = self.netparams
-      self.cfg.Update(self.group, feedback_fn)
-
-
-def _NetworkConflictCheck(lu, check_fn, action, instances):
-  """Checks for network interface conflicts with a network.
-
-  @type lu: L{LogicalUnit}
-  @type check_fn: callable receiving one parameter (L{objects.NIC}) and
-    returning boolean
-  @param check_fn: Function checking for conflict
-  @type action: string
-  @param action: Part of error message (see code)
-  @raise errors.OpPrereqError: If conflicting IP addresses are found.
-
-  """
-  conflicts = []
-
-  for (_, instance) in lu.cfg.GetMultiInstanceInfo(instances):
-    instconflicts = [(idx, nic.ip)
-                     for (idx, nic) in enumerate(instance.nics)
-                     if check_fn(nic)]
-
-    if instconflicts:
-      conflicts.append((instance.name, instconflicts))
-
-  if conflicts:
-    lu.LogWarning("IP addresses from network '%s', which is about to %s"
-                  " node group '%s', are in use: %s" %
-                  (lu.network_name, action, lu.group.name,
-                   utils.CommaJoin(("%s: %s" %
-                                    (name, _FmtNetworkConflict(details)))
-                                   for (name, details) in conflicts)))
-
-    raise errors.OpPrereqError("Conflicting IP addresses found; "
-                               " remove/modify the corresponding network"
-                               " interfaces", errors.ECODE_STATE)
-
-
-def _FmtNetworkConflict(details):
-  """Utility for L{_NetworkConflictCheck}.
-
-  """
-  return utils.CommaJoin("nic%s/%s" % (idx, ipaddr)
-                         for (idx, ipaddr) in details)
-
-
-class LUNetworkDisconnect(LogicalUnit):
-  """Disconnect a network to a nodegroup
-
-  """
-  HPATH = "network-disconnect"
-  HTYPE = constants.HTYPE_NETWORK
-  REQ_BGL = False
-
-  def ExpandNames(self):
-    self.network_name = self.op.network_name
-    self.group_name = self.op.group_name
-
-    self.network_uuid = self.cfg.LookupNetwork(self.network_name)
-    self.group_uuid = self.cfg.LookupNodeGroup(self.group_name)
-
-    self.needed_locks = {
-      locking.LEVEL_INSTANCE: [],
-      locking.LEVEL_NODEGROUP: [self.group_uuid],
-      }
-    self.share_locks[locking.LEVEL_INSTANCE] = 1
-
-  def DeclareLocks(self, level):
-    if level == locking.LEVEL_INSTANCE:
-      assert not self.needed_locks[locking.LEVEL_INSTANCE]
-
-      # Lock instances optimistically, needs verification once group lock has
-      # been acquired
-      self.needed_locks[locking.LEVEL_INSTANCE] = \
-        self.cfg.GetNodeGroupInstances(self.group_uuid)
-
-  def BuildHooksEnv(self):
-    ret = {
-      "GROUP_NAME": self.group_name,
-      }
-    return ret
-
-  def BuildHooksNodes(self):
-    nodes = self.cfg.GetNodeGroup(self.group_uuid).members
-    return (nodes, nodes)
-
-  def CheckPrereq(self):
-    owned_groups = frozenset(self.owned_locks(locking.LEVEL_NODEGROUP))
-
-    assert self.group_uuid in owned_groups
-
-    # Check if locked instances are still correct
-    owned_instances = frozenset(self.owned_locks(locking.LEVEL_INSTANCE))
-    _CheckNodeGroupInstances(self.cfg, self.group_uuid, owned_instances)
-
-    self.group = self.cfg.GetNodeGroup(self.group_uuid)
-    self.connected = True
-    if self.network_uuid not in self.group.networks:
-      self.LogWarning("Network '%s' is not mapped to group '%s'",
-                      self.network_name, self.group.name)
-      self.connected = False
-
-    # We need this check only if network is not already connected
-    else:
-      _NetworkConflictCheck(self, lambda nic: nic.network == self.network_uuid,
-                            "disconnect from", owned_instances)
-
-  def Exec(self, feedback_fn):
-    # Disconnect the network and update the group only if network is connected
-    if self.connected:
-      del self.group.networks[self.network_uuid]
-      self.cfg.Update(self.group, feedback_fn)
-
-
 #: Query type implementations
 _QUERY_IMPL = {
   constants.QR_CLUSTER: _ClusterQuery,
