cli2 4.2.5__tar.gz → 4.2.7__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 (56) hide show
  1. {cli2-4.2.5/cli2.egg-info → cli2-4.2.7}/PKG-INFO +1 -1
  2. {cli2-4.2.5 → cli2-4.2.7}/cli2/ansible/action.py +43 -4
  3. {cli2-4.2.5 → cli2-4.2.7/cli2.egg-info}/PKG-INFO +1 -1
  4. {cli2-4.2.5 → cli2-4.2.7}/setup.py +1 -1
  5. {cli2-4.2.5 → cli2-4.2.7}/tests/test_ansible.py +19 -0
  6. {cli2-4.2.5 → cli2-4.2.7}/MANIFEST.in +0 -0
  7. {cli2-4.2.5 → cli2-4.2.7}/README.rst +0 -0
  8. {cli2-4.2.5 → cli2-4.2.7}/classifiers.txt +0 -0
  9. {cli2-4.2.5 → cli2-4.2.7}/cli2/__init__.py +0 -0
  10. {cli2-4.2.5 → cli2-4.2.7}/cli2/ansible/__init__.py +0 -0
  11. {cli2-4.2.5 → cli2-4.2.7}/cli2/ansible/playbook.py +0 -0
  12. {cli2-4.2.5 → cli2-4.2.7}/cli2/ansible/variables.py +0 -0
  13. {cli2-4.2.5 → cli2-4.2.7}/cli2/asyncio.py +0 -0
  14. {cli2-4.2.5 → cli2-4.2.7}/cli2/cli.py +0 -0
  15. {cli2-4.2.5 → cli2-4.2.7}/cli2/cli2.py +0 -0
  16. {cli2-4.2.5 → cli2-4.2.7}/cli2/client.py +0 -0
  17. {cli2-4.2.5 → cli2-4.2.7}/cli2/colors.py +0 -0
  18. {cli2-4.2.5 → cli2-4.2.7}/cli2/configuration.py +0 -0
  19. {cli2-4.2.5 → cli2-4.2.7}/cli2/decorators.py +0 -0
  20. {cli2-4.2.5 → cli2-4.2.7}/cli2/display.py +0 -0
  21. {cli2-4.2.5 → cli2-4.2.7}/cli2/examples/__init__.py +0 -0
  22. {cli2-4.2.5 → cli2-4.2.7}/cli2/examples/client.py +0 -0
  23. {cli2-4.2.5 → cli2-4.2.7}/cli2/examples/conf.py +0 -0
  24. {cli2-4.2.5 → cli2-4.2.7}/cli2/examples/example.py +0 -0
  25. {cli2-4.2.5 → cli2-4.2.7}/cli2/examples/example_obj.py +0 -0
  26. {cli2-4.2.5 → cli2-4.2.7}/cli2/examples/nesting.py +0 -0
  27. {cli2-4.2.5 → cli2-4.2.7}/cli2/examples/obj.py +0 -0
  28. {cli2-4.2.5 → cli2-4.2.7}/cli2/examples/obj2.py +0 -0
  29. {cli2-4.2.5 → cli2-4.2.7}/cli2/examples/test.py +0 -0
  30. {cli2-4.2.5 → cli2-4.2.7}/cli2/lock.py +0 -0
  31. {cli2-4.2.5 → cli2-4.2.7}/cli2/log.py +0 -0
  32. {cli2-4.2.5 → cli2-4.2.7}/cli2/node.py +0 -0
  33. {cli2-4.2.5 → cli2-4.2.7}/cli2/sphinx.py +0 -0
  34. {cli2-4.2.5 → cli2-4.2.7}/cli2/table.py +0 -0
  35. {cli2-4.2.5 → cli2-4.2.7}/cli2/test.py +0 -0
  36. {cli2-4.2.5 → cli2-4.2.7}/cli2.egg-info/SOURCES.txt +0 -0
  37. {cli2-4.2.5 → cli2-4.2.7}/cli2.egg-info/dependency_links.txt +0 -0
  38. {cli2-4.2.5 → cli2-4.2.7}/cli2.egg-info/entry_points.txt +0 -0
  39. {cli2-4.2.5 → cli2-4.2.7}/cli2.egg-info/requires.txt +0 -0
  40. {cli2-4.2.5 → cli2-4.2.7}/cli2.egg-info/top_level.txt +0 -0
  41. {cli2-4.2.5 → cli2-4.2.7}/setup.cfg +0 -0
  42. {cli2-4.2.5 → cli2-4.2.7}/tests/test_ansible_variables.py +0 -0
  43. {cli2-4.2.5 → cli2-4.2.7}/tests/test_asyncio.py +0 -0
  44. {cli2-4.2.5 → cli2-4.2.7}/tests/test_cli.py +0 -0
  45. {cli2-4.2.5 → cli2-4.2.7}/tests/test_client.py +0 -0
  46. {cli2-4.2.5 → cli2-4.2.7}/tests/test_command.py +0 -0
  47. {cli2-4.2.5 → cli2-4.2.7}/tests/test_configuration.py +0 -0
  48. {cli2-4.2.5 → cli2-4.2.7}/tests/test_decorators.py +0 -0
  49. {cli2-4.2.5 → cli2-4.2.7}/tests/test_display.py +0 -0
  50. {cli2-4.2.5 → cli2-4.2.7}/tests/test_entry_point.py +0 -0
  51. {cli2-4.2.5 → cli2-4.2.7}/tests/test_group.py +0 -0
  52. {cli2-4.2.5 → cli2-4.2.7}/tests/test_inject.py +0 -0
  53. {cli2-4.2.5 → cli2-4.2.7}/tests/test_lock.py +0 -0
  54. {cli2-4.2.5 → cli2-4.2.7}/tests/test_node.py +0 -0
  55. {cli2-4.2.5 → cli2-4.2.7}/tests/test_restful.py +0 -0
  56. {cli2-4.2.5 → cli2-4.2.7}/tests/test_table.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.2
2
2
  Name: cli2
3
- Version: 4.2.5
3
+ Version: 4.2.7
4
4
  Summary: image:: https://yourlabs.io/oss/cli2/badges/master/pipeline.svg
5
5
  Home-page: https://yourlabs.io/oss/cli2
6
6
  Author: James Pic
@@ -9,6 +9,7 @@ import os
9
9
  import re
10
10
  import traceback
11
11
 
12
+ from ansible.parsing.yaml.objects import AnsibleUnicode
12
13
  from ansible.plugins.action import ActionBase
13
14
 
14
15
  # colors:
@@ -126,7 +127,15 @@ class ActionBase(ActionBase):
126
127
 
127
128
  The client object generated by :py:meth:`client_factory` if you
128
129
  implement it.
130
+
131
+ .. py:attribute:: mask
132
+
133
+ List of result keys to mask, if set, this module will print the result
134
+ with masked values, so you can set no_log: True for the task and still
135
+ see most of the result.
129
136
  """
137
+ mask = None
138
+
130
139
  def get(self, arg_name=None, fact_name=None, default=UNSET_DEFAULT):
131
140
  if arg_name and arg_name in self._task.args:
132
141
  return self._task.args[arg_name]
@@ -165,6 +174,9 @@ class ActionBase(ActionBase):
165
174
  except Exception as exc:
166
175
  self.result['failed'] = True
167
176
 
177
+ if self.verbosity:
178
+ traceback.print_exc()
179
+
168
180
  if isinstance(exc, AnsibleError):
169
181
  self.result['error'] = exc.message
170
182
  elif isinstance(exc, cli2.ResponseError):
@@ -179,12 +191,14 @@ class ActionBase(ActionBase):
179
191
  key, value = self.client.request_log_data(exc.request)
180
192
  if key:
181
193
  self.result[f'request_{key}'] = value
182
- elif self.verbosity:
183
- traceback.print_exc()
184
194
 
185
195
  # for pytest to raise
186
196
  self.exc = exc
187
197
  finally:
198
+ if self.mask and self.verbosity:
199
+ print('\nResult:')
200
+ cli2.print(self.masked_result())
201
+
188
202
  if (
189
203
  self._before_data != UNSET_DEFAULT
190
204
  and self._after_data != UNSET_DEFAULT
@@ -208,6 +222,31 @@ class ActionBase(ActionBase):
208
222
  else:
209
223
  cli2.diff(diff)
210
224
 
225
+ def native(self, data):
226
+ def _native(data):
227
+ for key, value in data.items():
228
+ if isinstance(value, AnsibleUnicode):
229
+ data[key] = str(value)
230
+ elif isinstance(value, dict):
231
+ data[key] = _native(value)
232
+ elif isinstance(value, list):
233
+ data[key] = [_native(item) for item in value]
234
+ return data
235
+ return _native(copy.deepcopy(data))
236
+
237
+ def masked_result(self):
238
+ def _mask(data):
239
+ if isinstance(data, dict):
240
+ for key, value in data.items():
241
+ if key in self.mask:
242
+ data[key] = '***MASKED***'
243
+ else:
244
+ data[key] = _mask(value)
245
+ elif isinstance(data, list):
246
+ return [_mask(item) for item in data]
247
+ return data
248
+ return _mask(self.native(self.result))
249
+
211
250
  async def run_async(self):
212
251
  """
213
252
  The method you are supposed to implement.
@@ -276,7 +315,7 @@ class ActionBase(ActionBase):
276
315
  :param data: Dictionnary of data
277
316
  :param label: Label to show in diff
278
317
  """
279
- self._before_data = copy.deepcopy(data)
318
+ self._before_data = self.native(data)
280
319
  self._before_label = label
281
320
 
282
321
  def after_set(self, data, label='after'):
@@ -286,5 +325,5 @@ class ActionBase(ActionBase):
286
325
  :param data: Dictionnary of data
287
326
  :param label: Label to show in diff
288
327
  """
289
- self._after_data = copy.deepcopy(data)
328
+ self._after_data = self.native(data)
290
329
  self._after_label = label
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.2
2
2
  Name: cli2
3
- Version: 4.2.5
3
+ Version: 4.2.7
4
4
  Summary: image:: https://yourlabs.io/oss/cli2/badges/master/pipeline.svg
5
5
  Home-page: https://yourlabs.io/oss/cli2
6
6
  Author: James Pic
@@ -44,7 +44,7 @@ from setuptools import setup
44
44
 
45
45
  setup(
46
46
  name='cli2',
47
- version='4.2.5',
47
+ version='4.2.7',
48
48
  setup_requires='setupmeta',
49
49
  packages=['cli2'],
50
50
  install_requires=[
@@ -8,6 +8,25 @@ import yaml
8
8
  from cli2 import ansible
9
9
 
10
10
 
11
+ class ActionModule(ansible.ActionBase):
12
+ mask = ['a']
13
+
14
+ async def run_async(self):
15
+ self.result['x'] = dict(a='a', b='b')
16
+
17
+
18
+ @pytest.mark.asyncio
19
+ async def test_mask(monkeypatch):
20
+ printer = mock.Mock()
21
+ from cli2.ansible import action
22
+ monkeypatch.setattr(action.cli2, 'print', printer)
23
+ module = await ActionModule.run_test_async()
24
+ assert module.result == dict(x=dict(a='a', b='b'))
25
+ printer.assert_called_once_with(
26
+ dict(x=dict(a='***MASKED***', b='b'))
27
+ )
28
+
29
+
11
30
  @pytest.mark.asyncio
12
31
  async def test_response_error(httpx_mock):
13
32
  class Client(cli2.Client):
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
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
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
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
File without changes
File without changes
File without changes
File without changes