satops 1.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,574 @@
1
+ module RHN
2
+ # Represent the RHN Satellite XML-RPC server
3
+ module Session
4
+ @@path="/rpc/api"
5
+
6
+ def self.running?(host, ssl)
7
+ server=XMLRPC::Client.new(host, @@path, nil, nil, nil, nil, nil, ssl, 30)
8
+ server.call('api.getVersion')
9
+ rescue Errno::ECONNREFUSED => e
10
+ puts "FATAL: #{host}: #{e}"
11
+ exit
12
+ end
13
+
14
+ # Instance methods
15
+
16
+ attr_accessor :exception
17
+
18
+ def connect(sat)
19
+ @server=XMLRPC::Client.new(@host.name, @@path, nil, nil, nil, nil, nil, @ssl, 90)
20
+ @session=@server.call('auth.login', sat.login, sat.auth)
21
+ @exception=nil
22
+ end
23
+
24
+ def get(command)
25
+ self.exec_async(command)
26
+ end
27
+
28
+ def run(command, *params)
29
+ @log.debug("API-CALL:#{command} => #{params.inspect}")
30
+ self.exec_async(command, @session, *params)
31
+ end
32
+
33
+ def exec(*params) # command, session
34
+ begin
35
+ result=@server.call(*params)
36
+ @log.debug("API-RETURN => #{params.inspect}")
37
+ rescue XMLRPC::FaultException => e
38
+ @exception=e
39
+ @log.debug e.faultCode.to_s+':' + e.faultString
40
+ end
41
+ return result
42
+ end
43
+
44
+ # Async call will reconnect if needed
45
+ def exec_async(*params) # command, session
46
+ begin
47
+ result=@server.call_async(*params)
48
+ @log.debug("API-RETURN:#{params.inspect}")
49
+ rescue XMLRPC::FaultException => e
50
+ @exception=e
51
+ @log.debug e.faultCode.to_s+':' + e.faultString
52
+ end
53
+ return result
54
+ end
55
+
56
+ def get_exception
57
+ "RHN API Exception:#{@exception.faultCode.to_s}:#{@exception.faultString}" if @exception
58
+ end
59
+
60
+ def terminate
61
+ @server.call_async('auth.logout', @session)
62
+ end
63
+ end
64
+
65
+ class Operation
66
+ def initialize(sat)
67
+ @sat=sat
68
+ end
69
+
70
+ ## Helpers
71
+
72
+ # Standard call
73
+ def action(cmd, *args)
74
+ result=@sat.run(cmd, *args)
75
+ if result
76
+ trace_info(cmd, args[0])
77
+ else
78
+ trace_warn(cmd, args[0], @sat.get_exception)
79
+ end
80
+ result
81
+ end
82
+
83
+ # List call
84
+ def action_list(cmd, *args)
85
+ list=Array.new
86
+ if list=@sat.run(cmd, *args)
87
+ trace_info(cmd, list.size)
88
+ else
89
+ trace_warn(cmd, @sat.get_exception)
90
+ end
91
+ list
92
+ end
93
+
94
+ def define(stub, type=nil)
95
+ return if stub.nil?
96
+ stubs=stub.split('.')
97
+ method_name=stubs[stubs.size-1].to_sym
98
+
99
+ self.class.class_eval do
100
+ case type
101
+ when :list
102
+ define_method(method_name) do |*args|
103
+ action_list(stub, *args)
104
+ end
105
+ when :boolean
106
+ define_method(method_name) do |*args|
107
+ if action(stub, *args) == 1
108
+ return true
109
+ else
110
+ return false
111
+ end
112
+ end
113
+ else
114
+ define_method(method_name) do |*args|
115
+ action(stub, *args)
116
+ end
117
+ end
118
+ end
119
+ end
120
+
121
+ def trace_info(*params)
122
+ str=""
123
+ params.each { |p| str << "#{p}:" }
124
+ @sat.log.info("#{@sat.host.login}@#{@sat.host.name}:#{str}")
125
+ end
126
+
127
+ def trace_warn(*params)
128
+ str=""
129
+ params.each { |p| str << "#{p}:" }
130
+ @sat.log.warn("#{@sat.host.login}@#{@sat.host.name}:#{str}")
131
+ end
132
+ end
133
+
134
+ class Activationkey < Operation
135
+ def initialize(sat)
136
+ super(sat)
137
+ define 'activationkey.addChildChannels'
138
+ define 'activationkey.addConfigChannels'
139
+ define 'activationkey.addEntitlements'
140
+ define 'activationkey.addPackages'
141
+ define 'activationkey.addServerGroups'
142
+ define 'activationkey.checkConfigDeployment'
143
+ define 'activationkey.delete'
144
+ define 'activationkey.disableConfigDeployment'
145
+ define 'activationkey.enableConfigDeployment'
146
+ define 'activationkey.getDetails'
147
+ define 'activationkey.listActivatedSystems', :list
148
+ define 'activationkey.listActivationKeys', :list
149
+ define 'activationkey.listConfigChannels', :list
150
+ define 'activationkey.removeChildChannels'
151
+ define 'activationkey.removeConfigChannels'
152
+ define 'activationkey.removeEntitlements'
153
+ define 'activationkey.removePackages'
154
+ define 'activationkey.removeServerGroups'
155
+ define 'activationkey.setConfigChannels'
156
+ define 'activationkey.setDetails'
157
+ end
158
+
159
+ def create(key, description, base_channel_label, usage_limit, entitlements, universal_default)
160
+ if usage_limit == 0 || usage_limit == nil
161
+ action('activationkey.create', key, description, base_channel_label, entitlements, universal_default)
162
+ else
163
+ action('activationkey.create', key, description, base_channel_label, usage_limit, entitlements, universal_default)
164
+ end
165
+ end
166
+
167
+ def exist?(key)
168
+ if get(key)
169
+ return true
170
+ else
171
+ return false
172
+ end
173
+ end
174
+
175
+ def list
176
+ # API doesn't provide a way to distinct from various Reactivation keys.
177
+ keys=[]
178
+ result=self.listActivationKeys
179
+ unless result.nil?
180
+ result.each do |e|
181
+ keys << e unless e['description'] == "Kickstart re-activation key for ." || e['description'] =~ /^Reactivation key for .*/ || e['description'] =~ /^Activation key for /
182
+ end
183
+ end
184
+ trace_info('activationkey.listActivationKeys', keys.size)
185
+ keys
186
+ end
187
+ end
188
+
189
+ class Channel < Operation
190
+ def initialize(sat)
191
+ super(sat)
192
+ define 'channel.listAllChannels', :list
193
+ define 'channel.listMyChannels', :list
194
+ define 'channel.listRedHatChannels', :list
195
+ end
196
+ end
197
+
198
+ class ChannelSoftware < Operation
199
+ def initialize(sat)
200
+ super(sat)
201
+ define 'channel.software.create'
202
+ define 'channel.software.delete'
203
+ define 'channel.software.getDetails'
204
+ define 'channel.software.isGloballySubscribable', :boolean
205
+ define 'channel.software.isUserManageable', :boolean
206
+ define 'channel.software.isUserSubscribable', :boolean
207
+ define 'channel.software.setGloballySubscribable'
208
+ define 'channel.software.setUserManageable'
209
+ define 'channel.software.setUserSubscribable'
210
+ define 'channel.software.setDetails'
211
+
212
+ # Repos
213
+ define 'channel.software.associateRepo'
214
+ define 'channel.software.createRepo'
215
+ define 'channel.software.disassociateRepo'
216
+ define 'channel.software.getRepoDetails'
217
+ define 'channel.software.getRepoSyncCronExpression'
218
+ define 'channel.software.listChannelRepos'
219
+ define 'channel.software.listUserRepos'
220
+ define 'channel.software.removeRepo'
221
+ define 'channel.software.syncRepo'
222
+ define 'channel.software.updateRepoUrl'
223
+ end
224
+ end
225
+
226
+ class Configchannel < Operation
227
+ def initialize(sat)
228
+ super(sat)
229
+ define 'configchannel.channelExists'
230
+ define 'configchannel.create'
231
+ define 'configchannel.deleteChannels'
232
+ define 'configchannel.deleteFiles'
233
+ define 'configchannel.deleteFileRevisions'
234
+ define 'configchannel.getDetails'
235
+ define 'configchannel.getFileRevision'
236
+ define 'configchannel.getFileRevisions'
237
+ define 'configchannel.listFiles', :list
238
+ define 'configchannel.listGlobals', :list
239
+ define 'configchannel.listSubscribedSystems', :list
240
+ define 'configchannel.lookupFileInfo'
241
+ define 'configchannel.update'
242
+ end
243
+
244
+ # Class Methods
245
+ # Remove fields not needed for creation from config file
246
+ def self.copyPath(cf)
247
+ perms=cf["permissions_mode"]
248
+ cf.delete_if { |k,v| k=="modified" || k=="creation" || k=="binary" || k=="channel" || k=="md5" || k=="path" || k=="type" || k == "permissions_mode" || k == "permissions" }
249
+ cf.merge({ "permissions"=> perms.to_s })
250
+ end
251
+
252
+ def createOrUpdatePath(label, file, type)
253
+ # Type is boolean : false is file, true is Directory
254
+ path=file['path']
255
+ if type
256
+ file_type='directory'
257
+ else
258
+ file_type='file'
259
+ end
260
+ name="configchannel:createOrUpdatePath"
261
+ result=@sat.run('configchannel.createOrUpdatePath', label, file['path'], type, Configchannel.copyPath(file))
262
+ if result
263
+ trace_info(name, label, path)
264
+ else
265
+ case @sat.exception.faultCode
266
+ when 1023
267
+ trace_warn(name, 'Existing', label, path)
268
+ else
269
+ trace_warn(name, 'KO', label, path, @sat.get_exception)
270
+ end
271
+ end
272
+ end
273
+
274
+ def createOrUpdateSymlink(label, cfg_file)
275
+ name="configchannel.createOrUpdateSymlink"
276
+ path=cfg_file['path']
277
+ if @sat.run('configchannel.createOrUpdateSymlink', label, cfg_file['path'], {'target_path' => cfg_file['target_path'], 'revision' => cfg_file['revision']})
278
+ trace_info(name, label, path)
279
+ else
280
+ case @sat.exception.faultCode
281
+ when 1023
282
+ trace_warn(name, 'Existing', label, path)
283
+ else
284
+ trace_warn(name, 'KO', label, path, @sat.get_exception)
285
+ end
286
+ end
287
+ end
288
+
289
+ def exist?(cfg_channel)
290
+ if @sat.run('configchannel.channelExists', cfg_channel['label']) == 1
291
+ return true
292
+ else
293
+ return false
294
+ end
295
+ end
296
+ end
297
+
298
+ class Kickstart < Operation
299
+ def initialize(sat)
300
+ super(sat)
301
+ define 'kickstart.createProfile'
302
+ define 'kickstart.deleteProfile'
303
+ define 'kickstart.disableProfile'
304
+ define 'kickstart.isProfileDisabled'
305
+ define 'kickstart.listKickstarts', :list
306
+ end
307
+ end
308
+
309
+ class KickstartFilepreservation < Operation
310
+ def initialize(sat)
311
+ super(sat)
312
+ define 'kickstart.filepreservation.create'
313
+ define 'kickstart.filepreservation.delete'
314
+ define 'kickstart.filepreservation.getDetails'
315
+ define 'kickstart.filepreservation.listAllFilePreservations', :list
316
+ end
317
+
318
+ def exist?(name)
319
+ if get(name)
320
+ return true
321
+ else
322
+ return false
323
+ end
324
+ end
325
+
326
+ def get(name)
327
+ action('kickstart.filepreservation.getDetails', name)
328
+ rescue RuntimeError # Workaround for bug 'cause empty
329
+ return nil
330
+ end
331
+ end
332
+
333
+ class KickstartKeys < Operation
334
+ def initialize(sat)
335
+ super(sat)
336
+ define 'kickstart.keys.create'
337
+ define 'kickstart.keys.delete'
338
+ define 'kickstart.keys.getDetails'
339
+ define 'kickstart.keys.listAllKeys', :list
340
+ define 'kickstart.keys.update'
341
+ end
342
+ end
343
+
344
+ class KickstartProfile < Operation
345
+ def initialize(sat)
346
+ super(sat)
347
+ define 'kickstart.profile.addIpRange'
348
+ define 'kickstart.profile.addScript'
349
+ define 'kickstart.profile.getAdvancedOptions'
350
+ define 'kickstart.profile.getChildChannels'
351
+ define 'kickstart.profile.getCustomOptions'
352
+ define 'kickstart.profile.getKickstartTree'
353
+ define 'kickstart.profile.getVariables'
354
+ define 'kickstart.profile.listScripts'
355
+ define 'kickstart.profile.listIpRanges', :list
356
+ define 'kickstart.profile.removeScript'
357
+ define 'kickstart.profile.setAdvancedOptions'
358
+ define 'kickstart.profile.setChildChannels'
359
+ define 'kickstart.profile.setCustomOptions'
360
+ define 'kickstart.profile.setKickstartTree'
361
+ define 'kickstart.profile.setLogging'
362
+ define 'kickstart.profile.setVariables'
363
+ end
364
+ end
365
+
366
+ class KickstartProfileSoftware < Operation
367
+ def initialize(sat)
368
+ super(sat)
369
+ define 'kickstart.profile.software.getSoftwareList', :list
370
+ define 'kickstart.profile.software.setSoftwareList'
371
+ end
372
+ end
373
+
374
+ class KickstartProfileSystem < Operation
375
+ def initialize(sat)
376
+ super(sat)
377
+ define 'kickstart.profile.system.addFilePreservations'
378
+ define 'kickstart.profile.system.addKeys'
379
+ define 'kickstart.profile.system.checkConfigManagement'
380
+ define 'kickstart.profile.system.checkRemoteCommands'
381
+ define 'kickstart.profile.system.disableConfigManagement'
382
+ define 'kickstart.profile.system.disableRemoteCommands'
383
+ define 'kickstart.profile.system.enableConfigManagement'
384
+ define 'kickstart.profile.system.enableRemoteCommands'
385
+ define 'kickstart.profile.system.getLocale'
386
+ define 'kickstart.profile.system.getPartitioningScheme'
387
+ define 'kickstart.profile.system.getRegistrationType'
388
+ define 'kickstart.profile.system.getSELinux'
389
+ define 'kickstart.profile.system.listFilePreservations', :list
390
+ define 'kickstart.profile.system.listKeys', :list
391
+ define 'kickstart.profile.system.setLocale'
392
+ define 'kickstart.profile.system.setPartitioningScheme'
393
+ define 'kickstart.profile.system.setRegistrationType'
394
+ define 'kickstart.profile.system.setSELinux'
395
+ end
396
+ end
397
+
398
+ class KickstartSnippet < Operation
399
+ def initialize(sat)
400
+ super(sat)
401
+ define 'kickstart.snippet.createOrUpdate'
402
+ define 'kickstart.snippet.delete'
403
+ define 'kickstart.snippet.listCustom', :list
404
+ end
405
+ end
406
+
407
+ class Org < Operation
408
+ def initialize(sat)
409
+ super(sat)
410
+ define 'org.create'
411
+ define 'org.delete', :boolean
412
+ define 'org.getDetails'
413
+ define 'org.listOrgs', :list
414
+ define 'org.listSoftwareEntitlements', :list
415
+ define 'org.listSoftwareEntitlementsForOrg', :list
416
+ define 'org.listSystemEntitlements', :list
417
+ define 'org.listSystemEntitlementsForOrg', :list
418
+ define 'org.listUsers', :list
419
+ define 'org.migrateSystems'
420
+ define 'org.setSoftwareEntitlements', :boolean
421
+ define 'org.setSoftwareFlexEntitlements', :boolean
422
+ define 'org.setSystemEntitlements', :boolean
423
+ define 'org.updateName'
424
+ end
425
+ end
426
+
427
+ class OrgTrusts < Operation
428
+ def initialize(sat)
429
+ super(sat)
430
+ define 'org.trusts.addTrust', :boolean
431
+ define 'org.trusts.getDetails', :list
432
+ define 'org.trusts.listChannelsConsumed', :list
433
+ define 'org.trusts.listChannelsProvided', :list
434
+ define 'org.trusts.listOrgs', :list
435
+ define 'org.trusts.listSystemsAffected', :list
436
+ define 'org.trusts.listTrusts', :list
437
+ define 'org.trusts.removeTrust', :boolean
438
+ end
439
+ end
440
+
441
+ class System < Operation
442
+ def initialize(sat)
443
+ super(sat)
444
+ define 'system.listSystems'
445
+ define 'system.deleteSystems'
446
+ define 'system.getDetails'
447
+ define 'system.getConnectionPath'
448
+ define 'system.getCpu'
449
+ define 'system.getCustomValues'
450
+ define 'system.getDevices'
451
+ define 'system.getDmi'
452
+ define 'system.getEntitlements'
453
+ define 'system.getEventHistory'
454
+ define 'system.getMemory'
455
+ define 'system.getName'
456
+ define 'system.getNetwork'
457
+ define 'system.getNetworkDevices'
458
+ define 'system.getRegistrationDate'
459
+ define 'system.getRunningKernel'
460
+ define 'system.getSubscribedBaseChannel'
461
+ end
462
+ end
463
+
464
+ class SystemConfig < Operation
465
+ def initialize(sat)
466
+ super(sat)
467
+ define 'system.config.addChannels'
468
+ define 'system.config.listChannels'
469
+ define 'system.config.removeChannels'
470
+ end
471
+ end
472
+
473
+ class SystemCustominfo < Operation
474
+ def initialize(sat)
475
+ super(sat)
476
+ define 'system.custominfo.createKey'
477
+ define 'system.custominfo.deleteKey'
478
+ define 'system.custominfo.listAllKeys', :list
479
+ define 'system.custominfo.updateKey'
480
+ end
481
+ end
482
+
483
+ class Systemgroup < Operation
484
+ def initialize(sat)
485
+ super(sat)
486
+ define 'systemgroup.create'
487
+ define 'systemgroup.delete'
488
+ define 'systemgroup.getDetails' # Accepts System Group name or id
489
+ define 'systemgroup.listAllGroups', :list
490
+ define 'systemgroup.update'
491
+ end
492
+
493
+ def exist?(name)
494
+ if self.getDetails(name)
495
+ true
496
+ else
497
+ false
498
+ end
499
+ end
500
+ end
501
+
502
+ class User < Operation
503
+ def initialize(sat)
504
+ super(sat)
505
+ define 'user.addAssignedSystemGroups'
506
+ define 'user.addDefaultSystemGroups'
507
+ define 'user.addRole'
508
+ define 'user.create'
509
+ define 'user.delete'
510
+ define 'user.disable'
511
+ define 'user.enable'
512
+ define 'user.getDetails'
513
+ define 'user.listAssignedSystemGroups', :list
514
+ define 'user.listDefaultSystemGroups', :list
515
+ define 'user.listRoles', :list
516
+ define 'user.listUsers', :list
517
+ define 'user.removeRole'
518
+ define 'user.setDetails'
519
+ end
520
+
521
+ def to_s
522
+ str=""
523
+ super('user.listUsers').each do |user|
524
+ str << "User #{user['login']}\n"
525
+ str << "Roles"
526
+ action('user.listRoles', user['login']).each do |role|
527
+ str << ":#{role}"
528
+ end
529
+ str << "\nAssigned System Groups"
530
+ action('user.listAssignedSystemGroups', user['login']).each do |group|
531
+ str << ":#{group['name']}"
532
+ end
533
+ str << "\nDefault System Groups"
534
+ action('user.listDefaultSystemGroups', user['login']).each do |def_group|
535
+ str << ":#{def_group['name']}"
536
+ end
537
+ str << "\n"
538
+ end
539
+ str
540
+ end
541
+ end
542
+
543
+ # Interface to Red Hat Network Satellite API
544
+ # Can be invoked with satellite object : sat.channel.create()
545
+ class Satellite
546
+ include Session
547
+ attr_reader :host, :log, :activationkey, :channel, :channelSoftware, :configchannel, :kickstart, :kickstartFilepreservation, :kickstartProfile, :kickstartProfileSystem, :kickstartProfileSoftware, :kickstartKeys, :kickstartSnippet, :org, :orgTrusts, :system, :systemConfig, :systemCustominfo, :systemgroup, :user
548
+
549
+ def initialize(sat_host, ssl, log)
550
+ @host=sat_host
551
+ @ssl=ssl
552
+ @log=log
553
+ @session=nil
554
+ @activationkey=Activationkey.new(self)
555
+ @channel=Channel.new(self)
556
+ @channelSoftware=ChannelSoftware.new(self)
557
+ @configchannel=Configchannel.new(self)
558
+ @kickstart=Kickstart.new(self)
559
+ @kickstartFilepreservation=KickstartFilepreservation.new(self)
560
+ @kickstartProfile=KickstartProfile.new(self)
561
+ @kickstartProfileSystem=KickstartProfileSystem.new(self)
562
+ @kickstartProfileSoftware=KickstartProfileSoftware.new(self)
563
+ @kickstartKeys=KickstartKeys.new(self)
564
+ @kickstartSnippet=KickstartSnippet.new(self)
565
+ @org=Org.new(self)
566
+ @orgTrusts=OrgTrusts.new(self)
567
+ @system=System.new(self)
568
+ @systemConfig=SystemConfig.new(self)
569
+ @systemCustominfo=SystemCustominfo.new(self)
570
+ @systemgroup=Systemgroup.new(self)
571
+ @user=User.new(self)
572
+ end
573
+ end
574
+ end