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