From bf643c49164d291d25f4f86d32efd7aa2000272e Mon Sep 17 00:00:00 2001 From: Thiago da Silva Date: Wed, 4 Dec 2013 18:12:12 -0500 Subject: fix error handing in swauth tools The swauth tools did not handle an invalid admin_url, so it just failed printing the stacktrace, which is not useful to end users. This fix catches the exception and prints an error message that can help user solve the issue. Change-Id: I806c1cf191b5921e904b155f65cdbde5f2aac695 Signed-off-by: Thiago da Silva Reviewed-on: http://review.gluster.org/6431 Reviewed-by: Luis Pabon Tested-by: Luis Pabon Reviewed-on: http://review.gluster.org/6707 Reviewed-by: Chetan Risbud Tested-by: Chetan Risbud --- .../middleware/gswauth/bin/gswauth-add-account | 17 +++++-- .../common/middleware/gswauth/bin/gswauth-add-user | 48 ++++++++++++++------ .../middleware/gswauth/bin/gswauth-cleanup-tokens | 6 +++ .../middleware/gswauth/bin/gswauth-delete-account | 17 +++++-- .../middleware/gswauth/bin/gswauth-delete-user | 17 +++++-- .../common/middleware/gswauth/bin/gswauth-list | 18 ++++++-- .../common/middleware/gswauth/bin/gswauth-prep | 17 +++++-- .../gswauth/bin/gswauth-set-account-service | 17 +++++-- test/functional_auth/gswauth/test_gswauth_cli.py | 53 ++++++++++++++++++++-- 9 files changed, 165 insertions(+), 45 deletions(-) diff --git a/gluster/swift/common/middleware/gswauth/bin/gswauth-add-account b/gluster/swift/common/middleware/gswauth/bin/gswauth-add-account index 37064ae..d3fd243 100755 --- a/gluster/swift/common/middleware/gswauth/bin/gswauth-add-account +++ b/gluster/swift/common/middleware/gswauth/bin/gswauth-add-account @@ -15,8 +15,9 @@ # limitations under the License. import gettext +import socket + from optparse import OptionParser -from os.path import basename from sys import argv, exit from swift.common.bufferedhttp import http_connect_raw as http_connect @@ -56,9 +57,17 @@ if __name__ == '__main__': headers = {'X-Auth-Admin-User': options.admin_user, 'X-Auth-Admin-Key': options.admin_key, 'Content-Length': '0'} - conn = http_connect(parsed.hostname, parsed.port, 'PUT', path, headers, - ssl=(parsed.scheme == 'https')) - resp = conn.getresponse() + try: + conn = http_connect(parsed.hostname, parsed.port, 'PUT', path, headers, + ssl=(parsed.scheme == 'https')) + resp = conn.getresponse() + except socket.gaierror, err: + exit('Account creation failed: %s. ' \ + 'Check that the admin_url is valid' % err) + except socket.error, (errno, msg): + exit('Account creation failed: %s. ' \ + 'Check that the admin_url is valid' % msg) + if resp.status // 100 != 2: if resp.status == 401: exit('Account creation failed: %s %s: Invalid user/key provided' % diff --git a/gluster/swift/common/middleware/gswauth/bin/gswauth-add-user b/gluster/swift/common/middleware/gswauth/bin/gswauth-add-user index a6de161..0eb2e9c 100755 --- a/gluster/swift/common/middleware/gswauth/bin/gswauth-add-user +++ b/gluster/swift/common/middleware/gswauth/bin/gswauth-add-user @@ -15,8 +15,9 @@ # limitations under the License. import gettext +import socket + from optparse import OptionParser -from os.path import basename from sys import argv, exit from swift.common.bufferedhttp import http_connect_raw as http_connect @@ -62,6 +63,7 @@ if __name__ == '__main__': parsed_path = '/' elif parsed_path[-1] != '/': parsed_path += '/' + # Check if user is changing his own password. This is carried out by # making sure that the user changing the password and the user whose # password is being changed are the same. @@ -71,19 +73,27 @@ if __name__ == '__main__': path = '%sv2/%s' % (parsed_path, account) headers = {'X-Auth-Admin-User': options.admin_user, 'X-Auth-Admin-Key': options.admin_key} - conn = http_connect(parsed.hostname, parsed.port, 'GET', path, headers, - ssl=(parsed.scheme == 'https')) - resp = conn.getresponse() - if resp.status // 100 != 2: - # If the GET operation fails, it means the account does not exist. - # Now we create the account by sending a PUT request. - headers['Content-Length'] = '0' - conn = http_connect(parsed.hostname, parsed.port, 'PUT', path, - headers, ssl=(parsed.scheme == 'https')) + try: + conn = http_connect(parsed.hostname, parsed.port, 'GET', path, + headers, ssl=(parsed.scheme == 'https')) resp = conn.getresponse() if resp.status // 100 != 2: - print 'Account creation failed: %s %s' % \ - (resp.status, resp.reason) + # If the GET operation fails, it means the account does not + # exist. Now we create the account by sending a PUT request. + headers['Content-Length'] = '0' + conn = http_connect(parsed.hostname, parsed.port, 'PUT', path, + headers, ssl=(parsed.scheme == 'https')) + resp = conn.getresponse() + if resp.status // 100 != 2: + print 'Account creation failed: %s %s' % \ + (resp.status, resp.reason) + except socket.gaierror, err: + exit('User creation failed: %s. ' \ + 'Check that the admin_url is valid' % err) + except socket.error, (errno, msg): + exit('User creation failed: %s. ' \ + 'Check that the admin_url is valid' % msg) + # Add the user path = '%sv2/%s/%s' % (parsed_path, account, user) headers = {'X-Auth-Admin-User': options.admin_user, @@ -94,9 +104,17 @@ if __name__ == '__main__': headers['X-Auth-User-Admin'] = 'true' if options.reseller_admin: headers['X-Auth-User-Reseller-Admin'] = 'true' - conn = http_connect(parsed.hostname, parsed.port, 'PUT', path, headers, - ssl=(parsed.scheme == 'https')) - resp = conn.getresponse() + try: + conn = http_connect(parsed.hostname, parsed.port, 'PUT', path, headers, + ssl=(parsed.scheme == 'https')) + resp = conn.getresponse() + except socket.gaierror, err: + exit('User creation failed: %s. ' \ + 'Check that the admin_url is valid' % err) + except socket.error, (errno, msg): + exit('User creation failed: %s. ' \ + 'Check that the admin_url is valid' % msg) + if resp.status // 100 != 2: if resp.status == 401: exit('User creation failed: %s %s: Invalid user/key provided' % diff --git a/gluster/swift/common/middleware/gswauth/bin/gswauth-cleanup-tokens b/gluster/swift/common/middleware/gswauth/bin/gswauth-cleanup-tokens index cc2d18d..3f3593b 100755 --- a/gluster/swift/common/middleware/gswauth/bin/gswauth-cleanup-tokens +++ b/gluster/swift/common/middleware/gswauth/bin/gswauth-cleanup-tokens @@ -20,6 +20,8 @@ except ImportError: import json import gettext import re +import socket + from datetime import datetime, timedelta from optparse import OptionParser from sys import argv, exit @@ -114,6 +116,10 @@ if __name__ == '__main__': else: exit('Object listing on container %s failed with status ' 'code %d' % (container, e.http_status)) + except socket.error, (errno, msg): + exit('Token clean-up failed: %s. ' \ + 'Check that the admin_url is valid' % msg) + if objs: marker = objs[-1]['name'] else: diff --git a/gluster/swift/common/middleware/gswauth/bin/gswauth-delete-account b/gluster/swift/common/middleware/gswauth/bin/gswauth-delete-account index b1440f4..204bb95 100755 --- a/gluster/swift/common/middleware/gswauth/bin/gswauth-delete-account +++ b/gluster/swift/common/middleware/gswauth/bin/gswauth-delete-account @@ -15,8 +15,9 @@ # limitations under the License. import gettext +import socket + from optparse import OptionParser -from os.path import basename from sys import argv, exit from swift.common.bufferedhttp import http_connect_raw as http_connect @@ -57,9 +58,17 @@ if __name__ == '__main__': path = '%sv2/%s' % (parsed_path, account) headers = {'X-Auth-Admin-User': options.admin_user, 'X-Auth-Admin-Key': options.admin_key} - conn = http_connect(parsed.hostname, parsed.port, 'DELETE', path, headers, - ssl=(parsed.scheme == 'https')) - resp = conn.getresponse() + try: + conn = http_connect(parsed.hostname, parsed.port, 'DELETE', path, headers, + ssl=(parsed.scheme == 'https')) + resp = conn.getresponse() + except socket.gaierror, err: + exit('Account deletion failed: %s. ' \ + 'Check that the admin_url is valid' % err) + except socket.error, (errno, msg): + exit('Account deletion failed: %s. ' \ + 'Check that the admin_url is valid' % msg) + if resp.status // 100 != 2: if resp.status == 401: exit('Delete account failed: %s %s: Invalid user/key provided' % diff --git a/gluster/swift/common/middleware/gswauth/bin/gswauth-delete-user b/gluster/swift/common/middleware/gswauth/bin/gswauth-delete-user index f778603..5e56a79 100755 --- a/gluster/swift/common/middleware/gswauth/bin/gswauth-delete-user +++ b/gluster/swift/common/middleware/gswauth/bin/gswauth-delete-user @@ -15,8 +15,9 @@ # limitations under the License. import gettext +import socket + from optparse import OptionParser -from os.path import basename from sys import argv, exit from swift.common.bufferedhttp import http_connect_raw as http_connect @@ -57,9 +58,17 @@ if __name__ == '__main__': path = '%sv2/%s/%s' % (parsed_path, account, user) headers = {'X-Auth-Admin-User': options.admin_user, 'X-Auth-Admin-Key': options.admin_key} - conn = http_connect(parsed.hostname, parsed.port, 'DELETE', path, headers, - ssl=(parsed.scheme == 'https')) - resp = conn.getresponse() + try: + conn = http_connect(parsed.hostname, parsed.port, 'DELETE', path, headers, + ssl=(parsed.scheme == 'https')) + resp = conn.getresponse() + except socket.gaierror, err: + exit('User deletion failed: %s. ' \ + 'Check that the admin_url is valid' % err) + except socket.error, (errno, msg): + exit('User deletion failed: %s. ' \ + 'Check that the admin_url is valid' % msg) + if resp.status // 100 != 2: if resp.status == 401: exit('Delete user failed: %s %s: Invalid user/key provided' % diff --git a/gluster/swift/common/middleware/gswauth/bin/gswauth-list b/gluster/swift/common/middleware/gswauth/bin/gswauth-list index 4f2d834..50b7936 100755 --- a/gluster/swift/common/middleware/gswauth/bin/gswauth-list +++ b/gluster/swift/common/middleware/gswauth/bin/gswauth-list @@ -19,8 +19,10 @@ try: except ImportError: import json import gettext +import socket +import types + from optparse import OptionParser -from os.path import basename from sys import argv, exit from swift.common.bufferedhttp import http_connect_raw as http_connect @@ -79,9 +81,17 @@ If the [user] is '.groups', the active groups for the account will be listed. path = '%sv2/%s' % (parsed_path, '/'.join(args)) headers = {'X-Auth-Admin-User': options.admin_user, 'X-Auth-Admin-Key': options.admin_key} - conn = http_connect(parsed.hostname, parsed.port, 'GET', path, headers, - ssl=(parsed.scheme == 'https')) - resp = conn.getresponse() + try: + conn = http_connect(parsed.hostname, parsed.port, 'GET', path, headers, + ssl=(parsed.scheme == 'https')) + resp = conn.getresponse() + except socket.gaierror, err: + exit('List failed: %s. ' \ + 'Check that the admin_url is valid' % err) + except socket.error, (errno, msg): + exit('List failed: %s. ' \ + 'Check that the admin_url is valid' % msg) + body = resp.read() if resp.status // 100 != 2: if resp.status == 401: diff --git a/gluster/swift/common/middleware/gswauth/bin/gswauth-prep b/gluster/swift/common/middleware/gswauth/bin/gswauth-prep index d153719..a73aa1d 100755 --- a/gluster/swift/common/middleware/gswauth/bin/gswauth-prep +++ b/gluster/swift/common/middleware/gswauth/bin/gswauth-prep @@ -15,8 +15,9 @@ # limitations under the License. import gettext +import socket + from optparse import OptionParser -from os.path import basename from sys import argv, exit from swift.common.bufferedhttp import http_connect_raw as http_connect @@ -54,9 +55,17 @@ if __name__ == '__main__': path = '%sv2/.prep' % parsed_path headers = {'X-Auth-Admin-User': options.admin_user, 'X-Auth-Admin-Key': options.admin_key} - conn = http_connect(parsed.hostname, parsed.port, 'POST', path, headers, - ssl=(parsed.scheme == 'https')) - resp = conn.getresponse() + try: + conn = http_connect(parsed.hostname, parsed.port, 'POST', path, headers, + ssl=(parsed.scheme == 'https')) + resp = conn.getresponse() + except socket.gaierror, err: + exit('gswauth preparation failed: %s. ' \ + 'Check that the admin_url is valid' % err) + except socket.error, (errno, msg): + exit('gswauth preparation failed: %s. ' \ + 'Check that the admin_url is valid' % msg) + if resp.status // 100 != 2: if resp.status == 401: exit('gswauth preparation failed: %s %s: Invalid user/key provided' % diff --git a/gluster/swift/common/middleware/gswauth/bin/gswauth-set-account-service b/gluster/swift/common/middleware/gswauth/bin/gswauth-set-account-service index 5be8319..426ce3c 100755 --- a/gluster/swift/common/middleware/gswauth/bin/gswauth-set-account-service +++ b/gluster/swift/common/middleware/gswauth/bin/gswauth-set-account-service @@ -19,8 +19,8 @@ try: except ImportError: import json import gettext +import socket from optparse import OptionParser -from os.path import basename from sys import argv, exit from swift.common.bufferedhttp import http_connect_raw as http_connect @@ -67,10 +67,17 @@ Example: %prog -K gswauthkey test storage local http://127.0.0.1:8080/v1/AUTH_01 headers = {'Content-Length': str(len(body)), 'X-Auth-Admin-User': options.admin_user, 'X-Auth-Admin-Key': options.admin_key} - conn = http_connect(parsed.hostname, parsed.port, 'POST', path, headers, - ssl=(parsed.scheme == 'https')) - conn.send(body) - resp = conn.getresponse() + try: + conn = http_connect(parsed.hostname, parsed.port, 'POST', path, headers, + ssl=(parsed.scheme == 'https')) + conn.send(body) + resp = conn.getresponse() + except socket.gaierror, err: + exit('Service set failed: %s. ' \ + 'Check that the admin_url is valid' % err) + except socket.error, (errno, msg): + exit('Service set failed: %s. ' \ + 'Check that the admin_url is valid' % msg) if resp.status // 100 != 2: if resp.status == 401: exit('Service set failed: %s %s: Invalid user/key provided' % diff --git a/test/functional_auth/gswauth/test_gswauth_cli.py b/test/functional_auth/gswauth/test_gswauth_cli.py index e228f31..29a48b3 100644 --- a/test/functional_auth/gswauth/test_gswauth_cli.py +++ b/test/functional_auth/gswauth/test_gswauth_cli.py @@ -124,6 +124,14 @@ class TestSwauthPrep(unittest.TestCase): self.assertNotEqual(status, 0, 'Invalid swauth-prep request accepted(wrong key provided):'+output) self.assertEqual('gswauth preparation failed: 401 Unauthorized: Invalid user/key provided' \ in output,True, 'Invalid swauth-prep request accepted: '+output) + + (status,output)=Utils.swauthPrep(authurl='http://127.0.0.1:80/auth/') + self.assertEqual('ECONNREFUSED' in output, True, + 'Invalid swauth-prep request accepted(wrong admin-url provided): %s' % output) + + (status,output)=Utils.swauthPrep(authurl='http://127.0.1:80/auth/') + self.assertEqual('No address associated with hostname' in output, True, + 'Invalid swauth-prep request accepted(wrong admin-url provided): %s' % output) #TODO:More cases for invalid url and admin user def testAddAccountWithoutSwauthPrep(self): @@ -176,8 +184,15 @@ class TestAccount(unittest.TestCase): (status,output)=Utils.addAccount('testinvalidkey',key='invalidkey') self.assertEqual('Account creation failed: 401 Unauthorized: Invalid user/key provided' \ - in output,True, 'Invalid account creation request accepted: '+output) - #TODO:more cases? + in output,True, 'Invalid account creation request accepted: '+output) + + (status,output)=Utils.addAccount('test2', authurl='http://127.0.0.1:80/auth/') + self.assertEqual('ECONNREFUSED' in output, True, + 'Invalid account creation request accepted(wrong admin-url provided): %s' % output) + + (status,output)=Utils.addAccount('test2', authurl='http://127.0.1:80/auth/') + self.assertEqual('No address associated with hostname' in output, True, + 'Invalid account creation request accepted(wrong admin-url provided): %s' % output) def testAddAccountNonSuperAdminUsers(self): #set test account with all types of user @@ -229,7 +244,14 @@ class TestAccount(unittest.TestCase): (status,output)=Utils.deleteAccount('accountdoesnotexist') self.assertNotEqual(status, 0, 'account deletion failed for accountdoesnotexist'+output) self.assertEqual('Delete account failed: 404 Not Found: Account accountdoesnotexist does not exist' in output,True, 'account deletion failed for test account'+output) - #TODO:more cases + + (status,output)=Utils.deleteAccount('test3', authurl='http://127.0.0.1:80/auth/') + self.assertEqual('ECONNREFUSED' in output, True, + 'Invalid deletion request accepted(wrong admin-url provided): %s' % output) + + (status,output)=Utils.deleteAccount('test3', authurl='http://127.0.1:80/auth/') + self.assertEqual('No address associated with hostname' in output, True, + 'Invalid deletion request accepted(wrong admin-url provided): %s' % output) def testDeleteAccountNonSuperAdminUsers(self): #set test account with all types of user @@ -264,6 +286,14 @@ class TestAccount(unittest.TestCase): '+----------+\n| Accounts |\n+----------+\n| test |\n+----------+', 'swauth-list failed:\n%s' % output) + (status,output)=Utils.listAccounts(authurl='http://127.0.0.1:80/auth/') + self.assertEqual('ECONNREFUSED' in output, True, + 'Invalid list request accepted(wrong admin-url provided): %s' % output) + + (status,output)=Utils.listAccounts(authurl='http://127.0.1:80/auth/') + self.assertEqual('No address associated with hostname' in output, True, + 'Invalid list request accepted(wrong admin-url provided): %s' % output) + (status,output)=Utils.listAccounts('-j') self.assertEqual(output, '{"accounts": [{"name": "test"}]}', @@ -293,7 +323,6 @@ class TestAccount(unittest.TestCase): self.assertNotEqual(status, 0, 'account listing success with regular user: '+output) self.assertEqual('403 Forbidden' in output,True, 'account listing success with regular user: '+output) - class TestUser(unittest.TestCase): def setUp(self): @@ -348,7 +377,14 @@ class TestUser(unittest.TestCase): (status,output) = Utils.addAdminUser('accountdoesnotexist', 'testcli', 'testcli') self.assertEqual(status, 0, 'User creation request failed, where accountdoesnotexist: '+output) - #TODO: more test cases? + + (status,output)=Utils.addAdminUser('test', 'admin2', 'adminpwd', authurl='http://127.0.0.1:80/auth/') + self.assertEqual('ECONNREFUSED' in output, True, + 'Invalid add user request accepted(wrong admin-url provided): %s' % output) + + (status,output)=Utils.addAdminUser('test', 'admin2', 'adminpwd', authurl='http://127.0.1:80/auth/') + self.assertEqual('No address associated with hostname' in output, True, + 'Invalid add user request accepted(wrong admin-url provided): %s' % output) def testAddUserNonSuperAdminUsers (self): #setup test,testr accounts with all user types @@ -463,6 +499,13 @@ class TestUser(unittest.TestCase): (status,output) = Utils.deleteUser('accountisnothere', 'testcli') self.assertNotEqual(status, 0, 'Invalid user deletion request accepted, accountdoesnotexist:'+output) #TODO:more testcases? + (status,output)=Utils.deleteUser('test', 'admin2', authurl='http://127.0.0.1:80/auth/') + self.assertEqual('ECONNREFUSED' in output, True, + 'Invalid delete user request accepted(wrong admin-url provided): %s' % output) + + (status,output)=Utils.deleteUser('test', 'admin2', authurl='http://127.0.1:80/auth/') + self.assertEqual('No address associated with hostname' in output, True, + 'Invalid delete user request accepted(wrong admin-url provided): %s' % output) def testDeleteUserNonSuperAdminUsers(self): -- cgit