示例#1
0
def galaxy_api(request):
    gc = GalaxyContext(server=request.param['server'])
    # log.debug('gc: %s', gc)

    # mock the result of _get_server_api_versions here, so that we dont get the extra
    # call when calling the tests

    patcher = mock.patch(
        'ansible_galaxy.rest_api.requests.Session.request',
        new=FauxUrlResponder([
            FauxUrlOpenResponse(data={'current_version': 'v1'}),
            FauxUrlOpenResponse(data={'results': [{
                'foo1': 11,
                'foo2': 12
            }]},
                                url='blippyblopfakeurl'),
        ]))

    patcher.start()
    api = rest_api.GalaxyAPI(gc)

    # do a call so that we run g_connect and _get_server_api_versions by side effect now
    api.get_collection_detail('test-namespace', 'test-repo')

    # now unpatch
    patcher.stop()

    yield api
示例#2
0
def test_galaxy_api_get_server_api_version_not_supported_version(mocker):
    mocker.patch(
        'ansible_galaxy.rest_api.requests.Session.request',
        new=FauxUrlResponder([
            FauxUrlOpenResponse(data={
                'current_version':
                'v11.22.13beta4.preRC-16.0.0.0.42.42.37.1final'
            }),
            # doesn't matter response, just need a second call
            FauxUrlOpenResponse(data={'results': 'stuff'},
                                url='blippyblopfakeurl'),
        ]))

    gc = GalaxyContext(server=default_server_dict)
    api = rest_api.GalaxyAPI(gc)

    # expected to raise a client error about the server version not being supported in client
    # TODO: should be the server deciding if the client version is sufficient
    try:
        api.get_collection_detail('test-namespace', 'test-repo')
    except exceptions.GalaxyClientError as e:
        log.exception(e)
        assert 'Unsupported Galaxy server API' in '%s' % e
        return

    assert False, 'Expected a GalaxyClientError about supported server apis, but didnt happen'
示例#3
0
def test__publish(galaxy_context, mock_get_api, requests_mock):
    faux_api_key = 'da39a3ee5e6b4b0d3255bfef95601890afd80709'
    context = GalaxyContext(collections_path=galaxy_context.collections_path,
                            server={
                                'url': 'http://notreal.invalid:8000',
                                'ignore_certs': False,
                                'api_key': faux_api_key
                            })
    log.debug('galaxy_context: %s', context)

    response_body_202 = {"task": "/api/v2/collection-imports/8675309"}
    post_mock = requests_mock.post(
        'http://notreal.invalid:8000/api/v2/collections/',
        status_code=202,
        json=response_body_202)
    res = publish._publish(context, "/dev/null", display_callback)

    log.debug('res: %s', res)

    assert post_mock.last_request.headers[
        'Authorization'] == 'Token %s' % faux_api_key
    assert post_mock.last_request.headers['Content-type'].startswith(
        'multipart/form-data;')

    assert res['errors'] == []
    assert res['success'] is True
    assert res['response_data']['task'] == "/api/v2/collection-imports/8675309"
示例#4
0
def test_galaxy_api_init():

    gc = GalaxyContext()
    api = rest_api.GalaxyAPI(gc)

    assert isinstance(api, rest_api.GalaxyAPI)
    assert api.galaxy_context == gc
示例#5
0
def galaxy_context(tmpdir):
    # tmp_content_path = tempfile.mkdtemp()
    # FIXME: mock
    server = {'url': 'http://localhost:8000',
              'ignore_certs': False}
    content_dir = tmpdir.mkdir('collections')
    collections_dir = content_dir.mkdir('ansible_collections')
    from ansible_galaxy.models.context import GalaxyContext
    return GalaxyContext(server=server, content_path=collections_dir.strpath)
示例#6
0
def galaxy_context(tmpdir):
    # FIXME: mock
    server = {
        'url': 'http://localhost:8000',
        'ignore_certs': False,
        'api_key': None,
    }
    collections_path = tmpdir.mkdir('collections')

    from ansible_galaxy.models.context import GalaxyContext

    return GalaxyContext(server=server,
                         collections_path=collections_path.strpath)
示例#7
0
def test_galaxy_api_get_server_api_version(mocker):
    mocker.patch('ansible_galaxy.rest_api.requests.Session.request',
                 new=FauxUrlResponder([
                     FauxUrlOpenResponse(data={'current_version': 'v1'}),
                 ]))

    gc = GalaxyContext(server=default_server_dict)
    api = rest_api.GalaxyAPI(gc)
    res = api._get_server_api_version()

    log.debug('res: %s %r', res, res)

    assert isinstance(res, text_type)
    assert res == 'v1'
示例#8
0
def test__publish_api_key_is_none(galaxy_context, mock_get_api, requests_mock):
    context = GalaxyContext(collections_path=galaxy_context.collections_path,
                            server={
                                'url': 'http://notreal.invalid:8000',
                                'ignore_certs': False,
                                'api_key': None
                            })
    log.debug('galaxy_context: %s', context)

    response_body_202 = {}
    post_mock = requests_mock.post(
        'http://notreal.invalid:8000/api/v2/collections/',
        status_code=202,
        json=response_body_202)

    publish._publish(context, "/dev/null", display_callback)

    assert 'Authorization' not in post_mock.last_request.headers
示例#9
0
def test_galaxy_api_get_server_api_version_HTTPError_not_json(mocker):
    mocker.patch('ansible_galaxy.rest_api.requests.Session.request',
                 new=FauxUrlResponder([
                     FauxUrlOpenResponse(status=500,
                                         body='{stuff-that-is-not-valid-json'),
                 ]))

    gc = GalaxyContext(server=default_server_dict)
    api = rest_api.GalaxyAPI(gc)
    try:
        api._get_server_api_version()
    except exceptions.GalaxyClientError as e:
        log.exception(e)
        # fragile, but currently return same exception so look for the right msg in args
        assert 'Could not process data from the API server' in '%s' % e

        return

    assert False, 'Expected a GalaxyClientError here but that did not happen'
示例#10
0
def test_galaxy_api_get_server_api_version_no_current_version(mocker):
    mocker.patch('ansible_galaxy.rest_api.open_url',
                 new=FauxUrlResponder(
                     [
                         FauxUrlOpenResponse(status=500, data={'some_key': 'some_value',
                                                               'but_not_current_value': 2}),
                     ]
                 ))

    gc = GalaxyContext(server=default_server_dict)
    api = rest_api.GalaxyAPI(gc)
    try:
        api._get_server_api_version()
    except exceptions.GalaxyClientError as e:
        log.exception(e)
        # fragile, but currently return same exception so look for the right msg in args
        assert "missing required 'current_version'" in '%s' % e

        return

    assert False, 'Expected a GalaxyClientError here but that did not happen'
示例#11
0
def test_galaxy_api_get_server_api_version_HTTPError_500(mocker):
    error_body = u'{"detail": "Stuff broke, 500 error but server response has valid json include the detail key"}'

    mocker.patch('ansible_galaxy.rest_api.open_url',
                 side_effect=HTTPError(url='http://whatever',
                                       code=500,
                                       msg='Stuff broke.',
                                       hdrs={},
                                       fp=io.StringIO(initial_value=error_body)))

    gc = GalaxyContext(server=default_server_dict)
    api = rest_api.GalaxyAPI(gc)
    try:
        api._get_server_api_version()
    except exceptions.GalaxyClientError as e:
        log.exception(e)
        # fragile, but currently return same exception so look for the right msg in args
        assert 'Failed to get data from the API server' in '%s' % e
        return

    assert False, 'Expected a GalaxyClientError here but that did not happen'
示例#12
0
def test_galaxy_api_get_server_api_version_HTTPError_500(mocker):
    data = {
        "detail":
        "Stuff broke, 500 error but server response has valid json include the detail key"
    }

    mocker.patch('ansible_galaxy.rest_api.requests.Session.request',
                 new=FauxUrlResponder([
                     FauxUrlOpenResponse(status=500, data=data),
                 ], ))

    gc = GalaxyContext(server=default_server_dict)
    api = rest_api.GalaxyAPI(gc)
    try:
        api._get_server_api_version()
    except exceptions.GalaxyClientError as e:
        log.exception(e)
        # fragile, but currently return same exception so look for the right msg in args
        assert 'Failed to get data from the API server' in '%s' % e
        return

    assert False, 'Expected a GalaxyClientError here but that did not happen'
示例#13
0
def test__publish_api_error(galaxy_context, mock_get_api, requests_mock):
    faux_api_key = 'da39a3ee5e6b4b0d3255bfef95601890afd80709'
    context = GalaxyContext(collections_path=galaxy_context.collections_path,
                            server={
                                'url': 'http://notreal.invalid:8000',
                                'ignore_certs': False,
                                'api_key': faux_api_key
                            })
    log.debug('galaxy_context: %s', context)

    err_409_conflict_json = {
        'code':
        'conflict.collection_exists',
        'message':
        'Collection "testing-ansible_testing_content-4.0.4" already exists.'
    }
    post_mock = requests_mock.post(
        'http://notreal.invalid:8000/api/v2/collections/',
        status_code=409,
        reason='Conflict',
        json=err_409_conflict_json)

    res = publish._publish(context, "/dev/null", display_callback)

    log.debug('res: %s', res)

    assert post_mock.last_request.headers[
        'Authorization'] == 'Token %s' % faux_api_key
    assert post_mock.last_request.headers['Content-type'].startswith(
        'multipart/form-data;')

    assert res['errors'] == [
        'Error publishing null to http://notreal.invalid:8000/api/v2/collections/ '
        +
        '- Collection "testing-ansible_testing_content-4.0.4" already exists.'
    ]
    assert res['success'] is False
示例#14
0
def sync(remote_pk, repository_pk):
    """
    Sync Collections with ``remote_pk``, and save a new RepositoryVersion for ``repository_pk``.

    Args:
        remote_pk (str): The remote PK.
        repository_pk (str): The repository PK.

    Raises:
        ValueError: If the remote does not specify a URL to sync or a ``whitelist`` of Collections
            to sync.

    """
    remote = CollectionRemote.objects.get(pk=remote_pk)
    repository = Repository.objects.get(pk=repository_pk)

    if not remote.url:
        raise ValueError(
            _("A CollectionRemote must have a 'url' specified to synchronize.")
        )

    if not remote.whitelist:
        raise ValueError(
            _("A CollectionRemote must have a 'whitelist' specified to synchronize."
              ))

    repository_spec_strings = remote.whitelist.split(' ')

    def nowhere(*args, **kwargs):
        pass

    collections_created_pks = []

    with tempfile.TemporaryDirectory() as temp_ansible_path:
        galaxy_context = GalaxyContext(
            collections_path=temp_ansible_path,
            server={
                'url': remote.url,
                'ignore_certs': False,
            },
        )

        install_repository_specs_loop(
            display_callback=nowhere,
            galaxy_context=galaxy_context,
            repository_spec_strings=repository_spec_strings,
        )

        content_walk_generator = os.walk(temp_ansible_path)
        for dirpath, dirnames, filenames in content_walk_generator:
            if 'MANIFEST.json' in filenames:
                with open(dirpath + os.path.sep +
                          'MANIFEST.json') as manifest_file:
                    manifest_data = json.load(manifest_file)
                info = manifest_data['collection_info']
                filename = '{namespace}-{name}-{version}'.format(
                    namespace=info['namespace'],
                    name=info['name'],
                    version=info['version'],
                )
                tarfile_path = temp_ansible_path + os.path.sep + filename + '.tar.gz'
                with tarfile.open(name=tarfile_path, mode='w|gz') as newtar:
                    newtar.add(dirpath, arcname=filename)

                with transaction.atomic():
                    collection, created = Collection.objects.get_or_create(
                        namespace=info['namespace'],
                        name=info['name'],
                        version=info['version'])

                    if created:
                        artifact = Artifact.init_and_validate(newtar.name)
                        artifact.save()

                        ContentArtifact.objects.create(
                            artifact=artifact,
                            content=collection,
                            relative_path=collection.relative_path,
                        )

                        collections_created_pks.append(collection)

    if collections_created_pks:
        with RepositoryVersion.create(repository) as new_version:
            collections = Collection.objects.filter(
                pk__in=collections_created_pks)
            new_version.add_content(collections)
示例#15
0
def galaxy_context_example_invalid(galaxy_context):
    context = GalaxyContext(collections_path=galaxy_context.collections_path,
                            server={'url': default_server_dict['url'],
                                    'ignore_certs': False})
    return context
示例#16
0
def galaxy_context_example_invalid(galaxy_context):
    context = GalaxyContext(content_path=galaxy_context.content_path,
                            server={'url': 'http://example.invalid',
                                    'ignore_certs': False})
    return context
示例#17
0
def _galaxy_context():
    tmp_content_path = tempfile.mkdtemp()
    # FIXME: mock
    server = {'url': 'http://localhost:8000', 'ignore_certs': False}
    return GalaxyContext(server=server, content_path=tmp_content_path)