aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--sos/collector/clusters/kubernetes.py8
-rw-r--r--sos/collector/clusters/ocp.py109
2 files changed, 109 insertions, 8 deletions
diff --git a/sos/collector/clusters/kubernetes.py b/sos/collector/clusters/kubernetes.py
index 6a867e31..08fd9554 100644
--- a/sos/collector/clusters/kubernetes.py
+++ b/sos/collector/clusters/kubernetes.py
@@ -44,11 +44,3 @@ class kubernetes(Cluster):
return nodes
else:
raise Exception('Node enumeration did not return usable output')
-
-
-class openshift(kubernetes):
-
- cluster_name = 'OpenShift Container Platform'
- packages = ('atomic-openshift',)
- sos_preset = 'ocp'
- cmd = 'oc'
diff --git a/sos/collector/clusters/ocp.py b/sos/collector/clusters/ocp.py
new file mode 100644
index 00000000..283fcfd1
--- /dev/null
+++ b/sos/collector/clusters/ocp.py
@@ -0,0 +1,109 @@
+# Copyright Red Hat 2021, Jake Hunsaker <jhunsake@redhat.com>
+
+# This file is part of the sos project: https://github.com/sosreport/sos
+#
+# This copyrighted material is made available to anyone wishing to use,
+# modify, copy, or redistribute it subject to the terms and conditions of
+# version 2 of the GNU General Public License.
+#
+# See the LICENSE file in the source distribution for further information.
+
+from pipes import quote
+from sos.collector.clusters import Cluster
+
+
+class ocp(Cluster):
+ """OpenShift Container Platform v4"""
+
+ cluster_name = 'OpenShift Container Platform v4'
+ packages = ('openshift-hyperkube', 'openshift-clients')
+
+ option_list = [
+ ('label', '', 'Colon delimited list of labels to select nodes with'),
+ ('role', '', 'Colon delimited list of roles to select nodes with'),
+ ('kubeconfig', '', 'Path to the kubeconfig file')
+ ]
+
+ def fmt_oc_cmd(self, cmd):
+ """Format the oc command to optionall include the kubeconfig file if
+ one is specified
+ """
+ if self.get_option('kubeconfig'):
+ return "oc --config %s %s" % (self.get_option('kubeconfig'), cmd)
+ return "oc %s" % cmd
+
+ def check_enabled(self):
+ if super(ocp, self).check_enabled():
+ return True
+ _who = self.fmt_oc_cmd('whoami')
+ return self.exec_master_cmd(_who)['status'] == 0
+
+ def _build_dict(self, nodelist):
+ """From the output of get_nodes(), construct an easier-to-reference
+ dict of nodes that will be used in determining labels, master status,
+ etc...
+
+ :param nodelist: The split output of `oc get nodes`
+ :type nodelist: ``list``
+
+ :returns: A dict of nodes with `get nodes` columns as keys
+ :rtype: ``dict``
+ """
+ nodes = {}
+ if 'NAME' in nodelist[0]:
+ # get the index of the fields
+ statline = nodelist.pop(0).split()
+ idx = {}
+ for state in ['status', 'roles', 'version', 'os-image']:
+ try:
+ idx[state] = statline.index(state.upper())
+ except Exception:
+ pass
+ for node in nodelist:
+ _node = node.split()
+ nodes[_node[0]] = {}
+ for column in idx:
+ nodes[_node[0]][column] = _node[idx[column]]
+ return nodes
+
+ def get_nodes(self):
+ nodes = []
+ self.node_dict = {}
+ cmd = 'get nodes -o wide'
+ if self.get_option('label'):
+ labels = ','.join(self.get_option('label').split(':'))
+ cmd += " -l %s" % quote(labels)
+ res = self.exec_master_cmd(self.fmt_oc_cmd(cmd))
+ if res['status'] == 0:
+ roles = [r for r in self.get_option('role').split(':')]
+ self.node_dict = self._build_dict(res['stdout'].splitlines())
+ for node in self.node_dict:
+ if roles:
+ for role in roles:
+ if role in node:
+ nodes.append(node)
+ else:
+ nodes.append(node)
+ else:
+ msg = "'oc' command failed"
+ if 'Missing or incomplete' in res['stdout']:
+ msg = ("'oc' failed due to missing kubeconfig on master node."
+ " Specify one via '-c ocp.kubeconfig=<path>'")
+ raise Exception(msg)
+ return nodes
+
+ def set_node_label(self, node):
+ if node.address not in self.node_dict:
+ return ''
+ for label in ['master', 'worker']:
+ if label in self.node_dict[node.address]['roles']:
+ return label
+ return ''
+
+ def check_node_is_master(self, sosnode):
+ if sosnode.address not in self.node_dict:
+ return False
+ return 'master' in self.node_dict[sosnode.address]['roles']
+
+ def set_master_options(self, node):
+ node.opts.enable_plugins.append('openshift')