%PDF- %PDF-
Direktori : /usr/lib/python2.7/site-packages/salt/runners/ |
Current File : //usr/lib/python2.7/site-packages/salt/runners/spacewalk.py |
# -*- coding: utf-8 -*- ''' Spacewalk Runner ================ .. versionadded:: 2016.3.0 Runner to interact with Spacewalk using Spacewalk API :codeauthor: Nitin Madhok <nmadhok@clemson.edu>, Joachim Werner <joe@suse.com>, Benedikt Werner <1benediktwerner@gmail.com> :maintainer: Benedikt Werner <1benediktwerner@gmail.com> To use this runner, set up the Spacewalk URL, username and password in the master configuration at ``/etc/salt/master`` or ``/etc/salt/master.d/spacewalk.conf``: .. code-block:: yaml spacewalk: spacewalk01.domain.com: username: 'testuser' password: 'verybadpass' spacewalk02.domain.com: username: 'testuser' password: 'verybadpass' .. note:: Optionally, ``protocol`` can be specified if the spacewalk server is not using the defaults. Default is ``protocol: https``. ''' from __future__ import absolute_import, print_function, unicode_literals # Import python libs import atexit import logging # Import third party libs from salt.ext import six log = logging.getLogger(__name__) _sessions = {} def __virtual__(): ''' Check for spacewalk configuration in master config file or directory and load runner only if it is specified ''' if not _get_spacewalk_configuration(): return False, 'No spacewalk configuration found' return True def _get_spacewalk_configuration(spacewalk_url=''): ''' Return the configuration read from the master configuration file or directory ''' spacewalk_config = __opts__['spacewalk'] if 'spacewalk' in __opts__ else None if spacewalk_config: try: for spacewalk_server, service_config in six.iteritems(spacewalk_config): username = service_config.get('username', None) password = service_config.get('password', None) protocol = service_config.get('protocol', 'https') if not username or not password: log.error( 'Username or Password has not been specified in the master ' 'configuration for %s', spacewalk_server ) return False ret = { 'api_url': '{0}://{1}/rpc/api'.format(protocol, spacewalk_server), 'username': username, 'password': password } if (not spacewalk_url) or (spacewalk_url == spacewalk_server): return ret except Exception as exc: log.error('Exception encountered: %s', exc) return False if spacewalk_url: log.error( 'Configuration for %s has not been specified in the master ' 'configuration', spacewalk_url ) return False return False def _get_client_and_key(url, user, password, verbose=0): ''' Return the client object and session key for the client ''' session = {} session['client'] = six.moves.xmlrpc_client.Server(url, verbose=verbose, use_datetime=True) session['key'] = session['client'].auth.login(user, password) return session def _disconnect_session(session): ''' Disconnect API connection ''' session['client'].auth.logout(session['key']) def _get_session(server): ''' Get session and key ''' if server in _sessions: return _sessions[server] config = _get_spacewalk_configuration(server) if not config: raise Exception('No config for \'{0}\' found on master'.format(server)) session = _get_client_and_key(config['api_url'], config['username'], config['password']) atexit.register(_disconnect_session, session) client = session['client'] key = session['key'] _sessions[server] = (client, key) return client, key def api(server, command, *args, **kwargs): ''' Call the Spacewalk xmlrpc api. CLI Example: .. code-block:: bash salt-run spacewalk.api spacewalk01.domain.com systemgroup.create MyGroup Description salt-run spacewalk.api spacewalk01.domain.com systemgroup.create arguments='["MyGroup", "Description"]' State Example: .. code-block:: yaml create_group: salt.runner: - name: spacewalk.api - server: spacewalk01.domain.com - command: systemgroup.create - arguments: - MyGroup - Description ''' if 'arguments' in kwargs: arguments = kwargs['arguments'] else: arguments = args call = '{0} {1}'.format(command, arguments) try: client, key = _get_session(server) except Exception as exc: err_msg = 'Exception raised when connecting to spacewalk server ({0}): {1}'.format(server, exc) log.error(err_msg) return {call: err_msg} namespace, method = command.split('.') endpoint = getattr(getattr(client, namespace), method) try: output = endpoint(key, *arguments) except Exception as e: output = 'API call failed: {0}'.format(e) return {call: output} def addGroupsToKey(server, activation_key, groups): ''' Add server groups to a activation key CLI Example: .. code-block:: bash salt-run spacewalk.addGroupsToKey spacewalk01.domain.com 1-my-key '[group1, group2]' ''' try: client, key = _get_session(server) except Exception as exc: err_msg = 'Exception raised when connecting to spacewalk server ({0}): {1}'.format(server, exc) log.error(err_msg) return {'Error': err_msg} all_groups = client.systemgroup.listAllGroups(key) groupIds = [] for group in all_groups: if group['name'] in groups: groupIds.append(group['id']) if client.activationkey.addServerGroups(key, activation_key, groupIds) == 1: return {activation_key: groups} else: return {activation_key: 'Failed to add groups to activation key'} def deleteAllGroups(server): ''' Delete all server groups from Spacewalk ''' try: client, key = _get_session(server) except Exception as exc: err_msg = 'Exception raised when connecting to spacewalk server ({0}): {1}'.format(server, exc) log.error(err_msg) return {'Error': err_msg} groups = client.systemgroup.listAllGroups(key) deleted_groups = [] failed_groups = [] for group in groups: if client.systemgroup.delete(key, group['name']) == 1: deleted_groups.append(group['name']) else: failed_groups.append(group['name']) ret = {'deleted': deleted_groups} if failed_groups: ret['failed'] = failed_groups return ret def deleteAllSystems(server): ''' Delete all systems from Spacewalk CLI Example: .. code-block:: bash salt-run spacewalk.deleteAllSystems spacewalk01.domain.com ''' try: client, key = _get_session(server) except Exception as exc: err_msg = 'Exception raised when connecting to spacewalk server ({0}): {1}'.format(server, exc) log.error(err_msg) return {'Error': err_msg} systems = client.system.listSystems(key) ids = [] names = [] for system in systems: ids.append(system['id']) names.append(system['name']) if client.system.deleteSystems(key, ids) == 1: return {'deleted': names} else: return {'Error': 'Failed to delete all systems'} def deleteAllActivationKeys(server): ''' Delete all activation keys from Spacewalk CLI Example: .. code-block:: bash salt-run spacewalk.deleteAllActivationKeys spacewalk01.domain.com ''' try: client, key = _get_session(server) except Exception as exc: err_msg = 'Exception raised when connecting to spacewalk server ({0}): {1}'.format(server, exc) log.error(err_msg) return {'Error': err_msg} activation_keys = client.activationkey.listActivationKeys(key) deleted_keys = [] failed_keys = [] for aKey in activation_keys: if client.activationkey.delete(key, aKey['key']) == 1: deleted_keys.append(aKey['key']) else: failed_keys.append(aKey['key']) ret = {'deleted': deleted_keys} if failed_keys: ret['failed'] = failed_keys return ret def unregister(name, server_url): ''' Unregister specified server from Spacewalk CLI Example: .. code-block:: bash salt-run spacewalk.unregister my-test-vm spacewalk01.domain.com ''' try: client, key = _get_session(server_url) except Exception as exc: err_msg = 'Exception raised when connecting to spacewalk server ({0}): {1}'.format(server_url, exc) log.error(err_msg) return {name: err_msg} systems_list = client.system.getId(key, name) if systems_list: for system in systems_list: out = client.system.deleteSystem(key, system['id']) if out == 1: return {name: 'Successfully unregistered from {0}'.format(server_url)} else: return {name: 'Failed to unregister from {0}'.format(server_url)} else: return {name: 'System does not exist in spacewalk server ({0})'.format(server_url)}