improved key generation behavior. partially implemented ssh_check_connection.

This commit is contained in:
Borne Mace 2015-07-22 17:29:42 -07:00
parent 3ff5cc7222
commit 804e230e6a
4 changed files with 101 additions and 32 deletions

1
.gitignore vendored Normal file
View File

@ -0,0 +1 @@
etc/

View File

@ -1,6 +1,8 @@
import logging import logging
from kollaclient.i18n import _ from kollaclient.i18n import _
from kollaclient.sshutils import ssh_check_connect
from kollaclient.sshutils import ssh_check_keys
from kollaclient.sshutils import ssh_keygen from kollaclient.sshutils import ssh_keygen
from kollaclient.utils import load_etc_yaml from kollaclient.utils import load_etc_yaml
from kollaclient.utils import save_etc_yaml from kollaclient.utils import save_etc_yaml
@ -16,21 +18,21 @@ class HostAdd(Command):
def get_parser(self, prog_name): def get_parser(self, prog_name):
parser = super(HostAdd, self).get_parser(prog_name) parser = super(HostAdd, self).get_parser(prog_name)
parser.add_argument('hostname') parser.add_argument('hostname')
parser.add_argument('ipaddress') parser.add_argument('networkaddress')
# TODO(bmace) error if args missing # TODO(bmace) error if args missing
return parser return parser
def take_action(self, parsed_args): def take_action(self, parsed_args):
hostname = parsed_args.hostname hostname = parsed_args.hostname
ipaddr = parsed_args.ipaddress networkAddress = parsed_args.networkaddress
contents = load_etc_yaml('hosts.yml') contents = load_etc_yaml('hosts.yml')
for host, hostdata in contents.items(): for host, hostdata in contents.items():
if host == hostname: if host == hostname:
# TODO(bmace) fix message # TODO(bmace) fix message
self.log.info(_("host already exists")) self.log.info(_("host already exists"))
return return
hostEntry = {hostname: {'Services': '', 'IPAddress': hostEntry = {hostname: {'Services': '', 'NetworkAddress':
ipaddr, 'Zone': ''}} networkAddress, 'Zone': ''}}
contents.update(hostEntry) contents.update(hostEntry)
save_etc_yaml('hosts.yml', contents) save_etc_yaml('hosts.yml', contents)
@ -118,6 +120,9 @@ class HostCheck(Command):
def take_action(self, parsed_args): def take_action(self, parsed_args):
self.log.info(_("host check")) self.log.info(_("host check"))
sshKeysExist = ssh_check_keys()
if not sshKeysExist:
ssh_keygen()
hostname = parsed_args.hostname hostname = parsed_args.hostname
contents = load_etc_yaml('hosts.yml') contents = load_etc_yaml('hosts.yml')
hostFound = False hostFound = False
@ -125,8 +130,9 @@ class HostCheck(Command):
if host == hostname: if host == hostname:
# TODO(bmace) fix message # TODO(bmace) fix message
hostFound = True hostFound = True
self.log.info(hostdata['IPAddress']) networkAddress = hostdata['NetworkAddress']
return self.log.info(networkAddress)
ssh_check_connect(networkAddress)
if hostFound is False: if hostFound is False:
self.log.info("no host by name (" + hostname + ") found") self.log.info("no host by name (" + hostname + ") found")
@ -145,7 +151,9 @@ class HostInstall(Command):
def take_action(self, parsed_args): def take_action(self, parsed_args):
self.log.info(_("host install")) self.log.info(_("host install"))
ssh_keygen() sshKeysExist = ssh_check_keys()
if not sshKeysExist:
ssh_keygen()
hostname = parsed_args.hostname hostname = parsed_args.hostname
contents = load_etc_yaml('hosts.yml') contents = load_etc_yaml('hosts.yml')
hostFound = False hostFound = False
@ -153,8 +161,8 @@ class HostInstall(Command):
if host == hostname: if host == hostname:
# TODO(bmace) fix message # TODO(bmace) fix message
hostFound = True hostFound = True
self.log.info(hostdata['IPAddress']) networkAddress = hostdata['NetworkAddress']
return self.log.info(networkAddress)
if hostFound is False: if hostFound is False:
self.log.info("no host by name (" + hostname + ") found") self.log.info("no host by name (" + hostname + ") found")

View File

@ -1,41 +1,97 @@
import logging import logging
import os.path
import paramiko import paramiko
from kollaclient.utils import get_admin_user
from kollaclient.utils import get_pk_bits from kollaclient.utils import get_pk_bits
from kollaclient.utils import get_pk_file from kollaclient.utils import get_pk_file
from kollaclient.utils import get_pk_password from kollaclient.utils import get_pk_password
def ssh_connect(hostname): def ssh_check_keys():
privateKeyPath = get_pk_file()
publicKeyPath = privateKeyPath + ".pub"
if os.path.isfile(privateKeyPath) and os.path.isfile(publicKeyPath):
return True
else:
return False
def ssh_connect(netAddr, username, password, useKeys):
log = logging.getLogger(__name__) log = logging.getLogger(__name__)
log.info("ssh connect " + netAddr)
try:
sshClient = paramiko.SSHClient()
privateKey = ssh_get_private_key()
sshClient.set_missing_host_key_policy(paramiko.AutoAddPolicy())
if useKeys:
sshClient.connect(hostname=netAddr, username=username,
password=password, pkey=privateKey)
else:
sshClient.connect(hostname=netAddr, username=username,
password=password, pkey=None)
except Exception as e:
# TODO(bmace) better failure behavior here
log.error(e)
log.error(type(e))
log.error(e.args)
sshClient.close()
return sshClient
log.info("ssh connect " + hostname)
# ssh = paramiko.SSHClient() def ssh_check_connect(netAddr):
# privateKey = paramiko.RSAKey.from_private_key_file(get_pk_file()) log = logging.getLogger(__name__)
# ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy()) log.info("ssh check connect " + netAddr)
return try:
sshClient = ssh_connect(netAddr, get_admin_user(), '', True)
try:
sshClient.exec_command("ls")
return True
except paramiko.SSHException as sshException:
log.error("exec failed" + sshException)
log.error("exec failed" + type(sshException))
log.error("exec failed" + sshException.args)
sshClient.close()
return False
except Exception as e:
# TODO(bmace) better failure behavior here
log.error(e)
log.error(type(e))
log.error(e.args)
sshClient.close()
def ssh_keygen(): def ssh_keygen():
log = logging.getLogger(__name__) log = logging.getLogger(__name__)
try: try:
log.info("keygen") privateKeyPath = get_pk_file()
privateKey = paramiko.RSAKey.generate(get_pk_bits()) publicKeyPath = privateKeyPath + ".pub"
log.info("writekey") privateKey = None
privateKey.write_private_key_file(filename=get_pk_file(), privateKeyGenerated = False
password=get_pk_password()) if os.path.isfile(privateKeyPath) is False:
log.info("genpubkey") privateKey = paramiko.RSAKey.generate(get_pk_bits())
publicKey = paramiko.RSAKey(filename=get_pk_file(), privateKey.write_private_key_file(filename=privateKeyPath,
password=get_pk_password()) password=get_pk_password())
log.info("writepubkey") privateKeyGenerated = True
with open("%s.pub" % get_pk_file(), 'w') as pubFile: log.info("generated private key at: " + privateKeyPath)
pubFile.write("%s %s" % (publicKey.get_name(),
publicKey.get_base64())) # If the public key exists already, only regenerate it if the private
log.info("donekeygen") # key has changed
if os.path.isfile(publicKeyPath) is False or privateKeyGenerated:
publicKey = paramiko.RSAKey(filename=privateKeyPath,
password=get_pk_password())
with open(publicKeyPath, 'w') as pubFile:
pubFile.write("%s %s" % (publicKey.get_name(),
publicKey.get_base64()))
log.info("generated public key at: " + publicKeyPath)
except Exception as e: except Exception as e:
print e # TODO(bmace) better failure behavior here
print type(e) log.error(e)
print e.args log.error(type(e))
log.error(e.args)
def ssh_get_private_key():
return paramiko.RSAKey.from_private_key_file(get_pk_file(),
get_pk_password())

View File

@ -25,6 +25,10 @@ def get_client_etc():
return get_env("KOLLA_CLIENT_ETC", "/etc/kollaclient/etc/") return get_env("KOLLA_CLIENT_ETC", "/etc/kollaclient/etc/")
def get_admin_user():
return get_env("KOLLA_ADMIN_USER", "kolla")
def get_pk_file(): def get_pk_file():
return get_env("KOLLA_CLIENT_PKPATH", "/opt/kollaclient/etc/id_rsa") return get_env("KOLLA_CLIENT_PKPATH", "/opt/kollaclient/etc/id_rsa")