#!/usr/bin/python
#

# Copyright (C) 2010, 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.


"""Script for testing ganeti.backend"""

import collections
import copy
import mock
import os
import shutil
import tempfile
import testutils
import testutils_ssh
import unittest

from ganeti import backend
from ganeti import constants
from ganeti import errors
from ganeti import hypervisor
from ganeti import netutils
from ganeti import objects
from ganeti import serializer
from ganeti import ssh
from ganeti import utils
from testutils.config_mock import ConfigMock


class TestX509Certificates(unittest.TestCase):
  def setUp(self):
    self.tmpdir = tempfile.mkdtemp()

  def tearDown(self):
    shutil.rmtree(self.tmpdir)

  def test(self):
    (name, cert_pem) = backend.CreateX509Certificate(300, cryptodir=self.tmpdir)

    self.assertEqual(utils.ReadFile(os.path.join(self.tmpdir, name,
                                                 backend._X509_CERT_FILE)),
                     cert_pem)
    self.assert_(0 < os.path.getsize(os.path.join(self.tmpdir, name,
                                                  backend._X509_KEY_FILE)))

    (name2, cert_pem2) = \
      backend.CreateX509Certificate(300, cryptodir=self.tmpdir)

    backend.RemoveX509Certificate(name, cryptodir=self.tmpdir)
    backend.RemoveX509Certificate(name2, cryptodir=self.tmpdir)

    self.assertEqual(utils.ListVisibleFiles(self.tmpdir), [])

  def testNonEmpty(self):
    (name, _) = backend.CreateX509Certificate(300, cryptodir=self.tmpdir)

    utils.WriteFile(utils.PathJoin(self.tmpdir, name, "hello-world"),
                    data="Hello World")

    self.assertRaises(backend.RPCFail, backend.RemoveX509Certificate,
                      name, cryptodir=self.tmpdir)

    self.assertEqual(utils.ListVisibleFiles(self.tmpdir), [name])


class TestGetCryptoTokens(testutils.GanetiTestCase):

  def setUp(self):
    self._get_digest_fn_orig = utils.GetCertificateDigest
    self._create_digest_fn_orig = utils.GenerateNewSslCert
    self._ssl_digest = "12345"
    utils.GetCertificateDigest = mock.Mock(
      return_value=self._ssl_digest)
    utils.GenerateNewSslCert = mock.Mock()

  def tearDown(self):
    utils.GetCertificateDigest = self._get_digest_fn_orig
    utils.GenerateNewSslCert = self._create_digest_fn_orig

  def testGetSslToken(self):
    result = backend.GetCryptoTokens(
      [(constants.CRYPTO_TYPE_SSL_DIGEST, constants.CRYPTO_ACTION_GET, None)])
    self.assertTrue((constants.CRYPTO_TYPE_SSL_DIGEST, self._ssl_digest)
                    in result)

  def testUnknownTokenType(self):
    self.assertRaises(errors.ProgrammerError,
                      backend.GetCryptoTokens,
                      [("pink_bunny", constants.CRYPTO_ACTION_GET, None)])

  def testUnknownAction(self):
    self.assertRaises(errors.ProgrammerError,
                      backend.GetCryptoTokens,
                      [(constants.CRYPTO_TYPE_SSL_DIGEST, "illuminate", None)])


class TestNodeVerify(testutils.GanetiTestCase):

  def setUp(self):
    testutils.GanetiTestCase.setUp(self)
    self._mock_hv = None

  def _GetHypervisor(self, hv_name):
    self._mock_hv = hypervisor.GetHypervisor(hv_name)
    self._mock_hv.ValidateParameters = mock.Mock()
    self._mock_hv.Verify = mock.Mock()
    return self._mock_hv

  def testMasterIPLocalhost(self):
    # this a real functional test, but requires localhost to be reachable
    my_name = netutils.Hostname.GetSysName()
    local_data = (my_name,constants.IP4_ADDRESS_LOCALHOST, [my_name])
    result = backend.VerifyNode({constants.NV_MASTERIP: local_data},
                                None, {})
    self.failUnless(constants.NV_MASTERIP in result,
                    "Master IP data not returned")
    self.failUnless(result[constants.NV_MASTERIP],
                    "Cannot reach localhost")

  def testMasterIPSkipTest(self):
    # this a real functional test, but requires localhost to be reachable
    local_data = (netutils.Hostname.GetSysName(),
                  constants.IP4_ADDRESS_LOCALHOST, [])
    result = backend.VerifyNode({constants.NV_MASTERIP: local_data},
                                None, {})
    self.failUnless(constants.NV_MASTERIP in result,
                    "Master IP data not returned")
    self.failUnless(result[constants.NV_MASTERIP] == None,
                    "Test ran by non master candidate")

  def testMasterIPUnreachable(self):
    # Network 192.0.2.0/24 is reserved for test/documentation as per
    # RFC 5737
    my_name = "master.example.com"
    bad_data =  (my_name, "192.0.2.1", [my_name])
    # we just test that whatever TcpPing returns, VerifyNode returns too
    netutils.TcpPing = lambda a, b, source=None: False
    result = backend.VerifyNode({constants.NV_MASTERIP: bad_data},
                                None, {})
    self.failUnless(constants.NV_MASTERIP in result,
                    "Master IP data not returned")
    self.failIf(result[constants.NV_MASTERIP],
                "Result from netutils.TcpPing corrupted")

  def testVerifyNodeNetTestMissingSelf(self):
    my_name = netutils.Hostname.GetSysName()
    local_data = ([('n1.test.com', "any", "any")], [my_name])
    result = backend.VerifyNode({constants.NV_NODENETTEST: local_data},
                                None, {})

    self.failUnless(constants.NV_NODENETTEST in result,
                    "NodeNetTest data not returned")
    self.failUnless(my_name in result[constants.NV_NODENETTEST],
                    "Missing failure in net test")

  def testVerifyNodeNetTest(self):
    my_name = netutils.Hostname.GetSysName()
    local_data = ([(my_name, "any", "any")], [my_name])

    # we just test that whatever TcpPing returns, VerifyNode returns too
    netutils.TcpPing = lambda a, b, source=None: True
    result = backend.VerifyNode({constants.NV_NODENETTEST: local_data},
                                None, {})

    self.failUnless(constants.NV_NODENETTEST in result,
                    "NodeNetTest data not returned")
    self.failUnless(result[constants.NV_NODENETTEST] == {},
                    "NodeNetTest failed")

  def testVerifyNodeNetSkipTest(self):
    local_data = ([('n1.test.com', "any", "any")], [])
    result = backend.VerifyNode({constants.NV_NODENETTEST: local_data},
                                None, {})
    self.failUnless(constants.NV_NODENETTEST in result,
                    "NodeNetTest data not returned")
    self.failUnless(result[constants.NV_NODENETTEST] == {},
                    "Test ran by non master candidate")

  def testVerifyHvparams(self):
    test_hvparams = {constants.HV_XEN_CMD: constants.XEN_CMD_XL}
    test_what = {constants.NV_HVPARAMS: \
        [("mynode", constants.HT_XEN_PVM, test_hvparams)]}
    result = {}
    backend._VerifyHvparams(test_what, True, result,
                            get_hv_fn=self._GetHypervisor)
    self._mock_hv.ValidateParameters.assert_called_with(test_hvparams)

  def testVerifyHypervisors(self):
    hvname = constants.HT_XEN_PVM
    hvparams = {constants.HV_XEN_CMD: constants.XEN_CMD_XL}
    all_hvparams = {hvname: hvparams}
    test_what = {constants.NV_HYPERVISOR: [hvname]}
    result = {}
    backend._VerifyHypervisors(
        test_what, True, result, all_hvparams=all_hvparams,
        get_hv_fn=self._GetHypervisor)
    self._mock_hv.Verify.assert_called_with(hvparams=hvparams)

  @testutils.patch_object(utils, "VerifyCertificate")
  def testVerifyClientCertificateSuccess(self, verif_cert):
    # mock the underlying x509 verification because the test cert is expired
    verif_cert.return_value = (None, None)
    cert_file = testutils.TestDataFilename("cert2.pem")
    (errcode, digest) = backend._VerifyClientCertificate(cert_file=cert_file)
    self.assertEqual(constants.CV_WARNING, errcode)
    self.assertTrue(isinstance(digest, str))

  @testutils.patch_object(utils, "VerifyCertificate")
  def testVerifyClientCertificateFailed(self, verif_cert):
    expected_errcode = 666
    verif_cert.return_value = (expected_errcode,
                               "The devil created this certificate.")
    cert_file = testutils.TestDataFilename("cert2.pem")
    (errcode, digest) = backend._VerifyClientCertificate(cert_file=cert_file)
    self.assertEqual(expected_errcode, errcode)

  def testVerifyClientCertificateNoCert(self):
    cert_file = testutils.TestDataFilename("cert-that-does-not-exist.pem")
    (errcode, digest) = backend._VerifyClientCertificate(cert_file=cert_file)
    self.assertEqual(constants.CV_ERROR, errcode)


def _DefRestrictedCmdOwner():
  return (os.getuid(), os.getgid())


class TestVerifyRestrictedCmdName(unittest.TestCase):
  def testAcceptableName(self):
    for i in ["foo", "bar", "z1", "000first", "hello-world"]:
      for fn in [lambda s: s, lambda s: s.upper(), lambda s: s.title()]:
        (status, msg) = backend._VerifyRestrictedCmdName(fn(i))
        self.assertTrue(status)
        self.assertTrue(msg is None)

  def testEmptyAndSpace(self):
    for i in ["", " ", "\t", "\n"]:
      (status, msg) = backend._VerifyRestrictedCmdName(i)
      self.assertFalse(status)
      self.assertEqual(msg, "Missing command name")

  def testNameWithSlashes(self):
    for i in ["/", "./foo", "../moo", "some/name"]:
      (status, msg) = backend._VerifyRestrictedCmdName(i)
      self.assertFalse(status)
      self.assertEqual(msg, "Invalid command name")

  def testForbiddenCharacters(self):
    for i in ["#", ".", "..", "bash -c ls", "'"]:
      (status, msg) = backend._VerifyRestrictedCmdName(i)
      self.assertFalse(status)
      self.assertEqual(msg, "Command name contains forbidden characters")


class TestVerifyRestrictedCmdDirectory(unittest.TestCase):
  def setUp(self):
    self.tmpdir = tempfile.mkdtemp()

  def tearDown(self):
    shutil.rmtree(self.tmpdir)

  def testCanNotStat(self):
    tmpname = utils.PathJoin(self.tmpdir, "foobar")
    self.assertFalse(os.path.exists(tmpname))
    (status, msg) = \
      backend._VerifyRestrictedCmdDirectory(tmpname, _owner=NotImplemented)
    self.assertFalse(status)
    self.assertTrue(msg.startswith("Can't stat(2) '"))

  def testTooPermissive(self):
    tmpname = utils.PathJoin(self.tmpdir, "foobar")
    os.mkdir(tmpname)

    for mode in [0777, 0706, 0760, 0722]:
      os.chmod(tmpname, mode)
      self.assertTrue(os.path.isdir(tmpname))
      (status, msg) = \
        backend._VerifyRestrictedCmdDirectory(tmpname, _owner=NotImplemented)
      self.assertFalse(status)
      self.assertTrue(msg.startswith("Permissions on '"))

  def testNoDirectory(self):
    tmpname = utils.PathJoin(self.tmpdir, "foobar")
    utils.WriteFile(tmpname, data="empty\n")
    self.assertTrue(os.path.isfile(tmpname))
    (status, msg) = \
      backend._VerifyRestrictedCmdDirectory(tmpname,
                                            _owner=_DefRestrictedCmdOwner())
    self.assertFalse(status)
    self.assertTrue(msg.endswith("is not a directory"))

  def testNormal(self):
    tmpname = utils.PathJoin(self.tmpdir, "foobar")
    os.mkdir(tmpname)
    os.chmod(tmpname, 0755)
    self.assertTrue(os.path.isdir(tmpname))
    (status, msg) = \
      backend._VerifyRestrictedCmdDirectory(tmpname,
                                            _owner=_DefRestrictedCmdOwner())
    self.assertTrue(status)
    self.assertTrue(msg is None)


class TestVerifyRestrictedCmd(unittest.TestCase):
  def setUp(self):
    self.tmpdir = tempfile.mkdtemp()

  def tearDown(self):
    shutil.rmtree(self.tmpdir)

  def testCanNotStat(self):
    tmpname = utils.PathJoin(self.tmpdir, "helloworld")
    self.assertFalse(os.path.exists(tmpname))
    (status, msg) = \
      backend._VerifyRestrictedCmd(self.tmpdir, "helloworld",
                                   _owner=NotImplemented)
    self.assertFalse(status)
    self.assertTrue(msg.startswith("Can't stat(2) '"))

  def testNotExecutable(self):
    tmpname = utils.PathJoin(self.tmpdir, "cmdname")
    utils.WriteFile(tmpname, data="empty\n")
    (status, msg) = \
      backend._VerifyRestrictedCmd(self.tmpdir, "cmdname",
                                   _owner=_DefRestrictedCmdOwner())
    self.assertFalse(status)
    self.assertTrue(msg.startswith("access(2) thinks '"))

  def testExecutable(self):
    tmpname = utils.PathJoin(self.tmpdir, "cmdname")
    utils.WriteFile(tmpname, data="empty\n", mode=0700)
    (status, executable) = \
      backend._VerifyRestrictedCmd(self.tmpdir, "cmdname",
                                   _owner=_DefRestrictedCmdOwner())
    self.assertTrue(status)
    self.assertEqual(executable, tmpname)


class TestPrepareRestrictedCmd(unittest.TestCase):
  _TEST_PATH = "/tmp/some/test/path"

  def testDirFails(self):
    def fn(path):
      self.assertEqual(path, self._TEST_PATH)
      return (False, "test error 31420")

    (status, msg) = \
      backend._PrepareRestrictedCmd(self._TEST_PATH, "cmd21152",
                                    _verify_dir=fn,
                                    _verify_name=NotImplemented,
                                    _verify_cmd=NotImplemented)
    self.assertFalse(status)
    self.assertEqual(msg, "test error 31420")

  def testNameFails(self):
    def fn(cmd):
      self.assertEqual(cmd, "cmd4617")
      return (False, "test error 591")

    (status, msg) = \
      backend._PrepareRestrictedCmd(self._TEST_PATH, "cmd4617",
                                    _verify_dir=lambda _: (True, None),
                                    _verify_name=fn,
                                    _verify_cmd=NotImplemented)
    self.assertFalse(status)
    self.assertEqual(msg, "test error 591")

  def testCommandFails(self):
    def fn(path, cmd):
      self.assertEqual(path, self._TEST_PATH)
      self.assertEqual(cmd, "cmd17577")
      return (False, "test error 25524")

    (status, msg) = \
      backend._PrepareRestrictedCmd(self._TEST_PATH, "cmd17577",
                                    _verify_dir=lambda _: (True, None),
                                    _verify_name=lambda _: (True, None),
                                    _verify_cmd=fn)
    self.assertFalse(status)
    self.assertEqual(msg, "test error 25524")

  def testSuccess(self):
    def fn(path, cmd):
      return (True, utils.PathJoin(path, cmd))

    (status, executable) = \
      backend._PrepareRestrictedCmd(self._TEST_PATH, "cmd22633",
                                    _verify_dir=lambda _: (True, None),
                                    _verify_name=lambda _: (True, None),
                                    _verify_cmd=fn)
    self.assertTrue(status)
    self.assertEqual(executable, utils.PathJoin(self._TEST_PATH, "cmd22633"))


def _SleepForRestrictedCmd(duration):
  assert duration > 5


def _GenericRestrictedCmdError(cmd):
  return "Executing command '%s' failed" % cmd


class TestRunRestrictedCmd(unittest.TestCase):
  def setUp(self):
    self.tmpdir = tempfile.mkdtemp()

  def tearDown(self):
    shutil.rmtree(self.tmpdir)

  def testNonExistantLockDirectory(self):
    lockfile = utils.PathJoin(self.tmpdir, "does", "not", "exist")
    sleep_fn = testutils.CallCounter(_SleepForRestrictedCmd)
    self.assertFalse(os.path.exists(lockfile))
    self.assertRaises(backend.RPCFail,
                      backend.RunRestrictedCmd, "test",
                      _lock_timeout=NotImplemented,
                      _lock_file=lockfile,
                      _path=NotImplemented,
                      _sleep_fn=sleep_fn,
                      _prepare_fn=NotImplemented,
                      _runcmd_fn=NotImplemented,
                      _enabled=True)
    self.assertEqual(sleep_fn.Count(), 1)

  @staticmethod
  def _TryLock(lockfile):
    sleep_fn = testutils.CallCounter(_SleepForRestrictedCmd)

    result = False
    try:
      backend.RunRestrictedCmd("test22717",
                               _lock_timeout=0.1,
                               _lock_file=lockfile,
                               _path=NotImplemented,
                               _sleep_fn=sleep_fn,
                               _prepare_fn=NotImplemented,
                               _runcmd_fn=NotImplemented,
                               _enabled=True)
    except backend.RPCFail, err:
      assert str(err) == _GenericRestrictedCmdError("test22717"), \
             "Did not fail with generic error message"
      result = True

    assert sleep_fn.Count() == 1

    return result

  def testLockHeldByOtherProcess(self):
    lockfile = utils.PathJoin(self.tmpdir, "lock")

    lock = utils.FileLock.Open(lockfile)
    lock.Exclusive(blocking=True, timeout=1.0)
    try:
      self.assertTrue(utils.RunInSeparateProcess(self._TryLock, lockfile))
    finally:
      lock.Close()

  @staticmethod
  def _PrepareRaisingException(path, cmd):
    assert cmd == "test23122"
    raise Exception("test")

  def testPrepareRaisesException(self):
    lockfile = utils.PathJoin(self.tmpdir, "lock")

    sleep_fn = testutils.CallCounter(_SleepForRestrictedCmd)
    prepare_fn = testutils.CallCounter(self._PrepareRaisingException)

    try:
      backend.RunRestrictedCmd("test23122",
                               _lock_timeout=1.0, _lock_file=lockfile,
                               _path=NotImplemented, _runcmd_fn=NotImplemented,
                               _sleep_fn=sleep_fn, _prepare_fn=prepare_fn,
                               _enabled=True)
    except backend.RPCFail, err:
      self.assertEqual(str(err), _GenericRestrictedCmdError("test23122"))
    else:
      self.fail("Didn't fail")

    self.assertEqual(sleep_fn.Count(), 1)
    self.assertEqual(prepare_fn.Count(), 1)

  @staticmethod
  def _PrepareFails(path, cmd):
    assert cmd == "test29327"
    return ("some error message", None)

  def testPrepareFails(self):
    lockfile = utils.PathJoin(self.tmpdir, "lock")

    sleep_fn = testutils.CallCounter(_SleepForRestrictedCmd)
    prepare_fn = testutils.CallCounter(self._PrepareFails)

    try:
      backend.RunRestrictedCmd("test29327",
                               _lock_timeout=1.0, _lock_file=lockfile,
                               _path=NotImplemented, _runcmd_fn=NotImplemented,
                               _sleep_fn=sleep_fn, _prepare_fn=prepare_fn,
                               _enabled=True)
    except backend.RPCFail, err:
      self.assertEqual(str(err), _GenericRestrictedCmdError("test29327"))
    else:
      self.fail("Didn't fail")

    self.assertEqual(sleep_fn.Count(), 1)
    self.assertEqual(prepare_fn.Count(), 1)

  @staticmethod
  def _SuccessfulPrepare(path, cmd):
    return (True, utils.PathJoin(path, cmd))

  def testRunCmdFails(self):
    lockfile = utils.PathJoin(self.tmpdir, "lock")

    def fn(args, env=NotImplemented, reset_env=NotImplemented,
           postfork_fn=NotImplemented):
      self.assertEqual(args, [utils.PathJoin(self.tmpdir, "test3079")])
      self.assertEqual(env, {})
      self.assertTrue(reset_env)
      self.assertTrue(callable(postfork_fn))

      trylock = utils.FileLock.Open(lockfile)
      try:
        # See if lockfile is still held
        self.assertRaises(EnvironmentError, trylock.Exclusive, blocking=False)

        # Call back to release lock
        postfork_fn(NotImplemented)

        # See if lockfile can be acquired
        trylock.Exclusive(blocking=False)
      finally:
        trylock.Close()

      # Simulate a failed command
      return utils.RunResult(constants.EXIT_FAILURE, None,
                             "stdout", "stderr406328567",
                             utils.ShellQuoteArgs(args),
                             NotImplemented, NotImplemented)

    sleep_fn = testutils.CallCounter(_SleepForRestrictedCmd)
    prepare_fn = testutils.CallCounter(self._SuccessfulPrepare)
    runcmd_fn = testutils.CallCounter(fn)

    try:
      backend.RunRestrictedCmd("test3079",
                               _lock_timeout=1.0, _lock_file=lockfile,
                               _path=self.tmpdir, _runcmd_fn=runcmd_fn,
                               _sleep_fn=sleep_fn, _prepare_fn=prepare_fn,
                               _enabled=True)
    except backend.RPCFail, err:
      self.assertTrue(str(err).startswith("Restricted command 'test3079'"
                                          " failed:"))
      self.assertTrue("stderr406328567" in str(err),
                      msg="Error did not include output")
    else:
      self.fail("Didn't fail")

    self.assertEqual(sleep_fn.Count(), 0)
    self.assertEqual(prepare_fn.Count(), 1)
    self.assertEqual(runcmd_fn.Count(), 1)

  def testRunCmdSucceeds(self):
    lockfile = utils.PathJoin(self.tmpdir, "lock")

    def fn(args, env=NotImplemented, reset_env=NotImplemented,
           postfork_fn=NotImplemented):
      self.assertEqual(args, [utils.PathJoin(self.tmpdir, "test5667")])
      self.assertEqual(env, {})
      self.assertTrue(reset_env)

      # Call back to release lock
      postfork_fn(NotImplemented)

      # Simulate a successful command
      return utils.RunResult(constants.EXIT_SUCCESS, None, "stdout14463", "",
                             utils.ShellQuoteArgs(args),
                             NotImplemented, NotImplemented)

    sleep_fn = testutils.CallCounter(_SleepForRestrictedCmd)
    prepare_fn = testutils.CallCounter(self._SuccessfulPrepare)
    runcmd_fn = testutils.CallCounter(fn)

    result = backend.RunRestrictedCmd("test5667",
                                      _lock_timeout=1.0, _lock_file=lockfile,
                                      _path=self.tmpdir, _runcmd_fn=runcmd_fn,
                                      _sleep_fn=sleep_fn,
                                      _prepare_fn=prepare_fn,
                                      _enabled=True)
    self.assertEqual(result, "stdout14463")

    self.assertEqual(sleep_fn.Count(), 0)
    self.assertEqual(prepare_fn.Count(), 1)
    self.assertEqual(runcmd_fn.Count(), 1)

  def testCommandsDisabled(self):
    try:
      backend.RunRestrictedCmd("test",
                               _lock_timeout=NotImplemented,
                               _lock_file=NotImplemented,
                               _path=NotImplemented,
                               _sleep_fn=NotImplemented,
                               _prepare_fn=NotImplemented,
                               _runcmd_fn=NotImplemented,
                               _enabled=False)
    except backend.RPCFail, err:
      self.assertEqual(str(err),
                       "Restricted commands disabled at configure time")
    else:
      self.fail("Did not raise exception")


class TestSetWatcherPause(unittest.TestCase):
  def setUp(self):
    self.tmpdir = tempfile.mkdtemp()
    self.filename = utils.PathJoin(self.tmpdir, "pause")

  def tearDown(self):
    shutil.rmtree(self.tmpdir)

  def testUnsetNonExisting(self):
    self.assertFalse(os.path.exists(self.filename))
    backend.SetWatcherPause(None, _filename=self.filename)
    self.assertFalse(os.path.exists(self.filename))

  def testSetNonNumeric(self):
    for i in ["", [], {}, "Hello World", "0", "1.0"]:
      self.assertFalse(os.path.exists(self.filename))

      try:
        backend.SetWatcherPause(i, _filename=self.filename)
      except backend.RPCFail, err:
        self.assertEqual(str(err), "Duration must be numeric")
      else:
        self.fail("Did not raise exception")

      self.assertFalse(os.path.exists(self.filename))

  def testSet(self):
    self.assertFalse(os.path.exists(self.filename))

    for i in range(10):
      backend.SetWatcherPause(i, _filename=self.filename)
      self.assertEqual(utils.ReadFile(self.filename), "%s\n" % i)
      self.assertEqual(os.stat(self.filename).st_mode & 0777, 0644)


class TestGetBlockDevSymlinkPath(unittest.TestCase):
  def setUp(self):
    self.tmpdir = tempfile.mkdtemp()

  def tearDown(self):
    shutil.rmtree(self.tmpdir)

  def _Test(self, name, idx):
    self.assertEqual(backend._GetBlockDevSymlinkPath(name, idx,
                                                     _dir=self.tmpdir),
                     ("%s/%s%s%s" % (self.tmpdir, name,
                                     constants.DISK_SEPARATOR, idx)))

  def test(self):
    for idx in range(100):
      self._Test("inst1.example.com", idx)


class TestGetInstanceList(unittest.TestCase):

  def setUp(self):
    self._test_hv = self._TestHypervisor()
    self._test_hv.ListInstances = mock.Mock(
      return_value=["instance1", "instance2", "instance3"] )

  class _TestHypervisor(hypervisor.hv_base.BaseHypervisor):
    def __init__(self):
      hypervisor.hv_base.BaseHypervisor.__init__(self)

  def _GetHypervisor(self, name):
    return self._test_hv

  def testHvparams(self):
    fake_hvparams = {constants.HV_XEN_CMD: constants.XEN_CMD_XL}
    hvparams = {constants.HT_FAKE: fake_hvparams}
    backend.GetInstanceList([constants.HT_FAKE], all_hvparams=hvparams,
                            get_hv_fn=self._GetHypervisor)
    self._test_hv.ListInstances.assert_called_with(hvparams=fake_hvparams)


class TestInstanceConsoleInfo(unittest.TestCase):

  def setUp(self):
    self._test_hv_a = self._TestHypervisor()
    self._test_hv_a.GetInstanceConsole = mock.Mock(
      return_value = objects.InstanceConsole(instance="inst", kind="aHy")
    )
    self._test_hv_b = self._TestHypervisor()
    self._test_hv_b.GetInstanceConsole = mock.Mock(
      return_value = objects.InstanceConsole(instance="inst", kind="bHy")
    )

  class _TestHypervisor(hypervisor.hv_base.BaseHypervisor):
    def __init__(self):
      hypervisor.hv_base.BaseHypervisor.__init__(self)

  def _GetHypervisor(self, name):
    if name == "a":
      return self._test_hv_a
    else:
      return self._test_hv_b

  def testRightHypervisor(self):
    dictMaker = lambda hyName: {
      "instance":{"hypervisor":hyName},
      "node":{},
      "group":{},
      "hvParams":{},
      "beParams":{},
    }

    call = {
      'i1':dictMaker("a"),
      'i2':dictMaker("b"),
    }

    res = backend.GetInstanceConsoleInfo(call, get_hv_fn=self._GetHypervisor)

    self.assertTrue(res["i1"]["kind"] == "aHy")
    self.assertTrue(res["i2"]["kind"] == "bHy")


class TestGetHvInfo(unittest.TestCase):

  def setUp(self):
    self._test_hv = self._TestHypervisor()
    self._test_hv.GetNodeInfo = mock.Mock()

  class _TestHypervisor(hypervisor.hv_base.BaseHypervisor):
    def __init__(self):
      hypervisor.hv_base.BaseHypervisor.__init__(self)

  def _GetHypervisor(self, name):
    return self._test_hv

  def testGetHvInfoAllNone(self):
    result = backend._GetHvInfoAll(None)
    self.assertTrue(result is None)

  def testGetHvInfoAll(self):
    hvname = constants.HT_XEN_PVM
    hvparams = {constants.HV_XEN_CMD: constants.XEN_CMD_XL}
    hv_specs = [(hvname, hvparams)]

    backend._GetHvInfoAll(hv_specs, self._GetHypervisor)
    self._test_hv.GetNodeInfo.assert_called_with(hvparams=hvparams)


class TestApplyStorageInfoFunction(unittest.TestCase):

  _STORAGE_KEY = "some_key"
  _SOME_ARGS = ["some_args"]

  def setUp(self):
    self.mock_storage_fn = mock.Mock()

  def testApplyValidStorageType(self):
    storage_type = constants.ST_LVM_VG
    info_fn_orig = backend._STORAGE_TYPE_INFO_FN
    backend._STORAGE_TYPE_INFO_FN = {
        storage_type: self.mock_storage_fn
      }

    backend._ApplyStorageInfoFunction(
        storage_type, self._STORAGE_KEY, self._SOME_ARGS)

    self.mock_storage_fn.assert_called_with(self._STORAGE_KEY, self._SOME_ARGS)
    backend._STORAGE_TYPE_INFO_FN = info_fn_orig

  def testApplyInValidStorageType(self):
    storage_type = "invalid_storage_type"
    info_fn_orig = backend._STORAGE_TYPE_INFO_FN
    backend._STORAGE_TYPE_INFO_FN = {}

    self.assertRaises(KeyError, backend._ApplyStorageInfoFunction,
                      storage_type, self._STORAGE_KEY, self._SOME_ARGS)
    backend._STORAGE_TYPE_INFO_FN = info_fn_orig

  def testApplyNotImplementedStorageType(self):
    storage_type = "not_implemented_storage_type"
    info_fn_orig = backend._STORAGE_TYPE_INFO_FN
    backend._STORAGE_TYPE_INFO_FN = {storage_type: None}

    self.assertRaises(NotImplementedError,
                      backend._ApplyStorageInfoFunction,
                      storage_type, self._STORAGE_KEY, self._SOME_ARGS)
    backend._STORAGE_TYPE_INFO_FN = info_fn_orig


class TestGetLvmVgSpaceInfo(unittest.TestCase):

  def testValid(self):
    path = "somepath"
    excl_stor = True
    orig_fn = backend._GetVgInfo
    backend._GetVgInfo = mock.Mock()
    backend._GetLvmVgSpaceInfo(path, [excl_stor])
    backend._GetVgInfo.assert_called_with(path, excl_stor)
    backend._GetVgInfo = orig_fn

  def testNoExclStorageNotBool(self):
    path = "somepath"
    excl_stor = "123"
    self.assertRaises(errors.ProgrammerError, backend._GetLvmVgSpaceInfo,
                      path, [excl_stor])

  def testNoExclStorageNotInList(self):
    path = "somepath"
    excl_stor = "123"
    self.assertRaises(errors.ProgrammerError, backend._GetLvmVgSpaceInfo,
                      path, excl_stor)

class TestGetLvmPvSpaceInfo(unittest.TestCase):

  def testValid(self):
    path = "somepath"
    excl_stor = True
    orig_fn = backend._GetVgSpindlesInfo
    backend._GetVgSpindlesInfo = mock.Mock()
    backend._GetLvmPvSpaceInfo(path, [excl_stor])
    backend._GetVgSpindlesInfo.assert_called_with(path, excl_stor)
    backend._GetVgSpindlesInfo = orig_fn


class TestCheckStorageParams(unittest.TestCase):

  def testParamsNone(self):
    self.assertRaises(errors.ProgrammerError, backend._CheckStorageParams,
                      None, NotImplemented)

  def testParamsWrongType(self):
    self.assertRaises(errors.ProgrammerError, backend._CheckStorageParams,
                      "string", NotImplemented)

  def testParamsEmpty(self):
    backend._CheckStorageParams([], 0)

  def testParamsValidNumber(self):
    backend._CheckStorageParams(["a", True], 2)

  def testParamsInvalidNumber(self):
    self.assertRaises(errors.ProgrammerError, backend._CheckStorageParams,
                      ["b", False], 3)


class TestGetVgSpindlesInfo(unittest.TestCase):

  def setUp(self):
    self.vg_free = 13
    self.vg_size = 31
    self.mock_fn = mock.Mock(return_value=(self.vg_free, self.vg_size))

  def testValidInput(self):
    name = "myvg"
    excl_stor = True
    result = backend._GetVgSpindlesInfo(name, excl_stor, info_fn=self.mock_fn)
    self.mock_fn.assert_called_with(name)
    self.assertEqual(name, result["name"])
    self.assertEqual(constants.ST_LVM_PV, result["type"])
    self.assertEqual(self.vg_free, result["storage_free"])
    self.assertEqual(self.vg_size, result["storage_size"])

  def testNoExclStor(self):
    name = "myvg"
    excl_stor = False
    result = backend._GetVgSpindlesInfo(name, excl_stor, info_fn=self.mock_fn)
    self.mock_fn.assert_not_called()
    self.assertEqual(name, result["name"])
    self.assertEqual(constants.ST_LVM_PV, result["type"])
    self.assertEqual(0, result["storage_free"])
    self.assertEqual(0, result["storage_size"])


class TestGetVgSpindlesInfo(unittest.TestCase):

  def testValidInput(self):
    self.vg_free = 13
    self.vg_size = 31
    self.mock_fn = mock.Mock(return_value=[(self.vg_free, self.vg_size)])
    name = "myvg"
    excl_stor = True
    result = backend._GetVgInfo(name, excl_stor, info_fn=self.mock_fn)
    self.mock_fn.assert_called_with([name], excl_stor)
    self.assertEqual(name, result["name"])
    self.assertEqual(constants.ST_LVM_VG, result["type"])
    self.assertEqual(self.vg_free, result["storage_free"])
    self.assertEqual(self.vg_size, result["storage_size"])

  def testNoExclStor(self):
    name = "myvg"
    excl_stor = True
    self.mock_fn = mock.Mock(return_value=None)
    result = backend._GetVgInfo(name, excl_stor, info_fn=self.mock_fn)
    self.mock_fn.assert_called_with([name], excl_stor)
    self.assertEqual(name, result["name"])
    self.assertEqual(constants.ST_LVM_VG, result["type"])
    self.assertEqual(None, result["storage_free"])
    self.assertEqual(None, result["storage_size"])


class TestGetNodeInfo(unittest.TestCase):

  _SOME_RESULT = None

  def testApplyStorageInfoFunction(self):
    orig_fn = backend._ApplyStorageInfoFunction
    backend._ApplyStorageInfoFunction = mock.Mock(
        return_value=self._SOME_RESULT)
    storage_units = [(st, st + "_key", [st + "_params"]) for st in
                     constants.STORAGE_TYPES]

    backend.GetNodeInfo(storage_units, None)

    call_args_list = backend._ApplyStorageInfoFunction.call_args_list
    self.assertEqual(len(constants.STORAGE_TYPES), len(call_args_list))
    for call in call_args_list:
      storage_type, storage_key, storage_params = call[0]
      self.assertEqual(storage_type + "_key", storage_key)
      self.assertEqual([storage_type + "_params"], storage_params)
      self.assertTrue(storage_type in constants.STORAGE_TYPES)
    backend._ApplyStorageInfoFunction = orig_fn


class TestSpaceReportingConstants(unittest.TestCase):
  """Ensures consistency between STS_REPORT and backend.

  These tests ensure, that the constant 'STS_REPORT' is consistent
  with the implementation of invoking space reporting functions
  in backend.py. Once space reporting is available for all types,
  the constant can be removed and these tests as well.

  """

  REPORTING = set(constants.STS_REPORT)
  NOT_REPORTING = set(constants.STORAGE_TYPES) - REPORTING

  def testAllReportingTypesHaveAReportingFunction(self):
    for storage_type in TestSpaceReportingConstants.REPORTING:
      self.assertTrue(backend._STORAGE_TYPE_INFO_FN[storage_type] is not None)

  def testAllNotReportingTypesDontHaveFunction(self):
    for storage_type in TestSpaceReportingConstants.NOT_REPORTING:
      self.assertEqual(None, backend._STORAGE_TYPE_INFO_FN[storage_type])


class TestAddRemoveGenerateNodeSshKey(testutils.GanetiTestCase):

  _CLUSTER_NAME = "mycluster"
  _SSH_PORT = 22

  def setUp(self):
    self._ssh_file_manager = testutils_ssh.FakeSshFileManager()
    testutils.GanetiTestCase.setUp(self)
    self._ssh_add_authorized_patcher = testutils \
      .patch_object(ssh, "AddAuthorizedKeys")
    self._ssh_remove_authorized_patcher = testutils \
      .patch_object(ssh, "RemoveAuthorizedKeys")
    self._ssh_add_authorized_mock = self._ssh_add_authorized_patcher.start()
    self._ssh_add_authorized_mock.side_effect = \
        self._ssh_file_manager.AddAuthorizedKeys

    self._ssconf_mock = mock.Mock()
    self._ssconf_mock.GetNodeList = mock.Mock()
    self._ssconf_mock.GetMasterNode = mock.Mock()
    self._ssconf_mock.GetClusterName = mock.Mock()
    self._ssconf_mock.GetOnlineNodeList = mock.Mock()
    self._ssconf_mock.GetSshPortMap = mock.Mock()

    self._run_cmd_mock = mock.Mock()
    self._run_cmd_mock.side_effect = self._ssh_file_manager.RunCommand

    self._ssh_remove_authorized_mock = \
      self._ssh_remove_authorized_patcher.start()
    self._ssh_remove_authorized_mock.side_effect = \
        self._ssh_file_manager.RemoveAuthorizedKeys

    self._ssh_add_public_key_patcher = testutils \
      .patch_object(ssh, "AddPublicKey")
    self._ssh_add_public_key_mock = \
      self._ssh_add_public_key_patcher.start()
    self._ssh_add_public_key_mock.side_effect = \
      self._ssh_file_manager.AddPublicKey

    self._ssh_remove_public_key_patcher = testutils \
      .patch_object(ssh, "RemovePublicKey")
    self._ssh_remove_public_key_mock = \
      self._ssh_remove_public_key_patcher.start()
    self._ssh_remove_public_key_mock.side_effect = \
      self._ssh_file_manager.RemovePublicKey

    self._ssh_query_pub_key_file_patcher = testutils \
      .patch_object(ssh, "QueryPubKeyFile")
    self._ssh_query_pub_key_file_mock = \
      self._ssh_query_pub_key_file_patcher.start()
    self._ssh_query_pub_key_file_mock.side_effect = \
      self._ssh_file_manager.QueryPubKeyFile

    self._ssh_replace_name_by_uuid_patcher = testutils \
      .patch_object(ssh, "ReplaceNameByUuid")
    self._ssh_replace_name_by_uuid_mock = \
      self._ssh_replace_name_by_uuid_patcher.start()
    self._ssh_replace_name_by_uuid_mock.side_effect = \
      self._ssh_file_manager.ReplaceNameByUuid

    self.noded_cert_file = testutils.TestDataFilename("cert1.pem")

    self._SetupTestData()

  def tearDown(self):
    super(testutils.GanetiTestCase, self).tearDown()
    self._ssh_add_authorized_patcher.stop()
    self._ssh_remove_authorized_patcher.stop()
    self._ssh_add_public_key_patcher.stop()
    self._ssh_remove_public_key_patcher.stop()
    self._ssh_query_pub_key_file_patcher.stop()
    self._ssh_replace_name_by_uuid_patcher.stop()
    self._TearDownTestData()

  def _SetupTestData(self, number_of_nodes=15, number_of_pot_mcs=5,
                     number_of_mcs=5):
    """Sets up consistent test data for a cluster with a couple of nodes.

    """
    self._pub_key_file = self._CreateTempFile()
    self._all_nodes = []
    self._potential_master_candidates = []
    self._master_candidate_uuids = []

    self._ssconf_mock.reset_mock()
    self._ssconf_mock.GetNodeList.reset_mock()
    self._ssconf_mock.GetMasterNode.reset_mock()
    self._ssconf_mock.GetClusterName.reset_mock()
    self._ssconf_mock.GetOnlineNodeList.reset_mock()
    self._run_cmd_mock.reset_mock()

    self._ssh_file_manager.InitAllNodes(15, 10, 5)
    self._master_node = self._ssh_file_manager.GetMasterNodeName()
    self._ssconf_mock.GetSshPortMap.return_value = \
        self._ssh_file_manager.GetSshPortMap(self._SSH_PORT)
    self._potential_master_candidates = \
        self._ssh_file_manager.GetAllPotentialMasterCandidateNodeNames()
    self._master_candidate_uuids = \
        self._ssh_file_manager.GetAllMasterCandidateUuids()
    self._all_nodes = self._ssh_file_manager.GetAllNodeNames()

    self._ssconf_mock.GetNodeList.side_effect = \
        self._ssh_file_manager.GetAllNodeNames
    self._ssconf_mock.GetOnlineNodeList.side_effect = \
        self._ssh_file_manager.GetAllNodeNames
    self._ssconf_mock.GetMasterNode.side_effect = \
        self._ssh_file_manager.GetMasterNodeName

  def _TearDownTestData(self):
    os.remove(self._pub_key_file)

  def _GetCallsPerNode(self):
    calls_per_node = {}
    for (pos, keyword) in self._run_cmd_mock.call_args_list:
      (cluster_name, node, _, _, data) = pos
      if not node in calls_per_node:
        calls_per_node[node] = []
      calls_per_node[node].append(data)
    return calls_per_node

  def testGenerateKey(self):
    test_node_name = "node_name_7"
    test_node_uuid = "node_uuid_7"

    self._SetupTestData()
    ssh.AddPublicKey(test_node_uuid, "some_old_key",
                     key_file=self._pub_key_file)

    backend._GenerateNodeSshKey(
        test_node_uuid, test_node_name,
        self._ssh_file_manager.GetSshPortMap(self._SSH_PORT),
        "rsa", 2048,
        pub_key_file=self._pub_key_file,
        ssconf_store=self._ssconf_mock,
        noded_cert_file=self.noded_cert_file,
        run_cmd_fn=self._run_cmd_mock)

    calls_per_node = self._GetCallsPerNode()
    for node, calls in calls_per_node.items():
      self.assertEquals(node, test_node_name)
      for call in calls:
        self.assertTrue(constants.SSHS_GENERATE in call)

  def _AddNewNodeToTestData(self, name, uuid, key, pot_mc, mc, master):
    self._ssh_file_manager.SetOrAddNode(name, uuid, key, pot_mc, mc, master)

    if pot_mc:
      ssh.AddPublicKey(name, key, key_file=self._pub_key_file)
      self._potential_master_candidates.append(name)

    self._ssconf_mock.GetSshPortMap.return_value = \
        self._ssh_file_manager.GetSshPortMap(self._SSH_PORT)

  def _GetNewMasterCandidate(self):
    """Returns the properties of a new master candidate node."""
    return ("new_node_name", "new_node_uuid", "new_node_key",
            True, True, False)

  def _GetNewNumberedMasterCandidate(self, num):
    """Returns the properties of a new master candidate node."""
    return ("new_node_name_%s" % num,
            "new_node_uuid_%s" % num,
            "new_node_key_%s" % num,
            True, True, False)

  def _GetNewNumberedPotentialMasterCandidate(self, num):
    """Returns the properties of a new potential master candidate node."""
    return ("new_node_name_%s" % num,
            "new_node_uuid_%s" % num,
            "new_node_key_%s" % num,
            False, True, False)

  def _GetNewNumberedNormalNode(self, num):
    """Returns the properties of a new normal node."""
    return ("new_node_name_%s" % num,
            "new_node_uuid_%s" % num,
            "new_node_key_%s" % num,
            False, False, False)

  def testAddMasterCandidate(self):
    (new_node_name, new_node_uuid, new_node_key, is_master_candidate,
     is_potential_master_candidate, is_master) = self._GetNewMasterCandidate()

    self._AddNewNodeToTestData(
        new_node_name, new_node_uuid, new_node_key,
        is_potential_master_candidate, is_master_candidate,
        is_master)

    backend.AddNodeSshKey(new_node_uuid, new_node_name,
                          self._potential_master_candidates,
                          to_authorized_keys=is_master_candidate,
                          to_public_keys=is_potential_master_candidate,
                          get_public_keys=is_potential_master_candidate,
                          pub_key_file=self._pub_key_file,
                          ssconf_store=self._ssconf_mock,
                          noded_cert_file=self.noded_cert_file,
                          run_cmd_fn=self._run_cmd_mock)

    self._ssh_file_manager.AssertPotentialMasterCandidatesOnlyHavePublicKey(
        new_node_name)
    self._ssh_file_manager.AssertAllNodesHaveAuthorizedKey(new_node_key)

  def _SetupNodeBulk(self, num_nodes, node_fn):
    """Sets up the test data for a bulk of nodes.

    @param num_nodes: number of nodes
    @type num_nodes: integer
    @param node_fn: function
    @param node_fn: function to generate data of one node, taking an
      integer as only argument

    """
    node_list = []
    key_map = {}

    for i in range(num_nodes):
      (new_node_name, new_node_uuid, new_node_key, is_master_candidate,
       is_potential_master_candidate, is_master) = \
          node_fn(i)

      self._AddNewNodeToTestData(
          new_node_name, new_node_uuid, new_node_key,
          is_potential_master_candidate, is_master_candidate,
          is_master)

      node_list.append(
          backend.SshAddNodeInfo(
              uuid=new_node_uuid,
              name=new_node_name,
              to_authorized_keys=is_master_candidate,
              to_public_keys=is_potential_master_candidate,
              get_public_keys=is_potential_master_candidate))

      key_map[new_node_name] = new_node_key

    return (node_list, key_map)

  def testAddMasterCandidateBulk(self):
    num_nodes = 3
    (node_list, key_map) = self._SetupNodeBulk(
        num_nodes, self._GetNewNumberedMasterCandidate)

    backend.AddNodeSshKeyBulk(node_list,
                              self._potential_master_candidates,
                              pub_key_file=self._pub_key_file,
                              ssconf_store=self._ssconf_mock,
                              noded_cert_file=self.noded_cert_file,
                              run_cmd_fn=self._run_cmd_mock)

    for node_info in node_list:
      self._ssh_file_manager.AssertPotentialMasterCandidatesOnlyHavePublicKey(
          node_info.name)
      self._ssh_file_manager.AssertAllNodesHaveAuthorizedKey(
          key_map[node_info.name])

  def testAddPotentialMasterCandidateBulk(self):
    num_nodes = 3
    (node_list, key_map) = self._SetupNodeBulk(
        num_nodes, self._GetNewNumberedPotentialMasterCandidate)

    backend.AddNodeSshKeyBulk(node_list,
                              self._potential_master_candidates,
                              pub_key_file=self._pub_key_file,
                              ssconf_store=self._ssconf_mock,
                              noded_cert_file=self.noded_cert_file,
                              run_cmd_fn=self._run_cmd_mock)

    for node_info in node_list:
      self._ssh_file_manager.AssertPotentialMasterCandidatesOnlyHavePublicKey(
          node_info.name)
      self._ssh_file_manager.AssertNoNodeHasAuthorizedKey(
          key_map[node_info.name])

  def testAddPotentialMasterCandidate(self):
    new_node_name = "new_node_name"
    new_node_uuid = "new_node_uuid"
    new_node_key = "new_node_key"
    is_master_candidate = False
    is_potential_master_candidate = True
    is_master = False

    self._AddNewNodeToTestData(
        new_node_name, new_node_uuid, new_node_key,
        is_potential_master_candidate, is_master_candidate,
        is_master)

    backend.AddNodeSshKey(new_node_uuid, new_node_name,
                          self._potential_master_candidates,
                          to_authorized_keys=is_master_candidate,
                          to_public_keys=is_potential_master_candidate,
                          get_public_keys=is_potential_master_candidate,
                          pub_key_file=self._pub_key_file,
                          ssconf_store=self._ssconf_mock,
                          noded_cert_file=self.noded_cert_file,
                          run_cmd_fn=self._run_cmd_mock)

    self._ssh_file_manager.AssertPotentialMasterCandidatesOnlyHavePublicKey(
        new_node_name)
    self._ssh_file_manager.AssertNoNodeHasAuthorizedKey(new_node_key)

  def testAddNormalNode(self):
    new_node_name = "new_node_name"
    new_node_uuid = "new_node_uuid"
    new_node_key = "new_node_key"
    is_master_candidate = False
    is_potential_master_candidate = False
    is_master = False

    self._AddNewNodeToTestData(
        new_node_name, new_node_uuid, new_node_key,
        is_potential_master_candidate, is_master_candidate,
        is_master)

    backend.AddNodeSshKey(new_node_uuid, new_node_name,
        self._potential_master_candidates,
        to_authorized_keys=is_master_candidate,
        to_public_keys=is_potential_master_candidate,
        get_public_keys=is_potential_master_candidate,
        pub_key_file=self._pub_key_file,
        ssconf_store=self._ssconf_mock,
        noded_cert_file=self.noded_cert_file,
        run_cmd_fn=self._run_cmd_mock)

    self._ssh_file_manager.AssertNoNodeHasPublicKey(new_node_uuid, new_node_key)
    self._ssh_file_manager.AssertNoNodeHasAuthorizedKey(new_node_key)

  def testAddNormalBulk(self):
    num_nodes = 3
    (node_list, key_map) = self._SetupNodeBulk(
        num_nodes, self._GetNewNumberedNormalNode)

    backend.AddNodeSshKeyBulk(node_list,
        self._potential_master_candidates,
        pub_key_file=self._pub_key_file,
        ssconf_store=self._ssconf_mock,
        noded_cert_file=self.noded_cert_file,
        run_cmd_fn=self._run_cmd_mock)

    for node_info in node_list:
      self._ssh_file_manager.AssertNoNodeHasPublicKey(
          node_info.uuid, key_map[node_info.name])
      self._ssh_file_manager.AssertNoNodeHasAuthorizedKey(
          key_map[node_info.name])

  def _GetNewNumberedNode(self, num):
    """Returns the properties of a node.

    This will in round-robin style return a master candidate, a
    potential master candiate and a normal node.

    """
    is_master_candidate = num % 3 == 0
    is_potential_master_candidate = num % 3 == 0 or num % 3 == 1
    is_master = False
    return ("new_node_name_%s" % num,
            "new_node_uuid_%s" % num,
            "new_node_key_%s" % num,
            is_master_candidate, is_potential_master_candidate, is_master)

  def testAddDiverseNodeBulk(self):
    """Tests adding keys of several nodes with several qualities.

    This tests subsumes previous tests. However, we leave the previous
    tests here, because debugging problems with this all-embracing test
    is much more tedious than having one of the one-purpose tests fail.

    """
    num_nodes = 9
    (node_list, key_map) = self._SetupNodeBulk(
        num_nodes, self._GetNewNumberedNode)

    backend.AddNodeSshKeyBulk(node_list,
                              self._potential_master_candidates,
                              pub_key_file=self._pub_key_file,
                              ssconf_store=self._ssconf_mock,
                              noded_cert_file=self.noded_cert_file,
                              run_cmd_fn=self._run_cmd_mock)

    for node_info in node_list:
      if node_info.to_authorized_keys:
        self._ssh_file_manager.AssertAllNodesHaveAuthorizedKey(
            key_map[node_info.name])
      else:
        self._ssh_file_manager.AssertNoNodeHasAuthorizedKey(
            key_map[node_info.name])
      if node_info.to_public_keys:
        self._ssh_file_manager.AssertPotentialMasterCandidatesOnlyHavePublicKey(
            node_info.name)
      else:
        self._ssh_file_manager.AssertNoNodeHasPublicKey(
            node_info.uuid, key_map[node_info.name])

  def testPromoteToMasterCandidate(self):
    # Get one of the potential master candidates
    node_name, node_info = \
      self._ssh_file_manager.GetAllPurePotentialMasterCandidates()[0]
    # Update it's role to master candidate in the test data
    self._ssh_file_manager.SetOrAddNode(
        node_name, node_info.uuid, node_info.key,
        node_info.is_potential_master_candidate, True, node_info.is_master)

    backend.AddNodeSshKey(node_info.uuid, node_name,
                          self._potential_master_candidates,
                          to_authorized_keys=True,
                          to_public_keys=False,
                          get_public_keys=False,
                          pub_key_file=self._pub_key_file,
                          ssconf_store=self._ssconf_mock,
                          noded_cert_file=self.noded_cert_file,
                          run_cmd_fn=self._run_cmd_mock)

    self._ssh_file_manager.AssertPotentialMasterCandidatesOnlyHavePublicKey(
        node_name)
    self._ssh_file_manager.AssertAllNodesHaveAuthorizedKey(node_info.key)

  def testRemoveMasterCandidate(self):
    node_name, (node_uuid, node_key, is_potential_master_candidate,
     is_master_candidate, is_master) = \
        self._ssh_file_manager.GetAllMasterCandidates()[0]

    backend.RemoveNodeSshKey(node_uuid, node_name,
                             self._master_candidate_uuids,
                             self._potential_master_candidates,
                             from_authorized_keys=True,
                             from_public_keys=True,
                             clear_authorized_keys=True,
                             clear_public_keys=True,
                             pub_key_file=self._pub_key_file,
                             ssconf_store=self._ssconf_mock,
                             noded_cert_file=self.noded_cert_file,
                             run_cmd_fn=self._run_cmd_mock)

    self._ssh_file_manager.AssertNoNodeHasPublicKey(node_uuid, node_key)
    self._ssh_file_manager.AssertNodeSetOnlyHasAuthorizedKey(
        [node_name], node_key)
    self.assertEqual(0,
        len(self._ssh_file_manager.GetPublicKeysOfNode(node_name)))
    self.assertEqual(1,
        len(self._ssh_file_manager.GetAuthorizedKeysOfNode(node_name)))

  def testRemoveMasterCandidateBulk(self):
    node_list = []
    key_map = {}
    for node_name, (node_uuid, node_key, _, _, _) in \
        self._ssh_file_manager.GetAllMasterCandidates()[:3]:
      node_list.append(backend.SshRemoveNodeInfo(uuid=node_uuid,
                                                 name=node_name,
                                                 from_authorized_keys=True,
                                                 from_public_keys=True,
                                                 clear_authorized_keys=True,
                                                 clear_public_keys=True))
      key_map[node_name] = node_key

    backend.RemoveNodeSshKeyBulk(node_list,
                                 self._master_candidate_uuids,
                                 self._potential_master_candidates,
                                 pub_key_file=self._pub_key_file,
                                 ssconf_store=self._ssconf_mock,
                                 noded_cert_file=self.noded_cert_file,
                                 run_cmd_fn=self._run_cmd_mock)

    for node_info in node_list:
      self._ssh_file_manager.AssertNoNodeHasPublicKey(
          node_info.uuid, key_map[node_info.name])
      self._ssh_file_manager.AssertNodeSetOnlyHasAuthorizedKey(
          [node_info.name], key_map[node_info.name])
      self.assertEqual(0,
          len(self._ssh_file_manager.GetPublicKeysOfNode(node_info.name)))
      self.assertEqual(1,
          len(self._ssh_file_manager.GetAuthorizedKeysOfNode(node_info.name)))

  def testRemovePotentialMasterCandidate(self):
    (node_name, node_info) = \
        self._ssh_file_manager.GetAllPurePotentialMasterCandidates()[0]

    backend.RemoveNodeSshKey(node_info.uuid, node_name,
                             self._master_candidate_uuids,
                             self._potential_master_candidates,
                             from_authorized_keys=False,
                             from_public_keys=True,
                             clear_authorized_keys=True,
                             clear_public_keys=True,
                             pub_key_file=self._pub_key_file,
                             ssconf_store=self._ssconf_mock,
                             noded_cert_file=self.noded_cert_file,
                             run_cmd_fn=self._run_cmd_mock)

    self._ssh_file_manager.AssertNoNodeHasPublicKey(
        node_info.uuid, node_info.key)
    self._ssh_file_manager.AssertNodeSetOnlyHasAuthorizedKey(
        [node_name], node_info.key)
    self.assertEqual(0,
        len(self._ssh_file_manager.GetPublicKeysOfNode(node_name)))
    self.assertEqual(1,
        len(self._ssh_file_manager.GetAuthorizedKeysOfNode(node_name)))

  def testRemovePotentialMasterCandidateBulk(self):
    node_list = []
    key_map = {}
    for node_name, (node_uuid, node_key, _, _, _) in \
        self._ssh_file_manager.GetAllPurePotentialMasterCandidates()[:3]:
      node_list.append(backend.SshRemoveNodeInfo(uuid=node_uuid,
                                                 name=node_name,
                                                 from_authorized_keys=False,
                                                 from_public_keys=True,
                                                 clear_authorized_keys=True,
                                                 clear_public_keys=True))
      key_map[node_name] = node_key

    backend.RemoveNodeSshKeyBulk(node_list,
                                 self._master_candidate_uuids,
                                 self._potential_master_candidates,
                                 pub_key_file=self._pub_key_file,
                                 ssconf_store=self._ssconf_mock,
                                 noded_cert_file=self.noded_cert_file,
                                 run_cmd_fn=self._run_cmd_mock)

    for node_info in node_list:
      self._ssh_file_manager.AssertNoNodeHasPublicKey(
          node_info.uuid, key_map[node_info.name])
      self._ssh_file_manager.AssertNodeSetOnlyHasAuthorizedKey(
          [node_info.name], key_map[node_info.name])
      self.assertEqual(0,
          len(self._ssh_file_manager.GetPublicKeysOfNode(node_info.name)))
      self.assertEqual(1,
          len(self._ssh_file_manager.GetAuthorizedKeysOfNode(node_info.name)))

  def testRemoveNormalNode(self):
    node_name, node_info = self._ssh_file_manager.GetAllNormalNodes()[0]

    backend.RemoveNodeSshKey(node_info.uuid, node_name,
                             self._master_candidate_uuids,
                             self._potential_master_candidates,
                             from_authorized_keys=False,
                             from_public_keys=False,
                             clear_authorized_keys=True,
                             clear_public_keys=True,
                             pub_key_file=self._pub_key_file,
                             ssconf_store=self._ssconf_mock,
                             noded_cert_file=self.noded_cert_file,
                             run_cmd_fn=self._run_cmd_mock)

    self._ssh_file_manager.AssertNoNodeHasPublicKey(
        node_info.uuid, node_info.key)
    self._ssh_file_manager.AssertNodeSetOnlyHasAuthorizedKey(
        [node_name], node_info.key)
    self.assertEqual(0,
        len(self._ssh_file_manager.GetPublicKeysOfNode(node_name)))
    self.assertEqual(1,
        len(self._ssh_file_manager.GetAuthorizedKeysOfNode(node_name)))

  def testRemoveNormalNodeBulk(self):
    node_list = []
    key_map = {}
    for node_name, (node_uuid, node_key, _, _, _) in \
        self._ssh_file_manager.GetAllNormalNodes()[:3]:
      node_list.append(backend.SshRemoveNodeInfo(uuid=node_uuid,
                                                 name=node_name,
                                                 from_authorized_keys=False,
                                                 from_public_keys=False,
                                                 clear_authorized_keys=True,
                                                 clear_public_keys=True))
      key_map[node_name] = node_key

    backend.RemoveNodeSshKeyBulk(node_list,
                                 self._master_candidate_uuids,
                                 self._potential_master_candidates,
                                 pub_key_file=self._pub_key_file,
                                 ssconf_store=self._ssconf_mock,
                                 noded_cert_file=self.noded_cert_file,
                                 run_cmd_fn=self._run_cmd_mock)

    for node_info in node_list:
      self._ssh_file_manager.AssertNoNodeHasPublicKey(
          node_info.uuid, key_map[node_info.name])
      self._ssh_file_manager.AssertNodeSetOnlyHasAuthorizedKey(
          [node_info.name], key_map[node_info.name])
      self.assertEqual(0,
          len(self._ssh_file_manager.GetPublicKeysOfNode(node_info.name)))
      self.assertEqual(1,
          len(self._ssh_file_manager.GetAuthorizedKeysOfNode(node_info.name)))

  def testRemoveDiverseNodesBulk(self):
    node_list = []
    key_map = {}
    for node_name, (node_uuid, node_key, is_potential_master_candidate,
                    is_master_candidate, _) in \
        self._ssh_file_manager.GetAllNodesDiverse()[:3]:
      node_list.append(backend.SshRemoveNodeInfo(
          uuid=node_uuid,
          name=node_name,
          from_authorized_keys=is_master_candidate,
          from_public_keys=is_potential_master_candidate,
          clear_authorized_keys=True,
          clear_public_keys=True))
      key_map[node_name] = node_key

    backend.RemoveNodeSshKeyBulk(node_list,
                                 self._master_candidate_uuids,
                                 self._potential_master_candidates,
                                 pub_key_file=self._pub_key_file,
                                 ssconf_store=self._ssconf_mock,
                                 noded_cert_file=self.noded_cert_file,
                                 run_cmd_fn=self._run_cmd_mock)

    for node_info in node_list:
      self._ssh_file_manager.AssertNoNodeHasPublicKey(
          node_info.uuid, key_map[node_info.name])
      self._ssh_file_manager.AssertNodeSetOnlyHasAuthorizedKey(
          [node_info.name], key_map[node_info.name])
      self.assertEqual(0,
          len(self._ssh_file_manager.GetPublicKeysOfNode(node_info.name)))
      self.assertEqual(1,
          len(self._ssh_file_manager.GetAuthorizedKeysOfNode(node_info.name)))

  def testDemoteMasterCandidateToPotentialMasterCandidate(self):
    node_name, node_info = self._ssh_file_manager.GetAllMasterCandidates()[0]
    self._ssh_file_manager.SetOrAddNode(
        node_name, node_info.uuid, node_info.key,
        node_info.is_potential_master_candidate, False, node_info.is_master)

    backend.RemoveNodeSshKey(node_info.uuid, node_name,
                             self._master_candidate_uuids,
                             self._potential_master_candidates,
                             from_authorized_keys=True,
                             from_public_keys=False,
                             clear_authorized_keys=False,
                             clear_public_keys=False,
                             pub_key_file=self._pub_key_file,
                             ssconf_store=self._ssconf_mock,
                             noded_cert_file=self.noded_cert_file,
                             run_cmd_fn=self._run_cmd_mock)

    self._ssh_file_manager.AssertPotentialMasterCandidatesOnlyHavePublicKey(
        node_name)
    self._ssh_file_manager.AssertNodeSetOnlyHasAuthorizedKey(
        [node_name], node_info.key)

  def testDemotePotentialMasterCandidateToNormalNode(self):
    (node_name, node_info) = \
        self._ssh_file_manager.GetAllPurePotentialMasterCandidates()[0]
    self._ssh_file_manager.SetOrAddNode(
        node_name, node_info.uuid, node_info.key, False,
        node_info.is_master_candidate, node_info.is_master)

    backend.RemoveNodeSshKey(node_info.uuid, node_name,
                             self._master_candidate_uuids,
                             self._potential_master_candidates,
                             from_authorized_keys=False,
                             from_public_keys=True,
                             clear_authorized_keys=False,
                             clear_public_keys=False,
                             pub_key_file=self._pub_key_file,
                             ssconf_store=self._ssconf_mock,
                             noded_cert_file=self.noded_cert_file,
                             run_cmd_fn=self._run_cmd_mock)

    self._ssh_file_manager.AssertNoNodeHasPublicKey(
        node_info.uuid, node_info.key)
    self._ssh_file_manager.AssertNodeSetOnlyHasAuthorizedKey(
        [node_name], node_info.key)

  def _GetReducedOnlineNodeList(self):
    """'Randomly' mark some nodes as offline."""
    return [name for name in self._all_nodes
            if '3' not in name and '5' not in name]

  def testAddKeyWithOfflineNodes(self):
    (new_node_name, new_node_uuid, new_node_key, is_master_candidate,
     is_potential_master_candidate, is_master) = self._GetNewMasterCandidate()

    self._AddNewNodeToTestData(
        new_node_name, new_node_uuid, new_node_key,
        is_potential_master_candidate, is_master_candidate,
        is_master)
    self._online_nodes = self._GetReducedOnlineNodeList()
    self._ssconf_mock.GetOnlineNodeList.side_effect = \
        lambda : self._online_nodes

    backend.AddNodeSshKey(new_node_uuid, new_node_name,
                          self._potential_master_candidates,
                          to_authorized_keys=is_master_candidate,
                          to_public_keys=is_potential_master_candidate,
                          get_public_keys=is_potential_master_candidate,
                          pub_key_file=self._pub_key_file,
                          ssconf_store=self._ssconf_mock,
                          noded_cert_file=self.noded_cert_file,
                          run_cmd_fn=self._run_cmd_mock)

    for node in self._all_nodes:
      if node in self._online_nodes:
        self.assertTrue(self._ssh_file_manager.NodeHasAuthorizedKey(
            node, new_node_key))
      else:
        self.assertFalse(self._ssh_file_manager.NodeHasAuthorizedKey(
            node, new_node_key))

  def testRemoveKeyWithOfflineNodes(self):
    (node_name, node_info) = \
        self._ssh_file_manager.GetAllMasterCandidates()[0]
    self._online_nodes = self._GetReducedOnlineNodeList()
    self._ssconf_mock.GetOnlineNodeList.side_effect = \
        lambda : self._online_nodes

    backend.RemoveNodeSshKey(node_info.uuid, node_name,
                             self._master_candidate_uuids,
                             self._potential_master_candidates,
                             from_authorized_keys=True,
                             from_public_keys=True,
                             clear_authorized_keys=True,
                             clear_public_keys=True,
                             pub_key_file=self._pub_key_file,
                             ssconf_store=self._ssconf_mock,
                             noded_cert_file=self.noded_cert_file,
                             run_cmd_fn=self._run_cmd_mock)

    offline_nodes = [node for node in self._all_nodes
                     if node not in self._online_nodes]
    self._ssh_file_manager.AssertNodeSetOnlyHasAuthorizedKey(
        offline_nodes + [node_name], node_info.key)

  def testAddKeySuccessfullyOnNewNodeWithRetries(self):
    """Tests adding a new node's key when updating that node takes retries.

    This test checks whether adding a new node's key successfully updates
    the SSH key files of all nodes, even if updating the new node's key files
    itself takes a couple of retries to succeed.

    """
    (new_node_name, new_node_uuid, new_node_key, is_master_candidate,
     is_potential_master_candidate, is_master) = self._GetNewMasterCandidate()

    self._AddNewNodeToTestData(
        new_node_name, new_node_uuid, new_node_key,
        is_potential_master_candidate, is_master_candidate,
        is_master)
    self._ssh_file_manager.SetMaxRetries(
        new_node_name, constants.SSHS_MAX_RETRIES)

    backend.AddNodeSshKey(new_node_uuid, new_node_name,
                          self._potential_master_candidates,
                          to_authorized_keys=is_master_candidate,
                          to_public_keys=is_potential_master_candidate,
                          get_public_keys=is_potential_master_candidate,
                          pub_key_file=self._pub_key_file,
                          ssconf_store=self._ssconf_mock,
                          noded_cert_file=self.noded_cert_file,
                          run_cmd_fn=self._run_cmd_mock)

    self._ssh_file_manager.AssertPotentialMasterCandidatesOnlyHavePublicKey(
        new_node_name)
    self._ssh_file_manager.AssertAllNodesHaveAuthorizedKey(
        new_node_key)

  def testAddKeyFailedOnNewNodeWithRetries(self):
    """Tests clean up if updating a new node's SSH setup fails.

    If adding the keys of a new node fails, because updating the SSH key files
    of that new node fails, check whether already carried out operations are
    successfully rolled back and thus the state of the cluster is cleaned up.

    """
    (new_node_name, new_node_uuid, new_node_key, is_master_candidate,
     is_potential_master_candidate, is_master) = self._GetNewMasterCandidate()

    self._AddNewNodeToTestData(
        new_node_name, new_node_uuid, new_node_key,
        is_potential_master_candidate, is_master_candidate,
        is_master)
    self._ssh_file_manager.SetMaxRetries(
        new_node_name, constants.SSHS_MAX_RETRIES + 1)

    self.assertRaises(
        errors.SshUpdateError, backend.AddNodeSshKey, new_node_uuid,
        new_node_name, self._potential_master_candidates,
        to_authorized_keys=is_master_candidate,
        to_public_keys=is_potential_master_candidate,
        get_public_keys=is_potential_master_candidate,
        pub_key_file=self._pub_key_file,
        ssconf_store=self._ssconf_mock,
        noded_cert_file=self.noded_cert_file,
        run_cmd_fn=self._run_cmd_mock)

    master_node = self._ssh_file_manager.GetMasterNodeName()
    for node in self._all_nodes:
      if node in [new_node_name, master_node]:
        self.assertTrue(self._ssh_file_manager.NodeHasAuthorizedKey(
          node, new_node_key))
      else:
        self.assertFalse(self._ssh_file_manager.NodeHasAuthorizedKey(
          node, new_node_key))

    self._ssh_file_manager.AssertNoNodeHasPublicKey(new_node_uuid, new_node_key)

  def testAddKeySuccessfullyOnOldNodeWithRetries(self):
    """Tests adding a new key even if updating nodes takes retries.

    This tests whether adding a new node's key successfully finishes,
    even if one of the other cluster nodes takes a couple of retries
    to succeed.

    """
    (new_node_name, new_node_uuid, new_node_key, is_master_candidate,
     is_potential_master_candidate, is_master) = self._GetNewMasterCandidate()

    other_node_name, _ = self._ssh_file_manager.GetAllMasterCandidates()[0]
    self._ssh_file_manager.SetMaxRetries(
        other_node_name, constants.SSHS_MAX_RETRIES)
    assert other_node_name != new_node_name
    self._AddNewNodeToTestData(
        new_node_name, new_node_uuid, new_node_key,
        is_potential_master_candidate, is_master_candidate,
        is_master)

    backend.AddNodeSshKey(new_node_uuid, new_node_name,
                          self._potential_master_candidates,
                          to_authorized_keys=is_master_candidate,
                          to_public_keys=is_potential_master_candidate,
                          get_public_keys=is_potential_master_candidate,
                          pub_key_file=self._pub_key_file,
                          ssconf_store=self._ssconf_mock,
                          noded_cert_file=self.noded_cert_file,
                          run_cmd_fn=self._run_cmd_mock)

    self._ssh_file_manager.AssertAllNodesHaveAuthorizedKey(new_node_key)

  def testAddKeyFailedOnOldNodeWithRetries(self):
    """Tests adding keys when updating one node's SSH setup fails.

    This tests whether when adding a new node's key and one node is
    unreachable (but not marked as offline) the operation still finishes
    properly and only that unreachable node's SSH key setup did not get
    updated.

    """
    (new_node_name, new_node_uuid, new_node_key, is_master_candidate,
     is_potential_master_candidate, is_master) = self._GetNewMasterCandidate()

    other_node_name, _ = self._ssh_file_manager.GetAllMasterCandidates()[0]
    self._ssh_file_manager.SetMaxRetries(
        other_node_name, constants.SSHS_MAX_RETRIES + 1)
    assert other_node_name != new_node_name
    self._AddNewNodeToTestData(
        new_node_name, new_node_uuid, new_node_key,
        is_potential_master_candidate, is_master_candidate,
        is_master)

    node_errors = backend.AddNodeSshKey(
        new_node_uuid, new_node_name, self._potential_master_candidates,
        to_authorized_keys=is_master_candidate,
        to_public_keys=is_potential_master_candidate,
        get_public_keys=is_potential_master_candidate,
        pub_key_file=self._pub_key_file,
        ssconf_store=self._ssconf_mock,
        noded_cert_file=self.noded_cert_file,
        run_cmd_fn=self._run_cmd_mock)

    rest_nodes = [node for node in self._all_nodes
                  if node != other_node_name]
    rest_nodes.append(new_node_name)
    self._ssh_file_manager.AssertNodeSetOnlyHasAuthorizedKey(
        rest_nodes, new_node_key)
    self.assertTrue([error_msg for (node, error_msg) in node_errors
                     if node == other_node_name])

  def testRemoveKeySuccessfullyWithRetriesOnOtherNode(self):
    """Test removing keys even if one of the old nodes needs retries.

    This tests checks whether a key can be removed successfully even
    when one of the other nodes needs to be contacted with several
    retries.

    """
    all_master_candidates = self._ssh_file_manager.GetAllMasterCandidates()
    node_name, node_info = all_master_candidates[0]
    other_node_name, _ = all_master_candidates[1]
    assert node_name != self._master_node
    assert other_node_name != self._master_node
    assert node_name != other_node_name
    self._ssh_file_manager.SetMaxRetries(
        other_node_name, constants.SSHS_MAX_RETRIES)

    backend.RemoveNodeSshKey(node_info.uuid, node_name,
                             self._master_candidate_uuids,
                             self._potential_master_candidates,
                             from_authorized_keys=True,
                             from_public_keys=True,
                             clear_authorized_keys=True,
                             clear_public_keys=True,
                             pub_key_file=self._pub_key_file,
                             ssconf_store=self._ssconf_mock,
                             noded_cert_file=self.noded_cert_file,
                             run_cmd_fn=self._run_cmd_mock)

    self._ssh_file_manager.AssertNoNodeHasPublicKey(
        node_info.uuid, node_info.key)
    self._ssh_file_manager.AssertNodeSetOnlyHasAuthorizedKey(
        [node_name], node_info.key)

  def testRemoveKeyFailedWithRetriesOnOtherNode(self):
    """Test removing keys even if one of the old nodes fails even with retries.

    This tests checks whether the removal of a key finishes properly, even if
    the update of the key files on one of the other nodes fails despite several
    retries.

    """
    all_master_candidates = self._ssh_file_manager.GetAllMasterCandidates()
    node_name, node_info = all_master_candidates[0]
    other_node_name, _ = all_master_candidates[1]
    assert node_name != self._master_node
    assert other_node_name != self._master_node
    assert node_name != other_node_name
    self._ssh_file_manager.SetMaxRetries(
        other_node_name, constants.SSHS_MAX_RETRIES + 1)

    error_msgs = backend.RemoveNodeSshKey(
        node_info.uuid, node_name, self._master_candidate_uuids,
        self._potential_master_candidates,
        from_authorized_keys=True, from_public_keys=True,
        clear_authorized_keys=True, clear_public_keys=True,
        pub_key_file=self._pub_key_file, ssconf_store=self._ssconf_mock,
        noded_cert_file=self.noded_cert_file, run_cmd_fn=self._run_cmd_mock)

    self._ssh_file_manager.AssertNodeSetOnlyHasAuthorizedKey(
        [other_node_name, node_name], node_info.key)
    self.assertTrue([error_msg for (node, error_msg) in error_msgs
                     if node == other_node_name])

  def testRemoveKeySuccessfullyWithRetriesOnTargetNode(self):
    """Test removing keys even if the target nodes needs retries.

    This tests checks whether a key can be removed successfully even
    when removing the key on the node itself needs retries.

    """
    all_master_candidates = self._ssh_file_manager.GetAllMasterCandidates()
    node_name, node_info = all_master_candidates[0]
    assert node_name != self._master_node
    self._ssh_file_manager.SetMaxRetries(
        node_name, constants.SSHS_MAX_RETRIES)

    backend.RemoveNodeSshKey(node_info.uuid, node_name,
                             self._master_candidate_uuids,
                             self._potential_master_candidates,
                             from_authorized_keys=True,
                             from_public_keys=True,
                             clear_authorized_keys=True,
                             clear_public_keys=True,
                             pub_key_file=self._pub_key_file,
                             ssconf_store=self._ssconf_mock,
                             noded_cert_file=self.noded_cert_file,
                             run_cmd_fn=self._run_cmd_mock)

    self._ssh_file_manager.AssertNoNodeHasPublicKey(
        node_info.uuid, node_info.key)
    self._ssh_file_manager.AssertNodeSetOnlyHasAuthorizedKey(
        [node_name], node_info.key)

  def testRemoveKeyFailedWithRetriesOnTargetNode(self):
    """Test removing keys even if contacting the node fails with retries.

    This tests checks whether the removal of a key finishes properly, even if
    the update of the key files on the node itself fails despite several
    retries.

    """
    all_master_candidates = self._ssh_file_manager.GetAllMasterCandidates()
    node_name, node_info = all_master_candidates[0]
    assert node_name != self._master_node
    self._ssh_file_manager.SetMaxRetries(
        node_name, constants.SSHS_MAX_RETRIES + 1)

    error_msgs = backend.RemoveNodeSshKey(
        node_info.uuid, node_name, self._master_candidate_uuids,
        self._potential_master_candidates,
        from_authorized_keys=True, from_public_keys=True,
        clear_authorized_keys=True, clear_public_keys=True,
        pub_key_file=self._pub_key_file, ssconf_store=self._ssconf_mock,
        noded_cert_file=self.noded_cert_file, run_cmd_fn=self._run_cmd_mock)

    self._ssh_file_manager.AssertNodeSetOnlyHasAuthorizedKey(
        [node_name], node_info.key)
    self.assertTrue([error_msg for (node, error_msg) in error_msgs
                     if node == node_name])


class TestVerifySshSetup(testutils.GanetiTestCase):

  _NODE1_UUID = "uuid1"
  _NODE2_UUID = "uuid2"
  _NODE3_UUID = "uuid3"
  _NODE1_NAME = "name1"
  _NODE2_NAME = "name2"
  _NODE3_NAME = "name3"
  _NODE1_KEYS = ["key11"]
  _NODE2_KEYS = ["key21"]
  _NODE3_KEYS = ["key31"]

  _NODE_STATUS_LIST = [
    (_NODE1_UUID, _NODE1_NAME, True, True, True),
    (_NODE2_UUID, _NODE2_NAME, False, True, True),
    (_NODE3_UUID, _NODE3_NAME, False, False, True),
    ]

  _PUB_KEY_RESULT = {
    _NODE1_UUID: _NODE1_KEYS,
    _NODE2_UUID: _NODE2_KEYS,
    _NODE3_UUID: _NODE3_KEYS,
    }

  _AUTH_RESULT = {
    _NODE1_KEYS[0]: True,
    _NODE2_KEYS[0]: False,
    _NODE3_KEYS[0]: False,
  }

  def setUp(self):
    testutils.GanetiTestCase.setUp(self)
    self._has_authorized_patcher = testutils \
      .patch_object(ssh, "HasAuthorizedKey")
    self._has_authorized_mock = self._has_authorized_patcher.start()
    self._query_patcher = testutils \
      .patch_object(ssh, "QueryPubKeyFile")
    self._query_mock = self._query_patcher.start()
    self._read_file_patcher = testutils \
      .patch_object(utils, "ReadFile")
    self._read_file_mock = self._read_file_patcher.start()
    self._read_file_mock.return_value = self._NODE1_KEYS[0]
    self.tmpdir = tempfile.mkdtemp()
    self.pub_keys_file = os.path.join(self.tmpdir, "pub_keys_file")
    open(self.pub_keys_file, "w").close()

  def tearDown(self):
    super(testutils.GanetiTestCase, self).tearDown()
    self._has_authorized_patcher.stop()
    self._query_patcher.stop()
    self._read_file_patcher.stop()
    shutil.rmtree(self.tmpdir)

  def testValidData(self):
    self._has_authorized_mock.side_effect = \
      lambda _, key : self._AUTH_RESULT[key]
    self._query_mock.return_value = self._PUB_KEY_RESULT
    result = backend._VerifySshSetup(self._NODE_STATUS_LIST,
                                     self._NODE1_NAME,
                                     "dsa",
                                     ganeti_pub_keys_file=self.pub_keys_file)
    self.assertEqual(result, [])

  def testMissingKey(self):
    self._has_authorized_mock.side_effect = \
      lambda _, key : self._AUTH_RESULT[key]
    pub_key_missing = copy.deepcopy(self._PUB_KEY_RESULT)
    del pub_key_missing[self._NODE2_UUID]
    self._query_mock.return_value = pub_key_missing
    result = backend._VerifySshSetup(self._NODE_STATUS_LIST,
                                     self._NODE1_NAME,
                                     "dsa",
                                     ganeti_pub_keys_file=self.pub_keys_file)
    self.assertTrue(self._NODE2_UUID in result[0])

  def testUnknownKey(self):
    self._has_authorized_mock.side_effect = \
      lambda _, key : self._AUTH_RESULT[key]
    pub_key_missing = copy.deepcopy(self._PUB_KEY_RESULT)
    pub_key_missing["unkownnodeuuid"] = "pinkbunny"
    self._query_mock.return_value = pub_key_missing
    result = backend._VerifySshSetup(self._NODE_STATUS_LIST,
                                     self._NODE1_NAME,
                                     "dsa",
                                     ganeti_pub_keys_file=self.pub_keys_file)
    self.assertTrue("unkownnodeuuid" in result[0])

  def testMissingMasterCandidate(self):
    auth_result = copy.deepcopy(self._AUTH_RESULT)
    auth_result["key11"] = False
    self._has_authorized_mock.side_effect = \
      lambda _, key : auth_result[key]
    self._query_mock.return_value = self._PUB_KEY_RESULT
    result = backend._VerifySshSetup(self._NODE_STATUS_LIST,
                                     self._NODE1_NAME,
                                     "dsa",
                                     ganeti_pub_keys_file=self.pub_keys_file)
    self.assertTrue(self._NODE1_UUID in result[0])

  def testSuperfluousNormalNode(self):
    auth_result = copy.deepcopy(self._AUTH_RESULT)
    auth_result["key31"] = True
    self._has_authorized_mock.side_effect = \
      lambda _, key : auth_result[key]
    self._query_mock.return_value = self._PUB_KEY_RESULT
    result = backend._VerifySshSetup(self._NODE_STATUS_LIST,
                                     self._NODE1_NAME,
                                     "dsa",
                                     ganeti_pub_keys_file=self.pub_keys_file)
    self.assertTrue(self._NODE3_UUID in result[0])


class TestOSEnvironment(unittest.TestCase):
  """Ensure the presence of public and private parameters.

  They have to be present inside os environment variables.

  """

  def _CreateEnv(self):
    """Create and return an environment."""
    config_mock = ConfigMock()
    inst = config_mock.AddNewInstance(
             osparams={"public_param": "public_info"},
             osparams_private=serializer.PrivateDict({"private_param":
                                                     "private_info",
                                                     "another_private_param":
                                                     "more_privacy"}),
             nics = [])
    inst.disks_info = ""
    inst.secondary_nodes = []

    return backend.OSEnvironment(inst, config_mock.CreateOs())

  def testParamPresence(self):
    env = self._CreateEnv()
    env_keys = env.keys()
    self.assertTrue("OSP_PUBLIC_PARAM" in env)
    self.assertTrue("OSP_PRIVATE_PARAM" in env)
    self.assertTrue("OSP_ANOTHER_PRIVATE_PARAM" in env)
    self.assertEqual("public_info", env["OSP_PUBLIC_PARAM"])
    self.assertEqual("private_info", env["OSP_PRIVATE_PARAM"])
    self.assertEqual("more_privacy", env["OSP_ANOTHER_PRIVATE_PARAM"])


if __name__ == "__main__":
  testutils.GanetiTestProgram()
