Summary: add 4 new cli group commands
Description: - new commands: - group add / remove - group listservices - group listhosts - make jsonpickle output read-able - add try/excepts in host.py to better debug errors - remove zones logic
This commit is contained in:
parent
226a017887
commit
755cf0f96c
|
@ -247,9 +247,13 @@ class Inventory(object):
|
|||
# if this is called many times you will have an unpleasant
|
||||
# file handle leak
|
||||
tmp_filehandle, tmp_path = mkstemp()
|
||||
|
||||
# multiple trips thru json to render a readable inventory file
|
||||
data = jsonpickle.encode(inventory)
|
||||
data_str = json.loads(data)
|
||||
pretty_data = json.dumps(data_str, indent=4)
|
||||
with open(tmp_path, 'w') as tmp_file:
|
||||
tmp_file.write(data)
|
||||
tmp_file.write(pretty_data)
|
||||
shutil.copyfile(tmp_path, inventory_path)
|
||||
os.remove(tmp_path)
|
||||
except Exception as e:
|
||||
|
@ -284,6 +288,17 @@ class Inventory(object):
|
|||
def get_hostnames(self):
|
||||
return self._hosts.keys()
|
||||
|
||||
def get_host_groups(self):
|
||||
"""return { hostname : groupnames }"""
|
||||
|
||||
host_groups = {}
|
||||
for host in self._hosts.values():
|
||||
host_groups[host.name] = []
|
||||
groups = self.get_groups(host)
|
||||
for group in groups:
|
||||
host_groups[host.name].append(group.name)
|
||||
return host_groups
|
||||
|
||||
def get_host(self, hostname):
|
||||
host = None
|
||||
if hostname in self._hosts:
|
||||
|
@ -318,6 +333,14 @@ class Inventory(object):
|
|||
if group_count == 0:
|
||||
del self._hosts[hostname]
|
||||
|
||||
def add_group(self, groupname):
|
||||
if groupname not in self._groups:
|
||||
self._groups[groupname] = Group(groupname)
|
||||
|
||||
def remove_group(self, groupname):
|
||||
if groupname in self._groups:
|
||||
del self._groups[groupname]
|
||||
|
||||
def get_groups(self, host=None):
|
||||
"""return all groups containing host
|
||||
|
||||
|
@ -325,31 +348,30 @@ class Inventory(object):
|
|||
"""
|
||||
if not host:
|
||||
return self._groups.values()
|
||||
host_groups = self.get_host_groups([host])
|
||||
groupnames = host_groups[host.name]
|
||||
|
||||
groups = []
|
||||
for groupname in groupnames:
|
||||
groups.append(self._groups[groupname])
|
||||
for group in self._groups.values():
|
||||
if host.name in group.get_hostnames():
|
||||
groups.append(group)
|
||||
return groups
|
||||
|
||||
def get_host_groups(self, hosts):
|
||||
"""returns a dict: { hostname : [groupnames] }"""
|
||||
host_groups = self._get_host_groups(hosts, self._groups.values())
|
||||
return host_groups
|
||||
def get_group_services(self):
|
||||
"""return { groupname : [servicenames] }"""
|
||||
group_services = {}
|
||||
for group in self._groups.values():
|
||||
group_services[group.name] = []
|
||||
for child in group.children:
|
||||
group_services[group.name].append(child.name)
|
||||
return group_services
|
||||
|
||||
def _get_host_groups(self, hosts, groups):
|
||||
host_groups = {}
|
||||
for group in groups:
|
||||
if group.children:
|
||||
hosts_children = self._get_host_groups(hosts, group.children)
|
||||
host_groups.update(hosts_children)
|
||||
for host in hosts:
|
||||
if host.name in group._hosts:
|
||||
if host.name not in host_groups:
|
||||
host_groups[host.name] = []
|
||||
host_groups[host.name].append(group.name)
|
||||
|
||||
return host_groups
|
||||
def get_group_hosts(self):
|
||||
"""return { groupname : [hostnames] }"""
|
||||
group_hosts = {}
|
||||
for group in self._groups.values():
|
||||
group_hosts[group.name] = []
|
||||
for host in group.get_hosts():
|
||||
group_hosts[group.name].append(host.name)
|
||||
return group_hosts
|
||||
|
||||
def get_ansible_json(self):
|
||||
"""generate json inventory for ansible
|
||||
|
|
|
@ -0,0 +1,113 @@
|
|||
# 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 traceback
|
||||
|
||||
from kollacli.ansible.inventory import Inventory
|
||||
from kollacli.exceptions import CommandError
|
||||
|
||||
from cliff.command import Command
|
||||
from cliff.lister import Lister
|
||||
|
||||
|
||||
class GroupAdd(Command):
|
||||
"""Add group to open-stack-kolla"""
|
||||
log = logging.getLogger(__name__)
|
||||
|
||||
def get_parser(self, prog_name):
|
||||
parser = super(GroupAdd, self).get_parser(prog_name)
|
||||
parser.add_argument('groupname', metavar='<groupname>',
|
||||
help='group')
|
||||
return parser
|
||||
|
||||
def take_action(self, parsed_args):
|
||||
try:
|
||||
groupname = parsed_args.groupname.strip()
|
||||
|
||||
inventory = Inventory.load()
|
||||
inventory.add_group(groupname)
|
||||
Inventory.save(inventory)
|
||||
except CommandError as e:
|
||||
raise e
|
||||
except Exception as e:
|
||||
raise Exception(traceback.format_exc())
|
||||
|
||||
|
||||
class GroupRemove(Command):
|
||||
"""Remove group from openstack-kolla"""
|
||||
|
||||
log = logging.getLogger(__name__)
|
||||
|
||||
def get_parser(self, prog_name):
|
||||
parser = super(GroupRemove, self).get_parser(prog_name)
|
||||
parser.add_argument('groupname', metavar='<groupname>',
|
||||
help='group name')
|
||||
return parser
|
||||
|
||||
def take_action(self, parsed_args):
|
||||
try:
|
||||
groupname = parsed_args.groupname.strip()
|
||||
inventory = Inventory.load()
|
||||
inventory.remove_group(groupname)
|
||||
Inventory.save(inventory)
|
||||
except CommandError as e:
|
||||
raise e
|
||||
except Exception as e:
|
||||
raise Exception(traceback.format_exc())
|
||||
|
||||
|
||||
class GroupListservices(Lister):
|
||||
"""List all groups and their services"""
|
||||
|
||||
log = logging.getLogger(__name__)
|
||||
|
||||
def take_action(self, parsed_args):
|
||||
try:
|
||||
inventory = Inventory.load()
|
||||
|
||||
data = []
|
||||
group_services = inventory.get_group_services()
|
||||
if group_services:
|
||||
for (groupname, servicenames) in group_services.items():
|
||||
data.append((groupname, servicenames))
|
||||
else:
|
||||
data.append(('', ''))
|
||||
return (('Group Name', 'Services'), sorted(data))
|
||||
except CommandError as e:
|
||||
raise e
|
||||
except Exception as e:
|
||||
raise Exception(traceback.format_exc())
|
||||
|
||||
|
||||
class GroupListhosts(Lister):
|
||||
"""List all groups and their hosts"""
|
||||
|
||||
log = logging.getLogger(__name__)
|
||||
|
||||
def take_action(self, parsed_args):
|
||||
try:
|
||||
inventory = Inventory.load()
|
||||
|
||||
data = []
|
||||
group_hosts = inventory.get_group_hosts()
|
||||
if group_hosts:
|
||||
for (groupname, hostnames) in group_hosts.items():
|
||||
data.append((groupname, hostnames))
|
||||
else:
|
||||
data.append(('', ''))
|
||||
return (('Group Name', 'Hosts'), sorted(data))
|
||||
except CommandError as e:
|
||||
raise e
|
||||
except Exception as e:
|
||||
raise Exception(traceback.format_exc())
|
217
kollacli/host.py
217
kollacli/host.py
|
@ -14,28 +14,21 @@
|
|||
import argparse
|
||||
import getpass
|
||||
import logging
|
||||
import traceback
|
||||
|
||||
from kollacli.ansible.inventory import Inventory
|
||||
from kollacli import exceptions
|
||||
from kollacli.i18n import _
|
||||
from kollacli.objects.zones import Zones
|
||||
from kollacli.exceptions import CommandError
|
||||
|
||||
from cliff.command import Command
|
||||
from cliff.lister import Lister
|
||||
|
||||
|
||||
def _host_not_found(log, hostname):
|
||||
raise exceptions.CommandError(
|
||||
raise CommandError(
|
||||
'ERROR: Host (%s) not found. ' % hostname +
|
||||
'Please add it with "host add"')
|
||||
|
||||
|
||||
def _zone_not_found(log, zonename):
|
||||
raise exceptions.CommandError(
|
||||
'ERROR: Zone (%s) not found. ' % zonename +
|
||||
'Please add it with "zone add"')
|
||||
|
||||
|
||||
class HostAdd(Command):
|
||||
"""Add host to open-stack-kolla"""
|
||||
log = logging.getLogger(__name__)
|
||||
|
@ -49,12 +42,17 @@ class HostAdd(Command):
|
|||
return parser
|
||||
|
||||
def take_action(self, parsed_args):
|
||||
hostname = parsed_args.hostname.strip()
|
||||
groupname = parsed_args.groupname.strip()
|
||||
try:
|
||||
hostname = parsed_args.hostname.strip()
|
||||
groupname = parsed_args.groupname.strip()
|
||||
|
||||
inventory = Inventory.load()
|
||||
inventory.add_host(hostname, groupname)
|
||||
Inventory.save(inventory)
|
||||
inventory = Inventory.load()
|
||||
inventory.add_host(hostname, groupname)
|
||||
Inventory.save(inventory)
|
||||
except CommandError as e:
|
||||
raise e
|
||||
except Exception as e:
|
||||
raise Exception(traceback.format_exc())
|
||||
|
||||
|
||||
class HostRemove(Command):
|
||||
|
@ -74,13 +72,18 @@ class HostRemove(Command):
|
|||
return parser
|
||||
|
||||
def take_action(self, parsed_args):
|
||||
hostname = parsed_args.hostname.strip()
|
||||
groupname = None
|
||||
if parsed_args.groupname:
|
||||
groupname = parsed_args.groupname.strip()
|
||||
inventory = Inventory.load()
|
||||
inventory.remove_host(hostname, groupname)
|
||||
Inventory.save(inventory)
|
||||
try:
|
||||
hostname = parsed_args.hostname.strip()
|
||||
groupname = None
|
||||
if parsed_args.groupname:
|
||||
groupname = parsed_args.groupname.strip()
|
||||
inventory = Inventory.load()
|
||||
inventory.remove_host(hostname, groupname)
|
||||
Inventory.save(inventory)
|
||||
except CommandError as e:
|
||||
raise e
|
||||
except Exception as e:
|
||||
raise Exception(traceback.format_exc())
|
||||
|
||||
|
||||
class HostList(Lister):
|
||||
|
@ -89,90 +92,21 @@ class HostList(Lister):
|
|||
log = logging.getLogger(__name__)
|
||||
|
||||
def take_action(self, parsed_args):
|
||||
inventory = Inventory.load()
|
||||
try:
|
||||
inventory = Inventory.load()
|
||||
|
||||
hosts = inventory.get_hosts()
|
||||
|
||||
data = []
|
||||
host_groups = inventory.get_host_groups(hosts)
|
||||
if host_groups:
|
||||
for (hostname, groupnames) in host_groups.items():
|
||||
data.append((hostname, groupnames))
|
||||
else:
|
||||
data.append(('', ''))
|
||||
return (('Host Name', 'Groups'), sorted(data))
|
||||
|
||||
|
||||
class HostSetzone(Command):
|
||||
"""Add a host to a zone"""
|
||||
|
||||
log = logging.getLogger(__name__)
|
||||
|
||||
def get_parser(self, prog_name):
|
||||
parser = super(HostSetzone, self).get_parser(prog_name)
|
||||
parser.add_argument('hostname', metavar='<hostname>', help='host name')
|
||||
parser.add_argument('zone', metavar='[zone]', help='zone name')
|
||||
return parser
|
||||
|
||||
def take_action(self, parsed_args):
|
||||
hostname = parsed_args.hostname.strip()
|
||||
zonename = parsed_args.zone.strip()
|
||||
|
||||
if zonename not in Zones().get_all():
|
||||
_zone_not_found(self.log, zonename)
|
||||
return False
|
||||
|
||||
hosts = Inventory()
|
||||
host = hosts.get_host(hostname)
|
||||
if not host:
|
||||
_host_not_found(self.log, hostname)
|
||||
return False
|
||||
|
||||
host.zone = zonename
|
||||
hosts.save()
|
||||
|
||||
|
||||
class HostClearzone(Command):
|
||||
"""Clear the zone from a host"""
|
||||
|
||||
log = logging.getLogger(__name__)
|
||||
|
||||
def get_parser(self, prog_name):
|
||||
parser = super(HostClearzone, self).get_parser(prog_name)
|
||||
parser.add_argument('hostname', metavar='<hostname>', help='host name')
|
||||
return parser
|
||||
|
||||
def take_action(self, parsed_args):
|
||||
hostname = parsed_args.hostname.strip()
|
||||
|
||||
hosts = Inventory()
|
||||
host = hosts.get_host(hostname)
|
||||
if not host:
|
||||
_host_not_found(self.log, hostname)
|
||||
return False
|
||||
|
||||
host.zone = ''
|
||||
hosts.save()
|
||||
|
||||
|
||||
class HostAddservice(Command):
|
||||
"""add service to a host"""
|
||||
|
||||
log = logging.getLogger(__name__)
|
||||
|
||||
def take_action(self, parsed_args):
|
||||
self.log.info(_('host addservice'))
|
||||
self.app.stdout.write(parsed_args)
|
||||
|
||||
|
||||
class HostRemoveservice(Command):
|
||||
"""Remove service from a host"""
|
||||
|
||||
log = logging.getLogger(__name__)
|
||||
|
||||
def take_action(self, parsed_args):
|
||||
self.log.info(_('host removeservice'))
|
||||
self.app.stdout.write(parsed_args)
|
||||
data = []
|
||||
host_groups = inventory.get_host_groups()
|
||||
if host_groups:
|
||||
for (hostname, groupnames) in host_groups.items():
|
||||
data.append((hostname, groupnames))
|
||||
else:
|
||||
data.append(('', ''))
|
||||
return (('Host Name', 'Groups'), sorted(data))
|
||||
except CommandError as e:
|
||||
raise e
|
||||
except Exception as e:
|
||||
raise Exception(traceback.format_exc())
|
||||
|
||||
|
||||
class HostCheck(Command):
|
||||
|
@ -186,15 +120,20 @@ class HostCheck(Command):
|
|||
return parser
|
||||
|
||||
def take_action(self, parsed_args):
|
||||
hostname = parsed_args.hostname.strip()
|
||||
try:
|
||||
hostname = parsed_args.hostname.strip()
|
||||
|
||||
inventory = Inventory.load()
|
||||
host = inventory.get_host(hostname)
|
||||
if not host:
|
||||
_host_not_found(self.log, hostname)
|
||||
return False
|
||||
inventory = Inventory.load()
|
||||
host = inventory.get_host(hostname)
|
||||
if not host:
|
||||
_host_not_found(self.log, hostname)
|
||||
return False
|
||||
|
||||
host.check()
|
||||
host.check()
|
||||
except CommandError as e:
|
||||
raise e
|
||||
except Exception as e:
|
||||
raise Exception(traceback.format_exc())
|
||||
|
||||
|
||||
class HostInstall(Command):
|
||||
|
@ -209,19 +148,24 @@ class HostInstall(Command):
|
|||
return parser
|
||||
|
||||
def take_action(self, parsed_args):
|
||||
hostname = parsed_args.hostname.strip()
|
||||
inventory = Inventory.load()
|
||||
host = inventory.get_host(hostname)
|
||||
if not host:
|
||||
_host_not_found(self.log, hostname)
|
||||
return False
|
||||
try:
|
||||
hostname = parsed_args.hostname.strip()
|
||||
inventory = Inventory.load()
|
||||
host = inventory.get_host(hostname)
|
||||
if not host:
|
||||
_host_not_found(self.log, hostname)
|
||||
return False
|
||||
|
||||
if parsed_args.insecure:
|
||||
password = parsed_args.insecure.strip()
|
||||
else:
|
||||
password = getpass.getpass('Root password for %s: ' % hostname)
|
||||
if parsed_args.insecure:
|
||||
password = parsed_args.insecure.strip()
|
||||
else:
|
||||
password = getpass.getpass('Root password for %s: ' % hostname)
|
||||
|
||||
host.install(password)
|
||||
host.install(password)
|
||||
except CommandError as e:
|
||||
raise e
|
||||
except Exception as e:
|
||||
raise Exception(traceback.format_exc())
|
||||
|
||||
|
||||
class HostUninstall(Command):
|
||||
|
@ -236,15 +180,20 @@ class HostUninstall(Command):
|
|||
return parser
|
||||
|
||||
def take_action(self, parsed_args):
|
||||
hostname = parsed_args.hostname.strip()
|
||||
inventory = Inventory.load()
|
||||
host = inventory.get_host(hostname)
|
||||
if not host:
|
||||
_host_not_found(self.log, hostname)
|
||||
return False
|
||||
try:
|
||||
hostname = parsed_args.hostname.strip()
|
||||
inventory = Inventory.load()
|
||||
host = inventory.get_host(hostname)
|
||||
if not host:
|
||||
_host_not_found(self.log, hostname)
|
||||
return False
|
||||
|
||||
if parsed_args.insecure:
|
||||
password = parsed_args.insecure.strip()
|
||||
else:
|
||||
password = getpass.getpass('Root password for %s: ' % hostname)
|
||||
host.uninstall(password)
|
||||
if parsed_args.insecure:
|
||||
password = parsed_args.insecure.strip()
|
||||
else:
|
||||
password = getpass.getpass('Root password for %s: ' % hostname)
|
||||
host.uninstall(password)
|
||||
except CommandError as e:
|
||||
raise e
|
||||
except Exception as e:
|
||||
raise Exception(traceback.format_exc())
|
||||
|
|
|
@ -31,11 +31,13 @@ console_scripts =
|
|||
kollacli = kollacli.shell:main
|
||||
|
||||
kolla.cli =
|
||||
group_add = kollacli.group:GroupAdd
|
||||
group_remove = kollacli.group:GroupRemove
|
||||
group_listservices = kollacli.group:GroupListservices
|
||||
group_listhosts = kollacli.group:GroupListhosts
|
||||
host_add = kollacli.host:HostAdd
|
||||
host_remove = kollacli.host:HostRemove
|
||||
host_list = kollacli.host:HostList
|
||||
host_setzone = kollacli.host:HostSetzone
|
||||
host_clearzone = kollacli.host:HostClearzone
|
||||
host_addservice = kollacli.host:HostAddservice
|
||||
host_removeservice = kollacli.host:HostRemoveservice
|
||||
host_check = kollacli.host:HostCheck
|
||||
|
|
|
@ -66,33 +66,6 @@ class TestFunctional(KollaCliTest):
|
|||
msg = self.run_client_cmd('host list -f json')
|
||||
self._check_cli_output(hosts, msg)
|
||||
|
||||
# def test_host_setzone(self):
|
||||
# hosts = self.TestHosts()
|
||||
# hostname = 'host_test1'
|
||||
# ip_addr = '1.1.1.1'
|
||||
# zonename = 'test_zone1'
|
||||
# hosts.add(hostname, ip_addr, zonename)
|
||||
# self.run_client_cmd('zone add %s' % zonename)
|
||||
#
|
||||
# self.run_client_cmd('host add %s %s' % (hostname, ip_addr))
|
||||
# self.run_client_cmd('host setzone %s %s' % (hostname, zonename))
|
||||
# msg = self.run_client_cmd('host list')
|
||||
# self._check_cli_output(hosts, msg)
|
||||
#
|
||||
# zonename = 'test_zone2'
|
||||
# hosts.add(hostname, ip_addr, zonename)
|
||||
# self.run_client_cmd('zone add %s' % zonename)
|
||||
#
|
||||
# self.run_client_cmd('host setzone %s %s' % (hostname, zonename))
|
||||
# msg = self.run_client_cmd('host list')
|
||||
# self._check_cli_output(hosts, msg)
|
||||
#
|
||||
# zonename = ''
|
||||
# hosts.add(hostname, ip_addr, zonename)
|
||||
# self.run_client_cmd('host clearzone %s' % hostname)
|
||||
# msg = self.run_client_cmd('host list')
|
||||
# self._check_cli_output(hosts, msg)
|
||||
|
||||
def test_host_install(self):
|
||||
test_hosts = TestHosts()
|
||||
test_hosts.load()
|
||||
|
|
Loading…
Reference in New Issue