Artem Panchenko | 0594cd7 | 2017-06-12 13:25:26 +0300 | [diff] [blame] | 1 | # Copyright 2017 Mirantis, Inc. |
| 2 | # |
| 3 | # Licensed under the Apache License, Version 2.0 (the "License"); you may |
| 4 | # not use this file except in compliance with the License. You may obtain |
| 5 | # a copy of the License at |
| 6 | # |
| 7 | # http://www.apache.org/licenses/LICENSE-2.0 |
| 8 | # |
| 9 | # Unless required by applicable law or agreed to in writing, software |
| 10 | # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT |
| 11 | # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the |
| 12 | # License for the specific language governing permissions and limitations |
| 13 | |
| 14 | |
Vladimir Jigulin | 4ad52a8 | 2018-08-12 05:51:30 +0400 | [diff] [blame] | 15 | import yaml |
| 16 | import requests |
| 17 | import os |
Artem Panchenko | 0594cd7 | 2017-06-12 13:25:26 +0300 | [diff] [blame] | 18 | |
Vladimir Jigulin | 4ad52a8 | 2018-08-12 05:51:30 +0400 | [diff] [blame] | 19 | from tcp_tests import logger |
| 20 | |
| 21 | LOG = logger.logger |
| 22 | |
| 23 | |
| 24 | class K8sBaseResource(object): |
| 25 | resource_type = None |
| 26 | |
| 27 | def __init__(self, manager, name=None, namespace=None, data=None): |
Artem Panchenko | 0594cd7 | 2017-06-12 13:25:26 +0300 | [diff] [blame] | 28 | self._manager = manager |
Vladimir Jigulin | 4ad52a8 | 2018-08-12 05:51:30 +0400 | [diff] [blame] | 29 | self._name = name |
| 30 | self._namespace = namespace |
| 31 | self._read_cache = None |
| 32 | if data is not None: |
| 33 | self._update_cache(data) |
Artem Panchenko | 0594cd7 | 2017-06-12 13:25:26 +0300 | [diff] [blame] | 34 | |
| 35 | def __repr__(self): |
Vladimir Jigulin | 4ad52a8 | 2018-08-12 05:51:30 +0400 | [diff] [blame] | 36 | uid = 'unknown-uid' |
| 37 | if self._read_cache is not None: |
| 38 | uid = self.uid |
| 39 | return "<{0} name='{1}' namespace='{2}' uuid='{3}'>".format( |
| 40 | self.__class__.__name__, self.name, self.namespace, uid) |
Artem Panchenko | 0594cd7 | 2017-06-12 13:25:26 +0300 | [diff] [blame] | 41 | |
| 42 | @property |
Vladimir Jigulin | 4ad52a8 | 2018-08-12 05:51:30 +0400 | [diff] [blame] | 43 | def name(self): |
| 44 | return self._name |
Artem Panchenko | 0594cd7 | 2017-06-12 13:25:26 +0300 | [diff] [blame] | 45 | |
| 46 | @property |
| 47 | def namespace(self): |
| 48 | return self._namespace |
| 49 | |
Vladimir Jigulin | 4ad52a8 | 2018-08-12 05:51:30 +0400 | [diff] [blame] | 50 | @property |
| 51 | def uid(self): |
| 52 | return self.read(cached=True).metadata.uid |
Artem Panchenko | 0594cd7 | 2017-06-12 13:25:26 +0300 | [diff] [blame] | 53 | |
Vladimir Jigulin | 4ad52a8 | 2018-08-12 05:51:30 +0400 | [diff] [blame] | 54 | def _update_cache(self, data): |
| 55 | self._read_cache = data |
| 56 | self._namespace = data.metadata.namespace |
| 57 | self._name = data.metadata.name |
Artem Panchenko | 0594cd7 | 2017-06-12 13:25:26 +0300 | [diff] [blame] | 58 | |
Vladimir Jigulin | 4ad52a8 | 2018-08-12 05:51:30 +0400 | [diff] [blame] | 59 | def read(self, cached=False, **kwargs): |
| 60 | if not cached: |
| 61 | self._update_cache(self._read(**kwargs)) |
| 62 | return self._read_cache |
Artem Panchenko | 0594cd7 | 2017-06-12 13:25:26 +0300 | [diff] [blame] | 63 | |
Vladimir Jigulin | 4ad52a8 | 2018-08-12 05:51:30 +0400 | [diff] [blame] | 64 | def create(self, body, **kwargs): |
| 65 | LOG.info("K8S API Creating {0} with body:\n{1}".format( |
| 66 | self.resource_type, body)) |
Artem Panchenko | 0594cd7 | 2017-06-12 13:25:26 +0300 | [diff] [blame] | 67 | |
Vladimir Jigulin | 4ad52a8 | 2018-08-12 05:51:30 +0400 | [diff] [blame] | 68 | self._update_cache(self._create(body, **kwargs)) |
| 69 | return self |
Artem Panchenko | 0594cd7 | 2017-06-12 13:25:26 +0300 | [diff] [blame] | 70 | |
Vladimir Jigulin | 4ad52a8 | 2018-08-12 05:51:30 +0400 | [diff] [blame] | 71 | def patch(self, body, **kwargs): |
Artem Panchenko | 0594cd7 | 2017-06-12 13:25:26 +0300 | [diff] [blame] | 72 | |
Vladimir Jigulin | 4ad52a8 | 2018-08-12 05:51:30 +0400 | [diff] [blame] | 73 | LOG.info("K8S API Patching {0} name={1} ns={2} with body:\n{3}".format( |
| 74 | self.resource_type, self.name, self.namespace, body)) |
Artem Panchenko | 0594cd7 | 2017-06-12 13:25:26 +0300 | [diff] [blame] | 75 | |
Vladimir Jigulin | 4ad52a8 | 2018-08-12 05:51:30 +0400 | [diff] [blame] | 76 | self._update_cache(self._patch(body, **kwargs)) |
| 77 | return self |
Artem Panchenko | 0594cd7 | 2017-06-12 13:25:26 +0300 | [diff] [blame] | 78 | |
Vladimir Jigulin | 4ad52a8 | 2018-08-12 05:51:30 +0400 | [diff] [blame] | 79 | def replace(self, body, **kwargs): |
| 80 | self._update_cache(self._replace(body, **kwargs)) |
| 81 | return self |
| 82 | |
| 83 | def delete(self, **kwargs): |
| 84 | self._delete(**kwargs) |
| 85 | return self |
| 86 | |
| 87 | def __eq__(self, other): |
| 88 | if not isinstance(other, K8sBaseResource): |
| 89 | return NotImplemented |
| 90 | |
| 91 | if not isinstance(other, self.__class__): |
| 92 | return False |
| 93 | |
| 94 | return self.uid == other.uid |
| 95 | |
| 96 | |
| 97 | class K8sBaseManager(object): |
| 98 | resource_class = None |
| 99 | |
| 100 | def __init__(self, cluster): |
| 101 | self._cluster = cluster |
| 102 | |
| 103 | @property |
| 104 | def resource_type(self): |
| 105 | return self.resource_class.resource_type |
| 106 | |
| 107 | def get(self, name=None, namespace=None, data=None): |
| 108 | namespace = namespace or self._cluster.default_namespace |
| 109 | return self.resource_class(self, name, namespace, data) |
| 110 | |
| 111 | def create(self, name=None, namespace=None, body=None, **kwargs): |
| 112 | return self.get(name=name, namespace=namespace).create(body, **kwargs) |
| 113 | |
| 114 | def __resource_from_data(self, data): |
| 115 | return self.resource_class(self, data=data) |
| 116 | |
| 117 | def __list_filter(self, items, name_prefix=None): |
| 118 | if name_prefix is not None: |
| 119 | items = [item for item in items if |
| 120 | item.metadata.name.startswith(name_prefix)] |
| 121 | return items |
| 122 | |
| 123 | def __list_to_resource(self, items): |
| 124 | return [self.__resource_from_data(item) for item in items] |
| 125 | |
| 126 | def list(self, namespace=None, name_prefix=None, **kwargs): |
| 127 | namespace = namespace or self._cluster.default_namespace |
| 128 | items = self._list(namespace=namespace, **kwargs).items |
| 129 | items = self.__list_filter(items, name_prefix=name_prefix) |
| 130 | return self.__list_to_resource(items) |
| 131 | |
| 132 | def list_all(self, name_prefix=None, **kwargs): |
| 133 | items = self._list_all(**kwargs).items |
| 134 | items = self.__list_filter(items, name_prefix=name_prefix) |
| 135 | return self.__list_to_resource(items) |
| 136 | |
| 137 | |
| 138 | def read_yaml_str(yaml_str): |
| 139 | """ load yaml from string helper """ |
| 140 | return yaml.safe_load(yaml_str) |
| 141 | |
| 142 | |
| 143 | def read_yaml_file(file_path, *args): |
| 144 | """ load yaml from joined file_path and *args helper """ |
| 145 | with open(os.path.join(file_path, *args)) as f: |
| 146 | return yaml.safe_load(f) |
| 147 | |
| 148 | |
| 149 | def read_yaml_url(yaml_file_url): |
| 150 | """ load yaml from url helper """ |
| 151 | return yaml.safe_load(requests.get(yaml_file_url).text) |