diff options
author | Peter Hatina <phatina@redhat.com> | 2012-09-13 09:38:12 +0200 |
---|---|---|
committer | Peter Hatina <phatina@redhat.com> | 2012-09-13 09:39:05 +0200 |
commit | 8de6088c8abf4ee1f392b97f63963065335ab977 (patch) | |
tree | 5176bc0ba16509811c8bedb3847276ffc4691f22 | |
parent | aefe1e49b515b55243096098f820367e53a58493 (diff) | |
download | openlmi-providers-8de6088c8abf4ee1f392b97f63963065335ab977.tar.gz openlmi-providers-8de6088c8abf4ee1f392b97f63963065335ab977.tar.xz openlmi-providers-8de6088c8abf4ee1f392b97f63963065335ab977.zip |
Introduce CLI tools
-rw-r--r-- | CMakeLists.txt | 1 | ||||
-rw-r--r-- | cli-tools/CMakeLists.txt | 34 | ||||
-rwxr-xr-x | cli-tools/cura-power.py | 74 | ||||
-rwxr-xr-x | cli-tools/cura-service.py | 92 | ||||
-rwxr-xr-x | cli-tools/cura-user.py | 79 | ||||
-rw-r--r-- | cli-tools/cura/__init__.py | 0 | ||||
-rw-r--r-- | cli-tools/cura/cura_address.py | 79 | ||||
-rw-r--r-- | cli-tools/cura/cura_client_power.py | 72 | ||||
-rw-r--r-- | cli-tools/cura/cura_client_service.py | 135 | ||||
-rw-r--r-- | cli-tools/cura/cura_client_user.py | 111 | ||||
-rw-r--r-- | cli-tools/cura/cura_options.py | 62 | ||||
-rw-r--r-- | cli-tools/setup.py | 29 |
12 files changed, 768 insertions, 0 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt index f32881d..58de8a1 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -30,6 +30,7 @@ find_package(KonkretCMPI REQUIRED) add_subdirectory(src) add_subdirectory(mof) +add_subdirectory(cli-tools) install(PROGRAMS register.sh reg2pegasus.py DESTINATION share/cura-providers) install(FILES cmake/modules/CuraMacros.cmake DESTINATION share/cmake/Modules) diff --git a/cli-tools/CMakeLists.txt b/cli-tools/CMakeLists.txt new file mode 100644 index 0000000..18471b4 --- /dev/null +++ b/cli-tools/CMakeLists.txt @@ -0,0 +1,34 @@ +cmake_minimum_required(VERSION 2.6) + +set(PYTHON python) +set(PYTHON_BIN_PATH bin) +exec_program( + ${PYTHON} + ARGS "-c \"from distutils.sysconfig import get_python_lib; print(get_python_lib())\"" + OUTPUT_VARIABLE PYTHON_SITE_PACKAGES_PATH +) + +add_custom_target( + PythonInstall ALL + COMMAND ${PYTHON} setup.py install + --install-lib ${PYTHON_SITE_PACKAGES_PATH} + --install-scripts ${PYTHON_BIN_PATH} + --root install + WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} +) + +install( + DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/install/bin + DESTINATION ${CMAKE_INSTALL_PREFIX} + FILES_MATCHING + PATTERN "*.py" + PERMISSIONS + OWNER_READ OWNER_WRITE OWNER_EXECUTE + GROUP_READ GROUP_EXECUTE + WORLD_READ WORLD_EXECUTE +) + +install( + DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/install/lib + DESTINATION ${CMAKE_INSTALL_PREFIX} +) diff --git a/cli-tools/cura-power.py b/cli-tools/cura-power.py new file mode 100755 index 0000000..4a22d38 --- /dev/null +++ b/cli-tools/cura-power.py @@ -0,0 +1,74 @@ +#!/usr/bin/env python +# Copyright (C) 2012 Peter Hatina <phatina@redhat.com> +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation; either version 2 +# of the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, see <http://www.gnu.org/licenses/>. + +import sys + +from cura.cura_options import CuraBasicOptions +from cura.cura_address import CuraIpv4Addr, CuraIpv4AddrGenerator +from cura.cura_client_power import CuraPowerClient + +class CuraPowerOptions(CuraBasicOptions): + def __init__(self): + super(self.__class__, self).__init__( + "Available actions:\n" + " poweroff, reboot, suspend, hibernate\n" + " force-poweroff, force-reboot\n") + self.m_parser.set_usage("Usage %prog [options] action") + + @property + def good(self): + return len(self.m_pos_options) == 1 + + @property + def action(self): + return self.m_pos_options[0] if self.good and self.m_pos_options[0] else "" + +if __name__ == "__main__": + options = CuraPowerOptions() + options.parse(sys.argv) + if not options.good: + sys.stderr.write( + "Wrong tool usage. Run " + __file__ + + " --help for detailed help.\n") + sys.exit(1) + + client_failed = False + client_hostnames = CuraIpv4AddrGenerator(options.hostname).enumerate() + client_action = options.action.lower() + for client_hostname in client_hostnames: + if not len(client_hostname): + continue + client = CuraPowerClient(client_hostname, options.username, options.password) + actions = { + "reboot": (client.reboot, "Reboot: "), + "poweroff": (client.poweroff, "Poweroff: "), + "suspend": (client.suspend, "Suspend: "), + "hibernate": (client.hibernate, "Hibernate: ") + } + + if not client_action in actions: + sys.stdout.write("No such action to perform!\n") + sys.exit(1) + + (rval, rparam) = actions[client_action][0]() + if rval: + sys.stdout.write("%s: %s\n" % (client_hostname, + actions[client_action][1] + rparam if rparam else "ok")) + else: + sys.stderr.write("%s: %s\n" % (client_hostname, rparam)) + client_failed = True + + sys.exit(client_failed) diff --git a/cli-tools/cura-service.py b/cli-tools/cura-service.py new file mode 100755 index 0000000..aab2876 --- /dev/null +++ b/cli-tools/cura-service.py @@ -0,0 +1,92 @@ +#!/usr/bin/env python +# Copyright (C) 2012 Peter Hatina <phatina@redhat.com> +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation; either version 2 +# of the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, see <http://www.gnu.org/licenses/>. + +import sys + +from cura.cura_options import CuraBasicOptions +from cura.cura_address import CuraIpv4Addr, CuraIpv4AddrGenerator +from cura.cura_client_service import CuraServiceClient + +class CuraServiceOptions(CuraBasicOptions): + def __init__(self): + super(self.__class__, self).__init__( + "Available actions:\n" + " start, stop, restart, enable, disable, reload,\n" + " try-restart, cond-restart, reload-or-restart,\n" + " reload-or-try-restart, status\n") + self.m_parser.set_usage("Usage: %prog [options] action service") + + @property + def good(self): + return len(self.m_pos_options) == 2 + + @property + def action(self): + return self.m_pos_options[0] if self.good and self.m_pos_options[0] else "" + + @property + def service(self): + if not self.good: + return "" + return self.m_pos_options[1] if self.good and self.m_pos_options[1] else "" + +if __name__ == "__main__": + options = CuraServiceOptions() + options.parse(sys.argv) + if not options.good: + sys.stderr.write( + "Wrong tool usage. Run " + __file__ + + " --help for detailed help.\n") + sys.exit(1) + + client_failed = False + client_hostnames = CuraIpv4AddrGenerator(options.hostname).enumerate() + client_action = options.action.lower() + for client_hostname in client_hostnames: + if not len(client_hostname): + continue + client = CuraServiceClient(client_hostname, options.username, options.password) + (service, rparam) = client.serviceFind(options.service) + if not service: + sys.stderr.write("%s: %s\n" % (client_hostname, rparam)) + continue + actions = { + "start": (service.start, "Start: "), + "stop": (service.stop, "Stop: "), + "restart": (service.restart, "Restart: "), + "enable": (service.enable, "Enabling: "), + "disable": (service.disable, "Disabling: "), + "reload": (service.reload, "Reload: "), + "try-restart": (service.tryRestart, "Try to restart: "), + "cond-restart": (service.condRestart, "Conditional restart: "), + "reload-or-restart": (service.reloadRestart, "Reload or restart: "), + "reload-or-try-restart": (service.reloadTryRestart, "Reload or try restart: "), + "status": (service.status, "Service status: ") + } + + if not client_action in actions: + sys.stderr.write("No such action to perform!\n") + sys.exit(1) + + (rval, rparam) = actions[client_action][0]() + if rval: + sys.stdout.write("%s: %s\n" % (client_hostname, + actions[client_action][1] + rparam if rparam else "ok")) + else: + sys.stderr.write("%s: %s\n" % (client_hostname, rparam)) + client_failed = True + + sys.exit(client_failed) diff --git a/cli-tools/cura-user.py b/cli-tools/cura-user.py new file mode 100755 index 0000000..98e1964 --- /dev/null +++ b/cli-tools/cura-user.py @@ -0,0 +1,79 @@ +#!/usr/bin/env python +# Copyright (C) 2012 Peter Hatina <phatina@redhat.com> +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation; either version 2 +# of the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, see <http://www.gnu.org/licenses/>. + +import sys + +from cura.cura_options import CuraBasicOptions +from cura.cura_address import CuraIpv4Addr, CuraIpv4AddrGenerator +from cura.cura_client_user import CuraUserClient + +class CuraUserOptions(CuraBasicOptions): + def __init__(self): + super(self.__class__, self).__init__( + "Available actions:\n" + " list-users, list-groups, group-members\n") + self.m_parser.set_usage("Usage: %prog [options] action [group]") + + @property + def good(self): + if not len(self.m_pos_options): + return False + elif self.m_pos_options[0] == "group-members": + return len(self.m_pos_options) == 2 + return len(self.m_pos_options) == 1 + + @property + def action(self): + return self.m_pos_options[0] if self.good and self.m_pos_options[0] else "" + + @property + def group(self): + return self.m_pos_options[1] if self.good and self.m_pos_options[1] else "" + +if __name__ == "__main__": + options = CuraUserOptions() + options.parse(sys.argv) + if not options.good: + sys.stderr.write( + "Wrong tool usage. Run " + __file__ + + " --help for detailed help.\n") + sys.exit(1) + + client_failed = False + client_hostnames = CuraIpv4AddrGenerator(options.hostname).enumerate() + client_action = options.action.lower() + for client_hostname in client_hostnames: + if not len(client_hostname): + continue + client = CuraUserClient(client_hostname, options.username, options.password) + actions = { + "list-users" : client.listUsers, + "list-groups" : client.listGroups + } + + if client_action == "group-members": + (rval, rparam) = client.listGroupMembers(options.group) + elif client_action in actions: + (rval, rparam) = actions[client_action]() + else: + sys.stderr.write("No such action to perform!\n") + sys.exit(1) + + if not rval: + sys.stderr.write("%s: %s\n" % (client_hostname, rparam)) + client_failed = True + + sys.exit(client_failed) diff --git a/cli-tools/cura/__init__.py b/cli-tools/cura/__init__.py new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/cli-tools/cura/__init__.py diff --git a/cli-tools/cura/cura_address.py b/cli-tools/cura/cura_address.py new file mode 100644 index 0000000..467a1c2 --- /dev/null +++ b/cli-tools/cura/cura_address.py @@ -0,0 +1,79 @@ +#!/usr/bin/env python +# Copyright (C) 2012 Peter Hatina <phatina@redhat.com> +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation; either version 2 +# of the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, see <http://www.gnu.org/licenses/>. + +import re +import sys +import itertools + +class CuraIpv4Addr: + class CuraIpv4Member: + def __init__(self, member): + self.m_member = member + + def enumerate(self): + pattern = re.compile("^{(.*)}$") + match = pattern.search(self.m_member) + member = match.group(1) if match else [] + if not member: + return [self.m_member] + ranges = (x.split("-") for x in member.split(";")) + try: + members = [] + for r in ranges: + if not 0 <= int(r[0]) <= 255 or not 0 <= int(r[-1]) <= 255: + return [] + low = int(r[0]) + high = int(r[-1]) + if low > high: + low, high = high, low + members += [str(i) for i in range(low, high + 1)] + except ValueError: + return [] + return members + + def __init__(self, addr_pattern): + self.m_addr_pattern = addr_pattern + + def enumerate(self): + str_members = self.m_addr_pattern.split(".") + if len(str_members) != 4: + return [] + members = [] + for m in str_members: + ipm = CuraIpv4Addr.CuraIpv4Member(m) + members.append(ipm) + addresses = members[3].enumerate() + if not addresses: + return [] + for i in reversed(range(0, 3)): + combined = [] + members_to_combine = members[i].enumerate() + if not members_to_combine: + return [] + for r in itertools.product(members_to_combine, addresses): + combined.append(".".join([r[0], r[1]])) + addresses = combined + return sorted(set(addresses)) + +class CuraIpv4AddrGenerator: + def __init__(self, addresses): + self.m_addresses = addresses + + def enumerate(self): + rval = [] + for addr in self.m_addresses.split(","): + rval += CuraIpv4Addr(addr).enumerate() + return rval diff --git a/cli-tools/cura/cura_client_power.py b/cli-tools/cura/cura_client_power.py new file mode 100644 index 0000000..c2e7b27 --- /dev/null +++ b/cli-tools/cura/cura_client_power.py @@ -0,0 +1,72 @@ +#!/usr/bin/env python +# Copyright (C) 2012 Peter Hatina <phatina@redhat.com> +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation; either version 2 +# of the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, see <http://www.gnu.org/licenses/>. + +import pywbem + +class CuraPowerClient(): + POWER_CLASS_NAME = "LMI_PowerManagementService" + POWER_STATE_SUSPEND = 4 + POWER_STATE_FORCE_REBOOT = 5 + POWER_STATE_HIBERNATE = 7 + POWER_STATE_FORCE_POWEROFF = 8 + POWER_STATE_POWEROFF = 12 + POWER_STATE_REBOOT = 15 + + def __init__(self, hostname, username="", password=""): + self.m_hostname = hostname + self.m_username = username + self.m_password = password + self.m_cliconn = pywbem.WBEMConnection("https://" + self.m_hostname, + (self.m_username, self.m_password)) + + def __getPowerInstance(self): + try: + inst_name_list = self.m_cliconn.EnumerateInstanceNames( + CuraPowerClient.POWER_CLASS_NAME) + except pywbem.cim_operations.CIMError, e: + return (None, e.args[1]) + except pywbem.cim_http.AuthError, e: + return (None, e.args[0]) + inst_list = self.m_cliconn.GetInstance(inst_name_list[0], + LocalOnly=False) + return (inst_list, "") + + def __powerCallMethod(self, method, **params): + (inst, rparam) = self.__getPowerInstance() + if not inst: + return (False, rparam) + try: + (rval, rparams) = self.m_cliconn.InvokeMethod(method, + inst.path, **params) + except pywbem.cim_operations.CIMError, e: + return (False, e.args[1]) + return (rval in (0, 4096), "") + + def poweroff(self): + return self.__powerCallMethod("RequestPowerStateChange", + PowerState=pywbem.Uint16(CuraPowerClient.POWER_STATE_POWEROFF)) + + def reboot(self): + return self.__powerCallMethod("RequestPowerStateChange", + PowerState=pywbem.Uint16(CuraPowerClient.POWER_STATE_REBOOT)) + + def suspend(self): + return self.__powerCallMethod("RequestPowerStateChange", + PowerState=pywbem.Uint16(CuraPowerClient.POWER_STATE_SUSPEND)) + + def hibernate(self): + return self.__powerCallMethod("RequestPowerStateChange", + PowerState=pywbem.Uint16(CuraPowerClient.POWER_STATE_HIBERNATE)) diff --git a/cli-tools/cura/cura_client_service.py b/cli-tools/cura/cura_client_service.py new file mode 100644 index 0000000..cf2235e --- /dev/null +++ b/cli-tools/cura/cura_client_service.py @@ -0,0 +1,135 @@ +#!/usr/bin/env python +# Copyright (C) 2012 Peter Hatina <phatina@redhat.com> +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation; either version 2 +# of the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, see <http://www.gnu.org/licenses/>. + +import pywbem + +class CuraService(): + def __init__(self, client, inst): + self.m_client = client + self.m_instance = inst + + def start(self): + return self.m_client.serviceStart(self.m_instance) + + def stop(self): + return self.m_client.serviceStop(self.m_instance) + + def restart(self): + return self.m_client.serviceRestart(self.m_instance) + + def enable(self): + return self.m_client.serviceEnable(self.m_instance) + + def disable(self): + return self.m_client.serviceDisable(self.m_instance) + + def reload(self): + return self.m_client.serviceReload(self.m_instance) + + def tryRestart(self): + return self.m_client.serviceTryRestart(self.m_instance) + + def condRestart(self): + return self.m_client.serviceCondRestart(self.m_instance) + + def reloadRestart(self): + return self.m_client.serviceReloadRestart(self.m_instance) + + def reloadTryRestart(self): + return self.m_client.serviceReloadTryRestart(self.m_instance) + + def status(self): + return self.m_client.serviceStatus(self.m_instance) + +class CuraServiceClient(): + SERVICE_CLASS_NAME = "LMI_Service" + + def __init__(self, hostname, username = "", password = ""): + self.m_hostname = hostname + self.m_username = username + self.m_password = password + self.m_cliconn = pywbem.WBEMConnection("https://" + self.m_hostname, + (self.m_username, self.m_password)) + + def __serviceGetInstance(self, service): + try: + inst_name_list = self.m_cliconn.EnumerateInstanceNames( + CuraServiceClient.SERVICE_CLASS_NAME) + except pywbem.cim_operations.CIMError, e: + return (None, e.args[1]) + except pywbem.cim_http.AuthError, e: + return (None, e.args[0]) + inst_name = filter(lambda n: n["Name"] == service, inst_name_list) + if not len(inst_name): + return (None, "No such service '" + service + "' found.") + inst_list = self.m_cliconn.GetInstance(inst_name[0], + LocalOnly = False) + return (inst_list, "") + + def __serviceCallMethod(self, service, method): + (inst, rparam) = self.__serviceGetInstance(service) if type(service) == str else (service, "") + if not inst: + return (False, rparam) + try: + (rval, params) = self.m_cliconn.InvokeMethod(method, inst.path) + except pywbem.cim_operations.CIMError, e: + return (False, e.args[1] + ": '" + method + "'") + return (rval == 0, "") + + def __serviceGetProperty(self, service, prop): + (inst, rparam) = self.__serviceGetInstance(service) if type(service) == str else (service, "") + if not inst or not prop in inst: + return (False, rparam) + return (True, inst[prop]) + + def serviceFind(self, service): + (inst, rparam) = self.__serviceGetInstance(service) + if not inst: + return (None, rparam) + return (CuraService(self, inst), "") + + def serviceStart(self, service): + return self.__serviceCallMethod(service, "StartService") + + def serviceStop(self, service): + return self.__serviceCallMethod(service, "StopService") + + def serviceRestart(self, service): + return self.__serviceCallMethod(service, "RestartService") + + def serviceEnable(self, service): + return self.__serviceCallMethod(service, "TurnServiceOn") + + def serviceDisable(self, service): + return self.__serviceCallMethod(service, "TurnServiceOff") + + def serviceReload(self, service): + return self.__serviceCallMethod(service, "ReloadService") + + def serviceTryRestart(self, service): + return self.__serviceCallMethod(service, "TryRestartService") + + def serviceCondRestart(self, service): + return self.__serviceCallMethod(service, "CondRestartService") + + def serviceReloadRestart(self, service): + return self.__serviceCallMethod(service, "ReloadOrRestartService") + + def serviceReloadTryRestart(self, service): + return self.__serviceCallMethod(service, "ReloadOrTryRestartService") + + def serviceStatus(self, service): + return self.__serviceGetProperty(service, "Status") diff --git a/cli-tools/cura/cura_client_user.py b/cli-tools/cura/cura_client_user.py new file mode 100644 index 0000000..b0b21fc --- /dev/null +++ b/cli-tools/cura/cura_client_user.py @@ -0,0 +1,111 @@ +#!/usr/bin/env python +# Copyright (C) 2012 Peter Hatina <phatina@redhat.com> +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation; either version 2 +# of the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, see <http://www.gnu.org/licenses/>. + +import sys +import pywbem + +class CuraUserClient(): + USER_CLASS_NAME = "LMI_Account" + GROUP_CLASS_NAME = "LMI_Group" + MEMBER_OF_GROUP_CLASS_NAME = "LMI_MemberOfGroup" + ASSIGNED_IDENTITY_CLASS_NAME = "LMI_AssignedAccountIdentity" + + def __init__(self, hostname, username = "", password = ""): + self.m_hostname = hostname + self.m_username = username + self.m_password = password + self.m_cliconn = pywbem.WBEMConnection("https://" + self.m_hostname, + (self.m_username, self.m_password)) + + def __getInstances(self, klass, filter_name = ""): + try: + inst_name_list = self.m_cliconn.EnumerateInstanceNames(klass) + except pywbem.cim_operations.CIMError, e: + return (None, e.args[1]) + except pywbem.cim_http.AuthError, e: + return (None, e.args[0]) + inst_names = inst_name_list + if len(filter_name): + inst_names = filter(lambda n: n["Name"] == filter_name, inst_name_list) + inst_list = [] + for i in inst_names: + inst_list.append(self.m_cliconn.GetInstance(i, LocalOnly = False)) + if not len(inst_list): + return (None, "Not found") + return (inst_list, "") + + def __getUserInstances(self): + return self.__getInstances(CuraUserClient.USER_CLASS_NAME) + + def __getGroupInstances(self): + return self.__getInstances(CuraUserClient.GROUP_CLASS_NAME) + + def __getMemberGroups(self, inst): + members = [] + identities = self.m_cliconn.Associators(inst.path, + AssocClass = CuraUserClient.ASSIGNED_IDENTITY_CLASS_NAME) + for identity in identities: + accounts = self.m_cliconn.Associators(identity.path, + AssocClass = CuraUserClient.MEMBER_OF_GROUP_CLASS_NAME) + members.extend(accounts) + return members + + def __getGroupMembers(self, inst): + members = [] + for g in inst: + identities = self.m_cliconn.Associators(g.path, + AssocClass = CuraUserClient.MEMBER_OF_GROUP_CLASS_NAME) + for i in identities: + accounts = self.m_cliconn.Associators(i.path, + AssocClass = CuraUserClient.ASSIGNED_IDENTITY_CLASS_NAME) + for a in accounts: + members.append(a["Name"]) + return members + + def listUsers(self): + (inst_list, rparam) = self.__getUserInstances() + if not inst_list: + return (False, "No users found") + sys.stdout.write("%s:\n" % self.m_hostname) + try: + for i in inst_list: + groups = self.__getMemberGroups(i) + gid = groups[0]["InstanceID"].split(":")[-1] + sys.stdout.write("%s:x:%s:%s:%s:%s:%s\n" % + (i["Name"], i["UserID"], gid, i["ElementName"], + i["HomeDirectory"], i["LoginShell"])) + except pywbem.cim_operations.CIMError, e: + return (False, e.args[1]) + return (True, "") + + def listGroups(self): + (inst_list, rparam) = self.__getGroupInstances() + if not inst_list: + return (False, "No groups found") + for i in inst_list: + sys.stdout.write("%s:%s\n" % + (i["Name"], i["InstanceID"].split(":")[-1])) + return (True, "") + + def listGroupMembers(self, member): + (inst_list, rparam) = self.__getInstances( + CuraUserClient.GROUP_CLASS_NAME, member) + if not inst_list: + return (False, "No such group '%s' found" % member) + members = self.__getGroupMembers(inst_list) + for m in members: + sys.stdout.write("%s\n" % m) + return (True, "") diff --git a/cli-tools/cura/cura_options.py b/cli-tools/cura/cura_options.py new file mode 100644 index 0000000..429740a --- /dev/null +++ b/cli-tools/cura/cura_options.py @@ -0,0 +1,62 @@ +#!/usr/bin/env python +# Copyright (C) 2012 Peter Hatina <phatina@redhat.com> +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation; either version 2 +# of the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, see <http://www.gnu.org/licenses/>. + +import sys +import optparse + +class CuraBasicOptions(object): + def __init__(self, epil = ""): + optparse.OptionParser.format_epilog = lambda self, formatter: self.epilog + self.m_parser = optparse.OptionParser( + add_help_option = False, + epilog = epil) + self.m_parser.add_option("", "--help", + action="help", + help = "print this message") + self.m_parser.add_option("-h", "--hostname", + action = "store", + dest = "hostname", + help = "remote machine hostname") + self.m_parser.add_option("-u", "--username", + action = "store", + dest = "username", + help = "remote machine username") + self.m_parser.add_option("-p", "--password", + action = "store", + dest = "password", + help = "remote machine password") + + def parse(self, argv): + (self.m_options, self.m_pos_options) = self.m_parser.parse_args(argv[1:]) + + def printHelp(self): + self.m_parser.print_help() + + @property + def good(self): + return len(self.m_pos_options) == 0 + + @property + def hostname(self): + return self.m_options.hostname if self.m_options.hostname else "" + + @property + def username(self): + return self.m_options.username if self.m_options.username else "" + + @property + def password(self): + return self.m_options.password if self.m_options.password else "" diff --git a/cli-tools/setup.py b/cli-tools/setup.py new file mode 100644 index 0000000..0232b4d --- /dev/null +++ b/cli-tools/setup.py @@ -0,0 +1,29 @@ +#!/usr/bin/env python +# Copyright (C) 2012 Peter Hatina <phatina@redhat.com> +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation; either version 2 +# of the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, see <http://www.gnu.org/licenses/>. + +from setuptools import setup + +setup( + name = "cura", + version = "0.1", + author = "Peter Hatina", + author_email = "phatina@redhat.com", + description = "CLI tools interfacing cura-providers.", + license = "GPLv2", + keywords = "cura service user power", + packages = ["cura"], + scripts = ["cura-service.py", "cura-power.py", "cura-user.py"] +) |