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