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