1#!/usr/bin/python 2# -*- coding: utf-8 -*- 3 4# Copyright: (c) 2019, Dag Wieers (@dagwieers) <dag@wieers.com> 5# GNU General Public License v3.0+ (see COPYING 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_site_vrf_region 17short_description: Manage site-local VRF regions in schema template 18description: 19- Manage site-local VRF regions in schema template on Cisco ACI Multi-Site. 20author: 21- Dag Wieers (@dagwieers) 22version_added: '2.8' 23options: 24 schema: 25 description: 26 - The name of the schema. 27 type: str 28 required: yes 29 site: 30 description: 31 - The name of the site. 32 type: str 33 required: yes 34 template: 35 description: 36 - The name of the template. 37 type: str 38 required: yes 39 vrf: 40 description: 41 - The name of the VRF. 42 type: str 43 region: 44 description: 45 - The name of the region to manage. 46 type: str 47 aliases: [ name ] 48 state: 49 description: 50 - Use C(present) or C(absent) for adding or removing. 51 - Use C(query) for listing an object or multiple objects. 52 type: str 53 choices: [ absent, present, query ] 54 default: present 55seealso: 56- module: mso_schema_site_vrf 57- module: mso_schema_template_vrf 58extends_documentation_fragment: mso 59''' 60 61EXAMPLES = r''' 62- name: Add a new site VRF region 63 mso_schema_template_vrf_region: 64 host: mso_host 65 username: admin 66 password: SomeSecretPassword 67 schema: Schema1 68 site: Site1 69 template: Template1 70 vrf: VRF1 71 region: us-west-1 72 state: present 73 delegate_to: localhost 74 75- name: Remove a site VRF region 76 mso_schema_template_vrf_region: 77 host: mso_host 78 username: admin 79 password: SomeSecretPassword 80 schema: Schema1 81 site: Site1 82 template: Template1 83 vrf: VRF1 84 region: us-west-1 85 state: absent 86 delegate_to: localhost 87 88- name: Query a specific site VRF region 89 mso_schema_template_vrf_region: 90 host: mso_host 91 username: admin 92 password: SomeSecretPassword 93 schema: Schema1 94 site: Site1 95 template: Template1 96 vrf: VRF1 97 region: us-west-1 98 state: query 99 delegate_to: localhost 100 register: query_result 101 102- name: Query all site VRF regions 103 mso_schema_template_vrf_region: 104 host: mso_host 105 username: admin 106 password: SomeSecretPassword 107 schema: Schema1 108 site: Site1 109 template: Template1 110 vrf: VRF1 111 state: query 112 delegate_to: localhost 113 register: query_result 114''' 115 116RETURN = r''' 117''' 118 119from ansible.module_utils.basic import AnsibleModule 120from ansible.module_utils.network.aci.mso import MSOModule, mso_argument_spec 121 122 123def main(): 124 argument_spec = mso_argument_spec() 125 argument_spec.update( 126 schema=dict(type='str', required=True), 127 site=dict(type='str', required=True), 128 template=dict(type='str', required=True), 129 vrf=dict(type='str', required=True), 130 region=dict(type='str', aliases=['name']), # This parameter is not required for querying all objects 131 state=dict(type='str', default='present', choices=['absent', 'present', 'query']), 132 ) 133 134 module = AnsibleModule( 135 argument_spec=argument_spec, 136 supports_check_mode=True, 137 required_if=[ 138 ['state', 'absent', ['region']], 139 ['state', 'present', ['region']], 140 ], 141 ) 142 143 schema = module.params['schema'] 144 site = module.params['site'] 145 template = module.params['template'] 146 vrf = module.params['vrf'] 147 region = module.params['region'] 148 state = module.params['state'] 149 150 mso = MSOModule(module) 151 152 # Get schema_id 153 schema_obj = mso.get_obj('schemas', displayName=schema) 154 if not schema_obj: 155 mso.fail_json(msg="Provided schema '{0}' does not exist".format(schema)) 156 157 schema_path = 'schemas/{id}'.format(**schema_obj) 158 schema_id = schema_obj['id'] 159 160 # Get site 161 site_id = mso.lookup_site(site) 162 163 # Get site_idx 164 sites = [(s['siteId'], s['templateName']) for s in schema_obj['sites']] 165 if (site_id, template) not in sites: 166 mso.fail_json(msg="Provided site/template '{0}-{1}' does not exist. Existing sites/templates: {2}".format(site, template, ', '.join(sites))) 167 168 # Schema-access uses indexes 169 site_idx = sites.index((site_id, template)) 170 # Path-based access uses site_id-template 171 site_template = '{0}-{1}'.format(site_id, template) 172 173 # Get VRF 174 vrf_ref = mso.vrf_ref(schema_id=schema_id, template=template, vrf=vrf) 175 vrfs = [v['vrfRef'] for v in schema_obj['sites'][site_idx]['vrfs']] 176 if vrf_ref not in vrfs: 177 mso.fail_json(msg="Provided vrf '{0}' does not exist. Existing vrfs: {1}".format(vrf, ', '.join(vrfs))) 178 vrf_idx = vrfs.index(vrf_ref) 179 180 # Get Region 181 regions = [r['name'] for r in schema_obj['sites'][site_idx]['vrfs'][vrf_idx]['regions']] 182 if region is not None and region in regions: 183 region_idx = regions.index(region) 184 region_path = '/sites/{0}/vrfs/{1}/regions/{2}'.format(site_template, vrf, region) 185 mso.existing = schema_obj['sites'][site_idx]['vrfs'][vrf_idx]['regions'][region_idx] 186 187 if state == 'query': 188 if region is None: 189 mso.existing = schema_obj['sites'][site_idx]['vrfs'][vrf_idx]['regions'] 190 elif not mso.existing: 191 mso.fail_json(msg="Region '{region}' not found".format(region=region)) 192 mso.exit_json() 193 194 regions_path = '/sites/{0}/vrfs/{1}/regions'.format(site_template, vrf) 195 ops = [] 196 197 mso.previous = mso.existing 198 if state == 'absent': 199 if mso.existing: 200 mso.sent = mso.existing = {} 201 ops.append(dict(op='remove', path=region_path)) 202 203 elif state == 'present': 204 205 payload = dict( 206 name=region, 207 ) 208 209 mso.sanitize(payload, collate=True) 210 211 if mso.existing: 212 ops.append(dict(op='replace', path=region_path, value=mso.sent)) 213 else: 214 ops.append(dict(op='add', path=regions_path + '/-', value=mso.sent)) 215 216 mso.existing = mso.proposed 217 218 if not module.check_mode: 219 mso.request(schema_path, method='PATCH', data=ops) 220 221 mso.exit_json() 222 223 224if __name__ == "__main__": 225 main() 226