besapi 3.7.6__tar.gz → 3.7.8__tar.gz

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.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: besapi
3
- Version: 3.7.6
3
+ Version: 3.7.8
4
4
  Summary: Library for working with the BigFix REST API
5
5
  Home-page: https://github.com/jgstew/besapi
6
6
  Author: Matt Hansen, James Stewart
@@ -29,7 +29,7 @@ import requests
29
29
  from lxml import etree, objectify
30
30
  from pkg_resources import resource_filename
31
31
 
32
- __version__ = "3.7.6"
32
+ __version__ = "3.7.8"
33
33
 
34
34
  besapi_logger = logging.getLogger("besapi")
35
35
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: besapi
3
- Version: 3.7.6
3
+ Version: 3.7.8
4
4
  Summary: Library for working with the BigFix REST API
5
5
  Home-page: https://github.com/jgstew/besapi
6
6
  Author: Matt Hansen, James Stewart
@@ -10,6 +10,7 @@ Simple command line interface for the BES (BigFix) REST API.
10
10
  """
11
11
 
12
12
  import getpass
13
+ import json
13
14
  import logging
14
15
  import os
15
16
  import site
@@ -39,6 +40,13 @@ class BESCLInterface(Cmd):
39
40
 
40
41
  def __init__(self, **kwargs):
41
42
  Cmd.__init__(self, **kwargs)
43
+
44
+ # set an intro message
45
+ self.intro = (
46
+ f"\nWelcome to the BigFix REST API Interactive Python Module v{__version__}"
47
+ )
48
+
49
+ # sets the prompt look:
42
50
  self.prompt = "BigFix> "
43
51
 
44
52
  self.num_errors = 0
@@ -49,8 +57,50 @@ class BESCLInterface(Cmd):
49
57
  # set default config file path
50
58
  self.conf_path = os.path.expanduser("~/.besapi.conf")
51
59
  self.CONFPARSER = SafeConfigParser()
60
+ # for completion:
61
+ self.api_resources = []
52
62
  self.do_conf()
53
63
 
64
+ def parse_help_resources(self):
65
+ """get api resources from help"""
66
+ if self.bes_conn:
67
+ help_result = self.bes_conn.get("help")
68
+ help_result = help_result.text.split("\n")
69
+ # print(help_result)
70
+ help_resources = []
71
+ for item in help_result:
72
+ if "/api/" in item:
73
+ _, _, res = item.partition("/api/")
74
+ # strip whitespace just in case:
75
+ help_resources.append(res.strip())
76
+
77
+ return help_resources
78
+ else:
79
+ return [
80
+ "actions",
81
+ "clientqueryresults",
82
+ "dashboardvariables",
83
+ "help",
84
+ "login",
85
+ "query",
86
+ "relaysites",
87
+ "serverinfo",
88
+ "sites",
89
+ ]
90
+
91
+ def complete_api_resources(self, text, line, begidx, endidx):
92
+ """define completion for apis"""
93
+
94
+ # only initialize once
95
+ if not self.api_resources:
96
+ self.api_resources = self.parse_help_resources()
97
+
98
+ # TODO: make this work to complete only the first word after get/post/delete
99
+ # return the matching subset:
100
+ return [name for name in self.api_resources if name.startswith(text)]
101
+
102
+ complete_get = complete_api_resources
103
+
54
104
  def do_get(self, line):
55
105
  """Perform get request to BigFix server using provided api endpoint argument"""
56
106
 
@@ -73,16 +123,18 @@ class BESCLInterface(Cmd):
73
123
  b = self.bes_conn.get(robjs[0])
74
124
  # print objectify.ObjectPath(robjs[1:])
75
125
  if b:
76
- print(eval("b()." + ".".join(robjs[1:])))
126
+ self.poutput(eval("b()." + ".".join(robjs[1:])))
77
127
  else:
78
128
  output_item = self.bes_conn.get(line)
79
- # print(type(output_item))
80
- print(output_item)
81
- # print(output_item.besdict)
82
- # print(output_item.besjson)
129
+ # self.poutput(type(output_item))
130
+ self.poutput(output_item)
131
+ # self.poutput(output_item.besdict)
132
+ # self.poutput(output_item.besjson)
83
133
  else:
84
134
  self.pfeedback("Not currently logged in. Type 'login'.")
85
135
 
136
+ complete_delete = complete_api_resources
137
+
86
138
  def do_delete(self, line):
87
139
  """Perform delete request to BigFix server using provided api endpoint argument"""
88
140
 
@@ -97,16 +149,18 @@ class BESCLInterface(Cmd):
97
149
  if self.bes_conn:
98
150
  output_item = self.bes_conn.delete(line)
99
151
 
100
- print(output_item)
101
- # print(output_item.besdict)
102
- # print(output_item.besjson)
152
+ self.poutput(output_item)
153
+ # self.poutput(output_item.besdict)
154
+ # self.poutput(output_item.besjson)
103
155
  else:
104
156
  self.pfeedback("Not currently logged in. Type 'login'.")
105
157
 
158
+ complete_post = complete_api_resources
159
+
106
160
  def do_post(self, statement):
107
161
  """post file as data to path"""
108
- print(statement)
109
- print("not yet implemented")
162
+ self.poutput(statement)
163
+ self.poutput("not yet implemented")
110
164
 
111
165
  def do_config(self, conf_file=None):
112
166
  """Attempt to load config info from file and login"""
@@ -237,7 +291,7 @@ class BESCLInterface(Cmd):
237
291
  else:
238
292
  self.perror("Login Error!")
239
293
 
240
- def do_logout(self, arg=None):
294
+ def do_logout(self, _=None):
241
295
  """Logout and clear session"""
242
296
  if self.bes_conn:
243
297
  self.bes_conn.logout()
@@ -247,7 +301,7 @@ class BESCLInterface(Cmd):
247
301
 
248
302
  def do_debug(self, setting):
249
303
  """Enable or Disable Debug Mode"""
250
- print(bool(setting))
304
+ self.poutput(bool(setting))
251
305
  self.debug = bool(setting)
252
306
  self.echo = bool(setting)
253
307
  self.quiet = bool(setting)
@@ -281,12 +335,12 @@ class BESCLInterface(Cmd):
281
335
  """save current config to file"""
282
336
  self.do_saveconf(arg)
283
337
 
284
- def do_saveconf(self, arg=None):
338
+ def do_saveconf(self, _=None):
285
339
  """save current config to file"""
286
340
  if not self.bes_conn:
287
341
  self.do_login()
288
342
  if not self.bes_conn:
289
- print("Can't save config without working login")
343
+ self.poutput("Can't save config without working login")
290
344
  else:
291
345
  conf_file_path = self.conf_path
292
346
  self.pfeedback(f"Saving Config File to: {conf_file_path}")
@@ -297,29 +351,31 @@ class BESCLInterface(Cmd):
297
351
  """List the current settings and connection status"""
298
352
  self.do_ls(arg)
299
353
 
300
- def do_ls(self, arg=None):
354
+ def do_ls(self, _=None):
301
355
  """List the current settings and connection status"""
302
- print(" Connected: " + str(bool(self.bes_conn)))
303
- print(
356
+ self.poutput(" Connected: " + str(bool(self.bes_conn)))
357
+ self.poutput(
304
358
  " BES_ROOT_SERVER: "
305
359
  + (self.BES_ROOT_SERVER if self.BES_ROOT_SERVER else "")
306
360
  )
307
- print(
361
+ self.poutput(
308
362
  " BES_USER_NAME: " + (self.BES_USER_NAME if self.BES_USER_NAME else "")
309
363
  )
310
- print(
364
+ self.poutput(
311
365
  " Password Length: "
312
366
  + str(len(self.BES_PASSWORD if self.BES_PASSWORD else ""))
313
367
  )
314
- print(" Config File Path: " + self.conf_path)
368
+ self.poutput(" Config File Path: " + self.conf_path)
315
369
  if self.bes_conn:
316
- print("Current Site Path: " + self.bes_conn.get_current_site_path(None))
370
+ self.poutput(
371
+ "Current Site Path: " + self.bes_conn.get_current_site_path(None)
372
+ )
317
373
 
318
- def do_error_count(self, arg=None):
374
+ def do_error_count(self, _=None):
319
375
  """Output the number of errors"""
320
376
  self.poutput(f"Error Count: {self.num_errors}")
321
377
 
322
- def do_exit(self, arg=None):
378
+ def do_exit(self, _=None):
323
379
  """Exit this application"""
324
380
  self.exit_code = self.num_errors
325
381
  # no matter what I try I can't get anything but exit code 0 on windows
@@ -340,7 +396,7 @@ class BESCLInterface(Cmd):
340
396
  self.pfeedback("A: ")
341
397
  self.poutput(rel_result)
342
398
 
343
- def do_version(self, statement=None):
399
+ def do_version(self, _=None):
344
400
  """output version of besapi"""
345
401
  self.poutput(f"besapi version: {__version__}")
346
402
 
@@ -354,7 +410,7 @@ class BESCLInterface(Cmd):
354
410
  result_op = self.bes_conn.get_user(statement)
355
411
  self.poutput(result_op)
356
412
 
357
- def do_get_current_site(self, statement=None):
413
+ def do_get_current_site(self, _=None):
358
414
  """output current site path context"""
359
415
  self.poutput(
360
416
  f"Current Site Path: `{ self.bes_conn.get_current_site_path(None) }`"
@@ -368,11 +424,11 @@ class BESCLInterface(Cmd):
368
424
 
369
425
  def do_get_content(self, resource_url):
370
426
  """get a specific item by resource url"""
371
- print(self.bes_conn.get_content_by_resource(resource_url))
427
+ self.poutput(self.bes_conn.get_content_by_resource(resource_url))
372
428
 
373
429
  def do_export_item_by_resource(self, statement):
374
430
  """export content itemb to current folder"""
375
- print(self.bes_conn.export_item_by_resource(statement))
431
+ self.poutput(self.bes_conn.export_item_by_resource(statement))
376
432
 
377
433
  def do_export_site(self, site_path):
378
434
  """export site contents to current folder"""
@@ -380,7 +436,7 @@ class BESCLInterface(Cmd):
380
436
  site_path, verbose=True, include_site_folder=False, include_item_ids=False
381
437
  )
382
438
 
383
- def do_export_all_sites(self, statement=None):
439
+ def do_export_all_sites(self, _=None):
384
440
  """export site contents to current folder"""
385
441
  self.bes_conn.export_all_sites(verbose=False)
386
442
 
@@ -402,47 +458,58 @@ class BESCLInterface(Cmd):
402
458
  def do_upload(self, file_path):
403
459
  """upload file to root server"""
404
460
  if not os.access(file_path, os.R_OK):
405
- print(file_path, "is not a readable file")
461
+ self.poutput(file_path, "is not a readable file")
406
462
  else:
407
463
  upload_result = self.bes_conn.upload(file_path)
408
- print(upload_result)
409
- print(self.bes_conn.parse_upload_result_to_prefetch(upload_result))
464
+ self.poutput(upload_result)
465
+ self.poutput(self.bes_conn.parse_upload_result_to_prefetch(upload_result))
410
466
 
411
467
  complete_create_group = Cmd.path_complete
412
468
 
413
469
  def do_create_group(self, file_path):
414
470
  """create bigfix group from bes file"""
415
471
  if not os.access(file_path, os.R_OK):
416
- print(file_path, "is not a readable file")
472
+ self.poutput(file_path, "is not a readable file")
417
473
  else:
418
- print(self.bes_conn.create_group_from_file(file_path))
474
+ self.poutput(self.bes_conn.create_group_from_file(file_path))
419
475
 
420
476
  complete_create_user = Cmd.path_complete
421
477
 
422
478
  def do_create_user(self, file_path):
423
479
  """create bigfix user from bes file"""
424
480
  if not os.access(file_path, os.R_OK):
425
- print(file_path, "is not a readable file")
481
+ self.poutput(file_path, "is not a readable file")
426
482
  else:
427
- print(self.bes_conn.create_user_from_file(file_path))
483
+ self.poutput(self.bes_conn.create_user_from_file(file_path))
428
484
 
429
485
  complete_create_site = Cmd.path_complete
430
486
 
431
487
  def do_create_site(self, file_path):
432
488
  """create bigfix site from bes file"""
433
489
  if not os.access(file_path, os.R_OK):
434
- print(file_path, "is not a readable file")
490
+ self.poutput(file_path, "is not a readable file")
435
491
  else:
436
- print(self.bes_conn.create_site_from_file(file_path))
492
+ self.poutput(self.bes_conn.create_site_from_file(file_path))
437
493
 
438
494
  complete_update_item = Cmd.path_complete
439
495
 
440
496
  def do_update_item(self, file_path):
441
497
  """update bigfix content item from bes file"""
442
498
  if not os.access(file_path, os.R_OK):
443
- print(file_path, "is not a readable file")
499
+ self.poutput(file_path, "is not a readable file")
444
500
  else:
445
- print(self.bes_conn.update_item_from_file(file_path))
501
+ self.poutput(self.bes_conn.update_item_from_file(file_path))
502
+
503
+ def do_serverinfo(self, _=None):
504
+ """get server info and return formatted"""
505
+
506
+ # not sure what the minimum version for this is:
507
+ result = self.bes_conn.get("serverinfo")
508
+
509
+ result_json = json.loads(result.text)
510
+
511
+ self.poutput(f"\nServer Info for {self.BES_ROOT_SERVER}")
512
+ self.poutput(json.dumps(result_json, indent=2))
446
513
 
447
514
 
448
515
  def main():
@@ -107,7 +107,9 @@ bigfix_cli.do_conf()
107
107
  # this should really only run if the config file is present:
108
108
  if bigfix_cli.bes_conn:
109
109
  # session relevance tests require functioning web reports server
110
- print(bigfix_cli.bes_conn.session_relevance_string("number of bes computers"))
110
+ assert (
111
+ int(bigfix_cli.bes_conn.session_relevance_string("number of bes computers")) > 0
112
+ )
111
113
  assert (
112
114
  "test session relevance string result"
113
115
  in bigfix_cli.bes_conn.session_relevance_string(
@@ -134,7 +136,7 @@ if bigfix_cli.bes_conn:
134
136
  var_name = "TestVarName"
135
137
  var_value = "TestVarValue " + str(random.randint(0, 9999))
136
138
 
137
- print(
139
+ assert var_value in str(
138
140
  bigfix_cli.bes_conn.set_dashboard_variable_value(
139
141
  dashboard_name, var_name, var_value
140
142
  )
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes