added into about i18n message abstraction to readme. made ssh key distribution mostly work (need to clean up output / debug).

This commit is contained in:
Borne Mace 2015-07-23 17:46:46 -07:00
parent 804e230e6a
commit 431f4e2d20
11 changed files with 354 additions and 65 deletions

View File

@ -16,3 +16,8 @@ available and any of the sub commands can be executed directly.
Alternately you can not use the shell and just execute commands
directly via >kollaclient host add, etc.
If you make changes to the i18n strings (denoted by methods like
_("message")) make sure to re-generate the i18n files with the
>python setup.py extract_messages command and check in the files
generated in openstack-kollaclient.

View File

@ -1,3 +1,16 @@
# Copyright(c) 2015, Oracle and/or its affiliates. All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
# not use this file except in compliance with the License. You may obtain
# a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations
# under the License.
import logging
import os

View File

@ -1,8 +1,22 @@
# Copyright(c) 2015, Oracle and/or its affiliates. All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
# not use this file except in compliance with the License. You may obtain
# a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations
# under the License.
import logging
from kollaclient.i18n import _
from kollaclient.sshutils import ssh_check_connect
from kollaclient.sshutils import ssh_check_host
from kollaclient.sshutils import ssh_check_keys
from kollaclient.sshutils import ssh_install_host
from kollaclient.sshutils import ssh_keygen
from kollaclient.utils import load_etc_yaml
from kollaclient.utils import save_etc_yaml
@ -23,8 +37,8 @@ class HostAdd(Command):
return parser
def take_action(self, parsed_args):
hostname = parsed_args.hostname
networkAddress = parsed_args.networkaddress
hostname = parsed_args.hostname.rstrip()
netAddr = parsed_args.networkaddress.rstrip()
contents = load_etc_yaml('hosts.yml')
for host, hostdata in contents.items():
if host == hostname:
@ -32,7 +46,7 @@ class HostAdd(Command):
self.log.info(_("host already exists"))
return
hostEntry = {hostname: {'Services': '', 'NetworkAddress':
networkAddress, 'Zone': ''}}
netAddr, 'Zone': ''}}
contents.update(hostEntry)
save_etc_yaml('hosts.yml', contents)
@ -49,7 +63,7 @@ class HostRemove(Command):
return parser
def take_action(self, parsed_args):
hostname = parsed_args.hostname
hostname = parsed_args.hostname.rstrip()
contents = load_etc_yaml('hosts.yml')
foundHost = False
for host, hostdata in contents.items():
@ -123,19 +137,25 @@ class HostCheck(Command):
sshKeysExist = ssh_check_keys()
if not sshKeysExist:
ssh_keygen()
hostname = parsed_args.hostname
hostname = parsed_args.hostname.rstrip()
netAddr = None
contents = load_etc_yaml('hosts.yml')
hostFound = False
for host, hostdata in contents.items():
if host == hostname:
# TODO(bmace) fix message
hostFound = True
networkAddress = hostdata['NetworkAddress']
self.log.info(networkAddress)
ssh_check_connect(networkAddress)
netAddr = hostdata['NetworkAddress']
self.log.info(netAddr)
if hostFound is False:
self.log.info("no host by name (" + hostname + ") found")
return False
sshCheck = ssh_check_host(netAddr)
if sshCheck is False:
self.log.error("ssh access to host failed")
return
class HostInstall(Command):
@ -146,6 +166,7 @@ class HostInstall(Command):
def get_parser(self, prog_name):
parser = super(HostInstall, self).get_parser(prog_name)
parser.add_argument('hostname')
parser.add_argument('password')
# TODO(bmace) error if arg missing
return parser
@ -154,15 +175,34 @@ class HostInstall(Command):
sshKeysExist = ssh_check_keys()
if not sshKeysExist:
ssh_keygen()
hostname = parsed_args.hostname
hostname = parsed_args.hostname.rstrip()
# TODO(bmace) get this password in another way?
password = parsed_args.password.rstrip()
netAddr = None
contents = load_etc_yaml('hosts.yml')
hostFound = False
for host, hostdata in contents.items():
if host == hostname:
# TODO(bmace) fix message
hostFound = True
networkAddress = hostdata['NetworkAddress']
self.log.info(networkAddress)
netAddr = hostdata['NetworkAddress']
self.log.info(netAddr)
if hostFound is False:
self.log.info("no host by name (" + hostname + ") found")
return False
sshCheck = ssh_check_host(netAddr)
# If sshCheck fails we need to set up the user / remote ssh keys
# using root and the available password
if sshCheck is False:
self.log.info("configuring admin user and ssh keys")
self.log.info("calling ssh_install_host with: " + netAddr +
" : " + password)
installHost = ssh_install_host(netAddr, password)
if installHost is False:
# TODO(bmace) probably throw out of ssh_install_host and
# log the error here, or maybe log it in ssh_install_host?
self.log.info("host install failed for host: " + hostname)
else:
self.log.info("host install succeeded")

View File

@ -1,3 +1,16 @@
# Copyright(c) 2015, Oracle and/or its affiliates. All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
# not use this file except in compliance with the License. You may obtain
# a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations
# under the License.
import logging
from kollaclient.i18n import _

View File

@ -1,3 +1,16 @@
# Copyright(c) 2015, Oracle and/or its affiliates. All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
# not use this file except in compliance with the License. You may obtain
# a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations
# under the License.
import logging
from kollaclient.i18n import _

View File

@ -1,18 +1,16 @@
# Copyright 2015 Oracle TODO(bmace) -- FIX THIS LINE
# Copyright(c) 2015, Oracle and/or its affiliates. All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
# not use this file except in compliance with the License. You may obtain
# a copy of the License at
# Licensed under the Apache License, Version 2.0 (the "License"); you may
# not use this file except in compliance with the License. You may obtain
# a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations
# under the License.
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations
# under the License.
"""Command-line interface to Kolla"""
import sys

View File

@ -1,3 +1,16 @@
# Copyright(c) 2015, Oracle and/or its affiliates. All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
# not use this file except in compliance with the License. You may obtain
# a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations
# under the License.
import logging
import os.path
import paramiko
@ -19,46 +32,130 @@ def ssh_check_keys():
def ssh_connect(netAddr, username, password, useKeys):
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())
log.info("connecting to addr: " + netAddr +
" user: " + username + " password: " + password +
" useKeys: " + str(useKeys))
if useKeys:
sshClient.connect(hostname=netAddr, username=username,
password=password, pkey=privateKey)
else:
sshClient.connect(hostname=netAddr, username=username,
password=password, pkey=None)
password=password)
return sshClient
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.error("connect exception: " + str(e))
log.error("connect exception: " + str(type(e)))
log.error("connect exception: " + str(e.args))
try:
sshClient.close()
except Exception:
pass
return None
def ssh_check_connect(netAddr):
def ssh_check_host(netAddr):
log = logging.getLogger(__name__)
log.info("ssh check connect " + netAddr)
try:
sshClient = ssh_connect(netAddr, get_admin_user(), '', True)
if sshClient is None:
log.info("check host failed as connect failed")
return False
try:
log.info("about to exec 'ls'")
sshClient.exec_command("ls")
return True
# TODO(bmace) do whatever other checks are needed
except paramiko.SSHException as sshException:
log.error("exec failed" + sshException)
log.error("exec failed" + str(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()
log.error(str(e))
log.error(str(type(e)))
log.error(str(e.args))
finally:
try:
sshClient.close()
except Exception:
pass
return False
def ssh_install_host(netAddr, password):
log = logging.getLogger(__name__)
log.info("ssh install host " + netAddr)
adminUser = get_admin_user()
publicKey = ssh_get_public_key()
try:
# TODO(bmace) allow setup as some user other than root?
# add user
sshClient = ssh_connect(netAddr, "root", password, False)
commandStr = "useradd -m " + adminUser
log.info(commandStr)
stdin, stdout, stderr = sshClient.exec_command(commandStr)
log.info(str(stdout.read()) + " : " + str(stderr.read()))
# create ssh dir
commandStr = ("su - " + adminUser +
" -c \"mkdir /home/" + adminUser +
"/.ssh\"")
log.info(commandStr)
stdin, stdout, stderr = sshClient.exec_command(commandStr)
log.info(str(stdout.read()) + " : " + str(stderr.read()))
# create authorized_keys file
commandStr = ("su - " + adminUser +
" -c \"touch /home/" + adminUser +
"/.ssh/authorized_keys\"")
log.info(commandStr)
stdin, stdout, stderr = sshClient.exec_command(commandStr)
log.info(str(stdout.read()) + " : " + str(stderr.read()))
# populate authorized keys file w/ public key
commandStr = ("su - " + adminUser +
" -c \"echo '" + publicKey +
"' > /home/" + adminUser +
"/.ssh/authorized_keys\"")
log.info(commandStr)
stdin, stdout, stderr = sshClient.exec_command(commandStr)
log.info(str(stdout.read()) + " : " + str(stderr.read()))
# set appropriate permissions for ssh dir
commandStr = ("su - " + adminUser +
" -c \"chmod 0700 /home/" + adminUser +
"/.ssh\"")
log.info(commandStr)
stdin, stdout, stderr = sshClient.exec_command(commandStr)
log.info(str(stdout.read()) + " : " + str(stderr.read()))
# set appropriate permissions for authorized_keys file
commandStr = ("su - " + adminUser +
" -c \"chmod 0740 /home/" + adminUser +
"/.ssh/authorized_keys\"")
log.info(commandStr)
stdin, stdout, stderr = sshClient.exec_command(commandStr)
log.info(str(stdout.read()) + " : " + str(stderr.read()))
# TODO(bmace) do whatever else needs to be done at install time
except Exception as e:
log.error(str(e))
log.error(str(type(e)))
log.error(str(e.args()))
finally:
try:
sshClient.close()
except Exception:
pass
def ssh_keygen():
@ -87,11 +184,18 @@ def ssh_keygen():
log.info("generated public key at: " + publicKeyPath)
except Exception as e:
# TODO(bmace) better failure behavior here
log.error(e)
log.error(type(e))
log.error(e.args)
log.error(str(e))
log.error(str(type(e)))
log.error(str(e.args))
def ssh_get_private_key():
return paramiko.RSAKey.from_private_key_file(get_pk_file(),
get_pk_password())
def ssh_get_public_key():
with open(get_pk_file() + ".pub", "r") as publicKeyFile:
publicKey = publicKeyFile.read()
return publicKey
return None

View File

@ -1,36 +1,42 @@
# Copyright(c) 2015, Oracle and/or its affiliates. All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
# not use this file except in compliance with the License. You may obtain
# a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations
# under the License.
import os
import yaml
def get_env(var, default):
value = os.environ.get(var, None)
if value:
return value
return default
def get_kolla_home():
return get_env("KOLLA_HOME", "/opt/kolla")
return os.environ.get("KOLLA_HOME", "/opt/kolla")
def get_kolla_etc():
return get_env("KOLLA_ETC", "/etc")
return os.environ.get("KOLLA_ETC", "/etc")
def get_client_home():
return get_env("KOLLA_CLIENT_HOME", "/opt/kollaclient/")
return os.environ.get("KOLLA_CLIENT_HOME", "/opt/kollaclient/")
def get_client_etc():
return get_env("KOLLA_CLIENT_ETC", "/etc/kollaclient/etc/")
return os.environ.get("KOLLA_CLIENT_ETC", "/etc/kollaclient/etc/")
def get_admin_user():
return get_env("KOLLA_ADMIN_USER", "kolla")
return os.environ.get("KOLLA_ADMIN_USER", "kolla")
def get_pk_file():
return get_env("KOLLA_CLIENT_PKPATH", "/opt/kollaclient/etc/id_rsa")
return os.environ.get("KOLLA_CLIENT_PKPATH", "/opt/kollaclient/etc/id_rsa")
def get_pk_password():

View File

@ -1,3 +1,16 @@
# Copyright(c) 2015, Oracle and/or its affiliates. All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
# not use this file except in compliance with the License. You may obtain
# a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations
# under the License.
import logging
from kollaclient.i18n import _

View File

@ -7,9 +7,9 @@
#, fuzzy
msgid ""
msgstr ""
"Project-Id-Version: kollaclient 0.1.dev0.g\n"
"Project-Id-Version: kollaclient 0.1.0.dev4\n"
"Report-Msgid-Bugs-To: EMAIL@ADDRESS\n"
"POT-Creation-Date: 2015-07-15 13:29-0700\n"
"POT-Creation-Date: 2015-07-23 10:32-0700\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n"
@ -18,15 +18,95 @@ msgstr ""
"Content-Transfer-Encoding: 8bit\n"
"Generated-By: Babel 1.3\n"
#: kollaclient/host.py:14
msgid "host add"
#: kollaclient/common.py:17
msgid "deploy"
msgstr ""
#: kollaclient/host.py:24
msgid "host remove"
#: kollaclient/common.py:27
msgid "install"
msgstr ""
#: kollaclient/host.py:34
#: kollaclient/common.py:37
msgid "list"
msgstr ""
#: kollaclient/common.py:49
msgid "start"
msgstr ""
#: kollaclient/common.py:67
msgid "stop"
msgstr ""
#: kollaclient/common.py:76
msgid "sync"
msgstr ""
#: kollaclient/common.py:85
msgid "upgrade"
msgstr ""
#: kollaclient/common.py:94
msgid "dump"
msgstr ""
#: kollaclient/host.py:32
msgid "host already exists"
msgstr ""
#: kollaclient/host.py:72
msgid "host list"
msgstr ""
#: kollaclient/host.py:86
msgid "host setzone"
msgstr ""
#: kollaclient/host.py:96
msgid "host addservice"
msgstr ""
#: kollaclient/host.py:106
msgid "host removeservice"
msgstr ""
#: kollaclient/host.py:122
msgid "host check"
msgstr ""
#: kollaclient/host.py:153
msgid "host install"
msgstr ""
#: kollaclient/property.py:14
msgid "property set"
msgstr ""
#: kollaclient/property.py:24
msgid "property list"
msgstr ""
#: kollaclient/service.py:14
msgid "service activate"
msgstr ""
#: kollaclient/service.py:24
msgid "service deactivate"
msgstr ""
#: kollaclient/service.py:34
msgid "service autodeploy"
msgstr ""
#: kollaclient/service.py:44
msgid "service list"
msgstr ""
#: kollaclient/zone.py:26
msgid "zone already exists"
msgstr ""
#: kollaclient/zone.py:64
msgid "zone list"
msgstr ""

View File

@ -1,5 +1,4 @@
#!/usr/bin/env python
# Copyright (c) 2015 Oracle TODO(bmace) fix this
# Copyright (c) 2013 Hewlett-Packard Development Company, L.P.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
@ -20,6 +19,11 @@ import setuptools
# In python < 2.7.4, a lazy loading of package `pbr` will break
# setuptools if some other modules registered functions in `atexit`.
# solution from: http://bugs.python.org/issue15881#msg170215
try:
import multiprocessing # noqa
except ImportError:
pass
setuptools.setup(
setup_requires=['pbr'],
setup_requires=['pbr>=1.3'],
pbr=True)