def testRemoveAllExistingKeys(self): pub_key_file = self._CreateTempFile() ssh.AddPublicKey(self.UUID_1, self.KEY_A, key_file=pub_key_file) ssh.AddPublicKey(self.UUID_1, self.KEY_B, key_file=pub_key_file) self.assertFileContent(pub_key_file, "123-456 ssh-dss AAAAB3NzaC1w5256closdj32mZaQU root@key-a\n" "123-456 ssh-dss BAasjkakfa234SFSFDA345462AAAB root@key-b\n") ssh.RemovePublicKey(self.UUID_1, key_file=pub_key_file) self.assertFileContent(pub_key_file, "")
def _SetupSSH(options, cluster_name, node, ssh_port, cl): """Configures a destination node's SSH daemon. @param options: Command line options @type cluster_name @param cluster_name: Cluster name @type node: string @param node: Destination node name @type ssh_port: int @param ssh_port: Destination node ssh port @param cl: luxi client """ # Retrieve the list of master and master candidates candidate_filter = ["|", ["=", "role", "M"], ["=", "role", "C"]] result = cl.Query(constants.QR_NODE, ["uuid"], candidate_filter) if len(result.data) < 1: raise errors.OpPrereqError("No master or master candidate node is found.") candidates = [uuid for ((_, uuid),) in result.data] candidate_keys = ssh.QueryPubKeyFile(candidates) if options.force_join: ToStderr("The \"--force-join\" option is no longer supported and will be" " ignored.") host_keys = _ReadSshKeys(constants.SSH_DAEMON_KEYFILES) (_, root_keyfiles) = \ ssh.GetAllUserFiles(constants.SSH_LOGIN_USER, mkdir=False, dircheck=False) dsa_root_keyfiles = dict((kind, value) for (kind, value) in root_keyfiles.items() if kind == constants.SSHK_DSA) root_keys = _ReadSshKeys(dsa_root_keyfiles) (_, cert_pem) = \ utils.ExtractX509Certificate(utils.ReadFile(pathutils.NODED_CERT_FILE)) data = { constants.SSHS_CLUSTER_NAME: cluster_name, constants.SSHS_NODE_DAEMON_CERTIFICATE: cert_pem, constants.SSHS_SSH_HOST_KEY: host_keys, constants.SSHS_SSH_ROOT_KEY: root_keys, constants.SSHS_SSH_AUTHORIZED_KEYS: candidate_keys, } ssh.RunSshCmdWithStdin(cluster_name, node, pathutils.PREPARE_NODE_JOIN, ssh_port, data, debug=options.debug, verbose=options.verbose, use_cluster_key=False, ask_key=options.ssh_key_check, strict_host_check=options.ssh_key_check) (_, dsa_pub_keyfile) = root_keyfiles[constants.SSHK_DSA] pub_key = ssh.ReadRemoteSshPubKeys(dsa_pub_keyfile, node, cluster_name, ssh_port, options.ssh_key_check, options.ssh_key_check) # Unfortunately, we have to add the key with the node name rather than # the node's UUID here, because at this point, we do not have a UUID yet. # The entry will be corrected in noded later. ssh.AddPublicKey(node, pub_key)
def testReplaceNameByUuid(self): pub_key_file = self._CreateTempFile() name = "my.precious.node" ssh.AddPublicKey(name, self.KEY_A, key_file=pub_key_file) ssh.AddPublicKey(self.UUID_2, self.KEY_A, key_file=pub_key_file) ssh.AddPublicKey(name, self.KEY_B, key_file=pub_key_file) self.assertFileContent(pub_key_file, "my.precious.node ssh-dss AAAAB3NzaC1w5256closdj32mZaQU root@key-a\n" "789-ABC ssh-dss AAAAB3NzaC1w5256closdj32mZaQU root@key-a\n" "my.precious.node ssh-dss BAasjkakfa234SFSFDA345462AAAB root@key-b\n") ssh.ReplaceNameByUuid(self.UUID_1, name, key_file=pub_key_file) self.assertFileContent(pub_key_file, "123-456 ssh-dss AAAAB3NzaC1w5256closdj32mZaQU root@key-a\n" "789-ABC ssh-dss AAAAB3NzaC1w5256closdj32mZaQU root@key-a\n" "123-456 ssh-dss BAasjkakfa234SFSFDA345462AAAB root@key-b\n")
def testAddingExistingPubKey(self): expected_file_content = \ "123-456 ssh-dss AAAAB3NzaC1w5256closdj32mZaQU root@key-a\n" + \ "789-ABC ssh-dss BAasjkakfa234SFSFDA345462AAAB root@key-b\n" pub_key_file = self._CreateTempFile() ssh.AddPublicKey(self.UUID_1, self.KEY_A, key_file=pub_key_file) ssh.AddPublicKey(self.UUID_2, self.KEY_B, key_file=pub_key_file) self.assertFileContent(pub_key_file, expected_file_content) ssh.AddPublicKey(self.UUID_1, self.KEY_A, key_file=pub_key_file) self.assertFileContent(pub_key_file, expected_file_content) ssh.AddPublicKey(self.UUID_1, self.KEY_B, key_file=pub_key_file) self.assertFileContent(pub_key_file, "123-456 ssh-dss AAAAB3NzaC1w5256closdj32mZaQU root@key-a\n" "789-ABC ssh-dss BAasjkakfa234SFSFDA345462AAAB root@key-b\n" "123-456 ssh-dss BAasjkakfa234SFSFDA345462AAAB root@key-b\n")
def testParseEmptyLines(self): pub_key_file = self._CreateTempFile() ssh.AddPublicKey(self.UUID_1, self.KEY_A, key_file=pub_key_file) # Add an empty line fd = open(pub_key_file, 'a') fd.write("\n") fd.close() ssh.AddPublicKey(self.UUID_2, self.KEY_B, key_file=pub_key_file) # Add a whitespace line fd = open(pub_key_file, 'a') fd.write(" \n") fd.close() result = ssh.QueryPubKeyFile(self.UUID_1, key_file=pub_key_file) self.assertEquals([self.KEY_A], result[self.UUID_1])
def testRetrieveKeys(self): pub_key_file = self._CreateTempFile() ssh.AddPublicKey(self.UUID_1, self.KEY_A, key_file=pub_key_file) ssh.AddPublicKey(self.UUID_2, self.KEY_B, key_file=pub_key_file) result = ssh.QueryPubKeyFile(self.UUID_1, key_file=pub_key_file) self.assertEquals([self.KEY_A], result[self.UUID_1]) target_uuids = [self.UUID_1, self.UUID_2, "non-existing-UUID"] result = ssh.QueryPubKeyFile(target_uuids, key_file=pub_key_file) self.assertEquals([self.KEY_A], result[self.UUID_1]) self.assertEquals([self.KEY_B], result[self.UUID_2]) self.assertEquals(2, len(result)) # Query all keys target_uuids = None result = ssh.QueryPubKeyFile(target_uuids, key_file=pub_key_file) self.assertEquals([self.KEY_A], result[self.UUID_1]) self.assertEquals([self.KEY_B], result[self.UUID_2])
def testRemoveNonexistingKey(self): pub_key_file = self._CreateTempFile() ssh.AddPublicKey(self.UUID_1, self.KEY_B, key_file=pub_key_file) self.assertFileContent(pub_key_file, "123-456 ssh-dss BAasjkakfa234SFSFDA345462AAAB root@key-b\n") ssh.RemovePublicKey(self.UUID_2, key_file=pub_key_file) self.assertFileContent(pub_key_file, "123-456 ssh-dss BAasjkakfa234SFSFDA345462AAAB root@key-b\n")
def UpdatePubKeyFile(data, dry_run, key_file=pathutils.SSH_PUB_KEYS): """Updates the file of public SSH keys. @type data: dict @param data: Input data @type dry_run: boolean @param dry_run: Whether to perform a dry run """ instructions = data.get(constants.SSHS_SSH_PUBLIC_KEYS) if not instructions: logging.info("No instructions to modify public keys received." " Not modifying the public key file at all.") return (action, public_keys) = instructions if action == constants.SSHS_OVERRIDE: if dry_run: logging.info("This is a dry run, not overriding %s", key_file) else: ssh.OverridePubKeyFile(public_keys, key_file=key_file) elif action in [constants.SSHS_ADD, constants.SSHS_REPLACE_OR_ADD]: if dry_run: logging.info( "This is a dry run, not adding or replacing a key to %s", key_file) else: for uuid, keys in public_keys.items(): if action == constants.SSHS_REPLACE_OR_ADD: ssh.RemovePublicKey(uuid, key_file=key_file) for key in keys: ssh.AddPublicKey(uuid, key, key_file=key_file) elif action == constants.SSHS_REMOVE: if dry_run: logging.info("This is a dry run, not removing keys from %s", key_file) else: for uuid in public_keys.keys(): ssh.RemovePublicKey(uuid, key_file=key_file) elif action == constants.SSHS_CLEAR: if dry_run: logging.info("This is a dry run, not clearing file %s", key_file) else: ssh.ClearPubKeyFile(key_file=key_file) else: raise SshUpdateError("Action '%s' not implemented for public keys." % action)
def testClearPubKeyFile(self): pub_key_file = self._CreateTempFile() ssh.AddPublicKey(self.UUID_2, self.KEY_A, key_file=pub_key_file) ssh.ClearPubKeyFile(key_file=pub_key_file) self.assertFileContent(pub_key_file, "")