1#!/usr/bin/python
2# -*- coding: utf-8 -*-
3
4# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
5
6from __future__ import absolute_import, division, print_function
7__metaclass__ = type
8
9ANSIBLE_METADATA = {'metadata_version': '1.1',
10                    'status': ['preview'],
11                    'supported_by': 'certified'}
12
13DOCUMENTATION = r'''
14---
15module: aci_l3out_route_tag_policy
16short_description: Manage route tag policies (l3ext:RouteTagPol)
17description:
18- Manage route tag policies on Cisco ACI fabrics.
19version_added: '2.4'
20options:
21  rtp:
22    description:
23    - The name of the route tag policy.
24    type: str
25    required: yes
26    aliases: [ name, rtp_name ]
27  description:
28    description:
29    - The description for the route tag policy.
30    type: str
31    aliases: [ descr ]
32  tenant:
33    description:
34    - The name of the tenant.
35    type: str
36    required: yes
37    aliases: [ tenant_name ]
38  tag:
39    description:
40    - The value of the route tag.
41    - Accepted values range between C(0) and C(4294967295).
42    - The APIC defaults to C(4294967295) when unset during creation.
43    type: int
44  state:
45    description:
46    - Use C(present) or C(absent) for adding or removing.
47    - Use C(query) for listing an object or multiple objects.
48    type: str
49    choices: [ absent, present, query ]
50    default: present
51extends_documentation_fragment: aci
52notes:
53- The C(tenant) used must exist before using this module in your playbook.
54  The M(aci_tenant) module can be used for this.
55seealso:
56- module: aci_tenant
57- name: APIC Management Information Model reference
58  description: More information about the internal APIC class B(l3ext:RouteTagPol).
59  link: https://developer.cisco.com/docs/apic-mim-ref/
60author:
61- Dag Wieers (@dagwieers)
62'''
63
64# FIXME: Add more, better examples
65EXAMPLES = r'''
66- aci_l3out_route_tag_policy:
67    host: apic
68    username: admin
69    password: SomeSecretPassword
70    rtp: '{{ rtp_name }}'
71    tenant: production
72    tag: '{{ tag }}'
73    description: '{{ description }}'
74  delegate_to: localhost
75'''
76
77RETURN = r'''
78current:
79  description: The existing configuration from the APIC after the module has finished
80  returned: success
81  type: list
82  sample:
83    [
84        {
85            "fvTenant": {
86                "attributes": {
87                    "descr": "Production environment",
88                    "dn": "uni/tn-production",
89                    "name": "production",
90                    "nameAlias": "",
91                    "ownerKey": "",
92                    "ownerTag": ""
93                }
94            }
95        }
96    ]
97error:
98  description: The error information as returned from the APIC
99  returned: failure
100  type: dict
101  sample:
102    {
103        "code": "122",
104        "text": "unknown managed object class foo"
105    }
106raw:
107  description: The raw output returned by the APIC REST API (xml or json)
108  returned: parse error
109  type: str
110  sample: '<?xml version="1.0" encoding="UTF-8"?><imdata totalCount="1"><error code="122" text="unknown managed object class foo"/></imdata>'
111sent:
112  description: The actual/minimal configuration pushed to the APIC
113  returned: info
114  type: list
115  sample:
116    {
117        "fvTenant": {
118            "attributes": {
119                "descr": "Production environment"
120            }
121        }
122    }
123previous:
124  description: The original configuration from the APIC before the module has started
125  returned: info
126  type: list
127  sample:
128    [
129        {
130            "fvTenant": {
131                "attributes": {
132                    "descr": "Production",
133                    "dn": "uni/tn-production",
134                    "name": "production",
135                    "nameAlias": "",
136                    "ownerKey": "",
137                    "ownerTag": ""
138                }
139            }
140        }
141    ]
142proposed:
143  description: The assembled configuration from the user-provided parameters
144  returned: info
145  type: dict
146  sample:
147    {
148        "fvTenant": {
149            "attributes": {
150                "descr": "Production environment",
151                "name": "production"
152            }
153        }
154    }
155filter_string:
156  description: The filter string used for the request
157  returned: failure or debug
158  type: str
159  sample: ?rsp-prop-include=config-only
160method:
161  description: The HTTP method used for the request to the APIC
162  returned: failure or debug
163  type: str
164  sample: POST
165response:
166  description: The HTTP response from the APIC
167  returned: failure or debug
168  type: str
169  sample: OK (30 bytes)
170status:
171  description: The HTTP status from the APIC
172  returned: failure or debug
173  type: int
174  sample: 200
175url:
176  description: The HTTP url used for the request to the APIC
177  returned: failure or debug
178  type: str
179  sample: https://10.11.12.13/api/mo/uni/tn-production.json
180'''
181
182from ansible.module_utils.basic import AnsibleModule
183from ansible.module_utils.network.aci.aci import ACIModule, aci_argument_spec
184
185
186def main():
187    argument_spec = aci_argument_spec()
188    argument_spec.update(
189        tenant=dict(type='str', aliases=['tenant_name']),  # Not required for querying all objects
190        rtp=dict(type='str', aliases=['name', 'rtp_name']),  # Not required for querying all objects
191        description=dict(type='str', aliases=['descr']),
192        tag=dict(type='int'),
193        state=dict(type='str', default='present', choices=['absent', 'present', 'query']),
194    )
195
196    module = AnsibleModule(
197        argument_spec=argument_spec,
198        supports_check_mode=True,
199        required_if=[
200            ['state', 'absent', ['rtp', 'tenant']],
201            ['state', 'present', ['rtp', 'tenant']],
202        ],
203    )
204
205    rtp = module.params['rtp']
206    description = module.params['description']
207    tag = module.params['tag']
208    state = module.params['state']
209    tenant = module.params['tenant']
210
211    aci = ACIModule(module)
212    aci.construct_url(
213        root_class=dict(
214            aci_class='fvTenant',
215            aci_rn='tn-{0}'.format(tenant),
216            module_object=tenant,
217            target_filter={'name': tenant},
218        ),
219        subclass_1=dict(
220            aci_class='l3extRouteTagPol',
221            aci_rn='rttag-{0}'.format(rtp),
222            module_object=rtp,
223            target_filter={'name': rtp},
224        ),
225    )
226
227    aci.get_existing()
228
229    if state == 'present':
230        aci.payload(
231            aci_class='l3extRouteTagPol',
232            class_config=dict(
233                name=rtp,
234                descr=description, tag=tag,
235            ),
236        )
237
238        aci.get_diff(aci_class='l3extRouteTagPol')
239
240        aci.post_config()
241
242    elif state == 'absent':
243        aci.delete_config()
244
245    aci.exit_json()
246
247
248if __name__ == "__main__":
249    main()
250