Refactoring of k8s manager and tests

Changes:
 - Official kubernetes python lib
 - Rewrite k8s api wrapper in OOP manner
 - Use api where its possible instead of cli
 - Remove virtlet code because its can be replaced with pod api
 - Remove unused/oudated manager code
 - Remove bug workaround in k8s upgrade template
 - Remove netchecker obsolete code
 - Remove unfinished test_rbd_flexvolume_driver

Change-Id: I446a240123282196a6ba54f588aea84791f175ba
Related-PROD: PROD-21700
diff --git a/tcp_tests/managers/k8s/base.py b/tcp_tests/managers/k8s/base.py
index 7adb41a..6ca6a88 100644
--- a/tcp_tests/managers/k8s/base.py
+++ b/tcp_tests/managers/k8s/base.py
@@ -12,97 +12,140 @@
 #    License for the specific language governing permissions and limitations
 
 
-class K8sBaseResource(object):
-    """docstring for K8sBaseResource"""
+import yaml
+import requests
+import os
 
-    def __init__(self, manager, data):
+from tcp_tests import logger
+
+LOG = logger.logger
+
+
+class K8sBaseResource(object):
+    resource_type = None
+
+    def __init__(self, manager, name=None, namespace=None, data=None):
         self._manager = manager
-        self._add_details(data)
+        self._name = name
+        self._namespace = namespace
+        self._read_cache = None
+        if data is not None:
+            self._update_cache(data)
 
     def __repr__(self):
-        reprkeys = sorted(k
-                          for k in self.__dict__.keys()
-                          if k[0] != '_' and
-                          k not in ['manager'])
-        info = ", ".join("%s=%s" % (k, getattr(self, k)) for k in reprkeys)
-        return "<%s %s>" % (self.__class__.__name__, info)
+        uid = 'unknown-uid'
+        if self._read_cache is not None:
+            uid = self.uid
+        return "<{0} name='{1}' namespace='{2}' uuid='{3}'>".format(
+            self.__class__.__name__, self.name, self.namespace, uid)
 
     @property
-    def api_version(self):
-        return self._data.api_version
-
-    def _add_details(self, data):
-        self._data = data
-        for k in [k for k in dir(data)
-                  if not any((k.startswith('_'), k in ('to_dict', 'to_str')))]:
-            try:
-                setattr(self, k, getattr(data, k))
-            except AttributeError:
-                # In this case we already defined the attribute on the class
-                pass
-
-    def __eq__(self, other):
-        if not isinstance(other, K8sBaseResource):
-            return NotImplemented
-        # two resources of different types are not equal
-        if not isinstance(other, self.__class__):
-            return False
-        return self._info == other._info
-
-
-class K8sBaseManager(object):
-
-    resource_class = None
-
-    def __init__(self, api, namespace):
-        self._api = api
-        self._namespace = namespace
-        self._raw = None
-
-    @property
-    def api(self):
-        return self._api
+    def name(self):
+        return self._name
 
     @property
     def namespace(self):
         return self._namespace
 
-    def get(self, *args, **kwargs):
-        if not hasattr(self, '_get'):
-            raise NotImplementedError(
-                '{} does not have {}'.format(self, '_get'))
+    @property
+    def uid(self):
+        return self.read(cached=True).metadata.uid
 
-        return self.resource_class(self, self._get(*args, **kwargs))
+    def _update_cache(self, data):
+        self._read_cache = data
+        self._namespace = data.metadata.namespace
+        self._name = data.metadata.name
 
-    def list(self, *args, **kwargs):
-        if not hasattr(self, '_list'):
-            raise NotImplementedError(
-                '{} does not have {}'.format(self, '_list'))
+    def read(self, cached=False, **kwargs):
+        if not cached:
+            self._update_cache(self._read(**kwargs))
+        return self._read_cache
 
-        lst = self._list(*args, **kwargs)
+    def create(self, body, **kwargs):
+        LOG.info("K8S API Creating {0} with body:\n{1}".format(
+                 self.resource_type, body))
 
-        return [self.resource_class(self, item) for item in lst.items]
+        self._update_cache(self._create(body, **kwargs))
+        return self
 
-    def create(self, *args, **kwargs):
-        if not hasattr(self, '_create'):
-            raise NotImplementedError(
-                '{} does not have {}'.format(self, '_create'))
-        return self.resource_class(self, self._create(*args, **kwargs))
+    def patch(self, body, **kwargs):
 
-    def replace(self, *args, **kwargs):
-        if not hasattr(self, '_replace'):
-            raise NotImplementedError(
-                '{} does not have {}'.format(self, '_replace'))
-        return self._replace(*args, **kwargs)
+        LOG.info("K8S API Patching {0} name={1} ns={2} with body:\n{3}".format(
+                 self.resource_type, self.name, self.namespace, body))
 
-    def delete(self, *args, **kwargs):
-        if not hasattr(self, '_delete'):
-            raise NotImplementedError(
-                '{} does not have {}'.format(self, '_delete'))
-        return self._delete(*args, **kwargs)
+        self._update_cache(self._patch(body, **kwargs))
+        return self
 
-    def deletecollection(self, *args, **kwargs):
-        if not hasattr(self, '_deletecollection'):
-            raise NotImplementedError(
-                '{} does not have {}'.format(self, '_deletecollection'))
-        return self._deletecollection(*args, **kwargs)
+    def replace(self, body, **kwargs):
+        self._update_cache(self._replace(body, **kwargs))
+        return self
+
+    def delete(self, **kwargs):
+        self._delete(**kwargs)
+        return self
+
+    def __eq__(self, other):
+        if not isinstance(other, K8sBaseResource):
+            return NotImplemented
+
+        if not isinstance(other, self.__class__):
+            return False
+
+        return self.uid == other.uid
+
+
+class K8sBaseManager(object):
+    resource_class = None
+
+    def __init__(self, cluster):
+        self._cluster = cluster
+
+    @property
+    def resource_type(self):
+        return self.resource_class.resource_type
+
+    def get(self, name=None, namespace=None, data=None):
+        namespace = namespace or self._cluster.default_namespace
+        return self.resource_class(self, name, namespace, data)
+
+    def create(self, name=None, namespace=None, body=None, **kwargs):
+        return self.get(name=name, namespace=namespace).create(body, **kwargs)
+
+    def __resource_from_data(self, data):
+        return self.resource_class(self, data=data)
+
+    def __list_filter(self, items, name_prefix=None):
+        if name_prefix is not None:
+            items = [item for item in items if
+                     item.metadata.name.startswith(name_prefix)]
+        return items
+
+    def __list_to_resource(self, items):
+        return [self.__resource_from_data(item) for item in items]
+
+    def list(self, namespace=None, name_prefix=None, **kwargs):
+        namespace = namespace or self._cluster.default_namespace
+        items = self._list(namespace=namespace, **kwargs).items
+        items = self.__list_filter(items, name_prefix=name_prefix)
+        return self.__list_to_resource(items)
+
+    def list_all(self, name_prefix=None, **kwargs):
+        items = self._list_all(**kwargs).items
+        items = self.__list_filter(items, name_prefix=name_prefix)
+        return self.__list_to_resource(items)
+
+
+def read_yaml_str(yaml_str):
+    """ load yaml from string helper """
+    return yaml.safe_load(yaml_str)
+
+
+def read_yaml_file(file_path, *args):
+    """ load yaml from joined file_path and *args helper """
+    with open(os.path.join(file_path, *args)) as f:
+        return yaml.safe_load(f)
+
+
+def read_yaml_url(yaml_file_url):
+    """ load yaml from url helper """
+    return yaml.safe_load(requests.get(yaml_file_url).text)