From 411b1b0292bb012e58ad34912dce35e4668b54e0 Mon Sep 17 00:00:00 2001 From: Russell Teague Date: Fri, 10 Mar 2017 15:53:35 -0500 Subject: Renaming oadm_manage_node to oc_adm_manage_node --- roles/lib_openshift/src/class/oadm_manage_node.py | 209 --------------------- .../lib_openshift/src/class/oc_adm_manage_node.py | 209 +++++++++++++++++++++ 2 files changed, 209 insertions(+), 209 deletions(-) delete mode 100644 roles/lib_openshift/src/class/oadm_manage_node.py create mode 100644 roles/lib_openshift/src/class/oc_adm_manage_node.py (limited to 'roles/lib_openshift/src/class') diff --git a/roles/lib_openshift/src/class/oadm_manage_node.py b/roles/lib_openshift/src/class/oadm_manage_node.py deleted file mode 100644 index c07320477..000000000 --- a/roles/lib_openshift/src/class/oadm_manage_node.py +++ /dev/null @@ -1,209 +0,0 @@ -# pylint: skip-file -# flake8: noqa - - -class ManageNodeException(Exception): - ''' manage-node exception class ''' - pass - - -class ManageNodeConfig(OpenShiftCLIConfig): - ''' ManageNodeConfig is a DTO for the manage-node command.''' - def __init__(self, kubeconfig, node_options): - super(ManageNodeConfig, self).__init__(None, None, kubeconfig, node_options) - - -# pylint: disable=too-many-instance-attributes -class ManageNode(OpenShiftCLI): - ''' Class to wrap the oc command line tools ''' - - # pylint allows 5 - # pylint: disable=too-many-arguments - def __init__(self, - config, - verbose=False): - ''' Constructor for ManageNode ''' - super(ManageNode, self).__init__(None, kubeconfig=config.kubeconfig, verbose=verbose) - self.config = config - - def evacuate(self): - ''' formulate the params and run oadm manage-node ''' - return self._evacuate(node=self.config.config_options['node']['value'], - selector=self.config.config_options['selector']['value'], - pod_selector=self.config.config_options['pod_selector']['value'], - dry_run=self.config.config_options['dry_run']['value'], - grace_period=self.config.config_options['grace_period']['value'], - force=self.config.config_options['force']['value'], - ) - def get_nodes(self, node=None, selector=''): - '''perform oc get node''' - _node = None - _sel = None - if node: - _node = node - if selector: - _sel = selector - - results = self._get('node', rname=_node, selector=_sel) - if results['returncode'] != 0: - return results - - nodes = [] - items = None - if results['results'][0]['kind'] == 'List': - items = results['results'][0]['items'] - else: - items = results['results'] - - for node in items: - _node = {} - _node['name'] = node['metadata']['name'] - _node['schedulable'] = True - if 'unschedulable' in node['spec']: - _node['schedulable'] = False - nodes.append(_node) - - return nodes - - def get_pods_from_node(self, node, pod_selector=None): - '''return pods for a node''' - results = self._list_pods(node=[node], pod_selector=pod_selector) - - if results['returncode'] != 0: - return results - - # When a selector or node is matched it is returned along with the json. - # We are going to split the results based on the regexp and then - # load the json for each matching node. - # Before we return we are going to loop over the results and pull out the node names. - # {'node': [pod, pod], 'node': [pod, pod]} - # 3.2 includes the following lines in stdout: "Listing matched pods on node:" - all_pods = [] - if "Listing matched" in results['results']: - listing_match = re.compile('\n^Listing matched.*$\n', flags=re.MULTILINE) - pods = listing_match.split(results['results']) - for pod in pods: - if pod: - all_pods.extend(json.loads(pod)['items']) - - # 3.3 specific - else: - # this is gross but I filed a bug... - # https://bugzilla.redhat.com/show_bug.cgi?id=1381621 - # build our own json from the output. - all_pods = json.loads(results['results'])['items'] - - return all_pods - - def list_pods(self): - ''' run oadm manage-node --list-pods''' - _nodes = self.config.config_options['node']['value'] - _selector = self.config.config_options['selector']['value'] - _pod_selector = self.config.config_options['pod_selector']['value'] - - if not _nodes: - _nodes = self.get_nodes(selector=_selector) - else: - _nodes = [{'name': name} for name in _nodes] - - all_pods = {} - for node in _nodes: - results = self.get_pods_from_node(node['name'], pod_selector=_pod_selector) - if isinstance(results, dict): - return results - all_pods[node['name']] = results - - results = {} - results['nodes'] = all_pods - results['returncode'] = 0 - return results - - def schedulable(self): - '''oadm manage-node call for making nodes unschedulable''' - nodes = self.config.config_options['node']['value'] - selector = self.config.config_options['selector']['value'] - - if not nodes: - nodes = self.get_nodes(selector=selector) - else: - tmp_nodes = [] - for name in nodes: - tmp_result = self.get_nodes(name) - if isinstance(tmp_result, dict): - tmp_nodes.append(tmp_result) - continue - tmp_nodes.extend(tmp_result) - nodes = tmp_nodes - - # This is a short circuit based on the way we fetch nodes. - # If node is a dict/list then we've already fetched them. - for node in nodes: - if isinstance(node, dict) and 'returncode' in node: - return {'results': nodes, 'returncode': node['returncode']} - if isinstance(node, list) and 'returncode' in node[0]: - return {'results': nodes, 'returncode': node[0]['returncode']} - # check all the nodes that were returned and verify they are: - # node['schedulable'] == self.config.config_options['schedulable']['value'] - if any([node['schedulable'] != self.config.config_options['schedulable']['value'] for node in nodes]): - - results = self._schedulable(node=self.config.config_options['node']['value'], - selector=self.config.config_options['selector']['value'], - schedulable=self.config.config_options['schedulable']['value']) - - # 'NAME STATUS AGE\\nip-172-31-49-140.ec2.internal Ready 4h\\n' # E501 - # normalize formatting with previous return objects - if results['results'].startswith('NAME'): - nodes = [] - # removing header line and trailing new line character of node lines - for node_results in results['results'].split('\n')[1:-1]: - parts = node_results.split() - nodes.append({'name': parts[0], 'schedulable': parts[1] == 'Ready'}) - results['nodes'] = nodes - - return results - - results = {} - results['returncode'] = 0 - results['changed'] = False - results['nodes'] = nodes - - return results - - @staticmethod - def run_ansible(params, check_mode): - '''run the idempotent ansible code''' - nconfig = ManageNodeConfig(params['kubeconfig'], - {'node': {'value': params['node'], 'include': True}, - 'selector': {'value': params['selector'], 'include': True}, - 'pod_selector': {'value': params['pod_selector'], 'include': True}, - 'schedulable': {'value': params['schedulable'], 'include': True}, - 'list_pods': {'value': params['list_pods'], 'include': True}, - 'evacuate': {'value': params['evacuate'], 'include': True}, - 'dry_run': {'value': params['dry_run'], 'include': True}, - 'force': {'value': params['force'], 'include': True}, - 'grace_period': {'value': params['grace_period'], 'include': True}, - }) - - oadm_mn = ManageNode(nconfig) - # Run the oadm manage-node commands - results = None - changed = False - if params['schedulable'] != None: - if check_mode: - # schedulable returns results after the fact. - # We need to redo how this works to support check_mode completely. - return {'changed': True, 'msg': 'CHECK_MODE: would have called schedulable.'} - results = oadm_mn.schedulable() - if 'changed' not in results: - changed = True - - if params['evacuate']: - results = oadm_mn.evacuate() - changed = True - elif params['list_pods']: - results = oadm_mn.list_pods() - - if not results or results['returncode'] != 0: - return {'failed': True, 'msg': results} - - return {'changed': changed, 'results': results, 'state': "present"} diff --git a/roles/lib_openshift/src/class/oc_adm_manage_node.py b/roles/lib_openshift/src/class/oc_adm_manage_node.py new file mode 100644 index 000000000..c07320477 --- /dev/null +++ b/roles/lib_openshift/src/class/oc_adm_manage_node.py @@ -0,0 +1,209 @@ +# pylint: skip-file +# flake8: noqa + + +class ManageNodeException(Exception): + ''' manage-node exception class ''' + pass + + +class ManageNodeConfig(OpenShiftCLIConfig): + ''' ManageNodeConfig is a DTO for the manage-node command.''' + def __init__(self, kubeconfig, node_options): + super(ManageNodeConfig, self).__init__(None, None, kubeconfig, node_options) + + +# pylint: disable=too-many-instance-attributes +class ManageNode(OpenShiftCLI): + ''' Class to wrap the oc command line tools ''' + + # pylint allows 5 + # pylint: disable=too-many-arguments + def __init__(self, + config, + verbose=False): + ''' Constructor for ManageNode ''' + super(ManageNode, self).__init__(None, kubeconfig=config.kubeconfig, verbose=verbose) + self.config = config + + def evacuate(self): + ''' formulate the params and run oadm manage-node ''' + return self._evacuate(node=self.config.config_options['node']['value'], + selector=self.config.config_options['selector']['value'], + pod_selector=self.config.config_options['pod_selector']['value'], + dry_run=self.config.config_options['dry_run']['value'], + grace_period=self.config.config_options['grace_period']['value'], + force=self.config.config_options['force']['value'], + ) + def get_nodes(self, node=None, selector=''): + '''perform oc get node''' + _node = None + _sel = None + if node: + _node = node + if selector: + _sel = selector + + results = self._get('node', rname=_node, selector=_sel) + if results['returncode'] != 0: + return results + + nodes = [] + items = None + if results['results'][0]['kind'] == 'List': + items = results['results'][0]['items'] + else: + items = results['results'] + + for node in items: + _node = {} + _node['name'] = node['metadata']['name'] + _node['schedulable'] = True + if 'unschedulable' in node['spec']: + _node['schedulable'] = False + nodes.append(_node) + + return nodes + + def get_pods_from_node(self, node, pod_selector=None): + '''return pods for a node''' + results = self._list_pods(node=[node], pod_selector=pod_selector) + + if results['returncode'] != 0: + return results + + # When a selector or node is matched it is returned along with the json. + # We are going to split the results based on the regexp and then + # load the json for each matching node. + # Before we return we are going to loop over the results and pull out the node names. + # {'node': [pod, pod], 'node': [pod, pod]} + # 3.2 includes the following lines in stdout: "Listing matched pods on node:" + all_pods = [] + if "Listing matched" in results['results']: + listing_match = re.compile('\n^Listing matched.*$\n', flags=re.MULTILINE) + pods = listing_match.split(results['results']) + for pod in pods: + if pod: + all_pods.extend(json.loads(pod)['items']) + + # 3.3 specific + else: + # this is gross but I filed a bug... + # https://bugzilla.redhat.com/show_bug.cgi?id=1381621 + # build our own json from the output. + all_pods = json.loads(results['results'])['items'] + + return all_pods + + def list_pods(self): + ''' run oadm manage-node --list-pods''' + _nodes = self.config.config_options['node']['value'] + _selector = self.config.config_options['selector']['value'] + _pod_selector = self.config.config_options['pod_selector']['value'] + + if not _nodes: + _nodes = self.get_nodes(selector=_selector) + else: + _nodes = [{'name': name} for name in _nodes] + + all_pods = {} + for node in _nodes: + results = self.get_pods_from_node(node['name'], pod_selector=_pod_selector) + if isinstance(results, dict): + return results + all_pods[node['name']] = results + + results = {} + results['nodes'] = all_pods + results['returncode'] = 0 + return results + + def schedulable(self): + '''oadm manage-node call for making nodes unschedulable''' + nodes = self.config.config_options['node']['value'] + selector = self.config.config_options['selector']['value'] + + if not nodes: + nodes = self.get_nodes(selector=selector) + else: + tmp_nodes = [] + for name in nodes: + tmp_result = self.get_nodes(name) + if isinstance(tmp_result, dict): + tmp_nodes.append(tmp_result) + continue + tmp_nodes.extend(tmp_result) + nodes = tmp_nodes + + # This is a short circuit based on the way we fetch nodes. + # If node is a dict/list then we've already fetched them. + for node in nodes: + if isinstance(node, dict) and 'returncode' in node: + return {'results': nodes, 'returncode': node['returncode']} + if isinstance(node, list) and 'returncode' in node[0]: + return {'results': nodes, 'returncode': node[0]['returncode']} + # check all the nodes that were returned and verify they are: + # node['schedulable'] == self.config.config_options['schedulable']['value'] + if any([node['schedulable'] != self.config.config_options['schedulable']['value'] for node in nodes]): + + results = self._schedulable(node=self.config.config_options['node']['value'], + selector=self.config.config_options['selector']['value'], + schedulable=self.config.config_options['schedulable']['value']) + + # 'NAME STATUS AGE\\nip-172-31-49-140.ec2.internal Ready 4h\\n' # E501 + # normalize formatting with previous return objects + if results['results'].startswith('NAME'): + nodes = [] + # removing header line and trailing new line character of node lines + for node_results in results['results'].split('\n')[1:-1]: + parts = node_results.split() + nodes.append({'name': parts[0], 'schedulable': parts[1] == 'Ready'}) + results['nodes'] = nodes + + return results + + results = {} + results['returncode'] = 0 + results['changed'] = False + results['nodes'] = nodes + + return results + + @staticmethod + def run_ansible(params, check_mode): + '''run the idempotent ansible code''' + nconfig = ManageNodeConfig(params['kubeconfig'], + {'node': {'value': params['node'], 'include': True}, + 'selector': {'value': params['selector'], 'include': True}, + 'pod_selector': {'value': params['pod_selector'], 'include': True}, + 'schedulable': {'value': params['schedulable'], 'include': True}, + 'list_pods': {'value': params['list_pods'], 'include': True}, + 'evacuate': {'value': params['evacuate'], 'include': True}, + 'dry_run': {'value': params['dry_run'], 'include': True}, + 'force': {'value': params['force'], 'include': True}, + 'grace_period': {'value': params['grace_period'], 'include': True}, + }) + + oadm_mn = ManageNode(nconfig) + # Run the oadm manage-node commands + results = None + changed = False + if params['schedulable'] != None: + if check_mode: + # schedulable returns results after the fact. + # We need to redo how this works to support check_mode completely. + return {'changed': True, 'msg': 'CHECK_MODE: would have called schedulable.'} + results = oadm_mn.schedulable() + if 'changed' not in results: + changed = True + + if params['evacuate']: + results = oadm_mn.evacuate() + changed = True + elif params['list_pods']: + results = oadm_mn.list_pods() + + if not results or results['returncode'] != 0: + return {'failed': True, 'msg': results} + + return {'changed': changed, 'results': results, 'state': "present"} -- cgit v1.2.3