satops 1.5.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -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