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