diff options
Diffstat (limited to 'gluster/swift/common/middleware/gswauth/bin/gswauth-cleanup-tokens')
-rwxr-xr-x | gluster/swift/common/middleware/gswauth/bin/gswauth-cleanup-tokens | 167 |
1 files changed, 167 insertions, 0 deletions
diff --git a/gluster/swift/common/middleware/gswauth/bin/gswauth-cleanup-tokens b/gluster/swift/common/middleware/gswauth/bin/gswauth-cleanup-tokens new file mode 100755 index 0000000..621124e --- /dev/null +++ b/gluster/swift/common/middleware/gswauth/bin/gswauth-cleanup-tokens @@ -0,0 +1,167 @@ +#!/usr/bin/env python +# Copyright (c) 2010-2011 OpenStack, LLC. +# +# 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. + +try: + import simplejson as json +except ImportError: + import json +import gettext +import re +from datetime import datetime, timedelta +from optparse import OptionParser +from sys import argv, exit +from time import sleep, time + +from swiftclient.client import Connection, ClientException + +if __name__ == '__main__': + gettext.install('gswauth', unicode=1) + parser = OptionParser(usage='Usage: %prog [options]') + parser.add_option('-t', '--token-life', dest='token_life', + default='86400', help='The expected life of tokens; token objects ' + 'modified more than this number of seconds ago will be checked for ' + 'expiration (default: 86400).') + parser.add_option('-s', '--sleep', dest='sleep', + default='0.1', help='The number of seconds to sleep between token ' + 'checks (default: 0.1)') + parser.add_option('-v', '--verbose', dest='verbose', action='store_true', + default=False, help='Outputs everything done instead of just the ' + 'deletions.') + parser.add_option('-A', '--admin-url', dest='admin_url', + default='http://127.0.0.1:8080/auth/', help='The URL to the auth ' + 'subsystem (default: http://127.0.0.1:8080/auth/)') + parser.add_option('-K', '--admin-key', dest='admin_key', + help='The key for .super_admin.') + parser.add_option('', '--purge', dest='purge_account', help='Purges all ' + 'tokens for a given account whether the tokens have expired or not.') + parser.add_option('', '--purge-all', dest='purge_all', action='store_true', + default=False, help='Purges all tokens for all accounts and users ' + 'whether the tokens have expired or not.') + args = argv[1:] + if not args: + args.append('-h') + (options, args) = parser.parse_args(args) + if len(args) != 0: + parser.parse_args(['-h']) + options.admin_url = options.admin_url.rstrip('/') + if not options.admin_url.endswith('/v1.0'): + options.admin_url += '/v1.0' + options.admin_user = '.super_admin:.super_admin' + options.token_life = timedelta(0, float(options.token_life)) + options.sleep = float(options.sleep) + conn = Connection(options.admin_url, options.admin_user, options.admin_key) + if options.purge_account: + marker = None + while True: + if options.verbose: + print 'GET %s?marker=%s' % (options.purge_account, marker) + objs = conn.get_container(options.purge_account, marker=marker)[1] + if objs: + marker = objs[-1]['name'] + else: + if options.verbose: + print 'No more objects in %s' % options.purge_account + break + for obj in objs: + if options.verbose: + print 'HEAD %s/%s' % (options.purge_account, obj['name']) + headers = conn.head_object(options.purge_account, obj['name']) + if 'x-object-meta-auth-token' in headers: + token = headers['x-object-meta-auth-token'] + container = '.token_%s' % token[-1] + if options.verbose: + print '%s/%s purge account %r; deleting' % \ + (container, token, options.purge_account) + print 'DELETE %s/%s' % (container, token) + try: + conn.delete_object(container, token) + except ClientException, err: + if err.http_status != 404: + raise + continue + if options.verbose: + print 'Done.' + exit(0) + for x in xrange(16): + container = '.token_%x' % x + marker = None + while True: + if options.verbose: + print 'GET %s?marker=%s' % (container, marker) + try: + objs = conn.get_container(container, marker=marker)[1] + except ClientException, e: + if e.http_status == 404: + exit('Container %s not found. gswauth-prep needs to be ' + 'rerun' % (container)) + elif e.http_status == 401: + exit('Cleanup tokens failed: 401 Unauthorized: Invalid user/key provided') + else: + exit('Object listing on container %s failed with status ' + 'code %d' % (container, e.http_status)) + if objs: + marker = objs[-1]['name'] + else: + if options.verbose: + print 'No more objects in %s' % container + break + for obj in objs: + if options.purge_all: + if options.verbose: + print '%s/%s purge all; deleting' % \ + (container, obj['name']) + print 'DELETE %s/%s' % (container, obj['name']) + try: + conn.delete_object(container, obj['name']) + except ClientException, err: + if err.http_status != 404: + raise + continue + last_modified = datetime(*map(int, re.split('[^\d]', + obj['last_modified'])[:-1])) + ago = datetime.utcnow() - last_modified + if ago > options.token_life: + if options.verbose: + print '%s/%s last modified %ss ago; investigating' % \ + (container, obj['name'], + ago.days * 86400 + ago.seconds) + print 'GET %s/%s' % (container, obj['name']) + detail = conn.get_object(container, obj['name'])[1] + detail = json.loads(detail) + if detail['expires'] < time(): + if options.verbose: + print '%s/%s expired %ds ago; deleting' % \ + (container, obj['name'], + time() - detail['expires']) + print 'DELETE %s/%s' % (container, obj['name']) + try: + conn.delete_object(container, obj['name']) + except ClientException, e: + if e.http_status != 404: + print 'DELETE of %s/%s failed with status ' \ + 'code %d' % (container, obj['name'], + e.http_status) + elif options.verbose: + print "%s/%s won't expire for %ds; skipping" % \ + (container, obj['name'], + detail['expires'] - time()) + elif options.verbose: + print '%s/%s last modified %ss ago; skipping' % \ + (container, obj['name'], + ago.days * 86400 + ago.seconds) + sleep(options.sleep) + if options.verbose: + print 'Done.' |