source: opsi/server/dass-opsi-tools/usr/bin/opsiclient@ 1248

Last change on this file since 1248 was 1239, checked in by joergs, on Feb 28, 2018 at 6:41:10 PM

added createBareosConfigFiles

  • try to allow alternatives to jsonrpc, however tests with jsonrpclib (jsonrpclib_pelix-0.3.1) have not been successful.
  • createBareosConfigFiles
    • replaced createBaculaConfigFiles
    • provide default parameter for JobDefs and FileSet
    • store resulting files to correct location /etc/bareos/bareos-dir.d/*/opsi-*-generated.conf
  • Property svn:executable set to *
File size: 26.3 KB
Line 
1#!/usr/bin/env python
2
3# -*- coding: utf-8 -*-
4
5"""ospi-client: performs operation for opsi clients on opsi server via JSON-RPC."""
6
7from __future__ import print_function
8
9__author__ = "Joerg Steffens"
10__copyright__ = "Copyright 2012-2018, dass IT GmbH"
11__license__ = "GPL"
12__version__ = "1.2"
13__email__ = "joerg.steffens@dass-it.de"
14
15#self.command("opsi-admin -d method host_createOpsiClient "+ \
16 #computername + " null " + "\\'"+description+"\\'" + \
17 #" \\'created by dassadmin\\' " + mac_address + " " + \
18 #ip_address)
19#self.command("opsi-admin -d method configState_create clientconfig.depot.id " + \
20 #computername + " " + depotName)
21
22import argparse
23from datetime import datetime, timedelta
24from dateutil import parser as dateparser
25import logging
26import os
27from pprint import pprint, pformat
28import sys
29import ssl
30import time
31
32try:
33 import jsonrpc
34except ImportError:
35 import jsonrpclib
36
37
38UrlJsonRpc="https://<username>:<password>@opsi:4447/rpc"
39
40HelpEpilog="WARNING: python-json-rpc is known to have problems with HTTP proxies. In case of problems, make sure, the environment variables http_proxy and/or https_proxy are *not* set. It might also be neccesary to set variable PYTHONHTTPSVERIFY=0"
41
42class Nrpe:
43 OK = 0
44 WARNING = 1
45 CRITICAL = 2
46 UNKNOWN = 3
47
48 def toString(self, status):
49 if status == self.OK:
50 return 'OK'
51 elif status == self.WARNING:
52 return 'WARNING'
53 elif status == self.CRITICAL:
54 return 'CRITICAL'
55 else:
56 return 'UNKNOWN'
57
58class Output(Nrpe):
59 def __init__(self, nagios=False):
60 self.nagios = nagios
61 self.result = Nrpe.UNKNOWN
62 self.message = ''
63
64 def setStatus(self, status, message = None):
65 self.result = status
66 if message is not None:
67 self.setMessage(message)
68
69 def setMessage(self, string):
70 self.message = string
71
72 def finalize(self):
73 if self.nagios:
74 print('{0} - {1}'.format(self.toString(self.result), self.message))
75 sys.exit(self.result)
76 else:
77 print('{0} - {1}'.format(self.toString(self.result), self.message))
78 return (self.result == Nrpe.OK)
79
80class OpsiRpc:
81
82 UrlJsonRpcDefault="https://opsi:4447/rpc"
83
84 ProductAttributesCopy = ['actionRequest','actionResult','installationStatus','packageVersion','productVersion']
85
86 def __init__(self, urlJsonRpc = UrlJsonRpcDefault, debug=False, nagios=False):
87 self.logger=logging.getLogger(__name__)
88 self.debug=debug
89 self.nagios=nagios
90 self.urlJsonRpc=urlJsonRpc
91 if 'jsonrpc' in sys.modules:
92 self.rpc=jsonrpc.ServiceProxy(self.urlJsonRpc)
93 else:
94 self.rpc=jsonrpclib.ServerProxy(self.urlJsonRpc)
95 self.logger.debug( "initialized: " + self.urlJsonRpc )
96 self.logger.debug(dir(self.rpc))
97
98
99 def list(self):
100 exceptions = []
101 if 'jsonrpc' in sys.modules:
102 exceptions = [ jsonrpc.json.JSONDecodeException ]
103 try:
104 print( "\n".join( self.rpc.getClientIds_list() ) )
105 except exceptions as e:
106 self.logger.debug( pformat(self.rpc.getClientIds_list()) )
107 self.logger.exception( "failed" )
108 return True
109
110
111 def getClientsWithProduct( self, product ):
112 return self.rpc.productOnClient_getObjects( [], { "productId": product, "installationStatus": "installed" } )
113
114 def getHardwareSerialNumber(self, src):
115 serialNumbers = self.rpc.auditHardwareOnHost_getHashes( [], {"hostId":src, "hardwareClass":"BIOS", "serialNumber":"*"} )
116 serialNumbers += self.rpc.auditHardwareOnHost_getHashes( [], {"hostId":src, "hardwareClass":"CHASSIS", "serialNumber":"*"} )
117 result = set()
118 for i in serialNumbers:
119 if i['serialNumber']:
120 result.add(i['serialNumber'])
121 if len(result) == 1:
122 return result.pop()
123 elif len(result) > 1:
124 self.logger.warning("found more then one serial number")
125 return list(result)
126
127 def listClients( self, product ):
128 if product:
129 for client in self.getClientsWithProduct( product ):
130 print(client['clientId'])
131 else:
132 return self.list()
133 return True
134
135 def exists(self, src):
136 return len( self.rpc.host_getObjects( [], {"id":src} ) ) == 1
137
138 def info(self, src):
139 if not self.exists( src ):
140 print("failed: opsi client", src, "does not exist")
141 return False
142 print(src + ":")
143 host = self.rpc.host_getHashes( [], {"id":src} )[0]
144 print(" IP:", host["ipAddress"])
145 print(" MAC:", host["hardwareAddress"])
146 print(" inventory:", host["inventoryNumber"])
147 print(" serial number:", self.getHardwareSerialNumber(src))
148 print(" last seen:", host["lastSeen"])
149 print(" notes:", host["notes"])
150 print(" depot:", self.clientGetDepot(src))
151
152 print(" products:")
153 products = self.getProductOnClient( src, [] )
154 for i in products:
155 print(" " + i['productId'] + ":")
156 print(" " + i['installationStatus'], "(", end='')
157 if i['actionRequest']:
158 print(i['actionRequest'], end='')
159 if i['actionProgress']:
160 print(i['actionProgress'], end='')
161 print(")")
162 print(" ", end='')
163 pprint( i, indent=8 )
164 return True
165
166 def clean(self, src):
167 if not self.exists( src ):
168 return False
169 products = self.rpc.productOnClient_getObjects( [], { 'clientId': src } )
170 self.rpc.productOnClient_deleteObjects( products )
171
172 products = self.rpc.productPropertyState_getObjects( [], { 'objectId': src } )
173 self.rpc.productPropertyState_deleteObjects( products )
174
175 if self.debug:
176 pprint( self.getProductOnClient( src ) )
177 return True
178
179 def getOpsiConfigserverId(self):
180 # there should always be only one OpsiConfigserver
181 opsiConfigservers=self.rpc.host_getHashes( [], { "type": "OpsiConfigserver" } )
182 try:
183 return opsiConfigservers[0]['id']
184 except (KeyError,IndexError) as e:
185 self.logger.error( "failed to retreive OpsiConfigserver" )
186
187 def createClient(self, name, opsiHostKey, description, notes, hardwareAddress, ipAddress):
188 # self.rpc.host_createOpsiClient( name, opsiHostKey, description, notes, hardwareAddress, ipAddress )
189 self.updateClient( name, opsiHostKey, description, notes, None, hardwareAddress, ipAddress )
190
191 def deleteClient(self, name):
192 self.rpc.host_delete( name )
193
194 def updateClient(self, src, opsiHostKey = None, description = None, notes = None, inventoryNumber = None, hardwareAddress = None, ipAddress = None, depot = None ):
195 obj = {
196 "id" : src,
197 "type" : "OpsiClient",
198 }
199 if opsiHostKey:
200 obj['opsiHostKey'] = opsiHostKey
201 if description:
202 obj['description'] = description
203 if notes:
204 obj['notes'] = notes
205 if inventoryNumber:
206 obj['inventoryNumber'] = inventoryNumber
207 if hardwareAddress:
208 obj['hardwareAddress'] = hardwareAddress
209 if ipAddress:
210 obj['ipAddress'] = ipAddress
211
212 if self.exists( src ):
213 self.rpc.host_updateObject(obj)
214 else:
215 self.rpc.host_insertObject(obj)
216
217 if depot:
218 self.clientSetDepot(src,depot)
219 return True
220
221 def clientGetDepot(self, name):
222 depot = self.rpc.configState_getHashes( [], {
223 "configId": "clientconfig.depot.id",
224 "objectId": name } )
225 try:
226 return depot[0]["values"][0]
227 except (IndexError,KeyError):
228 return self.getOpsiConfigserverId()
229
230 def clientSetDepot(self, name, depot):
231 self.rpc.configState_create( "clientconfig.depot.id", name, depot )
232
233 def copyClient( self, src, dst, ipAddress = None, hardwareAddress = None, depot = None, description = "", copyProperties = True ):
234
235 print("create/update", dst, "from template", src + ":", end='')
236 obj = {
237 "id" : dst,
238 "type" : "OpsiClient",
239 "notes" : "copy of " + src,
240 "description" : description,
241 #"inventoryNumber" : "",
242 }
243 if hardwareAddress:
244 obj['hardwareAddress'] = hardwareAddress
245 if ipAddress:
246 obj['ipAddress'] = ipAddress
247
248 if self.exists( dst ):
249 self.rpc.host_updateObject(obj)
250 else:
251 self.rpc.host_insertObject(obj)
252
253 if depot:
254 self.clientSetDepot(dst,depot)
255
256 if self.debug:
257 pprint( self.getProductOnClient( src ) )
258 self.copyProductOnClient( src, dst )
259 if copyProperties:
260 if self.debug:
261 print("copy product properties")
262 if not depot:
263 # get default Properties from Master Depot Server (OpsiConfigserver)
264 depot = self.getOpsiConfigserverId()
265 self.copyProductPropertyState( src, dst, depot )
266 print("done")
267 return True
268
269 def getProductOnClient( self, client, attributes = ProductAttributesCopy ):
270 return self.rpc.productOnClient_getHashes( [], { 'clientId': client } )
271
272 def copyProductOnClient( self, src, dst, attributes = ProductAttributesCopy ):
273 products_src = self.rpc.productOnClient_getHashes( attributes, { 'clientId': src } )
274 products_dst = []
275 for i in products_src:
276 if self.debug:
277 print(i['productId'])
278 pprint( i )
279 i['clientId'] = dst
280 products_dst.append(i)
281 self.rpc.productOnClient_createObjects( products_dst )
282 if self.debug:
283 pprint( self.getProductOnClient( dst ) )
284
285
286 def getProductPropertyState( self, client, attributes = [] ):
287 return self.rpc.productPropertyState_getHashes( [], { 'objectId': client } )
288
289
290 def copyProductPropertyState( self, src, dst, default = None, attributes = [] ):
291 if default:
292 productProperties_default = self.getProductPropertyState( default, attributes )
293 else:
294 productProperties_default = []
295 productProperties_src = self.getProductPropertyState( src, attributes )
296 productProperties_dst = []
297 for i in productProperties_src:
298 use_default=False
299 default_value=None
300 for j in productProperties_default:
301 if i['productId'] == j['productId'] and i["propertyId"] == j["propertyId"]:
302 default_value = j['values']
303 if i['values'] == j['values']:
304 use_default=True
305 if self.debug:
306 print(i['productId'], "-", i["propertyId"] + ": ", pformat(i["values"]), end='')
307 if use_default:
308 print("(use default)")
309 else:
310 print("(set, default:", default_value, ")")
311 if not use_default:
312 i['objectId'] = dst
313 productProperties_dst.append(i)
314 self.rpc.productPropertyState_createObjects( productProperties_dst )
315 if self.debug:
316 pprint( self.getProductPropertyState( dst ) )
317
318
319 def getClientProductProperty( self, client, product ):
320 return self.rpc.getProductProperties_hash( product, [ client ] )
321
322 def setProductPropertiesOnClient( self, dst, product, properties ):
323 self.rpc.setProductProperties(product,properties,dst)
324
325 def setProductPropertyOnClient( self, dst, product, prop, value):
326 self.rpc.setProductProperty(product,prop,value,dst)
327
328
329
330 def write_value_conf(self, fd, key, properties, default=None):
331 value = None
332 comment = ''
333 try:
334 value = properties[key.lower()]
335 except KeyError:
336 pass
337 if not value and default:
338 value = default
339 if not value:
340 # prevent a None to be written
341 value = ''
342 comment = '# '
343 fd.write(' {}{} = "{}"\n'.format(comment, key, value))
344
345
346
347 def write_client_conf( self, fd, client, properties ):
348 #Client {
349 #Name = ting-fd
350 #Address = ting.dass-it
351 #FDPort = 9102
352 #Password = "D5w2V5w6B8a9H5Z"
353 #Catalog = MyCatalog
354 #File Retention = 6 months
355 #Job Retention = 6 months
356 #AutoPrune = yes
357 #}
358 params = [ 'catalog', "FDPort", "FileRetention", "JobRetention", "AutoPrune" ]
359 fd.write( "Client {\n" )
360 fd.write( ' Name = "' + properties['filedaemon_full_name'] + '"' + "\n" )
361 fd.write( ' Address = "' + properties['filedaemon_client_address'] + '"' + "\n" )
362 # ipAddress: method host_getObjects [] '{"id":client['clientId']}'
363 #print(" # Address =", ipAddress)
364 fd.write( ' Password = "' + properties['filedaemon_full_password'] + '"' + "\n" )
365 for i in params:
366 self.write_value_conf(fd, i, properties)
367 fd.write( "}\n")
368 fd.write( "\n" )
369
370
371 def write_job_conf(self, fd, client, properties, defaultjobdefs, defaultfileset):
372 #Job {
373 #FileSet = "tingfileset"
374 #Name = "ting"
375 #Client = ting-fd
376 #JobDefs = "LaptopJob"
377 ## Write Bootstrap = "/var/lib/bacula/ting.bsr"
378 #}
379 params = [ "JobDefs", "FileSet" ]
380 fd.write( "Job {" + "\n" )
381 fd.write( ' Name = "' + client['clientId'] + '-job"' + "\n" )
382 fd.write( ' Client = "' + properties['filedaemon_full_name'] + '"' + "\n" )
383 self.write_value_conf(fd, 'JobDefs', properties, defaultjobdefs)
384 self.write_value_conf(fd, 'FileSet', properties, defaultfileset)
385 fd.write( "}" + "\n" )
386 fd.write( "\n" )
387
388
389 def write_config_file_header( self, fd ):
390 try:
391 fd.write( "#\n" )
392 fd.write( "# automatically generated at {0}\n".format( time.asctime() ) )
393 fd.write( "#\n\n" )
394 except BaseException as e:
395 self.logger.exception( "failed to create files" )
396 return False
397 return True
398
399
400
401 def createBareosConfigFiles(self, defaultjobdefs, defaultfileset):
402 bareosDirConfigPath = '/etc/bareos/bareos-dir.d/'
403 clientsWithBacula=self.getClientsWithProduct('winbareos')
404 if clientsWithBacula:
405 try:
406 configfile = bareosDirConfigPath + 'client/opsi-clients-generated.conf'
407 file_opsi_clients = open(configfile, 'w')
408 self.write_config_file_header( file_opsi_clients )
409 except (BaseException, IOError) as e:
410 self.logger.exception( "failed to create configuration file {}".format(configfile) )
411 return False
412
413 try:
414 configfile = bareosDirConfigPath + 'job/opsi-jobs-generated.conf'
415 file_opsi_jobs = open(configfile, 'w')
416 self.write_config_file_header( file_opsi_jobs )
417 except (BaseException, IOError) as e:
418 self.logger.exception( "failed to create configuration file {}".format(configfile) )
419 return False
420
421 for client in clientsWithBacula:
422 clientId = client['clientId']
423 try:
424 clientBaculaProperties=self.getClientProductProperty( clientId, 'winbareos' )
425 except ValueError as e:
426 self.logger.warn( "%s: no valid information found: %s" %(clientId, e) )
427 else:
428 if clientBaculaProperties:
429 #pprint( clientBaculaProperties )
430 self.write_client_conf(file_opsi_clients, client, clientBaculaProperties)
431 self.write_job_conf(file_opsi_jobs, client, clientBaculaProperties, defaultjobdefs, defaultfileset)
432 self.logger.info( "%s: OK" % clientId )
433 else:
434 self.logger.warn( "%s: failed: no product properties defined" %(clientId) )
435 return True
436
437 def __getVersionString(self, product):
438 return '{productVersion}-{packageVersion}'.format(**product)
439
440 def getProductCurrentVersion(self, productId):
441 products = self.rpc.product_getHashes( [], { 'id': productId } )
442 if products:
443 return self.__getVersionString(products[0])
444 else:
445 return None
446
447 def __getClientId(self, d):
448 return d.get("clientId")
449
450 def listInstalled(self, productId):
451 productVersion = self.getProductCurrentVersion(productId)
452 self.logger.debug('version: {0}'.format(productVersion))
453 products = self.rpc.productOnClient_getHashes( [], { 'productId': productId } )
454 for i in sorted(products, key=self.__getClientId):
455 i['version'] = self.__getVersionString(i)
456 if i.get('installationStatus') == 'installed':
457 if productVersion != i['version']:
458 i['proposedAction'] = 'update'
459 else:
460 i['proposedAction'] = 'None'
461 print('{clientId}: {version} (proposed action={proposedAction})'.format(**i))
462 else:
463 i['proposedAction'] = 'install'
464 print('{clientId}: (proposed action={proposedAction})'.format(**i))
465 self.logger.debug('{clientId}: {actionRequest} {installationStatus} {version}'.format(**i))
466 #pprint( i, indent=8 )
467 return True
468
469 def isInstalled(self, clientId, productId):
470 """
471 CRITICAL: not installed
472 WARNING: installed, but not current version
473 OK: current version is installed
474 UNKNOWN: otherwise
475 """
476 output = Output(self.nagios)
477 if not self.exists(clientId):
478 output.setMessage("failed: opsi client {0} does not exist".format(clientId))
479 return output.finalize()
480 productVersion = self.getProductCurrentVersion(productId)
481 if not productVersion:
482 output.setMessage("failed: product {0} does not exist".format(productId))
483 return output.finalize()
484 self.logger.debug('version: {0}'.format(productVersion))
485 products = self.rpc.productOnClient_getHashes( [], { "clientId": clientId,'productId': productId } )
486 if len(products) != 1:
487 print("failed: opsi client ({0}) product ({1}) combination does not exist".format(clientId, productId))
488 return False
489 for i in sorted(products, key=self.__getClientId):
490 i['version'] = self.__getVersionString(i)
491 if i.get('installationStatus') == 'installed':
492 if productVersion != i['version']:
493 i['proposedAction'] = 'update'
494 output.setStatus(Nrpe.WARNING)
495 else:
496 i['proposedAction'] = 'None'
497 output.setStatus(Nrpe.OK)
498 output.setMessage('{version} (proposed action={proposedAction})'.format(**i))
499 else:
500 i['proposedAction'] = 'install'
501 output.setStatus(Nrpe.CRITICAL, 'not installed (proposed action={proposedAction})'.format(**i))
502 self.logger.debug('{clientId}: {actionRequest} {installationStatus} {version}'.format(**i))
503 return output.finalize()
504
505
506 def clientLastSeen(self, clientId):
507 """
508 < 1 day: OK
509 < 2 days: WARNING
510 otherwise: CRITICAL
511 """
512 output = Output(self.nagios)
513 if not self.exists(clientId):
514 output.setMessage("failed: opsi client {0} does not exist".format(clientId))
515 return output.finalize()
516 host = self.rpc.host_getHashes( [], {"id":clientId} )[0]
517 lastSeen = dateparser.parse(host["lastSeen"])
518 output.setMessage(str(lastSeen))
519 diff = datetime.now() - lastSeen
520 output.setMessage('{0} ({1} ago)'.format(str(lastSeen), diff))
521 if diff < timedelta(1):
522 output.setStatus(Nrpe.OK)
523 elif diff < timedelta(2):
524 output.setStatus(Nrpe.WARNING)
525 else:
526 output.setStatus(Nrpe.CRITICAL)
527 return output.finalize()
528
529
530
531if __name__ == '__main__':
532 logging.basicConfig(format='%(message)s')
533 logger = logging.getLogger(__name__)
534 logger.setLevel(logging.INFO)
535
536 parser = argparse.ArgumentParser(
537 description='Command line tool for OPSI configuration.',
538 epilog=HelpEpilog
539 )
540
541 parser.add_argument( '--debug', action='store_true', help="enable debugging output" )
542 parser.add_argument('--nagios', action='store_true', help='output in Nagios NRPE format')
543
544 parser_url = parser.add_mutually_exclusive_group(required=True)
545 parser_url.add_argument( '--url', help="OPSI Server JSON-RPC url, in following format: " + UrlJsonRpc )
546
547 parser_url.add_argument( '--server', help="OPSI Server (instead of URL)" )
548 username_default=os.getlogin()
549
550 parser.add_argument( '--username', help="username (instead of URL), default: " + username_default, default=username_default )
551 parser.add_argument( '--password', help="password (instead of URL)" )
552
553 subparsers = parser.add_subparsers(title='subcommands',
554 description='valid subcommands',
555 help='additional help',
556 dest='subcommand' )
557
558 parser_clean = subparsers.add_parser('clean', help='remove all product states from a opsi client' )
559 parser_clean.add_argument( 'src', help="source opsi client to clean" )
560
561 parser_copy = subparsers.add_parser('copy', help='copy/create a opsi client from a template opsi client')
562 parser_copy.add_argument( 'src', help="source/template opsi client" )
563 parser_copy.add_argument( 'dst', help="opsi client to be created" )
564 parser_copy.add_argument( '--ip', help="IP address of the new opsi client" )
565 parser_copy.add_argument( '--mac', help="MAC address of the new opsi client" )
566 parser_copy.add_argument( '--depot', help="depot server the new opsi client should be located" )
567 #parser_copy.add_argument( '--no-properties', action='store_false', help="don't copy product properties" )
568
569 parser_createBareosConfigFiles = subparsers.add_parser(
570 'createBareosConfigFiles',
571 help='create Bareos config files for all clients that have winbareos installed',
572 formatter_class=argparse.ArgumentDefaultsHelpFormatter
573 )
574 parser_createBareosConfigFiles.add_argument(
575 '--defaultjobdefs',
576 metavar='JobDefs',
577 default='DefaultJob',
578 help="use this JobDefs if no other is defined for a client"
579 )
580 parser_createBareosConfigFiles.add_argument(
581 '--defaultfileset',
582 metavar='FileSet',
583 help="use this FileSet if no other is defined for a client"
584 )
585
586 parser_exists = subparsers.add_parser('exists', help='check, if a opsi clients exists' )
587 parser_exists.add_argument( 'src', help="source opsi client" )
588 #parser_list = subparsers.add_parser('list', help='list all opsi clients' )
589
590 parser_listClients = subparsers.add_parser('listClients', help='list opsi clients')
591 parser_listClients.add_argument( '--product', help="only list clients, that have product installed" )
592
593 parser_info = subparsers.add_parser('info', help='print information about a opsi client' )
594 parser_info.add_argument( 'src', help="opsi client" )
595
596 parser_clientLastSeen = subparsers.add_parser('clientLastSeen', help='print information about a opsi client' )
597 parser_clientLastSeen.add_argument( 'client', help="opsi client" )
598
599 parser_listInstalled = subparsers.add_parser('listInstalled', help='check if product is installed on client')
600 parser_listInstalled.add_argument('product', help='opsi product')
601
602 parser_isInstalled = subparsers.add_parser('isInstalled', help='check if product is installed on client')
603 parser_isInstalled.add_argument('client', help='opsi client')
604 parser_isInstalled.add_argument('product', help='opsi product')
605
606 parser_update = subparsers.add_parser('update', help='update/create a opsi client')
607 parser_update.add_argument( 'src', help="opsi client to be created/updated" )
608 parser_update.add_argument( '--ip', help="IP address of the opsi client" )
609 parser_update.add_argument( '--mac', help="MAC address of the opsi client" )
610 parser_update.add_argument( '--description', help="a description of the client" )
611 parser_update.add_argument( '--notes', help="notes about the client" )
612 parser_update.add_argument( '--inventory', help="inventory number" )
613 parser_update.add_argument( '--depot', help="depot server the opsi client should be located" )
614
615 args = parser.parse_args()
616
617 if args.debug:
618 logger.setLevel(logging.DEBUG)
619
620 url=args.url
621 if (not url):
622 if args.server:
623 account=""
624 if args.username and args.password:
625 account=args.username + ":" + args.password + "@"
626 elif args.username:
627 account=args.username + "@"
628 url="https://" + account + args.server + ":4447/rpc"
629 else:
630 parser.error( "argument --url is required" )
631
632 opsi=OpsiRpc(url, args.debug, args.nagios)
633
634 result = True
635
636 try:
637 if args.subcommand == "clean":
638 result = opsi.clean( args.src )
639 elif args.subcommand == "copy":
640 result = opsi.copyClient( args.src, args.dst, args.ip, args.mac, args.depot )
641 elif args.subcommand == "createBareosConfigFiles":
642 result = opsi.createBareosConfigFiles(args.defaultjobdefs, args.defaultfileset)
643 elif args.subcommand == "exists":
644 result = opsi.exists( args.src )
645 elif args.subcommand == "list":
646 result = opsi.list()
647 elif args.subcommand == "listClients":
648 result = opsi.listClients( args.product )
649 elif args.subcommand == "info":
650 result = opsi.info( args.src )
651 elif args.subcommand == "update":
652 result = opsi.updateClient( args.src, None, args.description, args.notes, args.inventory, args.mac, args.ip, args.depot )
653 elif args.subcommand == 'listInstalled':
654 result = opsi.listInstalled(args.product)
655 elif args.subcommand == 'isInstalled':
656 result = opsi.isInstalled(args.client, args.product)
657 elif args.subcommand == 'clientLastSeen':
658 result = opsi.clientLastSeen(args.client)
659 else:
660 print("not yet implemented")
661 except IOError as e:
662 result = False
663 # connection refused
664 print("failed:", e)
665
666 if args.debug: print(result)
667
668 if result:
669 exit(0)
670 else:
671 exit(1)
Note: See TracBrowser for help on using the repository browser.