A kubernetes client that dynamically discovers and interacts with the kubernetes API
| 65 | |
| 66 | |
| 67 | class DynamicClient: |
| 68 | """ A kubernetes client that dynamically discovers and interacts with |
| 69 | the kubernetes API |
| 70 | """ |
| 71 | |
| 72 | def __init__(self, client, cache_file=None, discoverer=None): |
| 73 | # Setting default here to delay evaluation of LazyDiscoverer class |
| 74 | # until constructor is called |
| 75 | discoverer = discoverer or LazyDiscoverer |
| 76 | |
| 77 | self.client = client |
| 78 | self.configuration = client.configuration |
| 79 | self.__discoverer = discoverer(self, cache_file) |
| 80 | |
| 81 | @property |
| 82 | def resources(self): |
| 83 | return self.__discoverer |
| 84 | |
| 85 | @property |
| 86 | def version(self): |
| 87 | return self.__discoverer.version |
| 88 | |
| 89 | def ensure_namespace(self, resource, namespace, body): |
| 90 | namespace = namespace or body.get('metadata', {}).get('namespace') |
| 91 | if not namespace: |
| 92 | raise ValueError("Namespace is required for {}.{}".format(resource.group_version, resource.kind)) |
| 93 | return namespace |
| 94 | |
| 95 | def serialize_body(self, body): |
| 96 | """Serialize body to raw dict so apiserver can handle it |
| 97 | |
| 98 | :param body: kubernetes resource body, current support: Union[Dict, ResourceInstance] |
| 99 | """ |
| 100 | # This should match any `ResourceInstance` instances |
| 101 | if callable(getattr(body, 'to_dict', None)): |
| 102 | return body.to_dict() |
| 103 | return body or {} |
| 104 | |
| 105 | def get(self, resource, name=None, namespace=None, **kwargs): |
| 106 | path = resource.path(name=name, namespace=namespace) |
| 107 | return self.request('get', path, **kwargs) |
| 108 | |
| 109 | def create(self, resource, body=None, namespace=None, **kwargs): |
| 110 | body = self.serialize_body(body) |
| 111 | if resource.namespaced: |
| 112 | namespace = self.ensure_namespace(resource, namespace, body) |
| 113 | path = resource.path(namespace=namespace) |
| 114 | return self.request('post', path, body=body, **kwargs) |
| 115 | |
| 116 | def delete(self, resource, name=None, namespace=None, body=None, label_selector=None, field_selector=None, **kwargs): |
| 117 | if not (name or label_selector or field_selector): |
| 118 | raise ValueError("At least one of name|label_selector|field_selector is required") |
| 119 | if resource.namespaced and not (label_selector or field_selector or namespace): |
| 120 | raise ValueError("At least one of namespace|label_selector|field_selector is required") |
| 121 | path = resource.path(name=name, namespace=namespace) |
| 122 | return self.request('delete', path, body=body, label_selector=label_selector, field_selector=field_selector, **kwargs) |
| 123 | |
| 124 | def replace(self, resource, body=None, name=None, namespace=None, **kwargs): |
no outgoing calls