コード例 #1
0
ファイル: fetching.py プロジェクト: kevindwei/kopf
def list_objs_rv(
        *,
        resource: resources.Resource,
        namespace: Optional[str] = None,
) -> Tuple[Collection[bodies.Body], str]:
    """
    List the objects of specific resource type.

    The cluster-scoped call is used in two cases:

    * The resource itself is cluster-scoped, and namespacing makes not sense.
    * The operator serves all namespaces for the namespaced custom resource.

    Otherwise, the namespace-scoped call is used:

    * The resource is namespace-scoped AND operator is namespaced-restricted.
    """
    api = auth.get_pykube_api()
    cls = classes._make_cls(resource=resource)
    namespace = namespace if issubclass(cls, pykube.objects.NamespacedAPIObject) else None
    lst = cls.objects(api, namespace=pykube.all if namespace is None else namespace)
    rsp = lst.response

    items: List[bodies.Body] = []
    resource_version = rsp.get('metadata', {}).get('resourceVersion', None)
    for item in rsp['items']:
        # FIXME: fix in pykube to inject the missing item's fields from the list's metainfo.
        if 'kind' in rsp:
            item.setdefault('kind', rsp['kind'][:-4] if rsp['kind'][-4:] == 'List' else rsp['kind'])
        if 'apiVersion' in rsp:
            item.setdefault('apiVersion', rsp['apiVersion'])
        items.append(item)

    return items, resource_version
コード例 #2
0
async def patch_obj(*, resource, patch, namespace=None, name=None, body=None):
    """
    Patch a resource of specific kind.

    Either the namespace+name should be specified, or the body,
    which is used only to get namespace+name identifiers.

    Unlike the object listing, the namespaced call is always
    used for the namespaced resources, even if the operator serves
    the whole cluster (i.e. is not namespace-restricted).
    """

    if body is not None and (name is not None or namespace is not None):
        raise TypeError(
            "Either body, or name+namespace can be specified. Got both.")

    namespace = body.get(
        'metadata', {}).get('namespace') if body is not None else namespace
    name = body.get('metadata', {}).get('name') if body is not None else name
    if body is None:
        nskw = {} if namespace is None else dict(namespace=namespace)
        body = {'metadata': {'name': name}}
        body['metadata'].update(nskw)

    api = auth.get_pykube_api()
    cls = classes._make_cls(resource=resource)
    obj = cls(api, body)

    loop = asyncio.get_running_loop()
    await loop.run_in_executor(config.WorkersConfig.get_syn_executor(),
                               obj.patch, patch)
コード例 #3
0
ファイル: patching.py プロジェクト: kevindwei/kopf
async def patch_obj(
    *,
    resource: resources.Resource,
    patch: patches.Patch,
    namespace: Optional[str] = None,
    name: Optional[str] = None,
    body: Optional[bodies.Body] = None,
) -> None:
    """
    Patch a resource of specific kind.

    Either the namespace+name should be specified, or the body,
    which is used only to get namespace+name identifiers.

    Unlike the object listing, the namespaced call is always
    used for the namespaced resources, even if the operator serves
    the whole cluster (i.e. is not namespace-restricted).
    """

    if body is not None and (name is not None or namespace is not None):
        raise TypeError(
            "Either body, or name+namespace can be specified. Got both.")

    namespace = body.get(
        'metadata', {}).get('namespace') if body is not None else namespace
    name = body.get('metadata', {}).get('name') if body is not None else name
    if body is None:
        body = cast(bodies.Body, {'metadata': {'name': name}})
        if namespace is not None:
            body['metadata']['namespace'] = namespace

    api = auth.get_pykube_api()
    cls = classes._make_cls(resource=resource)
    obj = cls(api, body)

    # The handler could delete its own object, so we have nothing to patch. It is okay, ignore.
    try:
        loop = asyncio.get_running_loop()
        await loop.run_in_executor(config.WorkersConfig.get_syn_executor(),
                                   obj.patch, patch)
    except pykube.ObjectDoesNotExist:
        pass
    except pykube.exceptions.HTTPError as e:
        if e.code == 404:
            pass
        else:
            raise
    except requests.exceptions.HTTPError as e:
        if e.response.status_code == 404:
            pass
        else:
            raise
コード例 #4
0
def read_obj(*, resource, namespace=None, name=None, default=_UNSET_):
    try:
        api = auth.get_pykube_api()
        cls = classes._make_cls(resource=resource)
        namespace = namespace if issubclass(
            cls, pykube.objects.NamespacedAPIObject) else None
        obj = cls.objects(api, namespace=namespace).get_by_name(name=name)
        return obj.obj
    except pykube.ObjectDoesNotExist:
        if default is not _UNSET_:
            return default
        raise
    except requests.exceptions.HTTPError as e:
        if e.response.status_code in [403, 404] and default is not _UNSET_:
            return default
        raise
コード例 #5
0
def list_objs(*, resource, namespace=None):
    """
    List the objects of specific resource type.

    The cluster-scoped call is used in two cases:

    * The resource itself is cluster-scoped, and namespacing makes not sense.
    * The operator serves all namespaces for the namespaced custom resource.

    Otherwise, the namespace-scoped call is used:

    * The resource is namespace-scoped AND operator is namespaced-restricted.
    """
    api = auth.get_pykube_api()
    cls = classes._make_cls(resource=resource)
    namespace = namespace if issubclass(
        cls, pykube.objects.NamespacedAPIObject) else None
    lst = cls.objects(api,
                      namespace=pykube.all if namespace is None else namespace)
    return lst.response
コード例 #6
0
ファイル: fetching.py プロジェクト: kevindwei/kopf
def read_obj(
        *,
        resource: resources.Resource,
        namespace: Optional[str] = None,
        name: Optional[str] = None,
        default: Union[_T, _UNSET] = _UNSET.token,
) -> Union[bodies.Body, _T]:
    try:
        api = auth.get_pykube_api()
        cls = classes._make_cls(resource=resource)
        namespace = namespace if issubclass(cls, pykube.objects.NamespacedAPIObject) else None
        obj = cls.objects(api, namespace=namespace).get_by_name(name=name)
        return cast(bodies.Body, obj.obj)
    except pykube.ObjectDoesNotExist:
        if not isinstance(default, _UNSET):
            return default
        raise
    except requests.exceptions.HTTPError as e:
        if not isinstance(default, _UNSET) and e.response.status_code in [403, 404]:
            return default
        raise
コード例 #7
0
def watch_objs(*, resource, namespace=None, timeout=None, since=None):
    """
    Watch the objects of specific resource type.

    The cluster-scoped call is used in two cases:

    * The resource itself is cluster-scoped, and namespacing makes not sense.
    * The operator serves all namespaces for the namespaced custom resource.

    Otherwise, the namespace-scoped call is used:

    * The resource is namespace-scoped AND operator is namespaced-restricted.
    """
    api = auth.get_pykube_api(timeout=timeout)
    cls = classes._make_cls(resource=resource)
    namespace = namespace if issubclass(
        cls, pykube.objects.NamespacedAPIObject) else None
    lst = cls.objects(api,
                      namespace=pykube.all if namespace is None else namespace)
    src = lst.watch(since=since)
    return iter({
        'type': event.type,
        'object': event.object.obj
    } for event in src)
コード例 #8
0
def watch_objs(
    *,
    resource: resources.Resource,
    namespace: Optional[str] = None,
    timeout: Optional[float] = None,
    since: Optional[str] = None,
) -> Iterator[bodies.RawEvent]:
    """
    Watch objects of a specific resource type.

    The cluster-scoped call is used in two cases:

    * The resource itself is cluster-scoped, and namespacing makes not sense.
    * The operator serves all namespaces for the namespaced custom resource.

    Otherwise, the namespace-scoped call is used:

    * The resource is namespace-scoped AND operator is namespaced-restricted.
    """

    params = {}
    if timeout is not None:
        params['timeoutSeconds'] = timeout

    api = auth.get_pykube_api(timeout=None)
    cls = classes._make_cls(resource=resource)
    namespace = namespace if issubclass(
        cls, pykube.objects.NamespacedAPIObject) else None
    lst = cls.objects(api,
                      namespace=pykube.all if namespace is None else namespace)
    src = lst.watch(since=since, params=params)
    return iter(
        cast(bodies.RawEvent, {
            'type': event.type,
            'object': event.object.obj,
        }) for event in src)