1#!/usr/local/bin/python3.8 2# -*- coding: utf-8 -*- 3 4# Copyright: (c) 2018, Dag Wieers (@dagwieers) <dag@wieers.com> 5# GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt) 6 7from __future__ import absolute_import, division, print_function 8__metaclass__ = type 9 10ANSIBLE_METADATA = {'metadata_version': '1.1', 11 'status': ['preview'], 12 'supported_by': 'community'} 13 14DOCUMENTATION = r''' 15--- 16module: mso_schema_template_anp 17short_description: Manage Application Network Profiles (ANPs) in schema templates 18description: 19- Manage ANPs in schema templates on Cisco ACI Multi-Site. 20author: 21- Dag Wieers (@dagwieers) 22options: 23 schema: 24 description: 25 - The name of the schema. 26 type: str 27 required: yes 28 template: 29 description: 30 - The name of the template. 31 type: str 32 required: yes 33 anp: 34 description: 35 - The name of the ANP to manage. 36 type: str 37 aliases: [ name ] 38 display_name: 39 description: 40 - The name as displayed on the MSO web interface. 41 type: str 42 state: 43 description: 44 - Use C(present) or C(absent) for adding or removing. 45 - Use C(query) for listing an object or multiple objects. 46 type: str 47 choices: [ absent, present, query ] 48 default: present 49seealso: 50- module: cisco.mso.mso_schema_template 51- module: cisco.mso.mso_schema_template_anp_epg 52extends_documentation_fragment: cisco.mso.modules 53''' 54 55EXAMPLES = r''' 56- name: Add a new ANP 57 cisco.mso.mso_schema_template_anp: 58 host: mso_host 59 username: admin 60 password: SomeSecretPassword 61 schema: Schema 1 62 template: Template 1 63 anp: ANP 1 64 state: present 65 delegate_to: localhost 66 67- name: Remove an ANP 68 cisco.mso.mso_schema_template_anp: 69 host: mso_host 70 username: admin 71 password: SomeSecretPassword 72 schema: Schema 1 73 template: Template 1 74 anp: ANP 1 75 state: absent 76 delegate_to: localhost 77 78- name: Query a specific ANPs 79 cisco.mso.mso_schema_template_anp: 80 host: mso_host 81 username: admin 82 password: SomeSecretPassword 83 schema: Schema 1 84 template: Template 1 85 state: query 86 delegate_to: localhost 87 register: query_result 88 89- name: Query all ANPs 90 cisco.mso.mso_schema_template_anp: 91 host: mso_host 92 username: admin 93 password: SomeSecretPassword 94 schema: Schema 1 95 template: Template 1 96 state: query 97 delegate_to: localhost 98 register: query_result 99''' 100 101RETURN = r''' 102''' 103 104from ansible.module_utils.basic import AnsibleModule 105from ansible_collections.cisco.mso.plugins.module_utils.mso import MSOModule, mso_argument_spec 106 107 108def main(): 109 argument_spec = mso_argument_spec() 110 argument_spec.update( 111 schema=dict(type='str', required=True), 112 template=dict(type='str', required=True), 113 anp=dict(type='str', aliases=['name']), # This parameter is not required for querying all objects 114 display_name=dict(type='str'), 115 state=dict(type='str', default='present', choices=['absent', 'present', 'query']), 116 ) 117 118 module = AnsibleModule( 119 argument_spec=argument_spec, 120 supports_check_mode=True, 121 required_if=[ 122 ['state', 'absent', ['anp']], 123 ['state', 'present', ['anp']], 124 ], 125 ) 126 127 schema = module.params.get('schema') 128 template = module.params.get('template').replace(' ', '') 129 anp = module.params.get('anp') 130 display_name = module.params.get('display_name') 131 state = module.params.get('state') 132 133 mso = MSOModule(module) 134 135 # Get schema 136 schema_id, schema_path, schema_obj = mso.query_schema(schema) 137 138 # Get template 139 templates = [t.get('name') for t in schema_obj.get('templates')] 140 if template not in templates: 141 mso.fail_json(msg="Provided template '{0}' does not exist. Existing templates: {1}".format(template, ', '.join(templates))) 142 template_idx = templates.index(template) 143 144 # Get ANP 145 anps = [a.get('name') for a in schema_obj.get('templates')[template_idx]['anps']] 146 147 if anp is not None and anp in anps: 148 anp_idx = anps.index(anp) 149 mso.existing = schema_obj.get('templates')[template_idx]['anps'][anp_idx] 150 151 if state == 'query': 152 if anp is None: 153 mso.existing = schema_obj.get('templates')[template_idx]['anps'] 154 elif not mso.existing: 155 mso.fail_json(msg="ANP '{anp}' not found".format(anp=anp)) 156 mso.exit_json() 157 158 anps_path = '/templates/{0}/anps'.format(template) 159 anp_path = '/templates/{0}/anps/{1}'.format(template, anp) 160 ops = [] 161 162 mso.previous = mso.existing 163 if state == 'absent': 164 if mso.existing: 165 mso.sent = mso.existing = {} 166 ops.append(dict(op='remove', path=anp_path)) 167 168 elif state == 'present': 169 170 if display_name is None and not mso.existing: 171 display_name = anp 172 173 epgs = [] 174 if mso.existing: 175 epgs = None 176 177 payload = dict( 178 name=anp, 179 displayName=display_name, 180 epgs=epgs, 181 ) 182 183 mso.sanitize(payload, collate=True) 184 185 if mso.existing: 186 if display_name is not None: 187 ops.append(dict(op='replace', path=anp_path + '/displayName', value=display_name)) 188 else: 189 ops.append(dict(op='add', path=anps_path + '/-', value=mso.sent)) 190 191 mso.existing = mso.proposed 192 193 if 'anpRef' in mso.previous: 194 del mso.previous['anpRef'] 195 196 if not module.check_mode: 197 mso.request(schema_path, method='PATCH', data=ops) 198 199 mso.exit_json() 200 201 202if __name__ == "__main__": 203 main() 204