Skip to content

Commit 5232d7f

Browse files
author
Mike Place
authored
Merge pull request saltstack#37336 from benediktwerner/spacewalk-api
Spacewalk api
2 parents d279464 + 5a5c5a1 commit 5232d7f

File tree

1 file changed

+221
-30
lines changed

1 file changed

+221
-30
lines changed

salt/runners/spacewalk.py

Lines changed: 221 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -7,20 +7,21 @@
77
88
Runner to interact with Spacewalk using Spacewalk API
99
10-
:codeauthor: Nitin Madhok <nmadhok@clemson.edu>
10+
:codeauthor: Nitin Madhok <nmadhok@clemson.edu>, Joachim Werner <joe@suse.com>, Benedikt Werner <1benediktwerner@gmail.com>
11+
:maintainer: Benedikt Werner <1benediktwerner@gmail.com>
1112
1213
To use this runner, set up the Spacewalk URL, username and password in the
1314
master configuration at ``/etc/salt/master`` or ``/etc/salt/master.d/spacewalk.conf``:
1415
1516
.. code-block:: yaml
1617
1718
spacewalk:
18-
spacewalk01.domain.com
19-
username: "testuser"
20-
password: "verybadpass"
21-
spacewalk02.domain.com
22-
username: "testuser"
23-
password: "verybadpass"
19+
spacewalk01.domain.com:
20+
username: 'testuser'
21+
password: 'verybadpass'
22+
spacewalk02.domain.com:
23+
username: 'testuser'
24+
password: 'verybadpass'
2425
2526
.. note::
2627
@@ -49,17 +50,18 @@
4950

5051
log = logging.getLogger(__name__)
5152

53+
_sessions = {}
54+
5255

5356
def __virtual__():
5457
'''
5558
Check for spacewalk configuration in master config file
5659
or directory and load runner only if it is specified
5760
'''
5861
if not HAS_LIBS:
59-
return False
60-
61-
if _get_spacewalk_configuration() is False:
62-
return False
62+
return False, 'Missing six library'
63+
if not _get_spacewalk_configuration():
64+
return False, 'No spacewalk configuration found'
6365
return True
6466

6567

@@ -79,13 +81,13 @@ def _get_spacewalk_configuration(spacewalk_url=''):
7981

8082
if not username or not password:
8183
log.error(
82-
"Username or Password has not been specified in the master "
83-
"configuration for {0}".format(spacewalk_server)
84+
'Username or Password has not been specified in the master '
85+
'configuration for {0}'.format(spacewalk_server)
8486
)
8587
return False
8688

8789
ret = {
88-
'api_url': "{0}://{1}/rpc/api".format(protocol, spacewalk_server),
90+
'api_url': '{0}://{1}/rpc/api'.format(protocol, spacewalk_server),
8991
'username': username,
9092
'password': password
9193
}
@@ -94,14 +96,14 @@ def _get_spacewalk_configuration(spacewalk_url=''):
9496
return ret
9597
except Exception as exc:
9698
log.error(
97-
"Exception encountered: {0}".format(exc)
99+
'Exception encountered: {0}'.format(exc)
98100
)
99101
return False
100102

101103
if spacewalk_url:
102104
log.error(
103-
"Configuration for {0} has not been specified in the master "
104-
"configuration".format(spacewalk_url)
105+
'Configuration for {0} has not been specified in the master '
106+
'configuration'.format(spacewalk_url)
105107
)
106108
return False
107109

@@ -113,7 +115,7 @@ def _get_client_and_key(url, user, password, verbose=0):
113115
Return the client object and session key for the client
114116
'''
115117
session = {}
116-
session['client'] = six.moves.xmlrpc_client.Server(url, verbose=verbose)
118+
session['client'] = six.moves.xmlrpc_client.Server(url, verbose=verbose, use_datetime=True)
117119
session['key'] = session['client'].auth.login(user, password)
118120

119121
return session
@@ -126,38 +128,227 @@ def _disconnect_session(session):
126128
session['client'].auth.logout(session['key'])
127129

128130

131+
def _get_session(server):
132+
'''
133+
Get session and key
134+
'''
135+
if server in _sessions:
136+
return _sessions[server]
137+
138+
config = _get_spacewalk_configuration(server)
139+
if not config:
140+
raise Exception('No config for \'{0}\' found on master'.format(server))
141+
142+
session = _get_client_and_key(config['api_url'], config['username'], config['password'])
143+
atexit.register(_disconnect_session, session)
144+
145+
client = session['client']
146+
key = session['key']
147+
_sessions[server] = (client, key)
148+
149+
return client, key
150+
151+
152+
def api(server, command, *args, **kwargs):
153+
'''
154+
Call the Spacewalk xmlrpc api.
155+
156+
CLI Example:
157+
158+
.. code-block:: bash
159+
160+
salt-run spacewalk.api spacewalk01.domain.com systemgroup.create MyGroup Description
161+
salt-run spacewalk.api spacewalk01.domain.com systemgroup.create arguments='["MyGroup", "Description"]'
162+
163+
State Example:
164+
165+
.. code-block:: yaml
166+
167+
create_group:
168+
salt.runner:
169+
- name: spacewalk.api
170+
- server: spacewalk01.domain.com
171+
- command: systemgroup.create
172+
- arguments:
173+
- MyGroup
174+
- Description
175+
'''
176+
if 'arguments' in kwargs:
177+
arguments = kwargs['arguments']
178+
else:
179+
arguments = args
180+
181+
call = '{0} {1}'.format(command, arguments)
182+
try:
183+
client, key = _get_session(server)
184+
except Exception as exc:
185+
err_msg = 'Exception raised when connecting to spacewalk server ({0}): {1}'.format(server, exc)
186+
log.error(err_msg)
187+
return {call: err_msg}
188+
189+
namespace, method = command.split('.')
190+
endpoint = getattr(getattr(client, namespace), method)
191+
192+
try:
193+
output = endpoint(key, *arguments)
194+
except Exception as e:
195+
output = 'API call failed: {0}'.format(e)
196+
197+
return {call: output}
198+
199+
200+
def addGroupsToKey(server, activation_key, groups):
201+
'''
202+
Add server groups to a activation key
203+
204+
CLI Example:
205+
206+
.. code-block:: bash
207+
208+
salt-run spacewalk.addGroupsToKey spacewalk01.domain.com 1-my-key '[group1, group2]'
209+
'''
210+
211+
try:
212+
client, key = _get_session(server)
213+
except Exception as exc:
214+
err_msg = 'Exception raised when connecting to spacewalk server ({0}): {1}'.format(server, exc)
215+
log.error(err_msg)
216+
return {'Error': err_msg}
217+
218+
all_groups = client.systemgroup.listAllGroups(key)
219+
groupIds = []
220+
for group in all_groups:
221+
if group['name'] in groups:
222+
groupIds.append(group['id'])
223+
224+
if client.activationkey.addServerGroups(key, activation_key, groupIds) == 1:
225+
return {activation_key: groups}
226+
else:
227+
return {activation_key: 'Failed to add groups to activation key'}
228+
229+
230+
def deleteAllGroups(server):
231+
'''
232+
Delete all server groups from Spacewalk
233+
'''
234+
235+
try:
236+
client, key = _get_session(server)
237+
except Exception as exc:
238+
err_msg = 'Exception raised when connecting to spacewalk server ({0}): {1}'.format(server, exc)
239+
log.error(err_msg)
240+
return {'Error': err_msg}
241+
242+
groups = client.systemgroup.listAllGroups(key)
243+
244+
deleted_groups = []
245+
failed_groups = []
246+
247+
for group in groups:
248+
if client.systemgroup.delete(key, group['name']) == 1:
249+
deleted_groups.append(group['name'])
250+
else:
251+
failed_groups.append(group['name'])
252+
253+
ret = {'deleted': deleted_groups}
254+
if failed_groups:
255+
ret['failed'] = failed_groups
256+
return ret
257+
258+
259+
def deleteAllSystems(server):
260+
'''
261+
Delete all systems from Spacewalk
262+
263+
CLI Example:
264+
265+
.. code-block:: bash
266+
267+
salt-run spacewalk.deleteAllSystems spacewalk01.domain.com
268+
'''
269+
270+
try:
271+
client, key = _get_session(server)
272+
except Exception as exc:
273+
err_msg = 'Exception raised when connecting to spacewalk server ({0}): {1}'.format(server, exc)
274+
log.error(err_msg)
275+
return {'Error': err_msg}
276+
277+
systems = client.system.listSystems(key)
278+
279+
ids = []
280+
names = []
281+
for system in systems:
282+
ids.append(system['id'])
283+
names.append(system['name'])
284+
285+
if client.system.deleteSystems(key, ids) == 1:
286+
return {'deleted': names}
287+
else:
288+
return {'Error': 'Failed to delete all systems'}
289+
290+
291+
def deleteAllActivationKeys(server):
292+
'''
293+
Delete all activation keys from Spacewalk
294+
295+
CLI Example:
296+
297+
.. code-block:: bash
298+
299+
salt-run spacewalk.deleteAllActivationKeys spacewalk01.domain.com
300+
'''
301+
302+
try:
303+
client, key = _get_session(server)
304+
except Exception as exc:
305+
err_msg = 'Exception raised when connecting to spacewalk server ({0}): {1}'.format(server, exc)
306+
log.error(err_msg)
307+
return {'Error': err_msg}
308+
309+
activation_keys = client.activationkey.listActivationKeys(key)
310+
311+
deleted_keys = []
312+
failed_keys = []
313+
314+
for aKey in activation_keys:
315+
if client.activationkey.delete(key, aKey['key']) == 1:
316+
deleted_keys.append(aKey['key'])
317+
else:
318+
failed_keys.append(aKey['key'])
319+
320+
ret = {'deleted': deleted_keys}
321+
if failed_keys:
322+
ret['failed'] = failed_keys
323+
return ret
324+
325+
129326
def unregister(name, server_url):
130327
'''
131-
To unregister specified server from Spacewalk
328+
Unregister specified server from Spacewalk
132329
133330
CLI Example:
134331
135332
.. code-block:: bash
136333
137334
salt-run spacewalk.unregister my-test-vm spacewalk01.domain.com
138335
'''
139-
config = _get_spacewalk_configuration(server_url)
140-
if not config:
141-
return False
142336

143337
try:
144-
session = _get_client_and_key(config['api_url'], config['username'], config['password'])
145-
atexit.register(_disconnect_session, session)
338+
client, key = _get_session(server_url)
146339
except Exception as exc:
147-
err_msg = "Exception raised when connecting to spacewalk server ({0}): {1}".format(server_url, exc)
340+
err_msg = 'Exception raised when connecting to spacewalk server ({0}): {1}'.format(server_url, exc)
148341
log.error(err_msg)
149342
return {name: err_msg}
150343

151-
client = session['client']
152-
key = session['key']
153344
systems_list = client.system.getId(key, name)
154345

155346
if systems_list:
156347
for system in systems_list:
157348
out = client.system.deleteSystem(key, system['id'])
158349
if out == 1:
159-
return {name: "Successfully unregistered from {0}".format(server_url)}
350+
return {name: 'Successfully unregistered from {0}'.format(server_url)}
160351
else:
161-
return {name: "Failed to unregister from {0}".format(server_url)}
352+
return {name: 'Failed to unregister from {0}'.format(server_url)}
162353
else:
163-
return {name: "System does not exist in spacewalk server ({0})".format(server_url)}
354+
return {name: 'System does not exist in spacewalk server ({0})'.format(server_url)}

0 commit comments

Comments
 (0)