remove ceph code
[stor4nfv.git] / src / ceph / src / powerdns / pdns-backend-rgw.py
diff --git a/src/ceph/src/powerdns/pdns-backend-rgw.py b/src/ceph/src/powerdns/pdns-backend-rgw.py
deleted file mode 100755 (executable)
index 6cb42d8..0000000
+++ /dev/null
@@ -1,283 +0,0 @@
-#!/usr/bin/python
-'''
-A backend for PowerDNS to direct RADOS Gateway bucket traffic to the correct regions.
-
-For example, two regions exist, US and EU.
-
-EU: o.myobjects.eu
-US: o.myobjects.us
-
-A global domain o.myobjects.com exists.
-
-Bucket 'foo' exists in the region EU and 'bar' in US.
-
-foo.o.myobjects.com will return a CNAME to foo.o.myobjects.eu
-bar.o.myobjects.com will return a CNAME to foo.o.myobjects.us
-
-The HTTP Remote Backend from PowerDNS is used in this case: http://doc.powerdns.com/html/remotebackend.html
-
-PowerDNS must be compiled with Remote HTTP backend support enabled, this is not default.
-
-Configuration for PowerDNS:
-
-launch=remote
-remote-connection-string=http:url=http://localhost:6780/dns
-
-Usage for this backend is showed by invoking with --help. See rgw-pdns.conf.in for a configuration example
-
-The ACCESS and SECRET key pair requires the caps "metadata=read"
-
-To test:
-
-$ curl -X GET http://localhost:6780/dns/lookup/foo.o.myobjects.com/ANY
-
-Should return something like:
-
-{
- "result": [
-  {
-   "content": "foo.o.myobjects.eu",
-   "qtype": "CNAME",
-   "qname": "foo.o.myobjects.com",
-   "ttl": 60
-  }
- ]
-}
-
-'''
-
-# Copyright: Wido den Hollander <wido@42on.com> 2014
-# License:   LGPL2.1
-
-from ConfigParser import SafeConfigParser, NoSectionError
-from flask import abort, Flask, request, Response
-from hashlib import sha1 as sha
-from time import gmtime, strftime
-from urlparse import urlparse
-import argparse
-import base64
-import hmac
-import json
-import pycurl
-import StringIO
-import urllib
-import os
-import sys
-
-config_locations = ['rgw-pdns.conf', '~/rgw-pdns.conf', '/etc/ceph/rgw-pdns.conf']
-
-# PowerDNS expects a 200 what ever happends and always wants
-# 'result' to 'true' if the query fails
-def abort_early():
-    return json.dumps({'result': 'true'}) + "\n"
-
-# Generate the Signature string for S3 Authorization with the RGW Admin API
-def generate_signature(method, date, uri, headers=None):
-    sign = "%s\n\n" % method
-
-    if 'Content-Type' in headers:
-        sign += "%s\n" % headers['Content-Type']
-    else:
-        sign += "\n"
-
-    sign += "%s\n/%s/%s" % (date, config['rgw']['admin_entry'], uri)
-    h = hmac.new(config['rgw']['secret_key'].encode('utf-8'), sign.encode('utf-8'), digestmod=sha)
-    return base64.encodestring(h.digest()).strip()
-
-def generate_auth_header(signature):
-    return str("AWS %s:%s" % (config['rgw']['access_key'], signature.decode('utf-8')))
-
-# Do a HTTP request to the RGW Admin API
-def do_rgw_request(uri, params=None, data=None, headers=None):
-    if headers == None:
-        headers = {}
-
-    headers['Date'] = strftime("%a, %d %b %Y %H:%M:%S +0000", gmtime())
-    signature = generate_signature("GET", headers['Date'], uri, headers)
-    headers['Authorization'] = generate_auth_header(signature)
-
-    query = None
-    if params != None:
-        query = '&'.join("%s=%s" % (key,val) for (key,val) in params.iteritems())
-
-    c = pycurl.Curl()
-    b = StringIO.StringIO()
-    url = "http://" + config['rgw']['endpoint'] + "/" + config['rgw']['admin_entry'] + "/" + uri + "?format=json"
-    if query != None:
-        url += "&" + urllib.quote_plus(query)
-
-    http_headers = []
-    for header in headers.keys():
-        http_headers.append(header + ": " + headers[header])
-
-    c.setopt(pycurl.URL, str(url))
-    c.setopt(pycurl.HTTPHEADER, http_headers)
-    c.setopt(pycurl.WRITEFUNCTION, b.write)
-    c.setopt(pycurl.FOLLOWLOCATION, 0)
-    c.setopt(pycurl.CONNECTTIMEOUT, 5)
-    c.perform()
-
-    response = b.getvalue()
-    if len(response) > 0:
-        return json.loads(response)
-
-    return None
-
-def get_radosgw_metadata(key):
-    return do_rgw_request('metadata', {'key': key})
-
-# Returns a string of the region where the bucket is in
-def get_bucket_region(bucket):
-    meta = get_radosgw_metadata("bucket:%s" % bucket)
-    bucket_id = meta['data']['bucket']['bucket_id']
-    meta_instance = get_radosgw_metadata("bucket.instance:%s:%s" % (bucket, bucket_id))
-    region = meta_instance['data']['bucket_info']['region']
-    return region
-
-# Returns the correct host for the bucket based on the regionmap
-def get_bucket_host(bucket, region_map):
-    region = get_bucket_region(bucket)
-    return bucket + "." + region_map[region]
-
-# This should support multiple endpoints per region!
-def parse_region_map(map):
-    regions = {}
-    for region in map['regions']:
-        url = urlparse(region['val']['endpoints'][0])
-        regions.update({region['key']: url.netloc})
-
-    return regions
-
-def str2bool(s):
-    return s.lower() in ("yes", "true", "1")
-
-def init_config():
-    parser = argparse.ArgumentParser()
-    parser.add_argument("--config", help="The configuration file to use.", action="store")
-
-    args = parser.parse_args()
-
-    defaults = {
-                   'listen_addr': '127.0.0.1',
-                   'listen_port': '6780',
-                   'dns_zone': 'rgw.local.lan',
-                   'dns_soa_record': 'dns1.icann.org. hostmaster.icann.org. 2012080849 7200 3600 1209600 3600',
-                   'dns_soa_ttl': '3600',
-                   'dns_default_ttl': '60',
-                   'rgw_endpoint': 'localhost:8080',
-                   'rgw_admin_entry': 'admin',
-                   'rgw_access_key': 'access',
-                   'rgw_secret_key': 'secret',
-                   'debug': False
-               }
-
-    cfg = SafeConfigParser(defaults)
-    if args.config == None:
-        cfg.read(config_locations)
-    else:
-        if not os.path.isfile(args.config):
-            print "Could not open configuration file %s" % args.config
-            sys.exit(1)
-
-        cfg.read(args.config)
-
-    config_section = 'powerdns'
-
-    try:
-        return {
-            'listen': {
-                'port': cfg.getint(config_section, 'listen_port'),
-                'addr': cfg.get(config_section, 'listen_addr')
-                },
-            'dns': {
-                'zone': cfg.get(config_section, 'dns_zone'),
-                'soa_record': cfg.get(config_section, 'dns_soa_record'),
-                'soa_ttl': cfg.get(config_section, 'dns_soa_ttl'),
-                'default_ttl': cfg.get(config_section, 'dns_default_ttl')
-            },
-            'rgw': {
-                'endpoint': cfg.get(config_section, 'rgw_endpoint'),
-                'admin_entry': cfg.get(config_section, 'rgw_admin_entry'),
-                'access_key': cfg.get(config_section, 'rgw_access_key'),
-                'secret_key': cfg.get(config_section, 'rgw_secret_key')
-            },
-            'debug': str2bool(cfg.get(config_section, 'debug'))
-        }
-
-    except NoSectionError:
-         return None
-
-def generate_app(config):
-    # The Flask App
-    app = Flask(__name__)
-
-    # Get the RGW Region Map
-    region_map = parse_region_map(do_rgw_request('config'))
-
-    @app.route('/')
-    def index():
-        abort(404)
-
-    @app.route("/dns/lookup/<qname>/<qtype>")
-    def bucket_location(qname, qtype):
-        if len(qname) == 0:
-            return abort_early()
-
-        split = qname.split(".", 1)
-        if len(split) != 2:
-            return abort_early()
-
-        bucket = split[0]
-        zone = split[1]
-
-        # If the received qname doesn't match our zone we abort
-        if zone != config['dns']['zone']:
-            return abort_early()
-
-        # We do not serve MX records
-        if qtype == "MX":
-            return abort_early()
-
-        # The basic result we always return, this is what PowerDNS expects.
-        response = {'result': 'true'}
-        result = {}
-
-        # A hardcoded SOA response (FIXME!)
-        if qtype == "SOA":
-            result.update({'qtype': qtype})
-            result.update({'qname': qname})
-            result.update({'content': config['dns']['soa_record']})
-            result.update({'ttl': config['dns']['soa_ttl']})
-        else:
-            region_hostname = get_bucket_host(bucket, region_map)
-            result.update({'qtype': 'CNAME'})
-            result.update({'qname': qname})
-            result.update({'content': region_hostname})
-            result.update({'ttl': config['dns']['default_ttl']})
-
-        if len(result) > 0:
-            res = []
-            res.append(result)
-            response['result'] = res
-
-        return json.dumps(response, indent=1) + "\n"
-
-    return app
-
-
-# Initialize the configuration and generate the Application
-config = init_config()
-if config == None:
-    print "Could not parse configuration file. Tried to parse %s" % config_locations
-    sys.exit(1)
-
-app = generate_app(config)
-app.debug = config['debug']
-
-# Only run the App if this script is invoked from a Shell
-if __name__ == '__main__':
-    app.run(host=config['listen']['addr'], port=config['listen']['port'])
-
-# Otherwise provide a variable called 'application' for mod_wsgi
-else:
-    application = app