aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJake Hunsaker <jhunsake@redhat.com>2021-06-14 09:31:07 -0400
committerJake Hunsaker <jhunsake@redhat.com>2021-06-21 12:48:07 -0400
commitec46e6a8fac58ed757344be3751eb1f925eab981 (patch)
treeb864d6394b5d85c12bb8a7a9a39be13b13de0265
parentf180150277b706e72f2445287f3d0b6943efa252 (diff)
downloadsos-ec46e6a8fac58ed757344be3751eb1f925eab981.tar.gz
[ocp] Refine OCP node options in cluster profile
Adds explicit setting of primary/node sos options for the `openshift` plugin within the cluster, rather than relying on default configurations and best practices to avoid duplicate collections. Signed-off-by: Jake Hunsaker <jhunsake@redhat.com>
-rw-r--r--sos/collector/clusters/ocp.py65
-rw-r--r--sos/collector/sosnode.py4
2 files changed, 65 insertions, 4 deletions
diff --git a/sos/collector/clusters/ocp.py b/sos/collector/clusters/ocp.py
index 283fcfd1..ddff84a4 100644
--- a/sos/collector/clusters/ocp.py
+++ b/sos/collector/clusters/ocp.py
@@ -8,6 +8,8 @@
#
# See the LICENSE file in the source distribution for further information.
+import os
+
from pipes import quote
from sos.collector.clusters import Cluster
@@ -18,10 +20,14 @@ class ocp(Cluster):
cluster_name = 'OpenShift Container Platform v4'
packages = ('openshift-hyperkube', 'openshift-clients')
+ api_collect_enabled = False
+ token = None
+
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')
+ ('kubeconfig', '', 'Path to the kubeconfig file'),
+ ('token', '', 'Service account token to use for oc authorization')
]
def fmt_oc_cmd(self, cmd):
@@ -32,9 +38,20 @@ class ocp(Cluster):
return "oc --config %s %s" % (self.get_option('kubeconfig'), cmd)
return "oc %s" % cmd
+ def _attempt_oc_login(self):
+ """Attempt to login to the API using the oc command using a provided
+ token
+ """
+ _res = self.exec_primary_cmd("oc login --insecure-skip-tls-verify=True"
+ " --token=%s" % self.token)
+ return _res['status'] == 0
+
def check_enabled(self):
if super(ocp, self).check_enabled():
return True
+ self.token = self.get_option('token') or os.getenv('SOSOCPTOKEN', None)
+ if self.token:
+ self._attempt_oc_login()
_who = self.fmt_oc_cmd('whoami')
return self.exec_master_cmd(_who)['status'] == 0
@@ -106,4 +123,48 @@ class ocp(Cluster):
return 'master' in self.node_dict[sosnode.address]['roles']
def set_master_options(self, node):
- node.opts.enable_plugins.append('openshift')
+ node.enable_plugins.append('openshift')
+ if self.api_collect_enabled:
+ # a primary has already been enabled for API collection, disable
+ # it among others
+ node.plugin_options.append('openshift.no-oc=on')
+ else:
+ _oc_cmd = 'oc'
+ if node.host.containerized:
+ _oc_cmd = '/host/bin/oc'
+ # when run from a container, the oc command does not inherit
+ # the default config, so if it's present then pass it here to
+ # detect a funcitonal oc command. This is sidestepped in sos
+ # report by being able to chroot the `oc` execution which we
+ # cannot do remotely
+ if node.file_exists('/root/.kube/config', need_root=True):
+ _oc_cmd += ' --kubeconfig /host/root/.kube/config'
+ can_oc = node.run_command("%s whoami" % _oc_cmd,
+ use_container=node.host.containerized,
+ # container is available only to root
+ # and if rhel, need to run sos as root
+ # anyways which will run oc as root
+ need_root=True)
+ if can_oc['status'] == 0:
+ # the primary node can already access the API
+ self.api_collect_enabled = True
+ elif self.token:
+ node.sos_env_vars['SOSOCPTOKEN'] = self.token
+ self.api_collect_enabled = True
+ elif self.get_option('kubeconfig'):
+ kc = self.get_option('kubeconfig')
+ if node.file_exists(kc):
+ if node.host.containerized:
+ kc = "/host/%s" % kc
+ node.sos_env_vars['KUBECONFIG'] = kc
+ self.api_collect_enabled = True
+ if self.api_collect_enabled:
+ msg = ("API collections will be performed on %s\nNote: API "
+ "collections may extend runtime by 10s of minutes\n"
+ % node.address)
+ self.soslog.info(msg)
+ self.ui_log.info(msg)
+
+ def set_node_options(self, node):
+ # don't attempt OC API collections on non-primary nodes
+ node.plugin_options.append('openshift.no-oc=on')
diff --git a/sos/collector/sosnode.py b/sos/collector/sosnode.py
index 1c25cc34..6597d236 100644
--- a/sos/collector/sosnode.py
+++ b/sos/collector/sosnode.py
@@ -202,11 +202,11 @@ class SosNode():
self.opts.registry_authfile or self.host.container_authfile
)
- def file_exists(self, fname):
+ def file_exists(self, fname, need_root=False):
"""Checks for the presence of fname on the remote node"""
if not self.local:
try:
- res = self.run_command("stat %s" % fname)
+ res = self.run_command("stat %s" % fname, need_root=need_root)
return res['status'] == 0
except Exception:
return False