Skip to content

Commit 1a81138

Browse files
authored
Merge pull request #307 from CiscoDevNet/dcnm_image_policy_v2
dcnm_image_policy v2: Ready for review
2 parents 9dc2ed0 + 148893f commit 1a81138

File tree

51 files changed

+7095
-5642
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

51 files changed

+7095
-5642
lines changed
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
all:
2+
vars:
3+
ansible_user: "admin"
4+
ansible_password: "password-secret"
5+
ansible_python_interpreter: python
6+
ansible_httpapi_validate_certs: False
7+
ansible_httpapi_use_ssl: True
8+
children:
9+
dcnm:
10+
vars:
11+
ansible_connection: ansible.netcommon.httpapi
12+
ansible_network_os: cisco.dcnm.dcnm
13+
hosts:
14+
dcnm-instance.example.com:
15+
nxos:
16+
hosts:
17+
n9k-hosta.example.com:
18+
ansible_connection: ansible.netcommon.network_cli
19+
ansible_network_os: cisco.nxos.nxos
20+
ansible_ssh_port: 22
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
---
2+
# This playbook can be used to execute integration tests for
3+
# the role located in:
4+
#
5+
# tests/integration/targets/dcnm_image_policy
6+
#
7+
# Modify the hosts and vars sections with details for your testing
8+
# setup and uncomment the testcase you want to run.
9+
#
10+
- hosts: dcnm
11+
gather_facts: no
12+
connection: ansible.netcommon.httpapi
13+
14+
vars:
15+
# testcase: dcnm_image_policy_deleted
16+
# testcase: dcnm_image_policy_merged
17+
# testcase: dcnm_image_policy_overridden
18+
# testcase: dcnm_image_policy_query
19+
# testcase: dcnm_image_policy_replaced
20+
switch_username: admin
21+
switch_password: "foobar"
22+
spine1: 192.168.1.2
23+
spine2: 192.168.1.3
24+
leaf1: 192.168.1.4
25+
leaf2: 192.168.1.5
26+
leaf3: 192.168.1.6
27+
leaf4: 192.168.1.7
28+
image_policy_1: "KR5M"
29+
image_policy_2: "NR3F"
30+
epld_image_1: n9000-epld.10.2.5.M.img
31+
epld_image_2: n9000-epld.10.3.1.F.img
32+
nxos_image_1: n9000-dk9.10.2.5.M.bin
33+
nxos_image_2: n9000-dk9.10.3.1.F.bin
34+
nxos_release_1: 10.2.5_nxos64-cs_64bit
35+
nxos_release_2: 10.3.1_nxos64-cs_64bit
36+
37+
roles:
38+
- dcnm_image_policy

plugins/module_utils/common/api/v1/imagemanagement/rest/policymgnt/policymgnt.py

Lines changed: 89 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -223,6 +223,50 @@ def verb(self):
223223
return "POST"
224224

225225

226+
class EpPolicyDelete(PolicyMgnt):
227+
"""
228+
## V1 API - PolicyMgnt().EpPolicyDelete()
229+
230+
### Description
231+
Delete image policies.
232+
233+
### Raises
234+
- None
235+
236+
### Path
237+
- ``/rest/policymgnt/policy``
238+
239+
### Verb
240+
- DELETE
241+
242+
### Notes
243+
Expects a JSON payload as shown below, where ``policyNames`` is a
244+
comma-separated list of policy names.
245+
246+
```json
247+
{
248+
"policyNames": "policyA,policyB,etc"
249+
}
250+
```
251+
"""
252+
253+
def __init__(self):
254+
super().__init__()
255+
self.class_name = self.__class__.__name__
256+
self.log = logging.getLogger(f"dcnm.{self.class_name}")
257+
msg = "ENTERED api.v1.imagemanagement.rest."
258+
msg += f"policymgnt.{self.class_name}"
259+
self.log.debug(msg)
260+
261+
@property
262+
def path(self):
263+
return f"{self.policymgnt}/policy"
264+
265+
@property
266+
def verb(self):
267+
return "DELETE"
268+
269+
226270
class EpPolicyDetach(PolicyMgnt):
227271
"""
228272
## V1 API - PolicyMgnt().EpPolicyDetach()
@@ -268,6 +312,51 @@ def verb(self):
268312
return "DELETE"
269313

270314

315+
class EpPolicyEdit(PolicyMgnt):
316+
"""
317+
## V1 API - PolicyMgnt().EpPolicyEdit()
318+
319+
### Description
320+
Return endpoint information.
321+
322+
### Raises
323+
- None
324+
325+
### Path
326+
- ``/rest/policymgnt/edit-policy``
327+
328+
### Verb
329+
- POST
330+
331+
### Parameters
332+
- path: retrieve the path for the endpoint
333+
- verb: retrieve the verb for the endpoint
334+
335+
### Usage
336+
```python
337+
instance = EpPolicyEdit()
338+
path = instance.path
339+
verb = instance.verb
340+
```
341+
"""
342+
343+
def __init__(self):
344+
super().__init__()
345+
self.class_name = self.__class__.__name__
346+
self.log = logging.getLogger(f"dcnm.{self.class_name}")
347+
msg = "ENTERED api.v1.imagemanagement.rest."
348+
msg += f"policymgnt.{self.class_name}"
349+
self.log.debug(msg)
350+
351+
@property
352+
def path(self):
353+
return f"{self.policymgnt}/edit-policy"
354+
355+
@property
356+
def verb(self):
357+
return "POST"
358+
359+
271360
class EpPolicyInfo(PolicyMgnt):
272361
"""
273362
## V1 API - PolicyMgnt().EpPolicyInfo()

plugins/module_utils/common/properties.py

Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,64 @@ class Properties:
3737
- ``rest_send``: Set and return nn instance of the ``RestSend`` class.
3838
- ``results``: Set and return an instance of the ``Results`` class.
3939
"""
40+
@property
41+
def params(self):
42+
"""
43+
### Summary
44+
Expects value to be a dictionary containing, at mimimum, the keys
45+
``state`` and ``check_mode``.
46+
47+
### Raises
48+
- setter: ``ValueError`` if value is not a dict.
49+
- setter: ``ValueError`` if value["state"] is missing.
50+
- setter: ``ValueError`` if value["state"] is not a valid state.
51+
- setter: ``ValueError`` if value["check_mode"] is missing.
52+
53+
### Valid values
54+
55+
#### ``state``
56+
- deleted
57+
- merged
58+
- overridden
59+
- query
60+
- replaced
61+
62+
#### ``check_mode``
63+
- ``False`` - The Ansible module should make requested changes.
64+
- ``True`` - The Ansible module should not make requested changed
65+
and should only report what changes it would make if ``check_mode``
66+
was ``False``.
67+
68+
### Details
69+
- Example Valid params:
70+
- ``{"state": "deleted", "check_mode": False}``
71+
- ``{"state": "merged", "check_mode": False}``
72+
- ``{"state": "overridden", "check_mode": False}``
73+
- ``{"state": "query", "check_mode": False}``
74+
- ``{"state": "replaced", "check_mode": False}``
75+
- getter: return the params
76+
- setter: set the params
77+
"""
78+
return self._params
79+
80+
@params.setter
81+
def params(self, value):
82+
method_name = inspect.stack()[0][3]
83+
if not isinstance(value, dict):
84+
msg = f"{self.class_name}.{method_name}: "
85+
msg += "params must be a dictionary. "
86+
msg += f"got {type(value).__name__} for "
87+
msg += f"value {value}"
88+
raise TypeError(msg)
89+
if value.get("state", None) is None:
90+
msg = f"{self.class_name}.{method_name}: "
91+
msg += "params.state is required but missing."
92+
raise ValueError(msg)
93+
if value.get("check_mode", None) is None:
94+
msg = f"{self.class_name}.{method_name}: "
95+
msg += "params.check_mode is required but missing."
96+
raise ValueError(msg)
97+
self._params = value
4098

4199
@property
42100
def rest_send(self):
@@ -106,6 +164,14 @@ def results(self, value):
106164
raise TypeError(msg)
107165
self._results = value
108166

167+
def add_params(self):
168+
"""
169+
### Summary
170+
Class decorator method to set the ``params`` property.
171+
"""
172+
self.params = Properties.params
173+
return self
174+
109175
def add_rest_send(self):
110176
"""
111177
### Summary

0 commit comments

Comments
 (0)