Esempio n. 1
0
        def new_request(self, method, url, **kwargs):
            kwargs_copy = kwargs.copy()
            if 'data' in kwargs:
                kwargs_copy['data'] = json.loads(kwargs['data'])
            if 'params' in kwargs and method == 'GET':
                # query params for GET are handled a bit differently by
                # tower-cli and python requests as opposed to REST framework APIRequestFactory
                kwargs_copy.setdefault('data', {})
                if isinstance(kwargs['params'], dict):
                    kwargs_copy['data'].update(kwargs['params'])
                elif isinstance(kwargs['params'], list):
                    for k, v in kwargs['params']:
                        kwargs_copy['data'][k] = v

            # make request
            rf = _request(method.lower())
            django_response = rf(url, user=request_user, expect=None, **kwargs_copy)

            # requests library response object is different from the Django response, but they are the same concept
            # this converts the Django response object into a requests response object for consumption
            resp = Response()
            py_data = django_response.data
            sanitize_dict(py_data)
            resp._content = bytes(json.dumps(django_response.data), encoding='utf8')
            resp.status_code = django_response.status_code

            if request.config.getoption('verbose') > 0:
                logger.info(
                    '%s %s by %s, code:%s',
                    method, '/api/' + url.split('/api/')[1],
                    request_user.username, resp.status_code
                )

            return resp
Esempio n. 2
0
        def new_request(self, method, url, **kwargs):
            kwargs_copy = kwargs.copy()
            if 'data' in kwargs:
                if isinstance(kwargs['data'], dict):
                    kwargs_copy['data'] = kwargs['data']
                elif kwargs['data'] is None:
                    pass
                elif isinstance(kwargs['data'], str):
                    kwargs_copy['data'] = json.loads(kwargs['data'])
                else:
                    raise RuntimeError(
                        'Expected data to be dict or str, got {0}, data: {1}'.
                        format(type(kwargs['data']), kwargs['data']))
            if 'params' in kwargs and method == 'GET':
                # query params for GET are handled a bit differently by
                # tower-cli and python requests as opposed to REST framework APIRequestFactory
                if not kwargs_copy.get('data'):
                    kwargs_copy['data'] = {}
                if isinstance(kwargs['params'], dict):
                    kwargs_copy['data'].update(kwargs['params'])
                elif isinstance(kwargs['params'], list):
                    for k, v in kwargs['params']:
                        kwargs_copy['data'][k] = v

            # make request
            with transaction.atomic():
                rf = _request(method.lower())
                django_response = rf(url,
                                     user=request_user,
                                     expect=None,
                                     **kwargs_copy)

            # requests library response object is different from the Django response, but they are the same concept
            # this converts the Django response object into a requests response object for consumption
            resp = Response()
            py_data = django_response.data
            sanitize_dict(py_data)
            resp._content = bytes(json.dumps(django_response.data),
                                  encoding='utf8')
            resp.status_code = django_response.status_code
            resp.headers = {
                'X-API-Product-Name': 'AWX',
                'X-API-Product-Version': '0.0.1-devel'
            }

            if request.config.getoption('verbose') > 0:
                logger.info('%s %s by %s, code:%s', method,
                            '/api/' + url.split('/api/')[1],
                            request_user.username, resp.status_code)

            resp.request = PreparedRequest()
            resp.request.prepare(method=method, url=url)
            return resp
Esempio n. 3
0
        def new_request(self, method, url, **kwargs):
            kwargs_copy = kwargs.copy()
            if 'data' in kwargs:
                kwargs_copy['data'] = json.loads(kwargs['data'])

            # make request
            rf = _request(method.lower())
            django_response = rf(url, user=request_user, expect=None, **kwargs_copy)

            # requests library response object is different from the Django response, but they are the same concept
            # this converts the Django response object into a requests response object for consumption
            resp = Response()
            py_data = django_response.data
            sanitize_dict(py_data)
            resp._content = bytes(json.dumps(django_response.data), encoding='utf8')
            resp.status_code = django_response.status_code
            return resp
Esempio n. 4
0
def test_completeness(collection_import, request, admin_user, job_template):
    option_comparison = {}
    # Load a list of existing module files from disk
    base_folder = os.path.abspath(
        os.path.join(os.path.dirname(__file__), os.pardir, os.pardir))
    module_directory = os.path.join(base_folder, 'plugins', 'modules')
    for root, dirs, files in os.walk(module_directory):
        if root == module_directory:
            for filename in files:
                if re.match('^tower_.*.py$', filename):
                    module_name = filename[:-3]
                    option_comparison[module_name] = {
                        'endpoint': 'N/A',
                        'api_options': {},
                        'module_options': {},
                        'module_name': module_name,
                    }
                    resource_module = collection_import(
                        'plugins.modules.{0}'.format(module_name))
                    option_comparison[module_name][
                        'module_options'] = yaml.load(
                            resource_module.DOCUMENTATION,
                            Loader=yaml.SafeLoader)['options']

    endpoint_response = _request('get')(
        url='/api/v2/',
        user=admin_user,
        expect=None,
    )
    for endpoint in endpoint_response.data.keys():
        # Module names are singular and endpoints are plural so we need to convert to singular
        singular_endpoint = '{0}'.format(endpoint)
        if singular_endpoint.endswith('ies'):
            singular_endpoint = singular_endpoint[:-3]
        if singular_endpoint != 'settings' and singular_endpoint.endswith('s'):
            singular_endpoint = singular_endpoint[:-1]
        module_name = 'tower_{0}'.format(singular_endpoint)

        endpoint_url = endpoint_response.data.get(endpoint)

        # If we don't have a module for this endpoint then we can create an empty one
        if module_name not in option_comparison:
            option_comparison[module_name] = {}
            option_comparison[module_name]['module_name'] = 'N/A'
            option_comparison[module_name]['module_options'] = {}

        # Add in our endpoint and an empty api_options
        option_comparison[module_name]['endpoint'] = endpoint_url
        option_comparison[module_name]['api_options'] = {}

        # Get out the endpoint, load and parse its options page
        options_response = _request('options')(
            url=endpoint_url,
            user=admin_user,
            expect=None,
        )
        if 'POST' in options_response.data.get('actions', {}):
            option_comparison[module_name][
                'api_options'] = options_response.data.get('actions').get(
                    'POST')
        else:
            read_only_endpoint.append(module_name)

    # Parse through our data to get string lengths to make a pretty report
    longest_module_name = 0
    longest_option_name = 0
    longest_endpoint = 0
    for module in option_comparison:
        if len(option_comparison[module]['module_name']) > longest_module_name:
            longest_module_name = len(option_comparison[module]['module_name'])
        if len(option_comparison[module]['endpoint']) > longest_endpoint:
            longest_endpoint = len(option_comparison[module]['endpoint'])
        for option in option_comparison[module][
                'api_options'], option_comparison[module]['module_options']:
            if len(option) > longest_option_name:
                longest_option_name = len(option)

    # Print out some headers
    print("".join([
        "End Point",
        " " * (longest_endpoint - len("End Point")),
        " | Module Name",
        " " * (longest_module_name - len("Module Name")),
        " | Option",
        " " * (longest_option_name - len("Option")),
        " | API | Module | State",
    ]))
    print("-|-".join([
        "-" * longest_endpoint,
        "-" * longest_module_name,
        "-" * longest_option_name,
        "---",
        "------",
        "---------------------------------------------",
    ]))

    # Print out all of our data
    for module in sorted(option_comparison):
        module_data = option_comparison[module]
        all_param_names = list(
            set(module_data['api_options'])
            | set(module_data['module_options']))
        for parameter in sorted(all_param_names):
            print("".join([
                module_data['endpoint'],
                " " * (longest_endpoint - len(module_data['endpoint'])),
                " | ",
                module_data['module_name'],
                " " * (longest_module_name - len(module_data['module_name'])),
                " | ",
                parameter,
                " " * (longest_option_name - len(parameter)),
                " | ",
                " X " if (parameter in module_data['api_options']) else '   ',
                " | ",
                '  X   ' if
                (parameter in module_data['module_options']) else '      ',
                " | ",
                determine_state(
                    module,
                    module_data['endpoint'],
                    module_data['module_name'],
                    parameter,
                    module_data['api_options'][parameter] if
                    (parameter in module_data['api_options']) else None,
                    module_data['module_options'][parameter] if
                    (parameter in module_data['module_options']) else None,
                ),
            ]))
        # This handles cases were we got no params from the options page nor from the modules
        if len(all_param_names) == 0:
            print("".join([
                module_data['endpoint'],
                " " * (longest_endpoint - len(module_data['endpoint'])),
                " | ",
                module_data['module_name'],
                " " * (longest_module_name - len(module_data['module_name'])),
                " | ",
                "N/A",
                " " * (longest_option_name - len("N/A")),
                " | ",
                '   ',
                " | ",
                '      ',
                " | ",
                determine_state(module, module_data['endpoint'],
                                module_data['module_name'], 'N/A', None, None),
            ]))

    if return_value != 0:
        raise Exception("One or more failures caused issues")