besapi 3.7.8__tar.gz → 3.8.1__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.8
3
+ Version: 3.8.1
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
@@ -12,13 +12,13 @@ Library for communicating with the BES (BigFix) REST API.
12
12
  import configparser
13
13
  import datetime
14
14
  import hashlib
15
- import io
16
15
  import json
17
16
  import logging
18
17
  import os
19
18
  import random
20
19
  import site
21
20
  import string
21
+ import typing
22
22
 
23
23
  try:
24
24
  from urllib import parse
@@ -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.8"
32
+ __version__ = "3.8.1"
33
33
 
34
34
  besapi_logger = logging.getLogger("besapi")
35
35
 
@@ -94,7 +94,7 @@ def elem2dict(node):
94
94
  def replace_text_between(
95
95
  original_text, first_delimiter, second_delimiter, replacement_text
96
96
  ):
97
- """Replace text between delimeters. Each delimiter should only appear once."""
97
+ """Replace text between delimiters. Each delimiter should only appear once."""
98
98
  leading_text = original_text.split(first_delimiter)[0]
99
99
  trailing_text = original_text.split(second_delimiter)[1]
100
100
 
@@ -120,7 +120,7 @@ def parse_bes_modtime(string_datetime):
120
120
  # """custom HTTPAdapter for requests to override blocksize
121
121
  # for Uploading or Downloading large files"""
122
122
 
123
- # # override inti_poolmanager from regular HTTPAdapter
123
+ # # override init_poolmanager from regular HTTPAdapter
124
124
  # # https://stackoverflow.com/questions/22915295/python-requests-post-and-big-content/22915488#comment125583017_22915488
125
125
  # def init_poolmanager(self, connections, maxsize, block=False, **pool_kwargs):
126
126
  # """Initializes a urllib3 PoolManager.
@@ -152,6 +152,92 @@ def parse_bes_modtime(string_datetime):
152
152
  # )
153
153
 
154
154
 
155
+ def get_action_combined_relevance(relevances: typing.List[str]):
156
+ """take array of ordered relevance clauses and return relevance string for action"""
157
+
158
+ relevance_combined = ""
159
+
160
+ if not relevances:
161
+ return "False"
162
+ if len(relevances) == 0:
163
+ return "False"
164
+ if len(relevances) == 1:
165
+ return relevances[0]
166
+ if len(relevances) > 0:
167
+ for clause in relevances:
168
+ if len(relevance_combined) == 0:
169
+ relevance_combined = clause
170
+ else:
171
+ relevance_combined = (
172
+ "( " + relevance_combined + " ) AND ( " + clause + " )"
173
+ )
174
+
175
+ return relevance_combined
176
+
177
+
178
+ def get_target_xml(targets=None):
179
+ """get target xml based upon input
180
+
181
+ Input can be a single string:
182
+ - starts with "<AllComputers>" if all computers should be targeted
183
+ - Otherwise will be interpreted as custom relevance
184
+
185
+ Input can be a single int:
186
+ - Single Computer ID Target
187
+
188
+ Input can be an array:
189
+ - Array of Strings: ComputerName
190
+ - Array of Integers: ComputerID
191
+ """
192
+ if targets is None or not targets:
193
+ logging.warning("No valid targeting found, will target no computers.")
194
+ # default if invalid:
195
+ return "<CustomRelevance>False</CustomRelevance>"
196
+
197
+ # if targets is int:
198
+ if isinstance(targets, int):
199
+ if targets == 0:
200
+ raise ValueError(
201
+ "Int 0 is not valid Computer ID, set targets to an array of strings of computer names or an array of ints of computer ids or custom relevance string or <AllComputers>"
202
+ )
203
+ return f"<ComputerID>{targets}</ComputerID>"
204
+
205
+ # if targets is str:
206
+ if isinstance(targets, str):
207
+ # if targets string starts with "<AllComputers>":
208
+ if targets.startswith("<AllComputers>"):
209
+ if "false" in targets.lower():
210
+ # In my testing, <AllComputers>false</AllComputers> does not work correctly
211
+ return "<CustomRelevance>False</CustomRelevance>"
212
+ # return "<AllComputers>false</AllComputers>"
213
+ return "<AllComputers>true</AllComputers>"
214
+ # treat as custom relevance:
215
+ return f"<CustomRelevance><![CDATA[{targets}]]></CustomRelevance>"
216
+
217
+ # if targets is array:
218
+ if isinstance(targets, list):
219
+ element_type = type(targets[0])
220
+ if element_type is int:
221
+ # array of computer ids
222
+ return (
223
+ "<ComputerID>"
224
+ + "</ComputerID><ComputerID>".join(map(str, targets))
225
+ + "</ComputerID>"
226
+ )
227
+ if element_type is str:
228
+ # array of computer names
229
+ return (
230
+ "<ComputerName>"
231
+ + "</ComputerName><ComputerName>".join(targets)
232
+ + "</ComputerName>"
233
+ )
234
+
235
+ logging.warning("No valid targeting found, will target no computers.")
236
+
237
+ # default if invalid:
238
+ return "<CustomRelevance>False</CustomRelevance>"
239
+
240
+
155
241
  def validate_xsd(doc):
156
242
  """validate results using XML XSDs"""
157
243
  try:
@@ -257,7 +343,7 @@ class BESConnection:
257
343
  def __repr__(self):
258
344
  """object representation"""
259
345
  # https://stackoverflow.com/a/2626364/861745
260
- return f"Object: besapi.BESConnction( username={self.username}, rootserver={self.rootserver} )"
346
+ return f"Object: besapi.BESConnection( username={self.username}, rootserver={self.rootserver} )"
261
347
 
262
348
  def __eq__(self, other):
263
349
  if (
@@ -669,7 +755,7 @@ class BESConnection:
669
755
  file_url = str(result_upload.besobj.FileUpload.URL)
670
756
  if use_https:
671
757
  file_url = file_url.replace("http://", "https://")
672
- # there are 3 different posibilities for the server FQDN
758
+ # there are 3 different possibilities for the server FQDN
673
759
  # localhost
674
760
  # self.rootserver (without port number)
675
761
  # the returned value from the upload result
@@ -927,7 +1013,7 @@ class RESTResult:
927
1013
  f"\n - HTTP Response Status Code: `403` Forbidden\n - ERROR: `{self.text}`\n - URL: `{self.request.url}`"
928
1014
  )
929
1015
 
930
- besapi_logger.info(
1016
+ besapi_logger.debug(
931
1017
  "HTTP Request Status Code `%d` from URL `%s`",
932
1018
  self.request.status_code,
933
1019
  self.request.url,
@@ -58,7 +58,7 @@ def get_invoke_file_name(verbose=0):
58
58
  def setup_plugin_argparse(plugin_args_required=False):
59
59
  """setup argparse for plugin use"""
60
60
  arg_parser = argparse.ArgumentParser(
61
- description="Provde command line arguments for REST URL, username, and password"
61
+ description="Provide command line arguments for REST URL, username, and password"
62
62
  )
63
63
  arg_parser.add_argument(
64
64
  "-v",
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: besapi
3
- Version: 3.7.8
3
+ Version: 3.8.1
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
@@ -91,6 +91,37 @@ assert b"<BES>Example</BES>" in rest_result.xmlparse_text("<BES>Example</BES>")
91
91
 
92
92
  assert rest_result.text == "this is just a test"
93
93
 
94
+ # test date parsing function:
95
+ assert 2017 == besapi.besapi.parse_bes_modtime("Tue, 05 Sep 2017 23:31:48 +0000").year
96
+
97
+ # test action combined relevance
98
+ assert (
99
+ "( ( True ) AND ( windows of operating system ) ) AND ( False )"
100
+ == besapi.besapi.get_action_combined_relevance(
101
+ ["True", "windows of operating system", "False"]
102
+ )
103
+ )
104
+
105
+ # test target xml
106
+ assert "<CustomRelevance>False</CustomRelevance>" == besapi.besapi.get_target_xml()
107
+ assert "<AllComputers>true</AllComputers>" == besapi.besapi.get_target_xml(
108
+ "<AllComputers>"
109
+ )
110
+ assert "<ComputerID>1</ComputerID>" == besapi.besapi.get_target_xml(1)
111
+ assert (
112
+ "<CustomRelevance><![CDATA[not windows of operating system]]></CustomRelevance>"
113
+ == besapi.besapi.get_target_xml("not windows of operating system")
114
+ )
115
+ assert (
116
+ "<ComputerID>1</ComputerID><ComputerID>2</ComputerID>"
117
+ == besapi.besapi.get_target_xml([1, 2])
118
+ )
119
+ assert (
120
+ "<ComputerName>Computer 1</ComputerName><ComputerName>Another Computer</ComputerName>"
121
+ == besapi.besapi.get_target_xml(["Computer 1", "Another Computer"])
122
+ )
123
+
124
+ # test bescli:
94
125
  import bescli
95
126
 
96
127
  bigfix_cli = bescli.bescli.BESCLInterface()
@@ -151,8 +182,10 @@ if bigfix_cli.bes_conn:
151
182
  'CMD /C python -m besapi ls clear ls conf "query number of bes computers" version error_count exit',
152
183
  check=True,
153
184
  )
154
- bes_conn = besapi.besapi.get_bes_conn_using_config_file()
155
- print("login succeeded:", bes_conn.login())
185
+
186
+ bes_conn = besapi.besapi.get_bes_conn_using_config_file()
187
+ print("login succeeded:", bes_conn.login())
188
+ assert bes_conn.login()
156
189
 
157
190
  # test plugin_utilities:
158
191
  print(besapi.plugin_utilities.get_invoke_folder())
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
File without changes