def apply_oc_resource( template_name, cluster_path, _templating, template_data={}, template_dir="ocs-deployment", ): """ Apply an oc resource after rendering the specified template with the rook data from cluster_conf. Args: template_name (str): Name of the ocs-deployment config template cluster_path (str): Path to cluster directory, where files will be written _templating (Templating): Object of Templating class used for templating template_data (dict): Data for render template (default: {}) template_dir (str): Directory under templates dir where template exists (default: ocs-deployment) """ template_path = os.path.join(template_dir, template_name) template = _templating.render_template(template_path, template_data) cfg_file = os.path.join(cluster_path, template_name) with open(cfg_file, "w") as f: f.write(template) log.info(f"Applying rook resource from {template_name}") occli = OCP() occli.apply(cfg_file)
def __init__(self, **kwargs): """ Initializer function Args: kwargs (dict): 1) For existing resource, use OCP.reload() to get the resource's dictionary and use it to pass as **kwargs 2) For new resource, use yaml files templates under /templates/CSI like: obj_dict = load_yaml_to_dict( os.path.join( TEMPLATE_DIR, "some_resource.yaml" ) ) """ self.data = kwargs self._api_version = self.data.get('api_version') self._kind = self.data.get('kind') self._namespace = None if 'metadata' in self.data: self._namespace = self.data.get('metadata').get('namespace') self._name = self.data.get('metadata').get('name') self.ocp = OCP(api_version=self._api_version, kind=self.kind, namespace=self._namespace) self.temp_yaml = tempfile.NamedTemporaryFile(mode='w+', prefix=self._kind, delete=False)
def get_all_pods(namespace=None): """ Get all pods in a namespace. If namespace is None - get all pods Returns: list: List of Pod objects """ ocp_pod_obj = OCP(kind=constants.POD, namespace=namespace) pods = ocp_pod_obj.get()['items'] pod_objs = [Pod(**pod) for pod in pods] return pod_objs
def get_all_pvcs(): """ Gets all pvc in given namespace Returns: dict: Dict of all pvc in namespaces """ ocp_pvc_obj = OCP(kind=constants.PVC, namespace=ENV_DATA['cluster_namespace']) out = ocp_pvc_obj.get() return out
def get_ceph_tools_pod(): """ Get the Ceph tools pod Returns: Pod object: The Ceph tools pod object """ ocp_pod_obj = OCP(kind=constants.POD, namespace=ENV_DATA['cluster_namespace']) ct_pod = ocp_pod_obj.get(selector='app=rook-ceph-tools')['items'][0] assert ct_pod, f"No Ceph tools pod found" ceph_pod = Pod(**ct_pod) return ceph_pod
def delete_all_pvcs(): """ Deletes all pvc in namespace Returns: bool: True if deletion is successful """ ocp_pvc_obj = OCP(kind=constants.PVC, namespace=ENV_DATA['cluster_namespace']) ocp_pvc_list = get_all_pvcs() pvc_list = ocp_pvc_list['items'] for item in pvc_list: ocp_pvc_obj.delete(resource_name=item.get('metadata').get('name')) return True
def __init__(self, **kwargs): """ Initializer function kwargs: Copy of ocs/defaults.py::<some pod> dictionary """ self.pod_data = kwargs super(Pod, self).__init__(**kwargs) self.temp_yaml = tempfile.NamedTemporaryFile(mode='w+', prefix='POD_', delete=False) self._name = self.pod_data.get('metadata').get('name') self._labels = self.get_labels() self._roles = [] self.ocp = OCP(api_version=defaults.API_VERSION, kind=constants.POD, namespace=self.namespace)
class Pod(OCS): """ Handles per pod related context """ def __init__(self, **kwargs): """ Initializer function kwargs: Copy of ocs/defaults.py::<some pod> dictionary """ self.pod_data = kwargs super(Pod, self).__init__(**kwargs) self.temp_yaml = tempfile.NamedTemporaryFile( mode='w+', prefix='POD_', delete=False ) self._name = self.pod_data.get('metadata').get('name') self._labels = self.get_labels() self._roles = [] self.ocp = OCP( api_version=defaults.API_VERSION, kind=constants.POD, namespace=self.namespace ) # TODO: get backend config !! @property def name(self): return self._name @property def namespace(self): return self._namespace @property def roles(self): return self._roles @property def labels(self): return self._labels def add_role(self, role): """ Adds a new role for this pod Args: role (str): New role to be assigned for this pod """ self._roles.append(role) def exec_cmd_on_pod(self, command): """ Execute a command on a pod (e.g. oc rsh) Args: command (str): The command to execute on the given pod Returns: Munch Obj: This object represents a returned yaml file """ rsh_cmd = f"rsh {self.name} " rsh_cmd += command return self.ocp.exec_oc_cmd(rsh_cmd) def get_labels(self): """ Get labels from pod Raises: NotFoundError: If resource not found Returns: dict: All the openshift labels on a given pod """ return self.pod_data.get('metadata').get('labels') def exec_ceph_cmd(self, ceph_cmd, format='json-pretty'): """ Execute a Ceph command on the Ceph tools pod Args: ceph_cmd (str): The Ceph command to execute on the Ceph tools pod format (str): The returning output format of the Ceph command Returns: dict: Ceph command output Raises: CommandFailed: In case the pod is not a toolbox pod """ if 'rook-ceph-tools' not in self.labels.values(): raise CommandFailed( "Ceph commands can be executed only on toolbox pod" ) ceph_cmd = ceph_cmd if format: ceph_cmd += f" --format {format}" out = self.exec_cmd_on_pod(ceph_cmd) # For some commands, like "ceph fs ls", the returned output is a list if isinstance(out, list): return [item for item in out if item] return out
import logging import pytest from ocs import defaults from ocsci import config from ocsci.testlib import tier1, ManageTest from resources.ocs import OCS from resources.pvc import PVC from tests import helpers from ocs.ocp import OCP from ocs.exceptions import CommandFailed log = logging.getLogger(__name__) OCCLI = OCP(kind='service', namespace=config.ENV_DATA['cluster_namespace']) SC_OBJ = None @pytest.fixture(scope='class') def test_fixture(request): """ This is a test fixture """ self = request.node.cls def finalizer(): teardown() request.addfinalizer(finalizer) setup(self)
class OCS(object): """ Base OCSClass """ def __init__(self, **kwargs): """ Initializer function Args: kwargs (dict): 1) For existing resource, use OCP.reload() to get the resource's dictionary and use it to pass as **kwargs 2) For new resource, use yaml files templates under /templates/CSI like: obj_dict = load_yaml_to_dict( os.path.join( TEMPLATE_DIR, "some_resource.yaml" ) ) """ self.data = kwargs self._api_version = self.data.get('api_version') self._kind = self.data.get('kind') self._namespace = None if 'metadata' in self.data: self._namespace = self.data.get('metadata').get('namespace') self._name = self.data.get('metadata').get('name') self.ocp = OCP(api_version=self._api_version, kind=self.kind, namespace=self._namespace) self.temp_yaml = tempfile.NamedTemporaryFile(mode='w+', prefix=self._kind, delete=False) @property def api_version(self): return self._api_version @property def kind(self): return self._kind @property def namespace(self): return self._namespace @property def name(self): return self._name def reload(self): """ Reloading the OCS instance with the new information from its actual data. After creating a resource from a yaml file, the actual yaml file is being changed and more information about the resource is added. """ self.data = self.get() self.__init__(**self.data) def get(self, out_yaml_format=True): return self.ocp.get(resource_name=self.name, out_yaml_format=out_yaml_format) def create(self): log.info(f"Adding {self.kind} with name {self.name}") templating.dump_dict_to_temp_yaml(self.data, self.temp_yaml.name) status = self.ocp.create(yaml_file=self.temp_yaml.name) self.reload() return status def delete(self, wait=True): return self.ocp.delete(resource_name=self.name, wait=wait) def apply(self, **data): with open(self.temp_yaml.name, 'w') as yaml_file: yaml.dump(data, yaml_file) assert self.ocp.apply( yaml_file=self.temp_yaml.name), (f"Failed to apply changes {data}") self.reload() def add_label(self, label): """ Addss a new label Args: label (str): New label to be assigned for this pod E.g: "label=app='rook-ceph-mds'" """ status = self.ocp.add_label(resource_name=self.name, label=label) self.reload() return status def delete_temp_yaml_file(self): utils.delete_file(self.temp_yaml.name)