예제 #1
0
async def test_headers_are_not_leaked(resp_mocker, aresponses, hostname,
                                      assert_logs, status):

    post_mock = resp_mocker(return_value=aresponses.Response(status=status))
    aresponses.add(hostname, '/api/v1/namespaces/ns/events', 'post', post_mock)

    obj = {
        'apiVersion': 'group/version',
        'kind': 'kind',
        'metadata': {
            'namespace': 'ns',
            'name': 'name',
            'uid': 'uid'
        }
    }
    ref = build_object_reference(obj)
    await post_event(ref=ref,
                     type='type',
                     reason='reason',
                     message='message',
                     resource=EVENTS)

    assert_logs([
        "Failed to post an event.",
    ],
                prohibited=[
                    "ClientResponseError",
                    "RequestInfo",
                    "headers=",
                ])
예제 #2
0
async def test_message_is_cut_to_max_length(resp_mocker, aresponses, hostname):

    post_mock = resp_mocker(return_value=aiohttp.web.json_response({}))
    aresponses.add(hostname, '/api/v1/namespaces/ns/events', 'post', post_mock)

    obj = {
        'apiVersion': 'group/version',
        'kind': 'kind',
        'metadata': {
            'namespace': 'ns',
            'name': 'name',
            'uid': 'uid'
        }
    }
    ref = build_object_reference(obj)
    message = 'start' + ('x' * 2048) + 'end'
    await post_event(ref=ref,
                     type='type',
                     reason='reason',
                     message=message,
                     resource=EVENTS)

    data = post_mock.call_args_list[0][0][
        0].data  # [callidx][args/kwargs][argidx]
    assert len(data['message']) <= 1024  # max supported API message length
    assert '...' in data['message']
    assert data['message'].startswith('start')
    assert data['message'].endswith('end')
예제 #3
0
def warn(
    objs: Union[bodies.Body, Iterable[bodies.Body]],
    *,
    reason: str,
    message: str = '',
) -> None:
    settings: configuration.OperatorSettings = settings_var.get()
    if settings.posting.level <= logging.WARNING:
        for obj in cast(Iterator[bodies.Body], dicts.walk(objs)):
            ref = bodies.build_object_reference(obj)
            enqueue(ref=ref, type='Warning', reason=reason, message=message)
예제 #4
0
def event(
    objs: Union[bodies.Body, Iterable[bodies.Body]],
    *,
    type: str,
    reason: str,
    message: str = '',
) -> None:
    settings: configuration.OperatorSettings = settings_var.get()
    if settings.posting.enabled:
        for obj in cast(Iterator[bodies.Body], dicts.walk(objs)):
            ref = bodies.build_object_reference(obj)
            enqueue(ref=ref, type=type, reason=reason, message=message)
예제 #5
0
def exception(
    objs: Union[bodies.Body, Iterable[bodies.Body]],
    *,
    reason: str = '',
    message: str = '',
    exc: Optional[BaseException] = None,
) -> None:
    if exc is None:
        _, exc, _ = sys.exc_info()
    reason = reason if reason else type(exc).__name__
    message = f'{message} {exc}' if message and exc else f'{exc}' if exc else f'{message}'
    settings: configuration.OperatorSettings = settings_var.get()
    if settings.posting.enabled and settings.posting.level <= logging.ERROR:
        for obj in cast(Iterator[bodies.Body], dicts.walk(objs)):
            ref = bodies.build_object_reference(obj)
            enqueue(ref=ref, type='Error', reason=reason, message=message)
예제 #6
0
async def test_no_events_for_events(resp_mocker, aresponses, hostname):

    post_mock = resp_mocker(return_value=aiohttp.web.json_response({}))
    aresponses.add(hostname, '/api/v1/namespaces/ns/events', 'post', post_mock)

    obj = {
        'apiVersion': 'v1',
        'kind': 'Event',
        'metadata': {
            'namespace': 'ns',
            'name': 'name',
            'uid': 'uid'
        }
    }
    ref = build_object_reference(obj)
    await post_event(ref=ref,
                     type='type',
                     reason='reason',
                     message='message',
                     resource=EVENTS)

    assert not post_mock.called
예제 #7
0
async def test_posting(resp_mocker, aresponses, hostname):

    post_mock = resp_mocker(return_value=aiohttp.web.json_response({}))
    aresponses.add(hostname, '/api/v1/namespaces/ns/events', 'post', post_mock)

    obj = {
        'apiVersion': 'group/version',
        'kind': 'kind',
        'metadata': {
            'namespace': 'ns',
            'name': 'name',
            'uid': 'uid'
        }
    }
    ref = build_object_reference(obj)
    await post_event(ref=ref,
                     type='type',
                     reason='reason',
                     message='message',
                     resource=EVENTS)

    assert post_mock.called
    assert post_mock.call_count == 1

    req = post_mock.call_args_list[0][0][0]  # [callidx][args/kwargs][argidx]
    assert req.method == 'POST'

    data = req.data
    assert data['type'] == 'type'
    assert data['reason'] == 'reason'
    assert data['message'] == 'message'
    assert data['source']['component'] == 'kopf'
    assert data['involvedObject']['apiVersion'] == 'group/version'
    assert data['involvedObject']['kind'] == 'kind'
    assert data['involvedObject']['namespace'] == 'ns'
    assert data['involvedObject']['name'] == 'name'
    assert data['involvedObject']['uid'] == 'uid'
예제 #8
0
async def test_regular_errors_escalate(resp_mocker, enforced_session, mocker):

    error = Exception('boo!')
    enforced_session.post = mocker.Mock(side_effect=error)

    obj = {
        'apiVersion': 'group/version',
        'kind': 'kind',
        'metadata': {
            'namespace': 'ns',
            'name': 'name',
            'uid': 'uid'
        }
    }
    ref = build_object_reference(obj)

    with pytest.raises(Exception) as excinfo:
        await post_event(ref=ref,
                         type='type',
                         reason='reason',
                         message='message',
                         resource=EVENTS)

    assert excinfo.value is error
예제 #9
0
async def test_api_errors_logged_but_suppressed(resp_mocker, aresponses,
                                                hostname, assert_logs):

    post_mock = resp_mocker(return_value=aresponses.Response(status=555))
    aresponses.add(hostname, '/api/v1/namespaces/ns/events', 'post', post_mock)

    obj = {
        'apiVersion': 'group/version',
        'kind': 'kind',
        'metadata': {
            'namespace': 'ns',
            'name': 'name',
            'uid': 'uid'
        }
    }
    ref = build_object_reference(obj)
    await post_event(ref=ref,
                     type='type',
                     reason='reason',
                     message='message',
                     resource=EVENTS)

    assert post_mock.called
    assert_logs(["Failed to post an event."])