From e5c4b921349f0a10b9a33f14e0a9845050ca1ea0 Mon Sep 17 00:00:00 2001 From: Jarrod Johnson Date: Tue, 24 Mar 2015 10:42:04 -0400 Subject: [PATCH] Add a nodehealth command nodehealth grabs the health summary of a node and provides some detail in 'not ok' condition. --- confluent_client/bin/nodehealth | 69 ++++++++++++++++++++++++++++ confluent_client/confluent/client.py | 10 ++-- 2 files changed, 76 insertions(+), 3 deletions(-) create mode 100644 confluent_client/bin/nodehealth diff --git a/confluent_client/bin/nodehealth b/confluent_client/bin/nodehealth new file mode 100644 index 00000000..affafc8e --- /dev/null +++ b/confluent_client/bin/nodehealth @@ -0,0 +1,69 @@ +#!/usr/bin/env python +# vim: tabstop=4 shiftwidth=4 softtabstop=4 + +# Copyright 2015 Lenovo +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import codecs +import os +import sys + +path = os.path.dirname(os.path.realpath(__file__)) +path = os.path.realpath(os.path.join(path, '..', 'lib', 'python')) +if path.startswith('/opt'): + sys.path.append(path) + +import confluent.client as client + +sys.stdout = codecs.getwriter('utf8')(sys.stdout) + +noderange = sys.argv[1] + +session = client.Command() +exitcode = 0 +healthbynode = {} +healthexplanations = {} +for health in session.read('/noderange/{0}/health/hardware'.format(noderange)): + if 'error' in health: + sys.stderr.write(health['error'] + '\n') + if 'errorcode' in health: + exitcode |= health['errorcode'] + else: + exitcode |= 1 + continue + if 'databynode' not in health: + continue + health = health['databynode'] + for node in health: + if 'health' in health[node]: + healthbynode[node] = health[node]['health']['value'] + if 'sensors' in health[node]: + healthexplanations[node] = [] + for sensor in health[node]['sensors']: + explanation = sensor['name'] + ':' + if sensor['value'] is not None: + explanation += sensor['value'] + if sensor['units'] is not None: + explanation += sensor['units'] + if sensor['states']: + explanation += ','.join(sensor['states']) + healthexplanations[node].append(explanation) + if node in healthbynode and node in healthexplanations: + if healthexplanations[node]: + print('{0}: {1} ({2})'.format( + node, healthbynode[node], + ','.join(healthexplanations[node]))) + else: + print('{0}: {1}'.format(node, healthbynode[node])) + diff --git a/confluent_client/confluent/client.py b/confluent_client/confluent/client.py index 1e819aca..d4d0593e 100644 --- a/confluent_client/confluent/client.py +++ b/confluent_client/confluent/client.py @@ -88,16 +88,20 @@ class Command(object): rc |= res[node]['errorcode'] else: rc |= 1 - else: + elif ikey in res[node]: print('{0}: {1}'.format(node, res[node][ikey]['value'])) return rc - def simple_noderange_command(self, noderange, resource, input=None): + def simple_noderange_command(self, noderange, resource, input=None, + key=None): rc = 0 if resource[0] == '/': resource = resource[1:] # The implicit key is the resource basename - ikey = resource.rpartition('/')[-1] + if key is None: + ikey = resource.rpartition('/')[-1] + else: + ikey = key if input is None: for res in self.read('/noderange/{0}/{1}'.format( noderange, resource)):