From ea9caa470b6d8b14597c2e06e9ca2c4f895cfa19 Mon Sep 17 00:00:00 2001 From: Jarrod Johnson Date: Tue, 27 Jun 2017 15:06:59 -0400 Subject: [PATCH] Fix unexpected error on retrieving nodegroup attributes Detect and more specifically report error message when an unknown group is used for nodegroup commands. --- confluent_server/confluent/core.py | 3 +- confluent_server/confluent/exceptions.py | 34 +++++++++++-------- .../plugins/configuration/attributes.py | 9 ++++- 3 files changed, 30 insertions(+), 16 deletions(-) diff --git a/confluent_server/confluent/core.py b/confluent_server/confluent/core.py index c2d647c6..e5003ef9 100644 --- a/confluent_server/confluent/core.py +++ b/confluent_server/confluent/core.py @@ -363,7 +363,8 @@ def delete_node_collection(collectionpath, configmanager, isnoderange): def enumerate_nodegroup_collection(collectionpath, configmanager): nodegroup = collectionpath[1] if not configmanager.is_nodegroup(nodegroup): - raise exc.NotFoundException("Invalid element requested") + raise exc.NotFoundException( + 'Invalid nodegroup: {0} not found'.format(nodegroup)) del collectionpath[0:2] collection = nested_lookup(nodegroupresources, collectionpath) return iterate_resources(collection) diff --git a/confluent_server/confluent/exceptions.py b/confluent_server/confluent/exceptions.py index ca618b0e..47f9efdf 100644 --- a/confluent_server/confluent/exceptions.py +++ b/confluent_server/confluent/exceptions.py @@ -1,7 +1,7 @@ # vim: tabstop=4 shiftwidth=4 softtabstop=4 # Copyright 2014 IBM Corporation -# Copyright 2015 Lenovo +# Copyright 2015-2017 Lenovo # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -21,75 +21,81 @@ import json class ConfluentException(Exception): apierrorcode = 500 - apierrorstr = 'Unexpected Error' + _apierrorstr = 'Unexpected Error' def get_error_body(self): - errstr = ' - '.join((self.apierrorstr, str(self))) + errstr = ' - '.join((self._apierrorstr, str(self))) return json.dumps({'error': errstr }) + @property + def apierrorstr(self): + if str(self): + return self._apierrorstr + ' - ' + str(self) + return self._apierrorstr + class NotFoundException(ConfluentException): # Something that could be construed as a name was not found # basically, picture an http error code 404 apierrorcode = 404 - apierrorstr = 'Request path not recognized' + _apierrorstr = 'Target not found' class InvalidArgumentException(ConfluentException): # Something from the remote client wasn't correct # like http code 400 apierrorcode = 400 - apierrorstr = 'Bad Request' + _apierrorstr = 'Bad Request' class TargetEndpointUnreachable(ConfluentException): # A target system was unavailable. For example, a BMC # was unreachable. http code 504 apierrorcode = 504 - apierrorstr = 'Unreachable Target' + _apierrorstr = 'Unreachable Target' class TargetEndpointBadCredentials(ConfluentException): # target was reachable, but authentication/authorization # failed apierrorcode = 502 - apierrorstr = 'Bad Credentials' + _apierrorstr = 'Bad Credentials' class LockedCredentials(ConfluentException): # A request was performed that required a credential, but the credential # store is locked - apierrorstr = 'Credential store locked' + _apierrorstr = 'Credential store locked' class ForbiddenRequest(ConfluentException): # The client request is not allowed by authorization engine apierrorcode = 403 - apierrorstr = 'Forbidden' + _apierrorstr = 'Forbidden' class NotImplementedException(ConfluentException): # The current configuration/plugin is unable to perform # the requested task. http code 501 apierrorcode = 501 - apierrorstr = '501 - Not Implemented' + _apierrorstr = '501 - Not Implemented' class GlobalConfigError(ConfluentException): # The configuration in the global config file is not right - apierrorstr = 'Global configuration contains an error' + _apierrorstr = 'Global configuration contains an error' class TargetResourceUnavailable(ConfluentException): # This is meant for scenarios like asking to read a sensor that is # currently unavailable. This may be a persistent or transient state apierrocode = 503 - apierrorstr = 'Target Resource Unavailable' + _apierrorstr = 'Target Resource Unavailable' class PubkeyInvalid(ConfluentException): apierrorcode = 502 - apierrorstr = '502 - Invalid certificate or key on target' + _apierrorstr = '502 - Invalid certificate or key on target' def __init__(self, text, certificate, fingerprint, attribname, event): super(PubkeyInvalid, self).__init__(self, text) @@ -106,7 +112,7 @@ class PubkeyInvalid(ConfluentException): class LoggedOut(ConfluentException): apierrorcode = 401 - apierrorstr = '401 - Logged out' + _apierrorstr = '401 - Logged out' def get_error_body(self): return '{"loggedout": 1}' diff --git a/confluent_server/confluent/plugins/configuration/attributes.py b/confluent_server/confluent/plugins/configuration/attributes.py index 11e00f8f..1139f3f5 100644 --- a/confluent_server/confluent/plugins/configuration/attributes.py +++ b/confluent_server/confluent/plugins/configuration/attributes.py @@ -1,4 +1,5 @@ # Copyright 2014 IBM Corporation +# Copyright 2017 Lenovo # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -26,7 +27,13 @@ def retrieve(nodes, element, configmanager, inputdata): def retrieve_nodegroup(nodegroup, element, configmanager, inputdata): - grpcfg = configmanager.get_nodegroup_attributes(nodegroup) + try: + grpcfg = configmanager.get_nodegroup_attributes(nodegroup) + except KeyError: + if not configmanager.is_nodegroup(nodegroup): + raise exc.NotFoundException( + 'Invalid nodegroup: {0} not found'.format(nodegroup)) + raise if element == 'all': theattrs = set(allattributes.node).union(set(grpcfg)) theattrs.add('nodes')