예제 #1
0
    def testEmpty(self):
        filename = utils.PathJoin(self.tmpdir, "config.data")
        utils.WriteFile(filename, data="")
        bname = utils.CreateBackup(filename)
        self.assertFileContent(bname, "")
        self.assertEqual(len(glob.glob("%s*" % filename)), 2)
        utils.CreateBackup(filename)
        self.assertEqual(len(glob.glob("%s*" % filename)), 3)
        utils.CreateBackup(filename)
        self.assertEqual(len(glob.glob("%s*" % filename)), 4)

        fifoname = utils.PathJoin(self.tmpdir, "fifo")
        os.mkfifo(fifoname)
        self.assertRaises(errors.ProgrammerError, utils.CreateBackup, fifoname)
예제 #2
0
def InitSSHSetup(key_type, key_bits, error_fn=errors.OpPrereqError,
                 _homedir_fn=None, _suffix=""):
  """Setup the SSH configuration for the node.

  This generates a dsa keypair for root, adds the pub key to the
  permitted hosts and adds the hostkey to its own known hosts.

  @param key_type: the type of SSH keypair to be generated
  @param key_bits: the key length, in bits, to be used

  """
  priv_key, _, auth_keys = GetUserFiles(constants.SSH_LOGIN_USER, kind=key_type,
                                        mkdir=True, _homedir_fn=_homedir_fn)

  new_priv_key_name = priv_key + _suffix
  new_pub_key_name = priv_key + _suffix + ".pub"

  for name in new_priv_key_name, new_pub_key_name:
    if os.path.exists(name):
      utils.CreateBackup(name)
    utils.RemoveFile(name)

  result = utils.RunCmd(["ssh-keygen", "-b", str(key_bits), "-t", key_type,
                         "-f", new_priv_key_name,
                         "-q", "-N", ""])
  if result.failed:
    raise error_fn("Could not generate ssh keypair, error %s" %
                   result.output)

  AddAuthorizedKey(auth_keys, utils.ReadFile(new_pub_key_name))
예제 #3
0
파일: ssh.py 프로젝트: nh2/ganeti-test-1
def InitSSHSetup(error_fn=errors.OpPrereqError, _homedir_fn=None, _suffix=""):
    """Setup the SSH configuration for the node.

  This generates a dsa keypair for root, adds the pub key to the
  permitted hosts and adds the hostkey to its own known hosts.

  """
    priv_key, pub_key, auth_keys = GetUserFiles(constants.SSH_LOGIN_USER,
                                                _homedir_fn=_homedir_fn)

    for name in priv_key, pub_key:
        if os.path.exists(name):
            utils.CreateBackup(name)
        if len(_suffix) == 0:
            utils.RemoveFile(name)

    new_priv_key_name = priv_key + _suffix
    new_pub_key_name = priv_key + _suffix + ".pub"

    result = utils.RunCmd(
        ["ssh-keygen", "-t", "dsa", "-f", new_priv_key_name, "-q", "-N", ""])
    if result.failed:
        raise error_fn("Could not generate ssh keypair, error %s" %
                       result.output)

    AddAuthorizedKey(auth_keys, utils.ReadFile(new_pub_key_name))
예제 #4
0
def Main():
    """Main routine.

  """
    opts = ParseOptions()

    utils.SetupToolLogging(opts.debug,
                           opts.verbose,
                           toolname=os.path.splitext(
                               os.path.basename(__file__))[0])

    try:
        # List of files to delete. Contains tuples consisting of the absolute path
        # and a boolean denoting whether a backup copy should be created before
        # deleting.
        clean_files = [
            (pathutils.CONFD_HMAC_KEY, True),
            (pathutils.CLUSTER_CONF_FILE, True),
            (pathutils.CLUSTER_DOMAIN_SECRET_FILE, True),
        ]
        clean_files.extend(map(lambda s: (s, True), pathutils.ALL_CERT_FILES))
        clean_files.extend(
            map(lambda s: (s, False),
                ssconf.SimpleStore().GetFileList()))

        if not opts.yes_do_it:
            cli.ToStderr(
                "Cleaning a node is irreversible. If you really want to"
                " clean this node, supply the --yes-do-it option.")
            return constants.EXIT_FAILURE

        logging.info("Stopping daemons")
        result = utils.RunCmd([pathutils.DAEMON_UTIL, "stop-all"],
                              interactive=True)
        if result.failed:
            raise Exception("Could not stop daemons, command '%s' failed: %s" %
                            (result.cmd, result.fail_reason))

        for (filename, backup) in clean_files:
            if os.path.exists(filename):
                if opts.backup and backup:
                    logging.info("Backing up %s", filename)
                    utils.CreateBackup(filename)

                logging.info("Removing %s", filename)
                utils.RemoveFile(filename)

        logging.info("Node successfully cleaned")
    except Exception, err:  # pylint: disable=W0703
        logging.debug("Caught unhandled exception", exc_info=True)

        (retcode, message) = cli.FormatError(err)
        logging.error(message)

        return retcode
예제 #5
0
  def testContent(self):
    bkpcount = 0
    for data in ["", "X", "Hello World!\n" * 100, "Binary data\0\x01\x02\n"]:
      for rep in [1, 2, 10, 127]:
        testdata = data * rep

        filename = utils.PathJoin(self.tmpdir, "test.data_")
        utils.WriteFile(filename, data=testdata)
        self.assertFileContent(filename, testdata)

        for _ in range(3):
          bname = utils.CreateBackup(filename)
          bkpcount += 1
          self.assertFileContent(bname, testdata)
          self.assertEqual(len(glob.glob("%s*" % filename)), 1 + bkpcount)
예제 #6
0
def ReplaceSshKeys(src_key_type,
                   dest_key_type,
                   src_key_suffix="",
                   dest_key_suffix=""):
    """Replaces an SSH key pair by another SSH key pair.

  Note that both parts, the private and the public key, are replaced.

  @type src_key_type: string
  @param src_key_type: key type of key pair that is replacing the other
      key pair
  @type dest_key_type: string
  @param dest_key_type: key type of the key pair that is being replaced
      by the source key pair
  @type src_key_suffix: string
  @param src_key_suffix: optional suffix of the key files of the source
      key pair
  @type dest_key_suffix: string
  @param dest_key_suffix: optional suffix of the keey files of the
      destination key pair

  """
    (src_priv_filename,
     src_pub_filename) = GetSshKeyFilenames(src_key_type,
                                            suffix=src_key_suffix)
    (dest_priv_filename,
     dest_pub_filename) = GetSshKeyFilenames(dest_key_type,
                                             suffix=dest_key_suffix)

    if not (os.path.exists(src_priv_filename)
            and os.path.exists(src_pub_filename)):
        raise errors.SshUpdateError(
            "At least one of the source key files is missing: %s",
            ", ".join([src_priv_filename, src_pub_filename]))

    for dest_file in [dest_priv_filename, dest_pub_filename]:
        if os.path.exists(dest_file):
            utils.CreateBackup(dest_file)
            utils.RemoveFile(dest_file)

    shutil.move(src_priv_filename, dest_priv_filename)
    shutil.move(src_pub_filename, dest_pub_filename)
예제 #7
0
파일: bootstrap.py 프로젝트: badp/ganeti
def _InitSSHSetup():
    """Setup the SSH configuration for the cluster.

  This generates a dsa keypair for root, adds the pub key to the
  permitted hosts and adds the hostkey to its own known hosts.

  """
    priv_key, pub_key, auth_keys = ssh.GetUserFiles(constants.SSH_LOGIN_USER)

    for name in priv_key, pub_key:
        if os.path.exists(name):
            utils.CreateBackup(name)
        utils.RemoveFile(name)

    result = utils.RunCmd(
        ["ssh-keygen", "-t", "dsa", "-f", priv_key, "-q", "-N", ""])
    if result.failed:
        raise errors.OpExecError("Could not generate ssh keypair, error %s" %
                                 result.output)

    utils.AddAuthorizedKey(auth_keys, utils.ReadFile(pub_key))
예제 #8
0
def GenerateClusterCrypto(new_cluster_cert,
                          new_rapi_cert,
                          new_spice_cert,
                          new_confd_hmac_key,
                          new_cds,
                          new_client_cert,
                          master_name,
                          rapi_cert_pem=None,
                          spice_cert_pem=None,
                          spice_cacert_pem=None,
                          cds=None,
                          nodecert_file=pathutils.NODED_CERT_FILE,
                          clientcert_file=pathutils.NODED_CLIENT_CERT_FILE,
                          rapicert_file=pathutils.RAPI_CERT_FILE,
                          spicecert_file=pathutils.SPICE_CERT_FILE,
                          spicecacert_file=pathutils.SPICE_CACERT_FILE,
                          hmackey_file=pathutils.CONFD_HMAC_KEY,
                          cds_file=pathutils.CLUSTER_DOMAIN_SECRET_FILE):
    """Updates the cluster certificates, keys and secrets.

  @type new_cluster_cert: bool
  @param new_cluster_cert: Whether to generate a new cluster certificate
  @type new_rapi_cert: bool
  @param new_rapi_cert: Whether to generate a new RAPI certificate
  @type new_spice_cert: bool
  @param new_spice_cert: Whether to generate a new SPICE certificate
  @type new_confd_hmac_key: bool
  @param new_confd_hmac_key: Whether to generate a new HMAC key
  @type new_cds: bool
  @param new_cds: Whether to generate a new cluster domain secret
  @type new_client_cert: bool
  @param new_client_cert: Whether to generate a new client certificate
  @type master_name: string
  @param master_name: FQDN of the master node
  @type rapi_cert_pem: string
  @param rapi_cert_pem: New RAPI certificate in PEM format
  @type spice_cert_pem: string
  @param spice_cert_pem: New SPICE certificate in PEM format
  @type spice_cacert_pem: string
  @param spice_cacert_pem: Certificate of the CA that signed the SPICE
                           certificate, in PEM format
  @type cds: string
  @param cds: New cluster domain secret
  @type nodecert_file: string
  @param nodecert_file: optional override of the node cert file path
  @type rapicert_file: string
  @param rapicert_file: optional override of the rapi cert file path
  @type spicecert_file: string
  @param spicecert_file: optional override of the spice cert file path
  @type spicecacert_file: string
  @param spicecacert_file: optional override of the spice CA cert file path
  @type hmackey_file: string
  @param hmackey_file: optional override of the hmac key file path

  """
    # pylint: disable=R0913
    # noded SSL certificate
    utils.GenerateNewSslCert(
        new_cluster_cert, nodecert_file, 1,
        "Generating new cluster certificate at %s" % nodecert_file)

    # If the cluster certificate was renewed, the client cert has to be
    # renewed and resigned.
    if new_cluster_cert or new_client_cert:
        utils.GenerateNewClientSslCert(clientcert_file, nodecert_file,
                                       master_name)

    # confd HMAC key
    if new_confd_hmac_key or not os.path.exists(hmackey_file):
        logging.debug("Writing new confd HMAC key to %s", hmackey_file)
        GenerateHmacKey(hmackey_file)

    if rapi_cert_pem:
        # Assume rapi_pem contains a valid PEM-formatted certificate and key
        logging.debug("Writing RAPI certificate at %s", rapicert_file)
        utils.WriteFile(rapicert_file, data=rapi_cert_pem, backup=True)

    else:
        utils.GenerateNewSslCert(
            new_rapi_cert, rapicert_file, 1,
            "Generating new RAPI certificate at %s" % rapicert_file)

    # SPICE
    spice_cert_exists = os.path.exists(spicecert_file)
    spice_cacert_exists = os.path.exists(spicecacert_file)
    if spice_cert_pem:
        # spice_cert_pem implies also spice_cacert_pem
        logging.debug("Writing SPICE certificate at %s", spicecert_file)
        utils.WriteFile(spicecert_file, data=spice_cert_pem, backup=True)
        logging.debug("Writing SPICE CA certificate at %s", spicecacert_file)
        utils.WriteFile(spicecacert_file, data=spice_cacert_pem, backup=True)
    elif new_spice_cert or not spice_cert_exists:
        if spice_cert_exists:
            utils.CreateBackup(spicecert_file)
        if spice_cacert_exists:
            utils.CreateBackup(spicecacert_file)

        logging.debug("Generating new self-signed SPICE certificate at %s",
                      spicecert_file)
        (_, cert_pem) = utils.GenerateSelfSignedSslCert(spicecert_file, 1)

        # Self-signed certificate -> the public certificate is also the CA public
        # certificate
        logging.debug("Writing the public certificate to %s", spicecert_file)
        utils.io.WriteFile(spicecacert_file, mode=0400, data=cert_pem)

    # Cluster domain secret
    if cds:
        logging.debug("Writing cluster domain secret to %s", cds_file)
        utils.WriteFile(cds_file, data=cds, backup=True)

    elif new_cds or not os.path.exists(cds_file):
        logging.debug("Generating new cluster domain secret at %s", cds_file)
        GenerateHmacKey(cds_file)