1+ #!/usr/bin/python
2+ # -*- coding: utf-8 -*-
3+
4+ # Copyright: (c) 2023, Gaspard Micol (@gmicol) <gmicol@cisco.com>
5+ # GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt)
6+
7+ from __future__ import absolute_import , division , print_function
8+
9+ __metaclass__ = type
10+
11+ ANSIBLE_METADATA = {"metadata_version" : "1.1" , "status" : ["preview" ], "supported_by" : "certified" }
12+
13+ DOCUMENTATION = r"""
14+ ---
15+ module: aci_route_control_profile
16+ short_description: Manage Context Policy (rtcrtl:CtxP)
17+ description:
18+ - Manage Context Policies for the Route Control Profiles on Cisco ACI fabrics.
19+ options:
20+ tenant:
21+ description:
22+ - The name of an existing tenant.
23+ type: str
24+ aliases: [ tenant_name ]
25+ l3out:
26+ description:
27+ - Name of an existing L3Out.
28+ type: str
29+ aliases: [ l3out_name ]
30+ route_control_profile:
31+ description:
32+ - Name of an existing route control profile.
33+ type: str
34+ aliases: [ rtctrl_profile_name ]
35+ context_policy:
36+ description:
37+ - Name of the context profile being created.
38+ type: str
39+ aliases: [ name, context_name ]
40+ action:
41+ description:
42+ - The action required when the condition is met.
43+ type: str
44+ choices: [ deny, permit ]
45+ order:
46+ description:
47+ - The order of the policy context.
48+ - The value range from 0 to 9.
49+ type: int
50+ description:
51+ description:
52+ - The description for the context policy.
53+ type: str
54+ aliases: [ descr ]
55+ state:
56+ description:
57+ - Use C(present) or C(absent) for adding or removing.
58+ - Use C(query) for listing an object or multiple objects.
59+ type: str
60+ choices: [ absent, present, query ]
61+ default: present
62+ name_alias:
63+ description:
64+ - The alias for the current object. This relates to the nameAlias field in ACI.
65+ type: str
66+ extends_documentation_fragment:
67+ - cisco.aci.aci
68+ - cisco.aci.annotation
69+ - cisco.aci.owner
70+
71+ notes:
72+ - The C(tenant) used must exist before using this module in your playbook.
73+ The M(cisco.aci.aci_tenant) module can be used for this.
74+ seealso:
75+ - module: cisco.aci.aci_tenant
76+ - name: APIC Management Information Model reference
77+ description: More information about the internal APIC class B(rtctrl:CtxP).
78+ link: https://developer.cisco.com/docs/apic-mim-ref/
79+ author:
80+ - Gaspard Micol (@gmicol)
81+ """
82+
83+ EXAMPLES = r"""
84+ """
85+
86+ RETURN = r"""
87+ current:
88+ description: The existing configuration from the APIC after the module has finished
89+ returned: success
90+ type: list
91+ sample:
92+ [
93+ {
94+ "fvTenant": {
95+ "attributes": {
96+ "descr": "Production environment",
97+ "dn": "uni/tn-production",
98+ "name": "production",
99+ "nameAlias": "",
100+ "ownerKey": "",
101+ "ownerauto_continue": ""
102+ }
103+ }
104+ }
105+ ]
106+ error:
107+ description: The error information as returned from the APIC
108+ returned: failure
109+ type: dict
110+ sample:
111+ {
112+ "code": "122",
113+ "text": "unknown managed object class foo"
114+ }
115+ raw:
116+ description: The raw output returned by the APIC REST API (xml or json)
117+ returned: parse error
118+ type: str
119+ sample: '<?xml version="1.0" encoding="UTF-8"?><imdata totalCount="1"><error code="122" text="unknown managed object class foo"/></imdata>'
120+ sent:
121+ description: The actual/minimal configuration pushed to the APIC
122+ returned: info
123+ type: list
124+ sample:
125+ {
126+ "fvTenant": {
127+ "attributes": {
128+ "descr": "Production environment"
129+ }
130+ }
131+ }
132+ previous:
133+ description: The original configuration from the APIC before the module has started
134+ returned: info
135+ type: list
136+ sample:
137+ [
138+ {
139+ "fvTenant": {
140+ "attributes": {
141+ "descr": "Production",
142+ "dn": "uni/tn-production",
143+ "name": "production",
144+ "nameAlias": "",
145+ "ownerKey": "",
146+ "ownerauto_continue": ""
147+ }
148+ }
149+ }
150+ ]
151+ proposed:
152+ description: The assembled configuration from the user-provided parameters
153+ returned: info
154+ type: dict
155+ sample:
156+ {
157+ "fvTenant": {
158+ "attributes": {
159+ "descr": "Production environment",
160+ "name": "production"
161+ }
162+ }
163+ }
164+ filter_string:
165+ description: The filter string used for the request
166+ returned: failure or debug
167+ type: str
168+ sample: ?rsp-prop-include=config-only
169+ method:
170+ description: The HTTP method used for the request to the APIC
171+ returned: failure or debug
172+ type: str
173+ sample: POST
174+ response:
175+ description: The HTTP response from the APIC
176+ returned: failure or debug
177+ type: str
178+ sample: OK (30 bytes)
179+ status:
180+ description: The HTTP status from the APIC
181+ returned: failure or debug
182+ type: int
183+ sample: 200
184+ url:
185+ description: The HTTP url used for the request to the APIC
186+ returned: failure or debug
187+ type: str
188+ sample: https://10.11.12.13/api/mo/uni/tn-production.json
189+ """
190+
191+ from ansible .module_utils .basic import AnsibleModule
192+ from ansible_collections .cisco .aci .plugins .module_utils .aci import ACIModule , aci_argument_spec , aci_annotation_spec , aci_owner_spec
193+
194+
195+ def main ():
196+ argument_spec = aci_argument_spec ()
197+ argument_spec .update (aci_annotation_spec ())
198+ argument_spec .update (aci_owner_spec ())
199+ argument_spec .update (
200+ tenant = dict (type = "str" , aliases = ["tenant_name" ]), # Not required for querying all objects
201+ l3out = dict (type = "str" , aliases = ["l3out_name" ]), # Not required for querying all objects
202+ route_control_profile = dict (type = "str" , aliases = ["rtctrl_profile_name" ]), # Not required for querying all objects
203+ context_policy = dict (type = "str" , aliases = ["name" , "context_name" ]), # Not required for querying all objects
204+ action = dict (type = "str" , choices = ["deny" , "permit" ]),
205+ order = dict (type = "int" ),
206+ description = dict (type = "str" , aliases = ["descr" ]),
207+ name_alias = dict (type = "str" ),
208+ state = dict (type = "str" , default = "present" , choices = ["present" , "absent" , "query" ]),
209+ )
210+
211+ module = AnsibleModule (
212+ argument_spec = argument_spec ,
213+ supports_check_mode = True ,
214+ required_if = [
215+ ["state" , "absent" , ["context_policy" , "tenant" ]],
216+ ["state" , "present" , ["context_policy" , "tenant" ]],
217+ ],
218+ )
219+
220+ context_policy = module .params .get ("context_policy" )
221+ description = module .params .get ("description" )
222+ action = module .params .get ("action" )
223+ order = module .params .get ("order" )
224+ state = module .params .get ("state" )
225+ tenant = module .params .get ("tenant" )
226+ l3out = module .params .get ("l3out" )
227+ route_control_profile = module .params .get ("route_control_profile" )
228+ name_alias = module .params .get ("name_alias" )
229+
230+ aci = ACIModule (module )
231+
232+ tenant_url_config = dict (
233+ aci_class = "fvTenant" ,
234+ aci_rn = "tn-{0}" .format (tenant ),
235+ module_object = tenant ,
236+ target_filter = {"name" : tenant },
237+ )
238+
239+ route_control_profile_url_config = dict (
240+ aci_class = "rtctrlProfile" ,
241+ aci_rn = "prof-{0}" .format (route_control_profile ),
242+ module_object = route_control_profile ,
243+ target_filter = {"name" : route_control_profile },
244+ )
245+
246+ context_policy_url_config = dict (
247+ aci_class = "rtctrlCtxP" ,
248+ aci_rn = "ctx-{0}" .format (context_policy ),
249+ module_object = context_policy ,
250+ target_filter = {"name" : context_policy },
251+ )
252+
253+ if l3out is not None :
254+ aci .construct_url (
255+ root_class = tenant_url_config ,
256+ subclass_1 = dict (
257+ aci_class = "l3extOut" ,
258+ aci_rn = "out-{0}" .format (l3out ),
259+ module_object = l3out ,
260+ target_filter = {"name" : l3out },
261+ ),
262+ subclass_2 = route_control_profile_url_config ,
263+ subclass_3 = context_policy_url_config ,
264+ )
265+ else :
266+ aci .construct_url (
267+ root_class = tenant_url_config ,
268+ subclass_1 = route_control_profile_url_config ,
269+ subclass_2 = context_policy_url_config ,
270+ )
271+
272+ aci .get_existing ()
273+
274+ if state == "present" :
275+ aci .payload (
276+ aci_class = "rtctrlCtxP" ,
277+ class_config = dict (
278+ name = route_control_profile ,
279+ descr = description ,
280+ action = action ,
281+ order = order ,
282+ nameAlias = name_alias ,
283+ ),
284+ )
285+
286+ aci .get_diff (aci_class = "rtctrlCtxP" )
287+
288+ aci .post_config ()
289+
290+ elif state == "absent" :
291+ aci .delete_config ()
292+
293+ aci .exit_json ()
294+
295+
296+ if __name__ == "__main__" :
297+ main ()
0 commit comments