#
#

# Copyright (C) 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013 Google Inc.
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful, but
# WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
# General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
# 02110-1301, USA.

"""Node related commands"""

# pylint: disable=W0401,W0613,W0614,C0103
# W0401: Wildcard import ganeti.cli
# W0613: Unused argument, since all functions follow the same API
# W0614: Unused import %s from wildcard import (since we need cli)
# C0103: Invalid name gnt-node

import itertools
import errno

from ganeti.cli import *
from ganeti import cli
from ganeti import bootstrap
from ganeti import opcodes
from ganeti import utils
from ganeti import constants
from ganeti import errors
from ganeti import netutils
from ganeti import pathutils
from ganeti import ssh
from ganeti import compat

from ganeti import confd
from ganeti.confd import client as confd_client

#: default list of field for L{ListNodes}
_LIST_DEF_FIELDS = [
  "name", "dtotal", "dfree",
  "mtotal", "mnode", "mfree",
  "pinst_cnt", "sinst_cnt",
  ]


#: Default field list for L{ListVolumes}
_LIST_VOL_DEF_FIELDS = ["node", "phys", "vg", "name", "size", "instance"]


#: default list of field for L{ListStorage}
_LIST_STOR_DEF_FIELDS = [
  constants.SF_NODE,
  constants.SF_TYPE,
  constants.SF_NAME,
  constants.SF_SIZE,
  constants.SF_USED,
  constants.SF_FREE,
  constants.SF_ALLOCATABLE,
  ]


#: default list of power commands
_LIST_POWER_COMMANDS = ["on", "off", "cycle", "status"]


#: headers (and full field list) for L{ListStorage}
_LIST_STOR_HEADERS = {
  constants.SF_NODE: "Node",
  constants.SF_TYPE: "Type",
  constants.SF_NAME: "Name",
  constants.SF_SIZE: "Size",
  constants.SF_USED: "Used",
  constants.SF_FREE: "Free",
  constants.SF_ALLOCATABLE: "Allocatable",
  }


#: User-facing storage unit types
_USER_STORAGE_TYPE = {
  constants.ST_FILE: "file",
  constants.ST_LVM_PV: "lvm-pv",
  constants.ST_LVM_VG: "lvm-vg",
  }

_STORAGE_TYPE_OPT = \
  cli_option("-t", "--storage-type",
             dest="user_storage_type",
             choices=_USER_STORAGE_TYPE.keys(),
             default=None,
             metavar="STORAGE_TYPE",
             help=("Storage type (%s)" %
                   utils.CommaJoin(_USER_STORAGE_TYPE.keys())))

_REPAIRABLE_STORAGE_TYPES = \
  [st for st, so in constants.VALID_STORAGE_OPERATIONS.iteritems()
   if constants.SO_FIX_CONSISTENCY in so]

_MODIFIABLE_STORAGE_TYPES = constants.MODIFIABLE_STORAGE_FIELDS.keys()

_OOB_COMMAND_ASK = compat.UniqueFrozenset([
  constants.OOB_POWER_OFF,
  constants.OOB_POWER_CYCLE,
  ])

_ENV_OVERRIDE = compat.UniqueFrozenset(["list"])

NONODE_SETUP_OPT = cli_option("--no-node-setup", default=True,
                              action="store_false", dest="node_setup",
                              help=("Do not make initial SSH setup on remote"
                                    " node (needs to be done manually)"))

IGNORE_STATUS_OPT = cli_option("--ignore-status", default=False,
                               action="store_true", dest="ignore_status",
                               help=("Ignore the Node(s) offline status"
                                     " (potentially DANGEROUS)"))


def ConvertStorageType(user_storage_type):
  """Converts a user storage type to its internal name.

  """
  try:
    return _USER_STORAGE_TYPE[user_storage_type]
  except KeyError:
    raise errors.OpPrereqError("Unknown storage type: %s" % user_storage_type,
                               errors.ECODE_INVAL)


def _TryReadFile(path):
  """Tries to read a file.

  If the file is not found, C{None} is returned.

  @type path: string
  @param path: Filename
  @rtype: None or string
  @todo: Consider adding a generic ENOENT wrapper

  """
  try:
    return utils.ReadFile(path)
  except EnvironmentError, err:
    if err.errno == errno.ENOENT:
      return None
    else:
      raise


def _ReadSshKeys(keyfiles, _tostderr_fn=ToStderr):
  """Reads SSH keys according to C{keyfiles}.

  @type keyfiles: dict
  @param keyfiles: Dictionary with keys of L{constants.SSHK_ALL} and two-values
    tuples (private and public key file)
  @rtype: list
  @return: List of three-values tuples (L{constants.SSHK_ALL}, private and
    public key as strings)

  """
  result = []

  for (kind, (private_file, public_file)) in keyfiles.items():
    private_key = _TryReadFile(private_file)
    public_key = _TryReadFile(public_file)

    if public_key and private_key:
      result.append((kind, private_key, public_key))
    elif public_key or private_key:
      _tostderr_fn("Couldn't find a complete set of keys for kind '%s'; files"
                   " '%s' and '%s'", kind, private_file, public_file)

  return result


def _SetupSSH(options, cluster_name, node):
  """Configures a destination node's SSH daemon.

  @param options: Command line options
  @type cluster_name
  @param cluster_name: Cluster name
  @type node: string
  @param node: Destination node name

  """
  if options.force_join:
    ToStderr("The \"--force-join\" option is no longer supported and will be"
             " ignored.")

  host_keys = _ReadSshKeys(constants.SSH_DAEMON_KEYFILES)

  (_, root_keyfiles) = \
    ssh.GetAllUserFiles(constants.SSH_LOGIN_USER, mkdir=False, dircheck=False)

  root_keys = _ReadSshKeys(root_keyfiles)

  (_, cert_pem) = \
    utils.ExtractX509Certificate(utils.ReadFile(pathutils.NODED_CERT_FILE))

  data = {
    constants.SSHS_CLUSTER_NAME: cluster_name,
    constants.SSHS_NODE_DAEMON_CERTIFICATE: cert_pem,
    constants.SSHS_SSH_HOST_KEY: host_keys,
    constants.SSHS_SSH_ROOT_KEY: root_keys,
    }

  bootstrap.RunNodeSetupCmd(cluster_name, node, pathutils.PREPARE_NODE_JOIN,
                            options.debug, options.verbose, False,
                            options.ssh_key_check, options.ssh_key_check, data)


@UsesRPC
def AddNode(opts, args):
  """Add a node to the cluster.

  @param opts: the command line options selected by the user
  @type args: list
  @param args: should contain only one element, the new node name
  @rtype: int
  @return: the desired exit code

  """
  cl = GetClient()
  node = netutils.GetHostname(name=args[0]).name
  readd = opts.readd

  try:
    output = cl.QueryNodes(names=[node], fields=["name", "sip", "master"],
                           use_locking=False)
    node_exists, sip, is_master = output[0]
  except (errors.OpPrereqError, errors.OpExecError):
    node_exists = ""
    sip = None

  if readd:
    if not node_exists:
      ToStderr("Node %s not in the cluster"
               " - please retry without '--readd'", node)
      return 1
    if is_master:
      ToStderr("Node %s is the master, cannot readd", node)
      return 1
  else:
    if node_exists:
      ToStderr("Node %s already in the cluster (as %s)"
               " - please retry with '--readd'", node, node_exists)
      return 1
    sip = opts.secondary_ip

  # read the cluster name from the master
  (cluster_name, ) = cl.QueryConfigValues(["cluster_name"])

  if not readd and opts.node_setup:
    ToStderr("-- WARNING -- \n"
             "Performing this operation is going to replace the ssh daemon"
             " keypair\n"
             "on the target machine (%s) with the ones of the"
             " current one\n"
             "and grant full intra-cluster ssh root access to/from it\n", node)

  if opts.node_setup:
    _SetupSSH(opts, cluster_name, node)

  bootstrap.SetupNodeDaemon(opts, cluster_name, node)

  if opts.disk_state:
    disk_state = utils.FlatToDict(opts.disk_state)
  else:
    disk_state = {}

  hv_state = dict(opts.hv_state)

  op = opcodes.OpNodeAdd(node_name=args[0], secondary_ip=sip,
                         readd=opts.readd, group=opts.nodegroup,
                         vm_capable=opts.vm_capable, ndparams=opts.ndparams,
                         master_capable=opts.master_capable,
                         disk_state=disk_state,
                         hv_state=hv_state)
  SubmitOpCode(op, opts=opts)


def ListNodes(opts, args):
  """List nodes and their properties.

  @param opts: the command line options selected by the user
  @type args: list
  @param args: nodes to list, or empty for all
  @rtype: int
  @return: the desired exit code

  """
  selected_fields = ParseFields(opts.output, _LIST_DEF_FIELDS)

  fmtoverride = dict.fromkeys(["pinst_list", "sinst_list", "tags"],
                              (",".join, False))

  cl = GetClient(query=True)

  return GenericList(constants.QR_NODE, selected_fields, args, opts.units,
                     opts.separator, not opts.no_headers,
                     format_override=fmtoverride, verbose=opts.verbose,
                     force_filter=opts.force_filter, cl=cl)


def ListNodeFields(opts, args):
  """List node fields.

  @param opts: the command line options selected by the user
  @type args: list
  @param args: fields to list, or empty for all
  @rtype: int
  @return: the desired exit code

  """
  cl = GetClient(query=True)

  return GenericListFields(constants.QR_NODE, args, opts.separator,
                           not opts.no_headers, cl=cl)


def EvacuateNode(opts, args):
  """Relocate all secondary instance from a node.

  @param opts: the command line options selected by the user
  @type args: list
  @param args: should be an empty list
  @rtype: int
  @return: the desired exit code

  """
  if opts.dst_node is not None:
    ToStderr("New secondary node given (disabling iallocator), hence evacuating"
             " secondary instances only.")
    opts.secondary_only = True
    opts.primary_only = False

  if opts.secondary_only and opts.primary_only:
    raise errors.OpPrereqError("Only one of the --primary-only and"
                               " --secondary-only options can be passed",
                               errors.ECODE_INVAL)
  elif opts.primary_only:
    mode = constants.NODE_EVAC_PRI
  elif opts.secondary_only:
    mode = constants.NODE_EVAC_SEC
  else:
    mode = constants.NODE_EVAC_ALL

  # Determine affected instances
  fields = []

  if not opts.secondary_only:
    fields.append("pinst_list")
  if not opts.primary_only:
    fields.append("sinst_list")

  cl = GetClient()

  qcl = GetClient(query=True)
  result = qcl.QueryNodes(names=args, fields=fields, use_locking=False)
  qcl.Close()

  instances = set(itertools.chain(*itertools.chain(*itertools.chain(result))))

  if not instances:
    # No instances to evacuate
    ToStderr("No instances to evacuate on node(s) %s, exiting.",
             utils.CommaJoin(args))
    return constants.EXIT_SUCCESS

  if not (opts.force or
          AskUser("Relocate instance(s) %s from node(s) %s?" %
                  (utils.CommaJoin(utils.NiceSort(instances)),
                   utils.CommaJoin(args)))):
    return constants.EXIT_CONFIRMATION

  # Evacuate node
  op = opcodes.OpNodeEvacuate(node_name=args[0], mode=mode,
                              remote_node=opts.dst_node,
                              iallocator=opts.iallocator,
                              early_release=opts.early_release)
  result = SubmitOrSend(op, opts, cl=cl)

  # Keep track of submitted jobs
  jex = JobExecutor(cl=cl, opts=opts)

  for (status, job_id) in result[constants.JOB_IDS_KEY]:
    jex.AddJobId(None, status, job_id)

  results = jex.GetResults()
  bad_cnt = len([row for row in results if not row[0]])
  if bad_cnt == 0:
    ToStdout("All instances evacuated successfully.")
    rcode = constants.EXIT_SUCCESS
  else:
    ToStdout("There were %s errors during the evacuation.", bad_cnt)
    rcode = constants.EXIT_FAILURE

  return rcode


def FailoverNode(opts, args):
  """Failover all primary instance on a node.

  @param opts: the command line options selected by the user
  @type args: list
  @param args: should be an empty list
  @rtype: int
  @return: the desired exit code

  """
  cl = GetClient()
  force = opts.force
  selected_fields = ["name", "pinst_list"]

  # these fields are static data anyway, so it doesn't matter, but
  # locking=True should be safer
  qcl = GetClient(query=True)
  result = cl.QueryNodes(names=args, fields=selected_fields,
                         use_locking=False)
  qcl.Close()
  node, pinst = result[0]

  if not pinst:
    ToStderr("No primary instances on node %s, exiting.", node)
    return 0

  pinst = utils.NiceSort(pinst)

  retcode = 0

  if not force and not AskUser("Fail over instance(s) %s?" %
                               (",".join("'%s'" % name for name in pinst))):
    return 2

  jex = JobExecutor(cl=cl, opts=opts)
  for iname in pinst:
    op = opcodes.OpInstanceFailover(instance_name=iname,
                                    ignore_consistency=opts.ignore_consistency,
                                    iallocator=opts.iallocator)
    jex.QueueJob(iname, op)
  results = jex.GetResults()
  bad_cnt = len([row for row in results if not row[0]])
  if bad_cnt == 0:
    ToStdout("All %d instance(s) failed over successfully.", len(results))
  else:
    ToStdout("There were errors during the failover:\n"
             "%d error(s) out of %d instance(s).", bad_cnt, len(results))
  return retcode


def MigrateNode(opts, args):
  """Migrate all primary instance on a node.

  """
  cl = GetClient()
  force = opts.force
  selected_fields = ["name", "pinst_list"]

  qcl = GetClient(query=True)
  result = cl.QueryNodes(names=args, fields=selected_fields, use_locking=False)
  qcl.Close()
  ((node, pinst), ) = result

  if not pinst:
    ToStdout("No primary instances on node %s, exiting." % node)
    return 0

  pinst = utils.NiceSort(pinst)

  if not (force or
          AskUser("Migrate instance(s) %s?" %
                  utils.CommaJoin(utils.NiceSort(pinst)))):
    return constants.EXIT_CONFIRMATION

  # this should be removed once --non-live is deprecated
  if not opts.live and opts.migration_mode is not None:
    raise errors.OpPrereqError("Only one of the --non-live and "
                               "--migration-mode options can be passed",
                               errors.ECODE_INVAL)
  if not opts.live: # --non-live passed
    mode = constants.HT_MIGRATION_NONLIVE
  else:
    mode = opts.migration_mode

  op = opcodes.OpNodeMigrate(node_name=args[0], mode=mode,
                             iallocator=opts.iallocator,
                             target_node=opts.dst_node,
                             allow_runtime_changes=opts.allow_runtime_chgs,
                             ignore_ipolicy=opts.ignore_ipolicy)

  result = SubmitOrSend(op, opts, cl=cl)

  # Keep track of submitted jobs
  jex = JobExecutor(cl=cl, opts=opts)

  for (status, job_id) in result[constants.JOB_IDS_KEY]:
    jex.AddJobId(None, status, job_id)

  results = jex.GetResults()
  bad_cnt = len([row for row in results if not row[0]])
  if bad_cnt == 0:
    ToStdout("All instances migrated successfully.")
    rcode = constants.EXIT_SUCCESS
  else:
    ToStdout("There were %s errors during the node migration.", bad_cnt)
    rcode = constants.EXIT_FAILURE

  return rcode


def _FormatNodeInfo(node_info):
  """Format node information for L{cli.PrintGenericInfo()}.

  """
  (name, primary_ip, secondary_ip, pinst, sinst, is_mc, drained, offline,
   master_capable, vm_capable, powered, ndparams, ndparams_custom) = node_info
  info = [
    ("Node name", name),
    ("primary ip", primary_ip),
    ("secondary ip", secondary_ip),
    ("master candidate", is_mc),
    ("drained", drained),
    ("offline", offline),
    ]
  if powered is not None:
    info.append(("powered", powered))
  info.extend([
    ("master_capable", master_capable),
    ("vm_capable", vm_capable),
    ])
  if vm_capable:
    info.extend([
      ("primary for instances",
       [iname for iname in utils.NiceSort(pinst)]),
      ("secondary for instances",
       [iname for iname in utils.NiceSort(sinst)]),
      ])
  info.append(("node parameters",
               FormatParamsDictInfo(ndparams_custom, ndparams)))
  return info


def ShowNodeConfig(opts, args):
  """Show node information.

  @param opts: the command line options selected by the user
  @type args: list
  @param args: should either be an empty list, in which case
      we show information about all nodes, or should contain
      a list of nodes to be queried for information
  @rtype: int
  @return: the desired exit code

  """
  cl = GetClient(query=True)
  result = cl.QueryNodes(fields=["name", "pip", "sip",
                                 "pinst_list", "sinst_list",
                                 "master_candidate", "drained", "offline",
                                 "master_capable", "vm_capable", "powered",
                                 "ndparams", "custom_ndparams"],
                         names=args, use_locking=False)
  PrintGenericInfo([
    _FormatNodeInfo(node_info)
    for node_info in result
    ])
  return 0


def RemoveNode(opts, args):
  """Remove a node from the cluster.

  @param opts: the command line options selected by the user
  @type args: list
  @param args: should contain only one element, the name of
      the node to be removed
  @rtype: int
  @return: the desired exit code

  """
  op = opcodes.OpNodeRemove(node_name=args[0])
  SubmitOpCode(op, opts=opts)
  return 0


def PowercycleNode(opts, args):
  """Remove a node from the cluster.

  @param opts: the command line options selected by the user
  @type args: list
  @param args: should contain only one element, the name of
      the node to be removed
  @rtype: int
  @return: the desired exit code

  """
  node = args[0]
  if (not opts.confirm and
      not AskUser("Are you sure you want to hard powercycle node %s?" % node)):
    return 2

  op = opcodes.OpNodePowercycle(node_name=node, force=opts.force)
  result = SubmitOrSend(op, opts)
  if result:
    ToStderr(result)
  return 0


def PowerNode(opts, args):
  """Change/ask power state of a node.

  @param opts: the command line options selected by the user
  @type args: list
  @param args: should contain only one element, the name of
      the node to be removed
  @rtype: int
  @return: the desired exit code

  """
  command = args.pop(0)

  if opts.no_headers:
    headers = None
  else:
    headers = {"node": "Node", "status": "Status"}

  if command not in _LIST_POWER_COMMANDS:
    ToStderr("power subcommand %s not supported." % command)
    return constants.EXIT_FAILURE

  oob_command = "power-%s" % command

  if oob_command in _OOB_COMMAND_ASK:
    if not args:
      ToStderr("Please provide at least one node for this command")
      return constants.EXIT_FAILURE
    elif not opts.force and not ConfirmOperation(args, "nodes",
                                                 "power %s" % command):
      return constants.EXIT_FAILURE
    assert len(args) > 0

  opcodelist = []
  if not opts.ignore_status and oob_command == constants.OOB_POWER_OFF:
    # TODO: This is a little ugly as we can't catch and revert
    for node in args:
      opcodelist.append(opcodes.OpNodeSetParams(node_name=node, offline=True,
                                                auto_promote=opts.auto_promote))

  opcodelist.append(opcodes.OpOobCommand(node_names=args,
                                         command=oob_command,
                                         ignore_status=opts.ignore_status,
                                         timeout=opts.oob_timeout,
                                         power_delay=opts.power_delay))

  cli.SetGenericOpcodeOpts(opcodelist, opts)

  job_id = cli.SendJob(opcodelist)

  # We just want the OOB Opcode status
  # If it fails PollJob gives us the error message in it
  result = cli.PollJob(job_id)[-1]

  errs = 0
  data = []
  for node_result in result:
    (node_tuple, data_tuple) = node_result
    (_, node_name) = node_tuple
    (data_status, data_node) = data_tuple
    if data_status == constants.RS_NORMAL:
      if oob_command == constants.OOB_POWER_STATUS:
        if data_node[constants.OOB_POWER_STATUS_POWERED]:
          text = "powered"
        else:
          text = "unpowered"
        data.append([node_name, text])
      else:
        # We don't expect data here, so we just say, it was successfully invoked
        data.append([node_name, "invoked"])
    else:
      errs += 1
      data.append([node_name, cli.FormatResultError(data_status, True)])

  data = GenerateTable(separator=opts.separator, headers=headers,
                       fields=["node", "status"], data=data)

  for line in data:
    ToStdout(line)

  if errs:
    return constants.EXIT_FAILURE
  else:
    return constants.EXIT_SUCCESS


def Health(opts, args):
  """Show health of a node using OOB.

  @param opts: the command line options selected by the user
  @type args: list
  @param args: should contain only one element, the name of
      the node to be removed
  @rtype: int
  @return: the desired exit code

  """
  op = opcodes.OpOobCommand(node_names=args, command=constants.OOB_HEALTH,
                            timeout=opts.oob_timeout)
  result = SubmitOpCode(op, opts=opts)

  if opts.no_headers:
    headers = None
  else:
    headers = {"node": "Node", "status": "Status"}

  errs = 0
  data = []
  for node_result in result:
    (node_tuple, data_tuple) = node_result
    (_, node_name) = node_tuple
    (data_status, data_node) = data_tuple
    if data_status == constants.RS_NORMAL:
      data.append([node_name, "%s=%s" % tuple(data_node[0])])
      for item, status in data_node[1:]:
        data.append(["", "%s=%s" % (item, status)])
    else:
      errs += 1
      data.append([node_name, cli.FormatResultError(data_status, True)])

  data = GenerateTable(separator=opts.separator, headers=headers,
                       fields=["node", "status"], data=data)

  for line in data:
    ToStdout(line)

  if errs:
    return constants.EXIT_FAILURE
  else:
    return constants.EXIT_SUCCESS


def ListVolumes(opts, args):
  """List logical volumes on node(s).

  @param opts: the command line options selected by the user
  @type args: list
  @param args: should either be an empty list, in which case
      we list data for all nodes, or contain a list of nodes
      to display data only for those
  @rtype: int
  @return: the desired exit code

  """
  selected_fields = ParseFields(opts.output, _LIST_VOL_DEF_FIELDS)

  op = opcodes.OpNodeQueryvols(nodes=args, output_fields=selected_fields)
  output = SubmitOpCode(op, opts=opts)

  if not opts.no_headers:
    headers = {"node": "Node", "phys": "PhysDev",
               "vg": "VG", "name": "Name",
               "size": "Size", "instance": "Instance"}
  else:
    headers = None

  unitfields = ["size"]

  numfields = ["size"]

  data = GenerateTable(separator=opts.separator, headers=headers,
                       fields=selected_fields, unitfields=unitfields,
                       numfields=numfields, data=output, units=opts.units)

  for line in data:
    ToStdout(line)

  return 0


def ListStorage(opts, args):
  """List physical volumes on node(s).

  @param opts: the command line options selected by the user
  @type args: list
  @param args: should either be an empty list, in which case
      we list data for all nodes, or contain a list of nodes
      to display data only for those
  @rtype: int
  @return: the desired exit code

  """
  # TODO: Default to ST_FILE if LVM is disabled on the cluster
  if opts.user_storage_type is None:
    opts.user_storage_type = constants.ST_LVM_PV

  storage_type = ConvertStorageType(opts.user_storage_type)

  selected_fields = ParseFields(opts.output, _LIST_STOR_DEF_FIELDS)

  op = opcodes.OpNodeQueryStorage(nodes=args,
                                  storage_type=storage_type,
                                  output_fields=selected_fields)
  output = SubmitOpCode(op, opts=opts)

  if not opts.no_headers:
    headers = {
      constants.SF_NODE: "Node",
      constants.SF_TYPE: "Type",
      constants.SF_NAME: "Name",
      constants.SF_SIZE: "Size",
      constants.SF_USED: "Used",
      constants.SF_FREE: "Free",
      constants.SF_ALLOCATABLE: "Allocatable",
      }
  else:
    headers = None

  unitfields = [constants.SF_SIZE, constants.SF_USED, constants.SF_FREE]
  numfields = [constants.SF_SIZE, constants.SF_USED, constants.SF_FREE]

  # change raw values to nicer strings
  for row in output:
    for idx, field in enumerate(selected_fields):
      val = row[idx]
      if field == constants.SF_ALLOCATABLE:
        if val:
          val = "Y"
        else:
          val = "N"
      row[idx] = str(val)

  data = GenerateTable(separator=opts.separator, headers=headers,
                       fields=selected_fields, unitfields=unitfields,
                       numfields=numfields, data=output, units=opts.units)

  for line in data:
    ToStdout(line)

  return 0


def ModifyStorage(opts, args):
  """Modify storage volume on a node.

  @param opts: the command line options selected by the user
  @type args: list
  @param args: should contain 3 items: node name, storage type and volume name
  @rtype: int
  @return: the desired exit code

  """
  (node_name, user_storage_type, volume_name) = args

  storage_type = ConvertStorageType(user_storage_type)

  changes = {}

  if opts.allocatable is not None:
    changes[constants.SF_ALLOCATABLE] = opts.allocatable

  if changes:
    op = opcodes.OpNodeModifyStorage(node_name=node_name,
                                     storage_type=storage_type,
                                     name=volume_name,
                                     changes=changes)
    SubmitOrSend(op, opts)
  else:
    ToStderr("No changes to perform, exiting.")


def RepairStorage(opts, args):
  """Repairs a storage volume on a node.

  @param opts: the command line options selected by the user
  @type args: list
  @param args: should contain 3 items: node name, storage type and volume name
  @rtype: int
  @return: the desired exit code

  """
  (node_name, user_storage_type, volume_name) = args

  storage_type = ConvertStorageType(user_storage_type)

  op = opcodes.OpRepairNodeStorage(node_name=node_name,
                                   storage_type=storage_type,
                                   name=volume_name,
                                   ignore_consistency=opts.ignore_consistency)
  SubmitOrSend(op, opts)


def SetNodeParams(opts, args):
  """Modifies a node.

  @param opts: the command line options selected by the user
  @type args: list
  @param args: should contain only one element, the node name
  @rtype: int
  @return: the desired exit code

  """
  all_changes = [opts.master_candidate, opts.drained, opts.offline,
                 opts.master_capable, opts.vm_capable, opts.secondary_ip,
                 opts.ndparams]
  if (all_changes.count(None) == len(all_changes) and
      not (opts.hv_state or opts.disk_state)):
    ToStderr("Please give at least one of the parameters.")
    return 1

  if opts.disk_state:
    disk_state = utils.FlatToDict(opts.disk_state)
  else:
    disk_state = {}

  hv_state = dict(opts.hv_state)

  op = opcodes.OpNodeSetParams(node_name=args[0],
                               master_candidate=opts.master_candidate,
                               offline=opts.offline,
                               drained=opts.drained,
                               master_capable=opts.master_capable,
                               vm_capable=opts.vm_capable,
                               secondary_ip=opts.secondary_ip,
                               force=opts.force,
                               ndparams=opts.ndparams,
                               auto_promote=opts.auto_promote,
                               powered=opts.node_powered,
                               hv_state=hv_state,
                               disk_state=disk_state)

  # even if here we process the result, we allow submit only
  result = SubmitOrSend(op, opts)

  if result:
    ToStdout("Modified node %s", args[0])
    for param, data in result:
      ToStdout(" - %-5s -> %s", param, data)
  return 0


def RestrictedCommand(opts, args):
  """Runs a remote command on node(s).

  @param opts: Command line options selected by user
  @type args: list
  @param args: Command line arguments
  @rtype: int
  @return: Exit code

  """
  cl = GetClient()

  if len(args) > 1 or opts.nodegroup:
    # Expand node names
    nodes = GetOnlineNodes(nodes=args[1:], cl=cl, nodegroup=opts.nodegroup)
  else:
    raise errors.OpPrereqError("Node group or node names must be given",
                               errors.ECODE_INVAL)

  op = opcodes.OpRestrictedCommand(command=args[0], nodes=nodes,
                                   use_locking=opts.do_locking)
  result = SubmitOrSend(op, opts, cl=cl)

  exit_code = constants.EXIT_SUCCESS

  for (node, (status, text)) in zip(nodes, result):
    ToStdout("------------------------------------------------")
    if status:
      if opts.show_machine_names:
        for line in text.splitlines():
          ToStdout("%s: %s", node, line)
      else:
        ToStdout("Node: %s", node)
        ToStdout(text)
    else:
      exit_code = constants.EXIT_FAILURE
      ToStdout(text)

  return exit_code


class ReplyStatus(object):
  """Class holding a reply status for synchronous confd clients.

  """
  def __init__(self):
    self.failure = True
    self.answer = False


def ListDrbd(opts, args):
  """Modifies a node.

  @param opts: the command line options selected by the user
  @type args: list
  @param args: should contain only one element, the node name
  @rtype: int
  @return: the desired exit code

  """
  if len(args) != 1:
    ToStderr("Please give one (and only one) node.")
    return constants.EXIT_FAILURE

  if not constants.ENABLE_CONFD:
    ToStderr("Error: this command requires confd support, but it has not"
             " been enabled at build time.")
    return constants.EXIT_FAILURE

  status = ReplyStatus()

  def ListDrbdConfdCallback(reply):
    """Callback for confd queries"""
    if reply.type == confd_client.UPCALL_REPLY:
      answer = reply.server_reply.answer
      reqtype = reply.orig_request.type
      if reqtype == constants.CONFD_REQ_NODE_DRBD:
        if reply.server_reply.status != constants.CONFD_REPL_STATUS_OK:
          ToStderr("Query gave non-ok status '%s': %s" %
                   (reply.server_reply.status,
                    reply.server_reply.answer))
          status.failure = True
          return
        if not confd.HTNodeDrbd(answer):
          ToStderr("Invalid response from server: expected %s, got %s",
                   confd.HTNodeDrbd, answer)
          status.failure = True
        else:
          status.failure = False
          status.answer = answer
      else:
        ToStderr("Unexpected reply %s!?", reqtype)
        status.failure = True

  node = args[0]
  hmac = utils.ReadFile(pathutils.CONFD_HMAC_KEY)
  filter_callback = confd_client.ConfdFilterCallback(ListDrbdConfdCallback)
  counting_callback = confd_client.ConfdCountingCallback(filter_callback)
  cf_client = confd_client.ConfdClient(hmac, [constants.IP4_ADDRESS_LOCALHOST],
                                       counting_callback)
  req = confd_client.ConfdClientRequest(type=constants.CONFD_REQ_NODE_DRBD,
                                        query=node)

  def DoConfdRequestReply(req):
    counting_callback.RegisterQuery(req.rsalt)
    cf_client.SendRequest(req, async=False)
    while not counting_callback.AllAnswered():
      if not cf_client.ReceiveReply():
        ToStderr("Did not receive all expected confd replies")
        break

  DoConfdRequestReply(req)

  if status.failure:
    return constants.EXIT_FAILURE

  fields = ["node", "minor", "instance", "disk", "role", "peer"]
  if opts.no_headers:
    headers = None
  else:
    headers = {"node": "Node", "minor": "Minor", "instance": "Instance",
               "disk": "Disk", "role": "Role", "peer": "PeerNode"}

  data = GenerateTable(separator=opts.separator, headers=headers,
                       fields=fields, data=sorted(status.answer),
                       numfields=["minor"])
  for line in data:
    ToStdout(line)

  return constants.EXIT_SUCCESS


commands = {
  "add": (
    AddNode, [ArgHost(min=1, max=1)],
    [SECONDARY_IP_OPT, READD_OPT, NOSSH_KEYCHECK_OPT, NODE_FORCE_JOIN_OPT,
     NONODE_SETUP_OPT, VERBOSE_OPT, NODEGROUP_OPT, PRIORITY_OPT,
     CAPAB_MASTER_OPT, CAPAB_VM_OPT, NODE_PARAMS_OPT, HV_STATE_OPT,
     DISK_STATE_OPT],
    "[-s ip] [--readd] [--no-ssh-key-check] [--force-join]"
    " [--no-node-setup] [--verbose]"
    " <node_name>",
    "Add a node to the cluster"),
  "evacuate": (
    EvacuateNode, ARGS_ONE_NODE,
    [FORCE_OPT, IALLOCATOR_OPT, NEW_SECONDARY_OPT, EARLY_RELEASE_OPT,
     PRIORITY_OPT, PRIMARY_ONLY_OPT, SECONDARY_ONLY_OPT] + SUBMIT_OPTS,
    "[-f] {-I <iallocator> | -n <dst>} [-p | -s] [options...] <node>",
    "Relocate the primary and/or secondary instances from a node"),
  "failover": (
    FailoverNode, ARGS_ONE_NODE, [FORCE_OPT, IGNORE_CONSIST_OPT,
                                  IALLOCATOR_OPT, PRIORITY_OPT],
    "[-f] <node>",
    "Stops the primary instances on a node and start them on their"
    " secondary node (only for instances with drbd disk template)"),
  "migrate": (
    MigrateNode, ARGS_ONE_NODE,
    [FORCE_OPT, NONLIVE_OPT, MIGRATION_MODE_OPT, DST_NODE_OPT,
     IALLOCATOR_OPT, PRIORITY_OPT, IGNORE_IPOLICY_OPT,
     NORUNTIME_CHGS_OPT] + SUBMIT_OPTS,
    "[-f] <node>",
    "Migrate all the primary instance on a node away from it"
    " (only for instances of type drbd)"),
  "info": (
    ShowNodeConfig, ARGS_MANY_NODES, [],
    "[<node_name>...]", "Show information about the node(s)"),
  "list": (
    ListNodes, ARGS_MANY_NODES,
    [NOHDR_OPT, SEP_OPT, USEUNITS_OPT, FIELDS_OPT, VERBOSE_OPT,
     FORCE_FILTER_OPT],
    "[nodes...]",
    "Lists the nodes in the cluster. The available fields can be shown using"
    " the \"list-fields\" command (see the man page for details)."
    " The default field list is (in order): %s." %
    utils.CommaJoin(_LIST_DEF_FIELDS)),
  "list-fields": (
    ListNodeFields, [ArgUnknown()],
    [NOHDR_OPT, SEP_OPT],
    "[fields...]",
    "Lists all available fields for nodes"),
  "modify": (
    SetNodeParams, ARGS_ONE_NODE,
    [FORCE_OPT] + SUBMIT_OPTS +
    [MC_OPT, DRAINED_OPT, OFFLINE_OPT,
     CAPAB_MASTER_OPT, CAPAB_VM_OPT, SECONDARY_IP_OPT,
     AUTO_PROMOTE_OPT, DRY_RUN_OPT, PRIORITY_OPT, NODE_PARAMS_OPT,
     NODE_POWERED_OPT, HV_STATE_OPT, DISK_STATE_OPT],
    "<node_name>", "Alters the parameters of a node"),
  "powercycle": (
    PowercycleNode, ARGS_ONE_NODE,
    [FORCE_OPT, CONFIRM_OPT, DRY_RUN_OPT, PRIORITY_OPT] + SUBMIT_OPTS,
    "<node_name>", "Tries to forcefully powercycle a node"),
  "power": (
    PowerNode,
    [ArgChoice(min=1, max=1, choices=_LIST_POWER_COMMANDS),
     ArgNode()],
    SUBMIT_OPTS +
    [AUTO_PROMOTE_OPT, PRIORITY_OPT,
     IGNORE_STATUS_OPT, FORCE_OPT, NOHDR_OPT, SEP_OPT, OOB_TIMEOUT_OPT,
     POWER_DELAY_OPT],
    "on|off|cycle|status [nodes...]",
    "Change power state of node by calling out-of-band helper."),
  "remove": (
    RemoveNode, ARGS_ONE_NODE, [DRY_RUN_OPT, PRIORITY_OPT],
    "<node_name>", "Removes a node from the cluster"),
  "volumes": (
    ListVolumes, [ArgNode()],
    [NOHDR_OPT, SEP_OPT, USEUNITS_OPT, FIELDS_OPT, PRIORITY_OPT],
    "[<node_name>...]", "List logical volumes on node(s)"),
  "list-storage": (
    ListStorage, ARGS_MANY_NODES,
    [NOHDR_OPT, SEP_OPT, USEUNITS_OPT, FIELDS_OPT, _STORAGE_TYPE_OPT,
     PRIORITY_OPT],
    "[<node_name>...]", "List physical volumes on node(s). The available"
    " fields are (see the man page for details): %s." %
    (utils.CommaJoin(_LIST_STOR_HEADERS))),
  "modify-storage": (
    ModifyStorage,
    [ArgNode(min=1, max=1),
     ArgChoice(min=1, max=1, choices=_MODIFIABLE_STORAGE_TYPES),
     ArgFile(min=1, max=1)],
    [ALLOCATABLE_OPT, DRY_RUN_OPT, PRIORITY_OPT] + SUBMIT_OPTS,
    "<node_name> <storage_type> <name>", "Modify storage volume on a node"),
  "repair-storage": (
    RepairStorage,
    [ArgNode(min=1, max=1),
     ArgChoice(min=1, max=1, choices=_REPAIRABLE_STORAGE_TYPES),
     ArgFile(min=1, max=1)],
    [IGNORE_CONSIST_OPT, DRY_RUN_OPT, PRIORITY_OPT] + SUBMIT_OPTS,
    "<node_name> <storage_type> <name>",
    "Repairs a storage volume on a node"),
  "list-tags": (
    ListTags, ARGS_ONE_NODE, [],
    "<node_name>", "List the tags of the given node"),
  "add-tags": (
    AddTags, [ArgNode(min=1, max=1), ArgUnknown()],
    [TAG_SRC_OPT, PRIORITY_OPT] + SUBMIT_OPTS,
    "<node_name> tag...", "Add tags to the given node"),
  "remove-tags": (
    RemoveTags, [ArgNode(min=1, max=1), ArgUnknown()],
    [TAG_SRC_OPT, PRIORITY_OPT] + SUBMIT_OPTS,
    "<node_name> tag...", "Remove tags from the given node"),
  "health": (
    Health, ARGS_MANY_NODES,
    [NOHDR_OPT, SEP_OPT, PRIORITY_OPT, OOB_TIMEOUT_OPT],
    "[<node_name>...]", "List health of node(s) using out-of-band"),
  "list-drbd": (
    ListDrbd, ARGS_ONE_NODE,
    [NOHDR_OPT, SEP_OPT],
    "[<node_name>]", "Query the list of used DRBD minors on the given node"),
  "restricted-command": (
    RestrictedCommand, [ArgUnknown(min=1, max=1)] + ARGS_MANY_NODES,
    [SYNC_OPT, PRIORITY_OPT] + SUBMIT_OPTS + [SHOW_MACHINE_OPT, NODEGROUP_OPT],
    "<command> <node_name> [<node_name>...]",
    "Executes a restricted command on node(s)"),
  }

#: dictionary with aliases for commands
aliases = {
  "show": "info",
  }


def Main():
  return GenericMain(commands, aliases=aliases,
                     override={"tag_type": constants.TAG_NODE},
                     env_override=_ENV_OVERRIDE)
