示例#1
0
def main():
    module = AnsibleModule(
        supports_check_mode=True,
        argument_spec=dict(
            url=dict(type='str', required=True),
            api_key=dict(type='str', required=True, no_log=True),
            text=dict(type='str', required=True),
            channel=dict(type='str', default=None),
            username=dict(type='str', default='Ansible'),
            icon_url=dict(type='str',
                          default='https://www.ansible.com/favicon.ico'),
            validate_certs=dict(default='yes', type='bool'),
        ))
    # init return dict
    result = dict(changed=False, msg="OK")

    # define webhook
    webhook_url = "{0}/hooks/{1}".format(module.params['url'],
                                         module.params['api_key'])
    result['webhook_url'] = webhook_url

    # define payload
    payload = {}
    for param in ['text', 'channel', 'username', 'icon_url']:
        if module.params[param] is not None:
            payload[param] = module.params[param]

    payload = module.jsonify(payload)
    result['payload'] = payload

    # http headers
    headers = {
        'Content-Type': 'application/json',
        'Accept': 'application/json',
    }

    # notes:
    # Nothing is done in check mode
    # it'll pass even if your server is down or/and if your token is invalid.
    # If someone find good way to check...

    # send request if not in test mode
    if module.check_mode is False:
        response, info = fetch_url(module=module,
                                   url=webhook_url,
                                   headers=headers,
                                   method='POST',
                                   data=payload)

        # something's wrong
        if info['status'] != 200:
            # some problem
            result[
                'msg'] = "Failed to send mattermost message, the error was: {0}".format(
                    info['msg'])
            module.fail_json(**result)

    # Looks good
    module.exit_json(**result)
示例#2
0
class NitroAPICaller(object):

    _argument_spec = dict(
        nsip=dict(
            fallback=(env_fallback, ['NETSCALER_NSIP']),
        ),
        nitro_user=dict(
            fallback=(env_fallback, ['NETSCALER_NITRO_USER']),
        ),
        nitro_pass=dict(
            fallback=(env_fallback, ['NETSCALER_NITRO_PASS']),
            no_log=True
        ),
        nitro_protocol=dict(
            choices=['http', 'https'],
            fallback=(env_fallback, ['NETSCALER_NITRO_PROTOCOL']),
            default='http'
        ),
        validate_certs=dict(
            default=True,
            type='bool'
        ),
        nitro_auth_token=dict(
            type='str',
            no_log=True
        ),
        resource=dict(type='str'),
        name=dict(type='str'),
        attributes=dict(type='dict'),

        args=dict(type='dict'),
        filter=dict(type='dict'),

        operation=dict(
            type='str',
            required=True,
            choices=[
                'add',
                'update',
                'get',
                'get_by_args',
                'get_filtered',
                'get_all',
                'delete',
                'delete_by_args',
                'count',

                'mas_login',

                # Actions
                'save_config',

                # Generic action handler
                'action',
            ]
        ),
        expected_nitro_errorcode=dict(
            type='list',
            default=[0],
        ),
        action=dict(type='str'),
        instance_ip=dict(type='str'),
        instance_name=dict(type='str'),
        instance_id=dict(type='str'),
    )

    def __init__(self):

        self._module = AnsibleModule(
            argument_spec=self._argument_spec,
            supports_check_mode=False,
        )

        self._module_result = dict(
            failed=False,
        )

        # Prepare the http headers according to module arguments
        self._headers = {}
        self._headers['Content-Type'] = 'application/json'

        # Check for conflicting authentication methods
        have_token = self._module.params['nitro_auth_token'] is not None
        have_userpass = None not in (self._module.params['nitro_user'], self._module.params['nitro_pass'])
        login_operation = self._module.params['operation'] == 'mas_login'

        if have_token and have_userpass:
            self.fail_module(msg='Cannot define both authentication token and username/password')

        if have_token:
            self._headers['Cookie'] = "NITRO_AUTH_TOKEN=%s" % self._module.params['nitro_auth_token']

        if have_userpass and not login_operation:
            self._headers['X-NITRO-USER'] = self._module.params['nitro_user']
            self._headers['X-NITRO-PASS'] = self._module.params['nitro_pass']

        # Do header manipulation when doing a MAS proxy call
        if self._module.params['instance_ip'] is not None:
            self._headers['_MPS_API_PROXY_MANAGED_INSTANCE_IP'] = self._module.params['instance_ip']
        elif self._module.params['instance_name'] is not None:
            self._headers['_MPS_API_PROXY_MANAGED_INSTANCE_NAME'] = self._module.params['instance_name']
        elif self._module.params['instance_id'] is not None:
            self._headers['_MPS_API_PROXY_MANAGED_INSTANCE_ID'] = self._module.params['instance_id']

    def edit_response_data(self, r, info, result, success_status):
        # Search for body in both http body and http data
        if r is not None:
            result['http_response_body'] = codecs.decode(r.read(), 'utf-8')
        elif 'body' in info:
            result['http_response_body'] = codecs.decode(info['body'], 'utf-8')
            del info['body']
        else:
            result['http_response_body'] = ''

        result['http_response_data'] = info

        # Update the nitro_* parameters according to expected success_status
        # Use explicit return values from http response or deduce from http status code

        # Nitro return code in http data
        result['nitro_errorcode'] = None
        result['nitro_message'] = None
        result['nitro_severity'] = None

        if result['http_response_body'] != '':
            try:
                data = self._module.from_json(result['http_response_body'])
            except ValueError:
                data = {}
            result['nitro_errorcode'] = data.get('errorcode')
            result['nitro_message'] = data.get('message')
            result['nitro_severity'] = data.get('severity')

        # If we do not have the nitro errorcode from body deduce it from the http status
        if result['nitro_errorcode'] is None:
            # HTTP status failed
            if result['http_response_data'].get('status') != success_status:
                result['nitro_errorcode'] = -1
                result['nitro_message'] = result['http_response_data'].get('msg', 'HTTP status %s' % result['http_response_data']['status'])
                result['nitro_severity'] = 'ERROR'
            # HTTP status succeeded
            else:
                result['nitro_errorcode'] = 0
                result['nitro_message'] = 'Success'
                result['nitro_severity'] = 'NONE'

    def handle_get_return_object(self, result):
        result['nitro_object'] = []
        if result['nitro_errorcode'] == 0:
            if result['http_response_body'] != '':
                data = self._module.from_json(result['http_response_body'])
                if self._module.params['resource'] in data:
                    result['nitro_object'] = data[self._module.params['resource']]
        else:
            del result['nitro_object']

    def fail_module(self, msg, **kwargs):
        self._module_result['failed'] = True
        self._module_result['changed'] = False
        self._module_result.update(kwargs)
        self._module_result['msg'] = msg
        self._module.fail_json(**self._module_result)

    def main(self):
        if self._module.params['operation'] == 'add':
            result = self.add()

        if self._module.params['operation'] == 'update':
            result = self.update()

        if self._module.params['operation'] == 'delete':
            result = self.delete()

        if self._module.params['operation'] == 'delete_by_args':
            result = self.delete_by_args()

        if self._module.params['operation'] == 'get':
            result = self.get()

        if self._module.params['operation'] == 'get_by_args':
            result = self.get_by_args()

        if self._module.params['operation'] == 'get_filtered':
            result = self.get_filtered()

        if self._module.params['operation'] == 'get_all':
            result = self.get_all()

        if self._module.params['operation'] == 'count':
            result = self.count()

        if self._module.params['operation'] == 'mas_login':
            result = self.mas_login()

        if self._module.params['operation'] == 'action':
            result = self.action()

        if self._module.params['operation'] == 'save_config':
            result = self.save_config()

        if result['nitro_errorcode'] not in self._module.params['expected_nitro_errorcode']:
            self.fail_module(msg='NITRO Failure', **result)

        self._module_result.update(result)
        self._module.exit_json(**self._module_result)

    def exit_module(self):
        self._module.exit_json()

    def add(self):
        # Check if required attributes are present
        if self._module.params['resource'] is None:
            self.fail_module(msg='NITRO resource is undefined.')
        if self._module.params['attributes'] is None:
            self.fail_module(msg='NITRO resource attributes are undefined.')

        url = '%s://%s/nitro/v1/config/%s' % (
            self._module.params['nitro_protocol'],
            self._module.params['nsip'],
            self._module.params['resource'],
        )

        data = self._module.jsonify({self._module.params['resource']: self._module.params['attributes']})

        r, info = fetch_url(
            self._module,
            url=url,
            headers=self._headers,
            data=data,
            method='POST',
        )

        result = {}

        self.edit_response_data(r, info, result, success_status=201)

        if result['nitro_errorcode'] == 0:
            self._module_result['changed'] = True
        else:
            self._module_result['changed'] = False

        return result

    def update(self):
        # Check if required attributes are arguments present
        if self._module.params['resource'] is None:
            self.fail_module(msg='NITRO resource is undefined.')
        if self._module.params['name'] is None:
            self.fail_module(msg='NITRO resource name is undefined.')

        if self._module.params['attributes'] is None:
            self.fail_module(msg='NITRO resource attributes are undefined.')

        url = '%s://%s/nitro/v1/config/%s/%s' % (
            self._module.params['nitro_protocol'],
            self._module.params['nsip'],
            self._module.params['resource'],
            self._module.params['name'],
        )

        data = self._module.jsonify({self._module.params['resource']: self._module.params['attributes']})

        r, info = fetch_url(
            self._module,
            url=url,
            headers=self._headers,
            data=data,
            method='PUT',
        )

        result = {}
        self.edit_response_data(r, info, result, success_status=200)

        if result['nitro_errorcode'] == 0:
            self._module_result['changed'] = True
        else:
            self._module_result['changed'] = False

        return result

    def get(self):
        if self._module.params['resource'] is None:
            self.fail_module(msg='NITRO resource is undefined.')
        if self._module.params['name'] is None:
            self.fail_module(msg='NITRO resource name is undefined.')

        url = '%s://%s/nitro/v1/config/%s/%s' % (
            self._module.params['nitro_protocol'],
            self._module.params['nsip'],
            self._module.params['resource'],
            self._module.params['name'],
        )

        r, info = fetch_url(
            self._module,
            url=url,
            headers=self._headers,
            method='GET',
        )

        result = {}
        self.edit_response_data(r, info, result, success_status=200)

        self.handle_get_return_object(result)
        self._module_result['changed'] = False

        return result

    def get_by_args(self):
        if self._module.params['resource'] is None:
            self.fail_module(msg='NITRO resource is undefined.')

        if self._module.params['args'] is None:
            self.fail_module(msg='NITRO args is undefined.')

        url = '%s://%s/nitro/v1/config/%s' % (
            self._module.params['nitro_protocol'],
            self._module.params['nsip'],
            self._module.params['resource'],
        )

        args_dict = self._module.params['args']
        args = ','.join(['%s:%s' % (k, args_dict[k]) for k in args_dict])

        args = 'args=' + args

        url = '?'.join([url, args])

        r, info = fetch_url(
            self._module,
            url=url,
            headers=self._headers,
            method='GET',
        )
        result = {}
        self.edit_response_data(r, info, result, success_status=200)

        self.handle_get_return_object(result)
        self._module_result['changed'] = False

        return result

    def get_filtered(self):
        if self._module.params['resource'] is None:
            self.fail_module(msg='NITRO resource is undefined.')

        if self._module.params['filter'] is None:
            self.fail_module(msg='NITRO filter is undefined.')

        keys = list(self._module.params['filter'].keys())
        filter_key = keys[0]
        filter_value = self._module.params['filter'][filter_key]
        filter_str = '%s:%s' % (filter_key, filter_value)

        url = '%s://%s/nitro/v1/config/%s?filter=%s' % (
            self._module.params['nitro_protocol'],
            self._module.params['nsip'],
            self._module.params['resource'],
            filter_str,
        )

        r, info = fetch_url(
            self._module,
            url=url,
            headers=self._headers,
            method='GET',
        )

        result = {}
        self.edit_response_data(r, info, result, success_status=200)
        self.handle_get_return_object(result)
        self._module_result['changed'] = False

        return result

    def get_all(self):
        if self._module.params['resource'] is None:
            self.fail_module(msg='NITRO resource is undefined.')

        url = '%s://%s/nitro/v1/config/%s' % (
            self._module.params['nitro_protocol'],
            self._module.params['nsip'],
            self._module.params['resource'],
        )

        print('headers %s' % self._headers)
        r, info = fetch_url(
            self._module,
            url=url,
            headers=self._headers,
            method='GET',
        )

        result = {}
        self.edit_response_data(r, info, result, success_status=200)
        self.handle_get_return_object(result)
        self._module_result['changed'] = False

        return result

    def delete(self):
        if self._module.params['resource'] is None:
            self.fail_module(msg='NITRO resource is undefined.')

        if self._module.params['name'] is None:
            self.fail_module(msg='NITRO resource is undefined.')

        # Deletion by name takes precedence over deletion by attributes

        url = '%s://%s/nitro/v1/config/%s/%s' % (
            self._module.params['nitro_protocol'],
            self._module.params['nsip'],
            self._module.params['resource'],
            self._module.params['name'],
        )

        r, info = fetch_url(
            self._module,
            url=url,
            headers=self._headers,
            method='DELETE',
        )

        result = {}
        self.edit_response_data(r, info, result, success_status=200)

        if result['nitro_errorcode'] == 0:
            self._module_result['changed'] = True
        else:
            self._module_result['changed'] = False

        return result

    def delete_by_args(self):
        if self._module.params['resource'] is None:
            self.fail_module(msg='NITRO resource is undefined.')

        if self._module.params['args'] is None:
            self.fail_module(msg='NITRO args is undefined.')

        url = '%s://%s/nitro/v1/config/%s' % (
            self._module.params['nitro_protocol'],
            self._module.params['nsip'],
            self._module.params['resource'],
        )

        args_dict = self._module.params['args']
        args = ','.join(['%s:%s' % (k, args_dict[k]) for k in args_dict])

        args = 'args=' + args

        url = '?'.join([url, args])
        r, info = fetch_url(
            self._module,
            url=url,
            headers=self._headers,
            method='DELETE',
        )
        result = {}
        self.edit_response_data(r, info, result, success_status=200)

        if result['nitro_errorcode'] == 0:
            self._module_result['changed'] = True
        else:
            self._module_result['changed'] = False

        return result

    def count(self):
        if self._module.params['resource'] is None:
            self.fail_module(msg='NITRO resource is undefined.')

        url = '%s://%s/nitro/v1/config/%s?count=yes' % (
            self._module.params['nitro_protocol'],
            self._module.params['nsip'],
            self._module.params['resource'],
        )

        r, info = fetch_url(
            self._module,
            url=url,
            headers=self._headers,
            method='GET',
        )

        result = {}
        self.edit_response_data(r, info, result)

        if result['http_response_body'] != '':
            data = self._module.from_json(result['http_response_body'])

            result['nitro_errorcode'] = data['errorcode']
            result['nitro_message'] = data['message']
            result['nitro_severity'] = data['severity']
            if self._module.params['resource'] in data:
                result['nitro_count'] = data[self._module.params['resource']][0]['__count']

        self._module_result['changed'] = False

        return result

    def action(self):
        # Check if required attributes are present
        if self._module.params['resource'] is None:
            self.fail_module(msg='NITRO resource is undefined.')
        if self._module.params['attributes'] is None:
            self.fail_module(msg='NITRO resource attributes are undefined.')
        if self._module.params['action'] is None:
            self.fail_module(msg='NITRO action is undefined.')

        url = '%s://%s/nitro/v1/config/%s?action=%s' % (
            self._module.params['nitro_protocol'],
            self._module.params['nsip'],
            self._module.params['resource'],
            self._module.params['action'],
        )

        data = self._module.jsonify({self._module.params['resource']: self._module.params['attributes']})

        r, info = fetch_url(
            self._module,
            url=url,
            headers=self._headers,
            data=data,
            method='POST',
        )

        result = {}

        self.edit_response_data(r, info, result, success_status=200)

        if result['nitro_errorcode'] == 0:
            self._module_result['changed'] = True
        else:
            self._module_result['changed'] = False

        return result

    def mas_login(self):
        url = '%s://%s/nitro/v1/config/login' % (
            self._module.params['nitro_protocol'],
            self._module.params['nsip'],
        )

        login_credentials = {
            'login': {

                'username': self._module.params['nitro_user'],
                'password': self._module.params['nitro_pass'],
            }
        }

        data = 'object=\n%s' % self._module.jsonify(login_credentials)

        r, info = fetch_url(
            self._module,
            url=url,
            headers=self._headers,
            data=data,
            method='POST',
        )
        print(r, info)

        result = {}
        self.edit_response_data(r, info, result, success_status=200)

        if result['nitro_errorcode'] == 0:
            body_data = self._module.from_json(result['http_response_body'])
            result['nitro_auth_token'] = body_data['login'][0]['sessionid']

        self._module_result['changed'] = False

        return result

    def save_config(self):

        url = '%s://%s/nitro/v1/config/nsconfig?action=save' % (
            self._module.params['nitro_protocol'],
            self._module.params['nsip'],
        )

        data = self._module.jsonify(
            {
                'nsconfig': {},
            }
        )
        r, info = fetch_url(
            self._module,
            url=url,
            headers=self._headers,
            data=data,
            method='POST',
        )

        result = {}

        self.edit_response_data(r, info, result, success_status=200)
        self._module_result['changed'] = False

        return result
示例#3
0
def main():

    backup_spec = dict(filename=dict(), dir_path=dict(type='path'))
    argument_spec = dict(lines=dict(aliases=['commands'], type='list'),
                         parents=dict(type='list'),
                         src=dict(type='path'),
                         before=dict(type='list'),
                         after=dict(type='list'),
                         match=dict(
                             default='line',
                             choices=['line', 'strict', 'exact', 'none']),
                         replace=dict(default='line',
                                      choices=['line', 'block']),
                         update=dict(choices=['merge', 'check'],
                                     default='merge'),
                         save=dict(type='bool', default=False),
                         config=dict(),
                         backup=dict(type='bool', default=False),
                         backup_options=dict(type='dict', options=backup_spec))

    argument_spec.update(dellos6_argument_spec)
    mutually_exclusive = [('lines', 'src'), ('parents', 'src')]

    module = AnsibleModule(argument_spec=argument_spec,
                           mutually_exclusive=mutually_exclusive,
                           supports_check_mode=True)

    parents = module.params['parents'] or list()

    match = module.params['match']
    replace = module.params['replace']

    warnings = list()
    check_args(module, warnings)
    result = dict(changed=False, saved=False, warnings=warnings)

    candidate = get_candidate(module)
    if module.params['backup']:
        if not module.check_mode:
            result['__backup__'] = get_config(module)

    commands = list()

    if any((module.params['lines'], module.params['src'])):
        if match != 'none':
            config = get_running_config(module)
            config = Dellos6NetworkConfig(contents=config, indent=0)
            if parents:
                config = get_sublevel_config(config, module)
            configobjs = candidate.difference(config,
                                              match=match,
                                              replace=replace)
        else:
            configobjs = candidate.items

        if configobjs:
            commands = dumps(configobjs, 'commands')
            if ((isinstance(module.params['lines'], list))
                    and (isinstance(module.params['lines'][0], dict))
                    and set(['prompt', 'answer']).issubset(
                        module.params['lines'][0])):
                cmd = {
                    'command': commands,
                    'prompt': module.params['lines'][0]['prompt'],
                    'answer': module.params['lines'][0]['answer']
                }
                commands = [module.jsonify(cmd)]
            else:
                commands = commands.split('\n')

            if module.params['before']:
                commands[:0] = module.params['before']

            if module.params['after']:
                commands.extend(module.params['after'])

            if not module.check_mode and module.params['update'] == 'merge':
                load_config(module, commands)

            result['changed'] = True
            result['commands'] = commands
            result['updates'] = commands

    if module.params['save']:
        result['changed'] = True
        if not module.check_mode:
            cmd = {
                'command': 'copy running-config startup-config',
                'prompt': r'\(y/n\)\s?$',
                'answer': 'y'
            }
            run_commands(module, [cmd])
            result['saved'] = True
        else:
            module.warn('Skipping command `copy running-config startup-config`'
                        'due to check_mode.  Configuration not copied to '
                        'non-volatile storage')

    module.exit_json(**result)