besapi 3.8.2__tar.gz → 3.8.3__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.
Files changed (26) hide show
  1. {besapi-3.8.2/src/besapi.egg-info → besapi-3.8.3}/PKG-INFO +9 -13
  2. {besapi-3.8.2 → besapi-3.8.3}/README.md +1 -1
  3. besapi-3.8.3/setup.cfg +46 -0
  4. besapi-3.8.3/setup.py +7 -0
  5. {besapi-3.8.2 → besapi-3.8.3}/src/besapi/besapi.py +69 -34
  6. {besapi-3.8.2 → besapi-3.8.3/src/besapi.egg-info}/PKG-INFO +9 -13
  7. {besapi-3.8.2 → besapi-3.8.3}/src/besapi.egg-info/SOURCES.txt +1 -0
  8. {besapi-3.8.2 → besapi-3.8.3}/src/bescli/bescli.py +1 -1
  9. besapi-3.8.3/tests/test_besapi.py +284 -0
  10. {besapi-3.8.2 → besapi-3.8.3}/tests/tests.py +22 -3
  11. besapi-3.8.2/setup.cfg +0 -21
  12. besapi-3.8.2/setup.py +0 -21
  13. {besapi-3.8.2 → besapi-3.8.3}/LICENSE.txt +0 -0
  14. {besapi-3.8.2 → besapi-3.8.3}/MANIFEST.in +0 -0
  15. {besapi-3.8.2 → besapi-3.8.3}/pyproject.toml +0 -0
  16. {besapi-3.8.2 → besapi-3.8.3}/src/besapi/__init__.py +0 -0
  17. {besapi-3.8.2 → besapi-3.8.3}/src/besapi/__main__.py +0 -0
  18. {besapi-3.8.2 → besapi-3.8.3}/src/besapi/plugin_utilities.py +0 -0
  19. {besapi-3.8.2 → besapi-3.8.3}/src/besapi/schemas/BES.xsd +0 -0
  20. {besapi-3.8.2 → besapi-3.8.3}/src/besapi/schemas/BESAPI.xsd +0 -0
  21. {besapi-3.8.2 → besapi-3.8.3}/src/besapi/schemas/BESActionSettings.xsd +0 -0
  22. {besapi-3.8.2 → besapi-3.8.3}/src/besapi.egg-info/dependency_links.txt +0 -0
  23. {besapi-3.8.2 → besapi-3.8.3}/src/besapi.egg-info/requires.txt +2 -2
  24. {besapi-3.8.2 → besapi-3.8.3}/src/besapi.egg-info/top_level.txt +0 -0
  25. {besapi-3.8.2 → besapi-3.8.3}/src/bescli/__init__.py +0 -0
  26. {besapi-3.8.2 → besapi-3.8.3}/src/bescli/__main__.py +0 -0
@@ -1,10 +1,12 @@
1
- Metadata-Version: 2.2
1
+ Metadata-Version: 2.4
2
2
  Name: besapi
3
- Version: 3.8.2
3
+ Version: 3.8.3
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
7
7
  Author-email: hansen.m@psu.edu, james@jgstew.com
8
+ Maintainer: James Stewart
9
+ Maintainer-email: james@jgstew.com
8
10
  License: MIT
9
11
  Keywords: bigfix iem tem rest api
10
12
  Classifier: Programming Language :: Python :: 3
@@ -15,20 +17,14 @@ Classifier: Development Status :: 5 - Production/Stable
15
17
  Classifier: Intended Audience :: Developers
16
18
  Classifier: Topic :: Software Development :: Libraries :: Python Modules
17
19
  Classifier: Topic :: System :: Systems Administration
18
- Requires-Python: >=3.7
20
+ Requires-Python: >=3.9
19
21
  Description-Content-Type: text/markdown
20
22
  License-File: LICENSE.txt
21
- Requires-Dist: requests
22
- Requires-Dist: lxml
23
23
  Requires-Dist: cmd2
24
+ Requires-Dist: lxml
25
+ Requires-Dist: requests
24
26
  Requires-Dist: setuptools
25
- Dynamic: author
26
- Dynamic: author-email
27
- Dynamic: home-page
28
- Dynamic: keywords
29
- Dynamic: license
30
- Dynamic: requires-dist
31
- Dynamic: summary
27
+ Dynamic: license-file
32
28
 
33
29
  # besapi
34
30
 
@@ -42,7 +38,7 @@ Usage:
42
38
 
43
39
  ```
44
40
  import besapi
45
- b = besapi.BESConnection('my_username', 'my_password', 'https://rootserver.domain.org:52311')
41
+ b = besapi.besapi.BESConnection('my_username', 'my_password', 'https://rootserver.domain.org:52311')
46
42
  rr = b.get('sites')
47
43
 
48
44
  # rr.request contains the original request object
@@ -10,7 +10,7 @@ Usage:
10
10
 
11
11
  ```
12
12
  import besapi
13
- b = besapi.BESConnection('my_username', 'my_password', 'https://rootserver.domain.org:52311')
13
+ b = besapi.besapi.BESConnection('my_username', 'my_password', 'https://rootserver.domain.org:52311')
14
14
  rr = b.get('sites')
15
15
 
16
16
  # rr.request contains the original request object
besapi-3.8.3/setup.cfg ADDED
@@ -0,0 +1,46 @@
1
+ [metadata]
2
+ name = besapi
3
+ author = Matt Hansen, James Stewart
4
+ author_email = hansen.m@psu.edu, james@jgstew.com
5
+ maintainer = James Stewart
6
+ maintainer_email = james@jgstew.com
7
+ version = attr: besapi.besapi.__version__
8
+ description = Library for working with the BigFix REST API
9
+ keywords = bigfix iem tem rest api
10
+ long_description = file: README.md
11
+ long_description_content_type = text/markdown
12
+ url = https://github.com/jgstew/besapi
13
+ license = MIT
14
+ license_file = LICENSE.txt
15
+ classifiers =
16
+ Programming Language :: Python :: 3
17
+ Programming Language :: Python :: 3.9
18
+ Operating System :: OS Independent
19
+ License :: OSI Approved :: MIT License
20
+ Development Status :: 5 - Production/Stable
21
+ Intended Audience :: Developers
22
+ Topic :: Software Development :: Libraries :: Python Modules
23
+ Topic :: System :: Systems Administration
24
+ package_dir =
25
+ = src
26
+
27
+ [options]
28
+ python_requires = >=3.9
29
+ include_package_data = True
30
+ packages = find:
31
+ install_requires =
32
+ cmd2
33
+ lxml
34
+ requests
35
+ setuptools
36
+
37
+ [options.package_data]
38
+ besapi = schemas/*.xsd
39
+
40
+ [options.packages.find]
41
+ where = src
42
+
43
+ [egg_info]
44
+ tag_build =
45
+ tag_date = 0
46
+
besapi-3.8.3/setup.py ADDED
@@ -0,0 +1,7 @@
1
+ #!/usr/bin/env python
2
+ """File to configure python build and packaging for pip."""
3
+
4
+ from setuptools import setup
5
+
6
+ if __name__ == "__main__":
7
+ setup()
@@ -12,24 +12,20 @@ Library for communicating with the BES (BigFix) REST API.
12
12
  import configparser
13
13
  import datetime
14
14
  import hashlib
15
+ import importlib.resources
15
16
  import json
16
17
  import logging
17
18
  import os
18
19
  import random
19
20
  import site
20
21
  import string
21
- import typing
22
-
23
- try:
24
- from urllib import parse
25
- except ImportError:
26
- from urlparse import parse_qs as parse # type: ignore[no-redef,import-not-found]
22
+ import urllib.parse
27
23
 
24
+ import lxml.etree
25
+ import lxml.objectify
28
26
  import requests
29
- from lxml import etree, objectify
30
- from pkg_resources import resource_filename
31
27
 
32
- __version__ = "3.8.2"
28
+ __version__ = "3.8.3"
33
29
 
34
30
  besapi_logger = logging.getLogger("besapi")
35
31
 
@@ -48,7 +44,7 @@ def rand_password(length=20):
48
44
 
49
45
  def sanitize_txt(*args):
50
46
  """Clean arbitrary text for safe file system usage."""
51
- valid_chars = "-_.() %s%s" % (string.ascii_letters, string.digits)
47
+ valid_chars = f"-_.() {string.ascii_letters}{string.digits}"
52
48
 
53
49
  sani_args = []
54
50
  for arg in args:
@@ -158,7 +154,7 @@ def parse_bes_modtime(string_datetime):
158
154
  # )
159
155
 
160
156
 
161
- def get_action_combined_relevance(relevances: typing.List[str]):
157
+ def get_action_combined_relevance(relevances: list[str]):
162
158
  """Take array of ordered relevance clauses and return relevance string for
163
159
  action.
164
160
  """
@@ -249,17 +245,19 @@ def get_target_xml(targets=None):
249
245
  def validate_xsd(doc):
250
246
  """Validate results using XML XSDs."""
251
247
  try:
252
- xmldoc = etree.fromstring(doc)
248
+ xmldoc = lxml.etree.fromstring(doc)
253
249
  except BaseException: # pylint: disable=broad-except
254
250
  return False
255
251
 
256
252
  for xsd in ["BES.xsd", "BESAPI.xsd", "BESActionSettings.xsd"]:
257
- xmlschema_doc = etree.parse(resource_filename(__name__, "schemas/%s" % xsd))
253
+ schema_path = importlib.resources.files(__package__) / f"schemas/{xsd}"
254
+ with schema_path.open("r") as xsd_file:
255
+ xmlschema_doc = lxml.etree.parse(xsd_file)
258
256
 
259
257
  # one schema may throw an error while another will validate
260
258
  try:
261
- xmlschema = etree.XMLSchema(xmlschema_doc)
262
- except etree.XMLSchemaParseError as err:
259
+ xmlschema = lxml.etree.XMLSchema(xmlschema_doc)
260
+ except lxml.etree.XMLSchemaParseError as err:
263
261
  # this should only error if the XSD itself is malformed
264
262
  besapi_logger.error("ERROR with `%s`: %s", xsd, err)
265
263
  raise err
@@ -392,7 +390,7 @@ class BESConnection:
392
390
  if path.startswith(self.rootserver):
393
391
  url = path
394
392
  else:
395
- url = "%s/api/%s" % (self.rootserver, path)
393
+ url = f"{self.rootserver}/api/{path}"
396
394
 
397
395
  return url
398
396
 
@@ -414,9 +412,9 @@ class BESConnection:
414
412
  if validate_xml:
415
413
  logging.error(err_msg)
416
414
  raise ValueError(err_msg)
417
- else:
418
- # this is intended it validate_xml is None, but not used currently
419
- logging.warning(err_msg)
415
+
416
+ # this is intended it validate_xml is None, but not used currently
417
+ logging.warning(err_msg)
420
418
 
421
419
  self.last_connected = datetime.datetime.now()
422
420
  return RESTResult(
@@ -435,9 +433,9 @@ class BESConnection:
435
433
  if validate_xml:
436
434
  logging.error(err_msg)
437
435
  raise ValueError(err_msg)
438
- else:
439
- # this is intended it validate_xml is None, but not used currently
440
- logging.warning(err_msg)
436
+
437
+ # this is intended it validate_xml is None, but not used currently
438
+ logging.warning(err_msg)
441
439
 
442
440
  return RESTResult(
443
441
  self.session.put(self.url(path), data=data, verify=self.verify, **kwargs)
@@ -450,13 +448,48 @@ class BESConnection:
450
448
  self.session.delete(self.url(path), verify=self.verify, **kwargs)
451
449
  )
452
450
 
451
+ def session_relevance_json(self, relevance, **kwargs):
452
+ """Get Session Relevance Results in JSON.
453
+
454
+ This will submit the relevance string as json instead of html form data.
455
+ """
456
+ session_relevance = urllib.parse.quote(relevance, safe=":+")
457
+ rel_data = {"output": "json", "relevance": session_relevance}
458
+ self.last_connected = datetime.datetime.now()
459
+ result = RESTResult(
460
+ self.session.post(
461
+ self.url("query"),
462
+ data=rel_data,
463
+ verify=self.verify,
464
+ **kwargs,
465
+ )
466
+ )
467
+ return json.loads(result.text)
468
+
469
+ def session_relevance_json_array(self, relevance, **kwargs):
470
+ """Get Session Relevance Results in an array from the json return.
471
+
472
+ This will submit the relevance string as json instead of html form data.
473
+ """
474
+ result = self.session_relevance_json(relevance, **kwargs)
475
+ return result["result"]
476
+
477
+ def session_relevance_json_string(self, relevance, **kwargs):
478
+ """Get Session Relevance Results in a string from the json return.
479
+
480
+ This will submit the relevance string as json instead of html form data.
481
+ """
482
+ rel_result_array = self.session_relevance_json_array(relevance, **kwargs)
483
+ # Ensure each element is converted to a string
484
+ return "\n".join(map(str, rel_result_array))
485
+
453
486
  def session_relevance_xml(self, relevance, **kwargs):
454
487
  """Get Session Relevance Results XML."""
455
488
  self.last_connected = datetime.datetime.now()
456
489
  return RESTResult(
457
490
  self.session.post(
458
491
  self.url("query"),
459
- data=f"relevance={parse.quote(relevance, safe=':+')}",
492
+ data=f"relevance={urllib.parse.quote(relevance, safe=':+')}",
460
493
  verify=self.verify,
461
494
  **kwargs,
462
495
  )
@@ -626,6 +659,8 @@ class BESConnection:
626
659
  self.site_path = site_path
627
660
  return self.site_path
628
661
 
662
+ return None
663
+
629
664
  def import_bes_to_site(self, bes_file_path, site_path=None):
630
665
  """Import bes file to site."""
631
666
 
@@ -651,7 +686,7 @@ class BESConnection:
651
686
 
652
687
  def create_site_from_file(self, bes_file_path, site_type="custom"):
653
688
  """Create new site."""
654
- xml_parsed = etree.parse(bes_file_path)
689
+ xml_parsed = lxml.etree.parse(bes_file_path)
655
690
  new_site_name = xml_parsed.xpath("/BES/CustomSite/Name/text()")[0]
656
691
 
657
692
  result_site_path = self.validate_site_path(
@@ -662,7 +697,7 @@ class BESConnection:
662
697
  besapi_logger.warning("Site `%s` already exists", result_site_path)
663
698
  return None
664
699
 
665
- result_site = self.post("sites", etree.tostring(xml_parsed))
700
+ result_site = self.post("sites", lxml.etree.tostring(xml_parsed))
666
701
 
667
702
  return result_site
668
703
 
@@ -678,7 +713,7 @@ class BESConnection:
678
713
 
679
714
  def create_user_from_file(self, bes_file_path):
680
715
  """Create user from xml."""
681
- xml_parsed = etree.parse(bes_file_path)
716
+ xml_parsed = lxml.etree.parse(bes_file_path)
682
717
  new_user_name = xml_parsed.xpath("/BESAPI/Operator/Name/text()")[0]
683
718
  result_user = self.get_user(new_user_name)
684
719
 
@@ -686,7 +721,7 @@ class BESConnection:
686
721
  besapi_logger.warning("User `%s` Already Exists!", new_user_name)
687
722
  return result_user
688
723
  besapi_logger.info("Creating User `%s`", new_user_name)
689
- _ = self.post("operators", etree.tostring(xml_parsed))
724
+ _ = self.post("operators", lxml.etree.tostring(xml_parsed))
690
725
  # print(user_result)
691
726
  return self.get_user(new_user_name)
692
727
 
@@ -708,7 +743,7 @@ class BESConnection:
708
743
  def create_group_from_file(self, bes_file_path, site_path=None):
709
744
  """Create a new group."""
710
745
  site_path = self.get_current_site_path(site_path)
711
- xml_parsed = etree.parse(bes_file_path)
746
+ xml_parsed = lxml.etree.parse(bes_file_path)
712
747
  new_group_name = xml_parsed.xpath("/BES/ComputerGroup/Title/text()")[0]
713
748
 
714
749
  existing_group = self.get_computergroup(new_group_name, site_path)
@@ -719,7 +754,7 @@ class BESConnection:
719
754
 
720
755
  # print(lxml.etree.tostring(xml_parsed))
721
756
 
722
- _ = self.post(f"computergroups/{site_path}", etree.tostring(xml_parsed))
757
+ _ = self.post(f"computergroups/{site_path}", lxml.etree.tostring(xml_parsed))
723
758
 
724
759
  return self.get_computergroup(site_path, new_group_name)
725
760
 
@@ -844,7 +879,7 @@ class BESConnection:
844
879
  def update_item_from_file(self, file_path, site_path=None):
845
880
  """Update an item by name and last modified."""
846
881
  site_path = self.get_current_site_path(site_path)
847
- bes_tree = etree.parse(file_path)
882
+ bes_tree = lxml.etree.parse(file_path)
848
883
 
849
884
  with open(file_path, "rb") as f:
850
885
  content = f.read()
@@ -1130,7 +1165,7 @@ class RESTResult:
1130
1165
  """Property for python dict representation."""
1131
1166
  if self._besdict is None:
1132
1167
  if self.valid:
1133
- self._besdict = elem2dict(etree.fromstring(self.besxml))
1168
+ self._besdict = elem2dict(lxml.etree.fromstring(self.besxml))
1134
1169
  else:
1135
1170
  self._besdict = {"text": str(self)}
1136
1171
 
@@ -1154,11 +1189,11 @@ class RESTResult:
1154
1189
  def xmlparse_text(self, text):
1155
1190
  """Parse response text as xml."""
1156
1191
  if type(text) is str:
1157
- root_xml = etree.fromstring(text.encode("utf-8"))
1192
+ root_xml = lxml.etree.fromstring(text.encode("utf-8"))
1158
1193
  else:
1159
1194
  root_xml = text
1160
1195
 
1161
- return etree.tostring(root_xml, encoding="utf-8", xml_declaration=True)
1196
+ return lxml.etree.tostring(root_xml, encoding="utf-8", xml_declaration=True)
1162
1197
 
1163
1198
  def objectify_text(self, text):
1164
1199
  """Parse response text as objectified xml."""
@@ -1167,7 +1202,7 @@ class RESTResult:
1167
1202
  else:
1168
1203
  root_xml = text
1169
1204
 
1170
- return objectify.fromstring(root_xml)
1205
+ return lxml.objectify.fromstring(root_xml)
1171
1206
 
1172
1207
 
1173
1208
  def main():
@@ -1,10 +1,12 @@
1
- Metadata-Version: 2.2
1
+ Metadata-Version: 2.4
2
2
  Name: besapi
3
- Version: 3.8.2
3
+ Version: 3.8.3
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
7
7
  Author-email: hansen.m@psu.edu, james@jgstew.com
8
+ Maintainer: James Stewart
9
+ Maintainer-email: james@jgstew.com
8
10
  License: MIT
9
11
  Keywords: bigfix iem tem rest api
10
12
  Classifier: Programming Language :: Python :: 3
@@ -15,20 +17,14 @@ Classifier: Development Status :: 5 - Production/Stable
15
17
  Classifier: Intended Audience :: Developers
16
18
  Classifier: Topic :: Software Development :: Libraries :: Python Modules
17
19
  Classifier: Topic :: System :: Systems Administration
18
- Requires-Python: >=3.7
20
+ Requires-Python: >=3.9
19
21
  Description-Content-Type: text/markdown
20
22
  License-File: LICENSE.txt
21
- Requires-Dist: requests
22
- Requires-Dist: lxml
23
23
  Requires-Dist: cmd2
24
+ Requires-Dist: lxml
25
+ Requires-Dist: requests
24
26
  Requires-Dist: setuptools
25
- Dynamic: author
26
- Dynamic: author-email
27
- Dynamic: home-page
28
- Dynamic: keywords
29
- Dynamic: license
30
- Dynamic: requires-dist
31
- Dynamic: summary
27
+ Dynamic: license-file
32
28
 
33
29
  # besapi
34
30
 
@@ -42,7 +38,7 @@ Usage:
42
38
 
43
39
  ```
44
40
  import besapi
45
- b = besapi.BESConnection('my_username', 'my_password', 'https://rootserver.domain.org:52311')
41
+ b = besapi.besapi.BESConnection('my_username', 'my_password', 'https://rootserver.domain.org:52311')
46
42
  rr = b.get('sites')
47
43
 
48
44
  # rr.request contains the original request object
@@ -19,4 +19,5 @@ src/besapi/schemas/BESActionSettings.xsd
19
19
  src/bescli/__init__.py
20
20
  src/bescli/__main__.py
21
21
  src/bescli/bescli.py
22
+ tests/test_besapi.py
22
23
  tests/tests.py
@@ -32,7 +32,7 @@ except ImportError:
32
32
  try:
33
33
  from besapi.besapi import __version__
34
34
  except ImportError:
35
- from besapi import __version__ # type: ignore
35
+ from besapi import __version__ # type: ignore[attr-defined, no-redef]
36
36
 
37
37
 
38
38
  class BESCLInterface(Cmd):
@@ -0,0 +1,284 @@
1
+ #!/usr/bin/env python
2
+ """Test besapi with pytest.
3
+
4
+ This was converted from tests/tests.py which was used before this pytest was added.
5
+ """
6
+
7
+ import json
8
+ import os
9
+ import random
10
+ import subprocess
11
+ import sys
12
+
13
+ import pytest
14
+
15
+ # mypy: disable-error-code="arg-type"
16
+
17
+ if not os.getenv("TEST_PIP"):
18
+ # add module folder to import paths for testing local src
19
+ sys.path.append(
20
+ os.path.join(os.path.dirname(os.path.dirname(os.path.abspath(__file__))), "src")
21
+ )
22
+ # reverse the order so we make sure to get the local src module
23
+ sys.path.reverse()
24
+
25
+ import besapi
26
+ import besapi.plugin_utilities
27
+
28
+
29
+ def test_besapi_version():
30
+ """Test that the besapi version is not None."""
31
+ assert besapi.besapi.__version__ is not None
32
+
33
+
34
+ def test_rand_password():
35
+ """Test that the generated random password has the correct length."""
36
+ assert 15 == len(besapi.besapi.rand_password(15))
37
+
38
+
39
+ def test_sanitize_txt():
40
+ """Test that the sanitize_txt function works correctly."""
41
+ assert ("test--string", "test") == besapi.besapi.sanitize_txt(
42
+ r"test/\string", "test%"
43
+ )
44
+
45
+
46
+ def test_replace_text_between():
47
+ """Test that the replace_text_between function works correctly."""
48
+ assert "http://localhost:52311/file.example" == besapi.besapi.replace_text_between(
49
+ "http://example:52311/file.example", "://", ":52311", "localhost"
50
+ )
51
+
52
+
53
+ def test_validate_site_path():
54
+ """Test the validate_site_path function with various inputs."""
55
+ assert "master" in besapi.besapi.BESConnection.validate_site_path(
56
+ "", "master", False
57
+ )
58
+ assert "custom/" in besapi.besapi.BESConnection.validate_site_path(
59
+ "", "custom/Example", False
60
+ )
61
+ assert "operator/" in besapi.besapi.BESConnection.validate_site_path(
62
+ "", "operator/Example", False
63
+ )
64
+
65
+
66
+ def test_validate_xml_bes_file():
67
+ """Test the validate_xml_bes_file function with good and bad files."""
68
+ assert besapi.besapi.validate_xml_bes_file("tests/good/RelaySelectTask.bes") is True
69
+ assert (
70
+ besapi.besapi.validate_xml_bes_file("tests/good/ComputerGroupsExample.bes")
71
+ is True
72
+ )
73
+ assert (
74
+ besapi.besapi.validate_xml_bes_file("tests/bad/RelaySelectTask_BAD.bes")
75
+ is False
76
+ )
77
+ assert (
78
+ besapi.besapi.validate_xml_bes_file("tests/bad/ComputerGroups_BAD.bes") is False
79
+ )
80
+
81
+
82
+ def test_failing_validate_site_path():
83
+ """Test that validate_site_path raises ValueError for invalid inputs."""
84
+
85
+ with pytest.raises(ValueError):
86
+ besapi.besapi.BESConnection.validate_site_path("", "bad/Example", False)
87
+
88
+ with pytest.raises(ValueError):
89
+ besapi.besapi.BESConnection.validate_site_path("", "bad/master", False)
90
+
91
+ with pytest.raises(ValueError):
92
+ besapi.besapi.BESConnection.validate_site_path("", "", False, True)
93
+
94
+ with pytest.raises(ValueError):
95
+ besapi.besapi.BESConnection.validate_site_path("", None, False, True)
96
+
97
+
98
+ class RequestResult:
99
+ text = "this is just a test"
100
+ headers: list = []
101
+
102
+
103
+ def test_rest_result():
104
+ """Test the RESTResult class."""
105
+ request_result = RequestResult()
106
+ rest_result = besapi.besapi.RESTResult(request_result)
107
+
108
+ assert rest_result.besdict is not None
109
+ assert rest_result.besjson is not None
110
+ assert b"<BES>Example</BES>" in rest_result.xmlparse_text("<BES>Example</BES>")
111
+ assert rest_result.text == "this is just a test"
112
+
113
+
114
+ def test_parse_bes_modtime():
115
+ """Test the parse_bes_modtime function."""
116
+ assert (
117
+ 2017 == besapi.besapi.parse_bes_modtime("Tue, 05 Sep 2017 23:31:48 +0000").year
118
+ )
119
+
120
+
121
+ def test_get_action_combined_relevance():
122
+ """Test the get_action_combined_relevance function."""
123
+ assert (
124
+ "( ( True ) AND ( windows of operating system ) ) AND ( False )"
125
+ == besapi.besapi.get_action_combined_relevance(
126
+ ["True", "windows of operating system", "False"]
127
+ )
128
+ )
129
+
130
+
131
+ def test_get_target_xml():
132
+ """Test the get_target_xml function with various inputs."""
133
+ assert "<CustomRelevance>False</CustomRelevance>" == besapi.besapi.get_target_xml()
134
+ assert "<AllComputers>true</AllComputers>" == besapi.besapi.get_target_xml(
135
+ "<AllComputers>"
136
+ )
137
+ assert "<ComputerID>1</ComputerID>" == besapi.besapi.get_target_xml(1)
138
+ assert (
139
+ "<CustomRelevance><![CDATA[not windows of operating system]]></CustomRelevance>"
140
+ == besapi.besapi.get_target_xml("not windows of operating system")
141
+ )
142
+ assert (
143
+ "<ComputerID>1</ComputerID><ComputerID>2</ComputerID>"
144
+ == besapi.besapi.get_target_xml([1, 2])
145
+ )
146
+ assert (
147
+ "<ComputerName>Computer 1</ComputerName><ComputerName>Another Computer</ComputerName>"
148
+ == besapi.besapi.get_target_xml(["Computer 1", "Another Computer"])
149
+ )
150
+
151
+
152
+ def test_bescli():
153
+ """Test the BESCLInterface class and its methods."""
154
+ import bescli
155
+
156
+ bigfix_cli = bescli.bescli.BESCLInterface()
157
+
158
+ # just make sure these don't throw errors:
159
+ bigfix_cli.do_ls()
160
+ bigfix_cli.do_clear()
161
+ bigfix_cli.do_ls()
162
+ bigfix_cli.do_logout()
163
+ bigfix_cli.do_error_count()
164
+ bigfix_cli.do_version()
165
+ bigfix_cli.do_conf()
166
+
167
+ # this should really only run if the config file is present:
168
+ if bigfix_cli.bes_conn:
169
+ # session relevance tests require functioning web reports server
170
+ assert (
171
+ int(bigfix_cli.bes_conn.session_relevance_string("number of bes computers"))
172
+ > 0
173
+ )
174
+ assert (
175
+ "test session relevance string result"
176
+ in bigfix_cli.bes_conn.session_relevance_string(
177
+ '"test session relevance string result"'
178
+ )
179
+ )
180
+ bigfix_cli.do_set_current_site("master")
181
+
182
+ # set working directory to folder this file is in:
183
+ os.chdir(os.path.dirname(os.path.abspath(__file__)))
184
+
185
+ # set working directory to src folder in parent folder
186
+ os.chdir("../src")
187
+
188
+ # Test file upload:
189
+ upload_result = bigfix_cli.bes_conn.upload(
190
+ "./besapi/__init__.py", "test_besapi_upload.txt"
191
+ )
192
+ # print(upload_result)
193
+ assert upload_result.besobj.FileUpload.Available == 1
194
+ assert upload_result.besdict["FileUpload"]["Available"] == "1"
195
+ assert upload_result.besjson is not None
196
+ upload_result_json = json.loads(upload_result.besjson)
197
+ assert upload_result_json["FileUpload"]["Available"] == "1"
198
+
199
+ assert "test_besapi_upload.txt</URL>" in str(upload_result)
200
+ upload_prefetch = bigfix_cli.bes_conn.parse_upload_result_to_prefetch(
201
+ upload_result
202
+ )
203
+ # print(upload_prefetch)
204
+ assert "prefetch test_besapi_upload.txt sha1:" in upload_prefetch
205
+
206
+ dashboard_name = "_PyBESAPI_tests.py"
207
+ var_name = "TestVarName"
208
+ var_value = "TestVarValue " + str(random.randint(0, 9999))
209
+
210
+ assert var_value in str(
211
+ bigfix_cli.bes_conn.set_dashboard_variable_value(
212
+ dashboard_name, var_name, var_value
213
+ )
214
+ )
215
+
216
+ assert var_value in str(
217
+ bigfix_cli.bes_conn.get_dashboard_variable_value(dashboard_name, var_name)
218
+ )
219
+
220
+ if os.name == "nt":
221
+ subprocess.run(
222
+ 'CMD /C python -m besapi ls clear ls conf "query number of bes computers" version error_count exit',
223
+ check=True,
224
+ )
225
+
226
+ bes_conn = besapi.besapi.get_bes_conn_using_config_file()
227
+ print("login succeeded:", bes_conn.login())
228
+ assert bes_conn.login()
229
+
230
+
231
+ def test_bes_conn_json():
232
+ """Test the BESConnection class with JSON output."""
233
+ bes_conn = besapi.besapi.get_bes_conn_using_config_file()
234
+ if bes_conn and bes_conn.login():
235
+ print("testing session_relevance_json")
236
+ result = bes_conn.session_relevance_json("number of bes computers")
237
+ assert result is not None
238
+ assert int(result["result"][0]) > 0
239
+ result = bes_conn.session_relevance_json(
240
+ """("[%22" & it & "%22]") of concatenation "%22, %22" of names of bes computers"""
241
+ )
242
+ assert result is not None
243
+ string_first_result_json = result["result"][0]
244
+ print(string_first_result_json)
245
+ assert '", "' in string_first_result_json
246
+ assert '["' in string_first_result_json
247
+ # NOTE: the following check is specific to my env:
248
+ if "10.0." in bes_conn.rootserver:
249
+ print("doing check specific to my env")
250
+ assert '", "BIGFIX", "' in string_first_result_json
251
+
252
+ print("testing session_relevance_json_array")
253
+ result = bes_conn.session_relevance_json_array("number of bes computers")
254
+ print(result)
255
+ assert result is not None
256
+ assert int(result[0]) > 0
257
+ print("testing session_relevance_json_string")
258
+ result = bes_conn.session_relevance_json_string("number of bes computers")
259
+ print(result)
260
+ assert result is not None
261
+ assert int(result) > 0
262
+
263
+
264
+ def test_plugin_utilities():
265
+ """Test the plugin_utilities module."""
266
+ print(besapi.plugin_utilities.get_invoke_folder())
267
+ print(besapi.plugin_utilities.get_invoke_file_name())
268
+
269
+ parser = besapi.plugin_utilities.setup_plugin_argparse(plugin_args_required=False)
270
+ # allow unknown args to be parsed instead of throwing an error:
271
+ args, _unknown = parser.parse_known_args()
272
+
273
+ # test logging plugin_utilities:
274
+ import logging
275
+
276
+ logging_config = besapi.plugin_utilities.get_plugin_logging_config("./tests.log")
277
+
278
+ # this use of logging.basicConfig requires python >= 3.9
279
+ if sys.version_info >= (3, 9):
280
+ logging.basicConfig(**logging_config)
281
+
282
+ logging.warning("Just testing to see if logging is working!")
283
+
284
+ assert os.path.isfile("./tests.log")
@@ -2,6 +2,7 @@
2
2
  """Test besapi."""
3
3
 
4
4
  import argparse
5
+ import json
5
6
  import os
6
7
  import random
7
8
  import subprocess
@@ -46,6 +47,13 @@ assert "operator/" in besapi.besapi.BESConnection.validate_site_path(
46
47
  "", "operator/Example", False
47
48
  )
48
49
 
50
+ assert besapi.besapi.validate_xml_bes_file("tests/good/RelaySelectTask.bes") is True
51
+ assert (
52
+ besapi.besapi.validate_xml_bes_file("tests/good/ComputerGroupsExample.bes") is True
53
+ )
54
+
55
+ assert besapi.besapi.validate_xml_bes_file("tests/bad/RelaySelectTask_BAD.bes") is False
56
+
49
57
  # start failing tests:
50
58
  raised_errors = 0
51
59
 
@@ -77,9 +85,9 @@ assert raised_errors == 4
77
85
  # end failing tests
78
86
 
79
87
 
80
- class RequestResult(object):
88
+ class RequestResult:
81
89
  text = "this is just a test"
82
- headers = [] # type: ignore
90
+ headers: list = []
83
91
 
84
92
 
85
93
  request_result = RequestResult()
@@ -159,9 +167,20 @@ if bigfix_cli.bes_conn:
159
167
  upload_result = bigfix_cli.bes_conn.upload(
160
168
  "./besapi/__init__.py", "test_besapi_upload.txt"
161
169
  )
170
+
162
171
  # print(upload_result)
172
+ # print(upload_result.besobj.FileUpload.Available)
173
+ assert upload_result.besobj.FileUpload.Available == 1
163
174
  assert "test_besapi_upload.txt</URL>" in str(upload_result)
164
- print(bigfix_cli.bes_conn.parse_upload_result_to_prefetch(upload_result))
175
+ upload_result_json = json.loads(upload_result.besjson)
176
+ # print(upload_result_json["FileUpload"]["Available"])
177
+ assert upload_result_json["FileUpload"]["Available"] == "1"
178
+
179
+ upload_prefetch = bigfix_cli.bes_conn.parse_upload_result_to_prefetch(upload_result)
180
+ # print(upload_prefetch)
181
+ assert "prefetch test_besapi_upload.txt sha1:" in upload_prefetch
182
+ assert "test_besapi_upload.txt" in str(upload_result)
183
+ # print(bigfix_cli.bes_conn.parse_upload_result_to_prefetch(upload_result))
165
184
 
166
185
  dashboard_name = "_PyBESAPI_tests.py"
167
186
  var_name = "TestVarName"
besapi-3.8.2/setup.cfg DELETED
@@ -1,21 +0,0 @@
1
- [metadata]
2
- version = attr: besapi.besapi.__version__
3
- long_description = file: README.md
4
- long_description_content_type = text/markdown
5
- classifiers =
6
- Programming Language :: Python :: 3
7
- Programming Language :: Python :: 3.9
8
- Operating System :: OS Independent
9
- License :: OSI Approved :: MIT License
10
- Development Status :: 5 - Production/Stable
11
- Intended Audience :: Developers
12
- Topic :: Software Development :: Libraries :: Python Modules
13
- Topic :: System :: Systems Administration
14
-
15
- [options]
16
- python_requires = >=3.7
17
-
18
- [egg_info]
19
- tag_build =
20
- tag_date = 0
21
-
besapi-3.8.2/setup.py DELETED
@@ -1,21 +0,0 @@
1
- #!/usr/bin/env python
2
- """File to configure python build and packaging for pip."""
3
-
4
- import setuptools
5
-
6
- setuptools.setup(
7
- name="besapi",
8
- # version= moved to setup.cfg
9
- author="Matt Hansen, James Stewart",
10
- author_email="hansen.m@psu.edu, james@jgstew.com",
11
- description="Library for working with the BigFix REST API",
12
- license="MIT",
13
- keywords="bigfix iem tem rest api",
14
- url="https://github.com/jgstew/besapi",
15
- # long_description= moved to setup.cfg
16
- packages=["besapi", "bescli"],
17
- package_data={"besapi": ["schemas/*.xsd"]},
18
- install_requires=["requests", "lxml", "cmd2", "setuptools"],
19
- include_package_data=True,
20
- package_dir={"": "src"},
21
- )
File without changes
File without changes
File without changes
File without changes
File without changes
@@ -1,4 +1,4 @@
1
- requests
2
- lxml
3
1
  cmd2
2
+ lxml
3
+ requests
4
4
  setuptools
File without changes
File without changes