"Fossies" - the Fresh Open Source Software Archive

Member "ansible-2.9.27/lib/ansible/modules/network/aci/aci_config_rollback.py" (11 Oct 2021, 9720 Bytes) of package /linux/misc/ansible-2.9.27.tar.gz:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) Python source code syntax highlighting (style: standard) with prefixed line numbers. Alternatively you can here view or download the uninterpreted source code file. For more information about "aci_config_rollback.py" see the Fossies "Dox" file reference documentation and the last Fossies "Diffs" side-by-side code changes report: 2.9.24_vs_4.3.0.

    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 
    6 from __future__ import absolute_import, division, print_function
    7 __metaclass__ = type
    8 
    9 ANSIBLE_METADATA = {'metadata_version': '1.1',
   10                     'status': ['preview'],
   11                     'supported_by': 'certified'}
   12 
   13 DOCUMENTATION = r'''
   14 ---
   15 module: aci_config_rollback
   16 short_description: Provides rollback and rollback preview functionality (config:ImportP)
   17 description:
   18 - Provides rollback and rollback preview functionality for Cisco ACI fabrics.
   19 - Config Rollbacks are done using snapshots C(aci_snapshot) with the configImportP class.
   20 version_added: '2.4'
   21 options:
   22   compare_export_policy:
   23     description:
   24     - The export policy that the C(compare_snapshot) is associated to.
   25     type: str
   26   compare_snapshot:
   27     description:
   28     - The name of the snapshot to compare with C(snapshot).
   29     type: str
   30   description:
   31     description:
   32     - The description for the Import Policy.
   33     type: str
   34     aliases: [ descr ]
   35   export_policy:
   36     description:
   37     - The export policy that the C(snapshot) is associated to.
   38     type: str
   39     required: yes
   40   fail_on_decrypt:
   41     description:
   42     - Determines if the APIC should fail the rollback if unable to decrypt secured data.
   43     - The APIC defaults to C(yes) when unset.
   44     type: bool
   45   import_mode:
   46     description:
   47     - Determines how the import should be handled by the APIC.
   48     - The APIC defaults to C(atomic) when unset.
   49     type: str
   50     choices: [ atomic, best-effort ]
   51   import_policy:
   52     description:
   53     - The name of the Import Policy to use for config rollback.
   54     type: str
   55   import_type:
   56     description:
   57     - Determines how the current and snapshot configuration should be compared for replacement.
   58     - The APIC defaults to C(replace) when unset.
   59     type: str
   60     choices: [ merge, replace ]
   61   snapshot:
   62     description:
   63     - The name of the snapshot to rollback to, or the base snapshot to use for comparison.
   64     - The C(aci_snapshot) module can be used to query the list of available snapshots.
   65     type: str
   66     required: yes
   67   state:
   68     description:
   69     - Use C(preview) for previewing the diff between two snapshots.
   70     - Use C(rollback) for reverting the configuration to a previous snapshot.
   71     type: str
   72     choices: [ preview, rollback ]
   73     default: rollback
   74 extends_documentation_fragment: aci
   75 seealso:
   76 - module: aci_config_snapshot
   77 - name: APIC Management Information Model reference
   78   description: More information about the internal APIC class B(config:ImportP).
   79   link: https://developer.cisco.com/docs/apic-mim-ref/
   80 author:
   81 - Jacob McGill (@jmcgill298)
   82 '''
   83 
   84 EXAMPLES = r'''
   85 ---
   86 - name: Create a Snapshot
   87   aci_config_snapshot:
   88     host: apic
   89     username: admin
   90     password: SomeSecretPassword
   91     export_policy: config_backup
   92     state: present
   93   delegate_to: localhost
   94 
   95 - name: Query Existing Snapshots
   96   aci_config_snapshot:
   97     host: apic
   98     username: admin
   99     password: SomeSecretPassword
  100     export_policy: config_backup
  101     state: query
  102   delegate_to: localhost
  103 
  104 - name: Compare Snapshot Files
  105   aci_config_rollback:
  106     host: apic
  107     username: admin
  108     password: SomeSecretPassword
  109     export_policy: config_backup
  110     snapshot: run-2017-08-28T06-24-01
  111     compare_export_policy: config_backup
  112     compare_snapshot: run-2017-08-27T23-43-56
  113     state: preview
  114   delegate_to: localhost
  115 
  116 - name: Rollback Configuration
  117   aci_config_rollback:
  118     host: apic
  119     username: admin
  120     password: SomeSecretPassword
  121     import_policy: rollback_config
  122     export_policy: config_backup
  123     snapshot: run-2017-08-28T06-24-01
  124     state: rollback
  125   delegate_to: localhost
  126 
  127 - name: Rollback Configuration
  128   aci_config_rollback:
  129     host: apic
  130     username: admin
  131     password: SomeSecretPassword
  132     import_policy: rollback_config
  133     export_policy: config_backup
  134     snapshot: run-2017-08-28T06-24-01
  135     description: Rollback 8-27 changes
  136     import_mode: atomic
  137     import_type: replace
  138     fail_on_decrypt: yes
  139     state: rollback
  140   delegate_to: localhost
  141 '''
  142 
  143 RETURN = r'''
  144 preview:
  145   description: A preview between two snapshots
  146   returned: when state is preview
  147   type: str
  148 error:
  149   description: The error information as returned from the APIC
  150   returned: failure
  151   type: dict
  152   sample:
  153     {
  154         "code": "122",
  155         "text": "unknown managed object class foo"
  156     }
  157 raw:
  158   description: The raw output returned by the APIC REST API (xml or json)
  159   returned: parse error
  160   type: str
  161   sample: '<?xml version="1.0" encoding="UTF-8"?><imdata totalCount="1"><error code="122" text="unknown managed object class foo"/></imdata>'
  162 filter_string:
  163   description: The filter string used for the request
  164   returned: failure or debug
  165   type: str
  166   sample: ?rsp-prop-include=config-only
  167 method:
  168   description: The HTTP method used for the request to the APIC
  169   returned: failure or debug
  170   type: str
  171   sample: POST
  172 response:
  173   description: The HTTP response from the APIC
  174   returned: failure or debug
  175   type: str
  176   sample: OK (30 bytes)
  177 status:
  178   description: The HTTP status from the APIC
  179   returned: failure or debug
  180   type: int
  181   sample: 200
  182 url:
  183   description: The HTTP url used for the request to the APIC
  184   returned: failure or debug
  185   type: str
  186   sample: https://10.11.12.13/api/mo/uni/tn-production.json
  187 '''
  188 
  189 from ansible.module_utils.network.aci.aci import ACIModule, aci_argument_spec
  190 from ansible.module_utils.basic import AnsibleModule
  191 from ansible.module_utils._text import to_bytes
  192 from ansible.module_utils.urls import fetch_url
  193 
  194 # Optional, only used for rollback preview
  195 try:
  196     import lxml.etree
  197     from xmljson import cobra
  198     XML_TO_JSON = True
  199 except ImportError:
  200     XML_TO_JSON = False
  201 
  202 
  203 def main():
  204     argument_spec = aci_argument_spec()
  205     argument_spec.update(
  206         compare_export_policy=dict(type='str'),
  207         compare_snapshot=dict(type='str'),
  208         description=dict(type='str', aliases=['descr']),
  209         export_policy=dict(type='str'),
  210         fail_on_decrypt=dict(type='bool'),
  211         import_mode=dict(type='str', choices=['atomic', 'best-effort']),
  212         import_policy=dict(type='str'),
  213         import_type=dict(type='str', choices=['merge', 'replace']),
  214         snapshot=dict(type='str', required=True),
  215         state=dict(type='str', default='rollback', choices=['preview', 'rollback']),
  216     )
  217 
  218     module = AnsibleModule(
  219         argument_spec=argument_spec,
  220         supports_check_mode=False,
  221         required_if=[
  222             ['state', 'preview', ['compare_export_policy', 'compare_snapshot']],
  223             ['state', 'rollback', ['import_policy']],
  224         ],
  225     )
  226 
  227     aci = ACIModule(module)
  228 
  229     description = module.params['description']
  230     export_policy = module.params['export_policy']
  231     fail_on_decrypt = aci.boolean(module.params['fail_on_decrypt'])
  232     import_mode = module.params['import_mode']
  233     import_policy = module.params['import_policy']
  234     import_type = module.params['import_type']
  235     snapshot = module.params['snapshot']
  236     state = module.params['state']
  237 
  238     if state == 'rollback':
  239         if snapshot.startswith('run-'):
  240             snapshot = snapshot.replace('run-', '', 1)
  241 
  242         if not snapshot.endswith('.tar.gz'):
  243             snapshot += '.tar.gz'
  244 
  245         filename = 'ce2_{0}-{1}'.format(export_policy, snapshot)
  246 
  247         aci.construct_url(
  248             root_class=dict(
  249                 aci_class='configImportP',
  250                 aci_rn='fabric/configimp-{0}'.format(import_policy),
  251                 module_object=import_policy,
  252                 target_filter={'name': import_policy},
  253             ),
  254         )
  255 
  256         aci.get_existing()
  257 
  258         aci.payload(
  259             aci_class='configImportP',
  260             class_config=dict(
  261                 adminSt='triggered',
  262                 descr=description,
  263                 failOnDecryptErrors=fail_on_decrypt,
  264                 fileName=filename,
  265                 importMode=import_mode,
  266                 importType=import_type,
  267                 name=import_policy,
  268                 snapshot='yes',
  269             ),
  270         )
  271 
  272         aci.get_diff(aci_class='configImportP')
  273 
  274         aci.post_config()
  275 
  276     elif state == 'preview':
  277         aci.url = '%(protocol)s://%(host)s/mqapi2/snapshots.diff.xml' % module.params
  278         aci.filter_string = (
  279             '?s1dn=uni/backupst/snapshots-[uni/fabric/configexp-%(export_policy)s]/snapshot-%(snapshot)s&'
  280             's2dn=uni/backupst/snapshots-[uni/fabric/configexp-%(compare_export_policy)s]/snapshot-%(compare_snapshot)s'
  281         ) % module.params
  282 
  283         # Generate rollback comparison
  284         get_preview(aci)
  285 
  286     aci.exit_json()
  287 
  288 
  289 def get_preview(aci):
  290     '''
  291     This function is used to generate a preview between two snapshots and add the parsed results to the aci module return data.
  292     '''
  293     uri = aci.url + aci.filter_string
  294     resp, info = fetch_url(aci.module, uri, headers=aci.headers, method='GET', timeout=aci.module.params['timeout'], use_proxy=aci.module.params['use_proxy'])
  295     aci.method = 'GET'
  296     aci.response = info['msg']
  297     aci.status = info['status']
  298 
  299     # Handle APIC response
  300     if info['status'] == 200:
  301         xml_to_json(aci, resp.read())
  302     else:
  303         aci.result['raw'] = resp.read()
  304         aci.fail_json(msg="Request failed: %(code)s %(text)s (see 'raw' output)" % aci.error)
  305 
  306 
  307 def xml_to_json(aci, response_data):
  308     '''
  309     This function is used to convert preview XML data into JSON.
  310     '''
  311     if XML_TO_JSON:
  312         xml = lxml.etree.fromstring(to_bytes(response_data))
  313         xmldata = cobra.data(xml)
  314         aci.result['preview'] = xmldata
  315     else:
  316         aci.result['preview'] = response_data
  317 
  318 
  319 if __name__ == "__main__":
  320     main()