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
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)
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
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
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
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
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)
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)