#
#

# Copyright (C) 2007, 2011, 2012, 2013 Google Inc.
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are
# met:
#
# 1. Redistributions of source code must retain the above copyright notice,
# this list of conditions and the following disclaimer.
#
# 2. Redistributions in binary form must reproduce the above copyright
# notice, this list of conditions and the following disclaimer in the
# documentation and/or other materials provided with the distribution.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
# IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
# TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
# PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
# LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
# NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.


"""Node-related QA tests.

"""

from ganeti import utils
from ganeti import constants
from ganeti import query
from ganeti import serializer

import qa_config
import qa_error
import qa_utils

from qa_utils import AssertCommand, AssertRedirectedCommand, AssertEqual, \
  AssertIn, GetCommandOutput


def NodeAdd(node, readd=False, group=None):
  if not readd and node.added:
    raise qa_error.Error("Node %s already in cluster" % node.primary)
  elif readd and not node.added:
    raise qa_error.Error("Node %s not yet in cluster" % node.primary)

  cmd = ["gnt-node", "add", "--no-ssh-key-check"]
  if node.secondary:
    cmd.append("--secondary-ip=%s" % node.secondary)
  if readd:
    cmd.append("--readd")
  if group is not None:
    cmd.extend(["--node-group", group])

  if not qa_config.GetModifySshSetup():
    cmd.append("--no-node-setup")

  cmd.append(node.primary)

  AssertCommand(cmd)

  if readd:
    AssertRedirectedCommand(["gnt-cluster", "verify"])

  if readd:
    assert node.added
  else:
    node.MarkAdded()


def NodeRemove(node):
  AssertCommand(["gnt-node", "remove", node.primary])
  node.MarkRemoved()


def MakeNodeOffline(node, value):
  """gnt-node modify --offline=value"""
  # value in ["yes", "no"]
  AssertCommand(["gnt-node", "modify", "--offline", value, node.primary])


def TestNodeAddAll():
  """Adding all nodes to cluster."""
  master = qa_config.GetMasterNode()
  for node in qa_config.get("nodes"):
    if node != master:
      NodeAdd(node, readd=False)

  for node in qa_config.get("nodes"):
    def GetNonStartDaemons():
      cmd = utils.ShellQuoteArgs(["ps", "-Ao", "comm"])
      prcs = AssertCommand(cmd, node=node)[1]

      non_start_daemons = []

      def AddIfNotStarted(daemon):
        if daemon not in prcs:
          non_start_daemons.append(daemon)

      AddIfNotStarted('ganeti-noded')
      if constants.ENABLE_MOND:
        AddIfNotStarted('ganeti-mond')
      if node == master:
        AddIfNotStarted('ganeti-wconfd')
        AddIfNotStarted('ganeti-rapi')
        AddIfNotStarted('ganeti-luxid')
        AddIfNotStarted('ganeti-maintd')
      return non_start_daemons

    nsd = GetNonStartDaemons()
    for daemon in nsd:
      raise qa_error.Error(daemon + ' is not running at %s' % node.primary)


def MarkNodeAddedAll():
  """Mark all nodes as added.

  This is useful if we don't create the cluster ourselves (in qa).

  """
  master = qa_config.GetMasterNode()
  for node in qa_config.get("nodes"):
    if node != master:
      node.MarkAdded()


def TestNodeRemoveAll():
  """Removing all nodes from cluster."""
  master = qa_config.GetMasterNode()
  for node in qa_config.get("nodes"):
    if node != master:
      NodeRemove(node)


def TestNodeReadd(node):
  """gnt-node add --readd"""
  NodeAdd(node, readd=True)


def TestNodeInfo():
  """gnt-node info"""
  AssertCommand(["gnt-node", "info"])


def TestNodeVolumes():
  """gnt-node volumes"""
  AssertCommand(["gnt-node", "volumes"])


def TestNodeStorage():
  """gnt-node storage"""
  master = qa_config.GetMasterNode()

  # FIXME: test all storage_types in constants.STORAGE_TYPES
  # as soon as they are implemented.
  enabled_storage_types = qa_config.GetEnabledStorageTypes()
  testable_storage_types = list(set(enabled_storage_types).intersection(
      set([constants.ST_FILE, constants.ST_LVM_VG, constants.ST_LVM_PV])))

  for storage_type in testable_storage_types:

    cmd = ["gnt-node", "list-storage", "--storage-type", storage_type]

    # Test simple list
    AssertCommand(cmd)

    # Test all storage fields
    cmd = ["gnt-node", "list-storage", "--storage-type", storage_type,
           "--output=%s" % ",".join(list(constants.VALID_STORAGE_FIELDS))]
    AssertCommand(cmd)

    # Get list of valid storage devices
    cmd = ["gnt-node", "list-storage", "--storage-type", storage_type,
           "--output=node,name,allocatable", "--separator=|",
           "--no-headers"]
    output = qa_utils.GetCommandOutput(master.primary,
                                       utils.ShellQuoteArgs(cmd))

    # Test with up to two devices
    testdevcount = 2

    for line in output.splitlines()[:testdevcount]:
      (node_name, st_name, st_allocatable) = line.split("|")

      # Dummy modification without any changes
      cmd = ["gnt-node", "modify-storage", node_name, storage_type, st_name]
      AssertCommand(cmd)

      # Make sure we end up with the same value as before
      if st_allocatable.lower() == "y":
        test_allocatable = ["no", "yes"]
      else:
        test_allocatable = ["yes", "no"]

      fail = (constants.SF_ALLOCATABLE not in
              constants.MODIFIABLE_STORAGE_FIELDS.get(storage_type, []))

      for i in test_allocatable:
        AssertCommand(["gnt-node", "modify-storage", "--allocatable", i,
                       node_name, storage_type, st_name], fail=fail)

        # Verify list output
        cmd = ["gnt-node", "list-storage", "--storage-type", storage_type,
               "--output=name,allocatable", "--separator=|",
               "--no-headers", node_name]
        listout = qa_utils.GetCommandOutput(master.primary,
                                            utils.ShellQuoteArgs(cmd))
        for line in listout.splitlines():
          (vfy_name, vfy_allocatable) = line.split("|")
          if vfy_name == st_name and not fail:
            AssertEqual(vfy_allocatable, i[0].upper())
          else:
            AssertEqual(vfy_allocatable, st_allocatable)

      # Test repair functionality
      fail = (constants.SO_FIX_CONSISTENCY not in
              constants.VALID_STORAGE_OPERATIONS.get(storage_type, []))
      AssertCommand(["gnt-node", "repair-storage", node_name,
                     storage_type, st_name], fail=fail)


def TestNodeFailover(node, node2):
  """gnt-node failover"""
  if qa_utils.GetNodeInstances(node2, secondaries=False):
    raise qa_error.UnusableNodeError("Secondary node has at least one"
                                     " primary instance. This test requires"
                                     " it to have no primary instances.")

  # Fail over to secondary node
  AssertCommand(["gnt-node", "failover", "-f", node.primary])

  # ... and back again.
  AssertCommand(["gnt-node", "failover", "-f", node2.primary])


def TestNodeMigrate(node, node2):
  """gnt-node migrate"""
  if qa_utils.GetNodeInstances(node2, secondaries=False):
    raise qa_error.UnusableNodeError("Secondary node has at least one"
                                     " primary instance. This test requires"
                                     " it to have no primary instances.")

  # Migrate to secondary node
  AssertCommand(["gnt-node", "migrate", "-f", node.primary])

  # ... and back again.
  AssertCommand(["gnt-node", "migrate", "-f", node2.primary])


def TestNodeEvacuate(node, node2):
  """gnt-node evacuate"""
  node3 = qa_config.AcquireNode(exclude=[node, node2])
  try:
    if qa_utils.GetNodeInstances(node3, secondaries=True):
      raise qa_error.UnusableNodeError("Evacuation node has at least one"
                                       " secondary instance. This test requires"
                                       " it to have no secondary instances.")

    # Evacuate all secondary instances
    AssertCommand(["gnt-node", "evacuate", "-f",
                   "--new-secondary=%s" % node3.primary, node2.primary])

    # ... and back again.
    AssertCommand(["gnt-node", "evacuate", "-f",
                   "--new-secondary=%s" % node2.primary, node3.primary])
  finally:
    node3.Release()


def TestNodeModify(node):
  """gnt-node modify"""

  default_pool_size = 10
  nodes = qa_config.GetAllNodes()
  test_pool_size = len(nodes) - 1

  # Reduce the number of master candidates, because otherwise all
  # subsequent 'gnt-cluster verify' commands fail due to not enough
  # master candidates.
  AssertCommand(["gnt-cluster", "modify",
                 "--candidate-pool-size=%s" % test_pool_size])

  # make sure enough master candidates will be available by disabling the
  # master candidate role first with --auto-promote
  AssertCommand(["gnt-node", "modify", "--master-candidate=no",
                "--auto-promote", node.primary])

  # now it's save to force-remove the master candidate role
  for flag in ["master-candidate", "drained", "offline"]:
    for value in ["yes", "no"]:
      AssertCommand(["gnt-node", "modify", "--force",
                     "--%s=%s" % (flag, value), node.primary])
      AssertCommand(["gnt-cluster", "verify"])

  AssertCommand(["gnt-node", "modify", "--master-candidate=yes", node.primary])

  # Test setting secondary IP address
  AssertCommand(["gnt-node", "modify", "--secondary-ip=%s" % node.secondary,
                 node.primary])

  AssertRedirectedCommand(["gnt-cluster", "verify"])
  AssertCommand(["gnt-cluster", "modify",
                 "--candidate-pool-size=%s" % default_pool_size])

  # For test clusters with more nodes than the default pool size,
  # we now have too many master candidates. To readjust to the original
  # size, manually demote all nodes and rely on auto-promotion to adjust.
  if len(nodes) > default_pool_size:
    master = qa_config.GetMasterNode()
    for n in nodes:
      if n.primary != master.primary:
        AssertCommand(["gnt-node", "modify", "--master-candidate=no",
                       "--auto-promote", n.primary])


def _CreateOobScriptStructure():
  """Create a simple OOB handling script and its structure."""
  master = qa_config.GetMasterNode()

  data_path = qa_utils.UploadData(master.primary, "")
  verify_path = qa_utils.UploadData(master.primary, "")
  exit_code_path = qa_utils.UploadData(master.primary, "")

  oob_script = (("#!/bin/bash\n"
                 "echo \"$@\" > %s\n"
                 "cat %s\n"
                 "exit $(< %s)\n") %
                (utils.ShellQuote(verify_path), utils.ShellQuote(data_path),
                 utils.ShellQuote(exit_code_path)))
  oob_path = qa_utils.UploadData(master.primary, oob_script, mode=0700)

  return [oob_path, verify_path, data_path, exit_code_path]


def _UpdateOobFile(path, data):
  """Updates the data file with data."""
  master = qa_config.GetMasterNode()
  qa_utils.UploadData(master.primary, data, filename=path)


def _AssertOobCall(verify_path, expected_args):
  """Assert the OOB call was performed with expetected args."""
  master = qa_config.GetMasterNode()

  verify_output_cmd = utils.ShellQuoteArgs(["cat", verify_path])
  output = qa_utils.GetCommandOutput(master.primary, verify_output_cmd,
                                     tty=False)

  AssertEqual(expected_args, output.strip())


def TestOutOfBand():
  """gnt-node power"""
  master = qa_config.GetMasterNode()

  node = qa_config.AcquireNode(exclude=master)

  master_name = master.primary
  node_name = node.primary
  full_node_name = qa_utils.ResolveNodeName(node)

  (oob_path, verify_path,
   data_path, exit_code_path) = _CreateOobScriptStructure()

  try:
    AssertCommand(["gnt-cluster", "modify", "--node-parameters",
                   "oob_program=%s" % oob_path])

    # No data, exit 0
    _UpdateOobFile(exit_code_path, "0")

    AssertCommand(["gnt-node", "power", "on", node_name])
    _AssertOobCall(verify_path, "power-on %s" % full_node_name)

    AssertCommand(["gnt-node", "power", "-f", "off", node_name])
    _AssertOobCall(verify_path, "power-off %s" % full_node_name)

    # Power off on master without options should fail
    AssertCommand(["gnt-node", "power", "-f", "off", master_name], fail=True)
    # With force master it should still fail
    AssertCommand(["gnt-node", "power", "-f", "--ignore-status", "off",
                   master_name],
                  fail=True)

    # Verify we can't transform back to online when not yet powered on
    AssertCommand(["gnt-node", "modify", "-O", "no", node_name],
                  fail=True)
    # Now reset state
    AssertCommand(["gnt-node", "modify", "-O", "no", "--node-powered", "yes",
                   node_name])

    AssertCommand(["gnt-node", "power", "-f", "cycle", node_name])
    _AssertOobCall(verify_path, "power-cycle %s" % full_node_name)

    # Those commands should fail as they expect output which isn't provided yet
    # But they should have called the oob helper nevermind
    AssertCommand(["gnt-node", "power", "status", node_name],
                  fail=True)
    _AssertOobCall(verify_path, "power-status %s" % full_node_name)

    AssertCommand(["gnt-node", "health", node_name],
                  fail=True)
    _AssertOobCall(verify_path, "health %s" % full_node_name)

    AssertCommand(["gnt-node", "health"], fail=True)

    # Correct Data, exit 0
    _UpdateOobFile(data_path, serializer.DumpJson({"powered": True}))

    AssertCommand(["gnt-node", "power", "status", node_name])
    _AssertOobCall(verify_path, "power-status %s" % full_node_name)

    _UpdateOobFile(data_path, serializer.DumpJson([["temp", "OK"],
                                                   ["disk0", "CRITICAL"]]))

    AssertCommand(["gnt-node", "health", node_name])
    _AssertOobCall(verify_path, "health %s" % full_node_name)

    AssertCommand(["gnt-node", "health"])

    # Those commands should fail as they expect no data regardless of exit 0
    AssertCommand(["gnt-node", "power", "on", node_name], fail=True)
    _AssertOobCall(verify_path, "power-on %s" % full_node_name)

    try:
      AssertCommand(["gnt-node", "power", "-f", "off", node_name], fail=True)
      _AssertOobCall(verify_path, "power-off %s" % full_node_name)
    finally:
      AssertCommand(["gnt-node", "modify", "-O", "no", node_name])

    AssertCommand(["gnt-node", "power", "-f", "cycle", node_name], fail=True)
    _AssertOobCall(verify_path, "power-cycle %s" % full_node_name)

    # Data, exit 1 (all should fail)
    _UpdateOobFile(exit_code_path, "1")

    AssertCommand(["gnt-node", "power", "on", node_name], fail=True)
    _AssertOobCall(verify_path, "power-on %s" % full_node_name)

    try:
      AssertCommand(["gnt-node", "power", "-f", "off", node_name], fail=True)
      _AssertOobCall(verify_path, "power-off %s" % full_node_name)
    finally:
      AssertCommand(["gnt-node", "modify", "-O", "no", node_name])

    AssertCommand(["gnt-node", "power", "-f", "cycle", node_name], fail=True)
    _AssertOobCall(verify_path, "power-cycle %s" % full_node_name)

    AssertCommand(["gnt-node", "power", "status", node_name],
                  fail=True)
    _AssertOobCall(verify_path, "power-status %s" % full_node_name)

    AssertCommand(["gnt-node", "health", node_name],
                  fail=True)
    _AssertOobCall(verify_path, "health %s" % full_node_name)

    AssertCommand(["gnt-node", "health"], fail=True)

    # No data, exit 1 (all should fail)
    _UpdateOobFile(data_path, "")
    AssertCommand(["gnt-node", "power", "on", node_name], fail=True)
    _AssertOobCall(verify_path, "power-on %s" % full_node_name)

    try:
      AssertCommand(["gnt-node", "power", "-f", "off", node_name], fail=True)
      _AssertOobCall(verify_path, "power-off %s" % full_node_name)
    finally:
      AssertCommand(["gnt-node", "modify", "-O", "no", node_name])

    AssertCommand(["gnt-node", "power", "-f", "cycle", node_name], fail=True)
    _AssertOobCall(verify_path, "power-cycle %s" % full_node_name)

    AssertCommand(["gnt-node", "power", "status", node_name],
                  fail=True)
    _AssertOobCall(verify_path, "power-status %s" % full_node_name)

    AssertCommand(["gnt-node", "health", node_name],
                  fail=True)
    _AssertOobCall(verify_path, "health %s" % full_node_name)

    AssertCommand(["gnt-node", "health"], fail=True)

    # Different OOB script for node
    verify_path2 = qa_utils.UploadData(master.primary, "")
    oob_script = ("#!/bin/sh\n"
                  "echo \"$@\" > %s\n") % verify_path2
    oob_path2 = qa_utils.UploadData(master.primary, oob_script, mode=0700)

    try:
      AssertCommand(["gnt-node", "modify", "--node-parameters",
                     "oob_program=%s" % oob_path2, node_name])
      AssertCommand(["gnt-node", "power", "on", node_name])
      _AssertOobCall(verify_path2, "power-on %s" % full_node_name)
    finally:
      AssertCommand(["gnt-node", "modify", "--node-parameters",
                     "oob_program=default", node_name])
      AssertCommand(["rm", "-f", oob_path2, verify_path2])
  finally:
    AssertCommand(["gnt-cluster", "modify", "--node-parameters",
                   "oob_program="])
    AssertCommand(["rm", "-f", oob_path, verify_path, data_path,
                   exit_code_path])


def TestNodeList():
  """gnt-node list"""
  qa_utils.GenericQueryTest("gnt-node", query.NODE_FIELDS.keys())


def TestNodeListFields():
  """gnt-node list-fields"""
  qa_utils.GenericQueryFieldsTest("gnt-node", query.NODE_FIELDS.keys())


def TestNodeListDrbd(node, is_drbd):
  """gnt-node list-drbd"""
  master = qa_config.GetMasterNode()
  result_output = GetCommandOutput(master.primary,
                                   "gnt-node list-drbd --no-header %s" %
                                   node.primary)
  # Meaningful to note: there is but one instance, and the node is either the
  # primary or one of the secondaries
  if is_drbd:
    # Invoked for both primary and secondary
    per_disk_info = result_output.splitlines()
    for line in per_disk_info:
      try:
        drbd_node, _, _, _, _, drbd_peer = line.split()
      except ValueError:
        raise qa_error.Error("Could not examine list-drbd output: expected a"
                             " single row of 6 entries, found the following:"
                             " %s" % line)

      AssertIn(node.primary, [drbd_node, drbd_peer],
               msg="The output %s does not contain the node" % line)
  else:
    # Output should be empty, barring newlines
    AssertEqual(result_output.strip(), "")


def _BuildSetESCmd(action, value, node_name):
  cmd = ["gnt-node"]
  if action == "add":
    cmd.extend(["add", "--readd"])
    if not qa_config.GetModifySshSetup():
      cmd.append("--no-node-setup")
  else:
    cmd.append("modify")
  cmd.extend(["--node-parameters", "exclusive_storage=%s" % value, node_name])
  return cmd


def TestExclStorSingleNode(node):
  """gnt-node add/modify cannot change the exclusive_storage flag.

  """
  for action in ["add", "modify"]:
    for value in (True, False, "default"):
      AssertCommand(_BuildSetESCmd(action, value, node.primary), fail=True)
