示例#1
0
def _matches_metadata(
    *,
    pattern: filters.MetaFilter,  # from the handler
    content: Mapping[str, str],  # from the body
    kwargs: MutableMapping[str, Any],
    cause: causation.ResourceCause,
) -> bool:
    for key, value in pattern.items():
        if value is filters.MetaFilterToken.ABSENT and key not in content:
            continue
        elif value is filters.MetaFilterToken.PRESENT and key in content:
            continue
        elif value is None and key in content:  # deprecated; warned in @kopf.on
            continue
        elif callable(value):
            if not kwargs:
                kwargs.update(invocation.build_kwargs(cause=cause))
            if value(content.get(key, None), **kwargs):
                continue
            else:
                return False
        elif key not in content:
            return False
        elif value != content[key]:
            return False
        else:
            continue
    return True
示例#2
0
def _matches_field_values(
    handler: handlers.ResourceHandler,
    cause: causation.ResourceCause,
    kwargs: MutableMapping[str, Any],
) -> bool:
    if not handler.field:
        return True

    if not kwargs:
        kwargs.update(invocation.build_kwargs(cause=cause))

    absent = _UNSET.token  # or any other identifyable object
    if isinstance(cause, causation.ResourceChangingCause):
        # For on.update/on.field, so as for on.create/resume/delete for uniformity and simplicity:
        old = dicts.resolve(cause.old, handler.field, absent)
        new = dicts.resolve(cause.new, handler.field, absent)
        values = [
            new, old
        ]  # keep "new" first, to avoid "old" callbacks if "new" works.
    else:
        # For event-watching, timers/daemons (could also work for on.create/resume/delete):
        val = dicts.resolve(cause.body, handler.field, absent)
        values = [val]
    return ((handler.value is None and any(value is not absent
                                           for value in values))
            or (handler.value is filters.PRESENT and any(value is not absent
                                                         for value in values))
            or (handler.value is filters.ABSENT and any(value is absent
                                                        for value in values))
            or (callable(handler.value)
                and any(handler.value(value, **kwargs) for value in values))
            or (any(handler.value == value for value in values)))
示例#3
0
def _matches_field_changes(
    handler: handlers.ResourceHandler,
    cause: causation.ResourceCause,
    kwargs: MutableMapping[str, Any],
) -> bool:
    if not isinstance(handler, handlers.ResourceChangingHandler):
        return True
    if not isinstance(cause, causation.ResourceChangingCause):
        return True
    if not handler.field:
        return True

    if not kwargs:
        kwargs.update(invocation.build_kwargs(cause=cause))

    absent = _UNSET.token  # or any other identifyable object
    old = dicts.resolve(cause.old, handler.field, absent)
    new = dicts.resolve(cause.new, handler.field, absent)
    return ((
        not handler.field_needs_change
        or old != new  # ... or there IS a change.
    ) and ((handler.old is None) or
           (handler.old is filters.ABSENT and old is absent) or
           (handler.old is filters.PRESENT and old is not absent) or
           (callable(handler.old) and handler.old(old, **kwargs)) or
           (handler.old == old))
            and ((handler.new is None) or
                 (handler.new is filters.ABSENT and new is absent) or
                 (handler.new is filters.PRESENT and new is not absent) or
                 (callable(handler.new) and handler.new(new, **kwargs)) or
                 (handler.new == new)))
示例#4
0
def _matches_filter_callback(
        handler: handlers.ResourceHandler,
        cause: causation.ResourceCause,
) -> bool:
    if not handler.when:
        return True
    return handler.when(**invocation.build_kwargs(cause=cause))
示例#5
0
def test_resource_changing_kwargs(resource, indices):
    body = {
        'metadata': {
            'uid': 'uid1',
            'name': 'name1',
            'namespace': 'ns1',
            'labels': {
                'l1': 'v1'
            },
            'annotations': {
                'a1': 'v1'
            }
        },
        'spec': {
            'field': 'value'
        },
        'status': {
            'info': 'payload'
        }
    }
    cause = ResourceChangingCause(
        logger=logging.getLogger('kopf.test.fake.logger'),
        indices=indices,
        resource=resource,
        patch=Patch(),
        initial=False,
        reason=Reason.NOOP,
        memo=Memo(),
        body=Body(body),
        diff=Diff([]),
        old=BodyEssence(),
        new=BodyEssence(),
    )
    kwargs = build_kwargs(cause=cause, extrakwarg=123)
    assert set(kwargs) == {
        'extrakwarg', 'logger', 'index1', 'index2', 'resource', 'patch',
        'reason', 'memo', 'body', 'spec', 'status', 'meta', 'uid', 'name',
        'namespace', 'labels', 'annotations', 'diff', 'old', 'new'
    }
    assert kwargs['extrakwarg'] == 123
    assert kwargs['resource'] is cause.resource
    assert kwargs['index1'] is indices['index1']
    assert kwargs['index2'] is indices['index2']
    assert kwargs['reason'] is cause.reason
    assert kwargs['logger'] is cause.logger
    assert kwargs['patch'] is cause.patch
    assert kwargs['memo'] is cause.memo
    assert kwargs['diff'] is cause.diff
    assert kwargs['old'] is cause.old
    assert kwargs['new'] is cause.new
    assert kwargs['body'] is cause.body
    assert kwargs['spec'] is cause.body.spec
    assert kwargs['meta'] is cause.body.metadata
    assert kwargs['status'] is cause.body.status
    assert kwargs['labels'] is cause.body.metadata.labels
    assert kwargs['annotations'] is cause.body.metadata.annotations
    assert kwargs['uid'] == cause.body.metadata.uid
    assert kwargs['name'] == cause.body.metadata.name
    assert kwargs['namespace'] == cause.body.metadata.namespace
示例#6
0
def test_resource_watching_kwargs(resource, indices):
    body = {
        'metadata': {
            'uid': 'uid1',
            'name': 'name1',
            'namespace': 'ns1',
            'labels': {
                'l1': 'v1'
            },
            'annotations': {
                'a1': 'v1'
            }
        },
        'spec': {
            'field': 'value'
        },
        'status': {
            'info': 'payload'
        }
    }
    cause = ResourceWatchingCause(
        logger=logging.getLogger('kopf.test.fake.logger'),
        indices=indices,
        resource=resource,
        patch=Patch(),
        memo=Memo(),
        body=Body(body),
        type='ADDED',
        raw={
            'type': 'ADDED',
            'object': {}
        },
    )
    kwargs = build_kwargs(cause=cause, extrakwarg=123)
    assert set(kwargs) == {
        'extrakwarg', 'logger', 'index1', 'index2', 'resource', 'patch',
        'event', 'type', 'memo', 'body', 'spec', 'status', 'meta', 'uid',
        'name', 'namespace', 'labels', 'annotations'
    }
    assert kwargs['extrakwarg'] == 123
    assert kwargs['resource'] is cause.resource
    assert kwargs['index1'] is indices['index1']
    assert kwargs['index2'] is indices['index2']
    assert kwargs['logger'] is cause.logger
    assert kwargs['patch'] is cause.patch
    assert kwargs['event'] is cause.raw
    assert kwargs['memo'] is cause.memo
    assert kwargs['type'] is cause.type
    assert kwargs['body'] is cause.body
    assert kwargs['spec'] is cause.body.spec
    assert kwargs['meta'] is cause.body.metadata
    assert kwargs['status'] is cause.body.status
    assert kwargs['labels'] is cause.body.metadata.labels
    assert kwargs['annotations'] is cause.body.metadata.annotations
    assert kwargs['uid'] == cause.body.metadata.uid
    assert kwargs['name'] == cause.body.metadata.name
    assert kwargs['namespace'] == cause.body.metadata.namespace
示例#7
0
def _matches_filter_callback(
    handler: handlers.ResourceHandler,
    cause: causation.ResourceCause,
    kwargs: MutableMapping[str, Any],
) -> bool:
    if handler.when is None:
        return True
    if not kwargs:
        kwargs.update(invocation.build_kwargs(cause=cause))
    return handler.when(**kwargs)
示例#8
0
def test_daemon_async_stopper(resource):
    cause = DaemonCause(
        logger=logging.getLogger('kopf.test.fake.logger'),
        resource=resource,
        patch=Patch(),
        memo=Memo(),
        body=Body({}),
        stopper=DaemonStopper(),
    )
    kwargs = build_kwargs(cause=cause, _sync=False)
    assert kwargs['stopped'] is cause.stopper.async_checker
示例#9
0
def test_activity_kwargs(resource, activity):
    cause = ActivityCause(
        logger=logging.getLogger('kopf.test.fake.logger'),
        activity=activity,
        settings=OperatorSettings(),
    )
    kwargs = build_kwargs(cause=cause, extrakwarg=123)
    assert set(kwargs) == {'extrakwarg', 'logger', 'activity'}
    assert kwargs['extrakwarg'] == 123
    assert kwargs['logger'] is cause.logger
    assert kwargs['activity'] is activity
示例#10
0
def test_daemon_kwargs(resource, indices):
    body = {
        'metadata': {
            'uid': 'uid1',
            'name': 'name1',
            'namespace': 'ns1',
            'labels': {
                'l1': 'v1'
            },
            'annotations': {
                'a1': 'v1'
            }
        },
        'spec': {
            'field': 'value'
        },
        'status': {
            'info': 'payload'
        }
    }
    cause = DaemonCause(
        logger=logging.getLogger('kopf.test.fake.logger'),
        indices=indices,
        resource=resource,
        patch=Patch(),
        memo=Memo(),
        body=Body(body),
        stopper=DaemonStopper(),
    )
    kwargs = build_kwargs(cause=cause, extrakwarg=123)
    assert set(kwargs) == {
        'extrakwarg', 'logger', 'index1', 'index2', 'resource', 'patch',
        'memo', 'body', 'spec', 'status', 'meta', 'uid', 'name', 'namespace',
        'labels', 'annotations'
    }
    assert kwargs['extrakwarg'] == 123
    assert kwargs['resource'] is cause.resource
    assert kwargs['index1'] is indices['index1']
    assert kwargs['index2'] is indices['index2']
    assert kwargs['logger'] is cause.logger
    assert kwargs['patch'] is cause.patch
    assert kwargs['memo'] is cause.memo
    assert kwargs['body'] is cause.body
    assert kwargs['spec'] is cause.body.spec
    assert kwargs['meta'] is cause.body.metadata
    assert kwargs['status'] is cause.body.status
    assert kwargs['labels'] is cause.body.metadata.labels
    assert kwargs['annotations'] is cause.body.metadata.annotations
    assert kwargs['uid'] == cause.body.metadata.uid
    assert kwargs['name'] == cause.body.metadata.name
    assert kwargs['namespace'] == cause.body.metadata.namespace
    assert 'stopped' not in kwargs
示例#11
0
def test_resource_spawning_kwargs(resource):
    body = {
        'metadata': {
            'uid': 'uid1',
            'name': 'name1',
            'namespace': 'ns1',
            'labels': {
                'l1': 'v1'
            },
            'annotations': {
                'a1': 'v1'
            }
        },
        'spec': {
            'field': 'value'
        },
        'status': {
            'info': 'payload'
        }
    }
    cause = ResourceSpawningCause(
        logger=logging.getLogger('kopf.test.fake.logger'),
        resource=resource,
        patch=Patch(),
        memo=Memo(),
        body=Body(body),
        reset=False,
    )
    kwargs = build_kwargs(cause=cause, extrakwarg=123)
    assert set(kwargs) == {
        'extrakwarg', 'logger', 'resource', 'patch', 'memo', 'body', 'spec',
        'status', 'meta', 'uid', 'name', 'namespace', 'labels', 'annotations'
    }
    assert kwargs['extrakwarg'] == 123
    assert kwargs['resource'] is cause.resource
    assert kwargs['logger'] is cause.logger
    assert kwargs['patch'] is cause.patch
    assert kwargs['memo'] is cause.memo
    assert kwargs['body'] is cause.body
    assert kwargs['spec'] is cause.body.spec
    assert kwargs['meta'] is cause.body.metadata
    assert kwargs['status'] is cause.body.status
    assert kwargs['labels'] is cause.body.metadata.labels
    assert kwargs['annotations'] is cause.body.metadata.annotations
    assert kwargs['uid'] == cause.body.metadata.uid
    assert kwargs['name'] == cause.body.metadata.name
    assert kwargs['namespace'] == cause.body.metadata.namespace
示例#12
0
def test_activity_kwargs(resource, activity, indices):
    cause = ActivityCause(
        memo=Memo(),
        logger=logging.getLogger('kopf.test.fake.logger'),
        indices=indices,
        activity=activity,
        settings=OperatorSettings(),
    )
    kwargs = build_kwargs(cause=cause, extrakwarg=123)
    assert set(kwargs) == {
        'extrakwarg', 'memo', 'logger', 'index1', 'index2', 'activity'
    }
    assert kwargs['extrakwarg'] == 123
    assert kwargs['index1'] is indices['index1']
    assert kwargs['index2'] is indices['index2']
    assert kwargs['logger'] is cause.logger
    assert kwargs['activity'] is activity
示例#13
0
async def execute_handlers_once(
    lifecycle: lifecycles.LifeCycleFn,
    settings: configuration.OperatorSettings,
    handlers: Collection[handlers_.BaseHandler],
    cause: causation.BaseCause,
    state: states.State,
    default_errors: handlers_.ErrorsMode = handlers_.ErrorsMode.TEMPORARY,
) -> Mapping[handlers_.HandlerId, states.HandlerOutcome]:
    """
    Call the next handler(s) from the chain of the handlers.

    Keep the record on the progression of the handlers in the object's state,
    and use it on the next invocation to determined which handler(s) to call.

    This routine is used both for the global handlers (via global registry),
    and for the sub-handlers (via a simple registry of the current handler).
    """

    # Filter and select the handlers to be executed right now, on this event reaction cycle.
    handlers_todo = [h for h in handlers if state[h.id].awakened]
    handlers_plan = lifecycle(
        handlers_todo, **invocation.build_kwargs(cause=cause, state=state))

    # Execute all planned (selected) handlers in one event reaction cycle, even if there are few.
    outcomes: MutableMapping[handlers_.HandlerId, states.HandlerOutcome] = {}
    for handler in handlers_plan:
        outcome = await execute_handler_once(
            settings=settings,
            handler=handler,
            state=state[handler.id],
            cause=cause,
            lifecycle=
            lifecycle,  # just a default for the sub-handlers, not used directly.
            default_errors=default_errors,
        )
        outcomes[handler.id] = outcome

    return outcomes
示例#14
0
def test_resource_admission_kwargs(resource, indices):
    body = {
        'metadata': {
            'uid': 'uid1',
            'name': 'name1',
            'namespace': 'ns1',
            'labels': {
                'l1': 'v1'
            },
            'annotations': {
                'a1': 'v1'
            }
        },
        'spec': {
            'field': 'value'
        },
        'status': {
            'info': 'payload'
        }
    }
    cause = ResourceWebhookCause(
        logger=logging.getLogger('kopf.test.fake.logger'),
        indices=indices,
        resource=resource,
        patch=Patch(),
        memo=Memo(),
        body=Body(body),
        dryrun=False,
        headers={'k1': 'v1'},
        sslpeer={'k2': 'v2'},
        userinfo={'k3': 'v3'},
        warnings=['w1'],
        webhook=None,
        reason=None,
        operation=None,
    )
    kwargs = build_kwargs(cause=cause, extrakwarg=123)
    assert set(kwargs) == {
        'extrakwarg', 'logger', 'index1', 'index2', 'resource', 'dryrun',
        'headers', 'sslpeer', 'userinfo', 'warnings', 'patch', 'memo', 'body',
        'spec', 'status', 'meta', 'uid', 'name', 'namespace', 'labels',
        'annotations'
    }
    assert kwargs['extrakwarg'] == 123
    assert kwargs['resource'] is cause.resource
    assert kwargs['index1'] is indices['index1']
    assert kwargs['index2'] is indices['index2']
    assert kwargs['logger'] is cause.logger
    assert kwargs['dryrun'] is cause.dryrun
    assert kwargs['headers'] is cause.headers
    assert kwargs['sslpeer'] is cause.sslpeer
    assert kwargs['userinfo'] is cause.userinfo
    assert kwargs['warnings'] is cause.warnings
    assert kwargs['patch'] is cause.patch
    assert kwargs['memo'] is cause.memo
    assert kwargs['body'] is cause.body
    assert kwargs['spec'] is cause.body.spec
    assert kwargs['meta'] is cause.body.metadata
    assert kwargs['status'] is cause.body.status
    assert kwargs['labels'] is cause.body.metadata.labels
    assert kwargs['annotations'] is cause.body.metadata.annotations
    assert kwargs['uid'] == cause.body.metadata.uid
    assert kwargs['name'] == cause.body.metadata.name
    assert kwargs['namespace'] == cause.body.metadata.namespace