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 route control profiles (rtcrtl:Profile)
17+ description:
18+ - Manage route auto_continue policies 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 the route control profile being created.
33+ type: str
34+ aliases: [ name, rtctrl_profile_name ]
35+ description:
36+ description:
37+ - The description for the route control profile.
38+ type: str
39+ aliases: [ descr ]
40+ state:
41+ description:
42+ - Use C(present) or C(absent) for adding or removing.
43+ - Use C(query) for listing an object or multiple objects.
44+ type: str
45+ choices: [ absent, present, query ]
46+ default: present
47+ name_alias:
48+ description:
49+ - The alias for the current object. This relates to the nameAlias field in ACI.
50+ type: str
51+ extends_documentation_fragment:
52+ - cisco.aci.aci
53+ - cisco.aci.annotation
54+ - cisco.aci.owner
55+
56+ notes:
57+ - The C(tenant) used must exist before using this module in your playbook.
58+ The M(cisco.aci.aci_tenant) module can be used for this.
59+ seealso:
60+ - module: cisco.aci.aci_tenant
61+ - name: APIC Management Information Model reference
62+ description: More information about the internal APIC class B(rtctrl:Profile).
63+ link: https://developer.cisco.com/docs/apic-mim-ref/
64+ author:
65+ - Gaspard Micol (@gmicol)
66+ """
67+
68+ EXAMPLES = r"""
69+ """
70+
71+ RETURN = r"""
72+ current:
73+ description: The existing configuration from the APIC after the module has finished
74+ returned: success
75+ type: list
76+ sample:
77+ [
78+ {
79+ "fvTenant": {
80+ "attributes": {
81+ "descr": "Production environment",
82+ "dn": "uni/tn-production",
83+ "name": "production",
84+ "nameAlias": "",
85+ "ownerKey": "",
86+ "ownerauto_continue": ""
87+ }
88+ }
89+ }
90+ ]
91+ error:
92+ description: The error information as returned from the APIC
93+ returned: failure
94+ type: dict
95+ sample:
96+ {
97+ "code": "122",
98+ "text": "unknown managed object class foo"
99+ }
100+ raw:
101+ description: The raw output returned by the APIC REST API (xml or json)
102+ returned: parse error
103+ type: str
104+ sample: '<?xml version="1.0" encoding="UTF-8"?><imdata totalCount="1"><error code="122" text="unknown managed object class foo"/></imdata>'
105+ sent:
106+ description: The actual/minimal configuration pushed to the APIC
107+ returned: info
108+ type: list
109+ sample:
110+ {
111+ "fvTenant": {
112+ "attributes": {
113+ "descr": "Production environment"
114+ }
115+ }
116+ }
117+ previous:
118+ description: The original configuration from the APIC before the module has started
119+ returned: info
120+ type: list
121+ sample:
122+ [
123+ {
124+ "fvTenant": {
125+ "attributes": {
126+ "descr": "Production",
127+ "dn": "uni/tn-production",
128+ "name": "production",
129+ "nameAlias": "",
130+ "ownerKey": "",
131+ "ownerauto_continue": ""
132+ }
133+ }
134+ }
135+ ]
136+ proposed:
137+ description: The assembled configuration from the user-provided parameters
138+ returned: info
139+ type: dict
140+ sample:
141+ {
142+ "fvTenant": {
143+ "attributes": {
144+ "descr": "Production environment",
145+ "name": "production"
146+ }
147+ }
148+ }
149+ filter_string:
150+ description: The filter string used for the request
151+ returned: failure or debug
152+ type: str
153+ sample: ?rsp-prop-include=config-only
154+ method:
155+ description: The HTTP method used for the request to the APIC
156+ returned: failure or debug
157+ type: str
158+ sample: POST
159+ response:
160+ description: The HTTP response from the APIC
161+ returned: failure or debug
162+ type: str
163+ sample: OK (30 bytes)
164+ status:
165+ description: The HTTP status from the APIC
166+ returned: failure or debug
167+ type: int
168+ sample: 200
169+ url:
170+ description: The HTTP url used for the request to the APIC
171+ returned: failure or debug
172+ type: str
173+ sample: https://10.11.12.13/api/mo/uni/tn-production.json
174+ """
175+
176+ from ansible .module_utils .basic import AnsibleModule
177+ from ansible_collections .cisco .aci .plugins .module_utils .aci import ACIModule , aci_argument_spec , aci_annotation_spec , aci_owner_spec
178+
179+
180+ def main ():
181+ argument_spec = aci_argument_spec ()
182+ argument_spec .update (aci_annotation_spec ())
183+ argument_spec .update (aci_owner_spec ())
184+ argument_spec .update (
185+ tenant = dict (type = "str" , aliases = ["tenant_name" ]), # Not required for querying all objects
186+ l3out = dict (type = "str" , aliases = ["l3out_name" ]), # Not required for querying all objects
187+ route_control_profile = dict (type = "str" , aliases = ["name" , "rtctrl_profile_name" ]), # Not required for querying all objects
188+ description = dict (type = "str" , aliases = ["descr" ]),
189+ auto_continue = dict (type = "str" , default = "no" , choices = ["no" , "yes" ]),
190+ policy_type = dict (type = "str" , default = "combinable" , choices = ["combinable" , "global" ]),
191+ name_alias = dict (type = "str" ),
192+ )
193+
194+ module = AnsibleModule (
195+ argument_spec = argument_spec ,
196+ supports_check_mode = True ,
197+ required_if = [
198+ ["state" , "absent" , ["route_control_profile" , "tenant" ]],
199+ ["state" , "present" , ["route_control_profile" , "tenant" ]],
200+ ],
201+ )
202+
203+ route_control_profile = module .params .get ("route_control_profile" )
204+ description = module .params .get ("description" )
205+ auto_continue = module .params .get ("auto_continue" )
206+ policy_type = module .params .get ("policy_type" )
207+ state = module .params .get ("state" )
208+ tenant = module .params .get ("tenant" )
209+ l3out = module .params .get ("l3out" )
210+ name_alias = module .params .get ("name_alias" )
211+
212+ aci = ACIModule (module )
213+
214+ if l3out is not None :
215+ aci .construct_url (
216+ root_class = dict (
217+ aci_class = "fvTenant" ,
218+ aci_rn = "tn-{0}" .format (tenant ),
219+ module_object = tenant ,
220+ target_filter = {"name" : tenant },
221+ ),
222+ subclass_1 = dict (
223+ aci_class = "l3extOut" ,
224+ aci_rn = "out-{0}" .format (l3out ),
225+ module_object = l3out ,
226+ target_filter = {"name" : l3out },
227+ ),
228+ subclass_2 = dict (
229+ aci_class = "rtcrtlProfile" ,
230+ aci_rn = "prof-{0}" .format (route_control_profile ),
231+ module_object = route_control_profile ,
232+ target_filter = {"name" : route_control_profile },
233+ ),
234+ )
235+ else :
236+ aci .construct_url (
237+ root_class = dict (
238+ aci_class = "fvTenant" ,
239+ aci_rn = "tn-{0}" .format (tenant ),
240+ module_object = tenant ,
241+ target_filter = {"name" : tenant },
242+ ),
243+ subclass_1 = dict (
244+ aci_class = "rtcrtlProfile" ,
245+ aci_rn = "prof-{0}" .format (route_control_profile ),
246+ module_object = route_control_profile ,
247+ target_filter = {"name" : route_control_profile },
248+ ),
249+ )
250+
251+ aci .get_existing ()
252+
253+ if state == "present" :
254+ aci .payload (
255+ aci_class = "rtctrlProfile" ,
256+ class_config = dict (
257+ name = route_control_profile ,
258+ descr = description ,
259+ autoContinue = auto_continue ,
260+ type = policy_type ,
261+ nameAlias = name_alias ,
262+ ),
263+ )
264+
265+ aci .get_diff (aci_class = "rtctrlProfile" )
266+
267+ aci .post_config ()
268+
269+ elif state == "absent" :
270+ aci .delete_config ()
271+
272+ aci .exit_json ()
273+
274+
275+ if __name__ == "__main__" :
276+ main ()
0 commit comments