Skip to content

Instantly share code, notes, and snippets.

@jeffbrl
Forked from smoser/mdserv
Last active August 29, 2015 14:10

Revisions

  1. @smoser smoser revised this gist Oct 7, 2014. 1 changed file with 19 additions and 14 deletions.
    33 changes: 19 additions & 14 deletions mdserv-maas
    Original file line number Diff line number Diff line change
    @@ -7,6 +7,7 @@ Then:
    http://localhost:9999/latest/
    """

    import socket
    import sys
    import BaseHTTPServer

    @@ -77,6 +78,9 @@ class myRequestHandler(BaseHTTPServer.BaseHTTPRequestHandler):
    return


    class HTTPServerV6(BaseHTTPServer.HTTPServer):
    address_family = socket.AF_INET6

    def run_while_true(server_class=BaseHTTPServer.HTTPServer,
    handler_class=BaseHTTPServer.BaseHTTPRequestHandler,
    port=8001, ipaddr=''):
    @@ -90,20 +94,21 @@ def run_while_true(server_class=BaseHTTPServer.HTTPServer,
    httpd.serve_forever()


    args = {
    'handler_class': myRequestHandler, 'port': 8000, 'ipaddr': '',
    }
    import argparse
    parser = argparse.ArgumentParser(description='run MAAS-like metadata server')
    parser.add_argument('-6', '--ipv6', action='store_true', default=False)
    parser.add_argument('-p', '--port', default=8000, type=int)
    parser.add_argument('ipaddr', help='listen only on provided address',
    default='', nargs='?')
    args = parser.parse_args()

    sclass = BaseHTTPServer.HTTPServer
    if args.ipv6:
    print("using ipv6")
    sclass = HTTPServerV6

    if len(sys.argv) == 2:
    toks = sys.argv[1].split(":")
    if len(toks) == 1:
    # port only
    args['port'] = sys.argv[1]
    if len(toks) == 2:
    # host:port
    (args['ipaddr'], args['port']) = toks

    print "listening on %s:%s" % (args['ipaddr'], args['port'])
    run_while_true(**args)
    print("listening on [%s]:%s" % (args.ipaddr, args.port))
    run_while_true(server_class=sclass, handler_class=myRequestHandler,
    port=args.port, ipaddr=args.ipaddr)

    # vi: ts=4 expandtab
  2. @smoser smoser revised this gist Oct 7, 2014. 1 changed file with 1 addition and 1 deletion.
    2 changes: 1 addition & 1 deletion mdserv-maas
    Original file line number Diff line number Diff line change
    @@ -91,7 +91,7 @@ def run_while_true(server_class=BaseHTTPServer.HTTPServer,


    args = {
    'handler_class': myRequestHandler, 'port': 8000, 'ipaddr': = '',
    'handler_class': myRequestHandler, 'port': 8000, 'ipaddr': '',
    }

    if len(sys.argv) == 2:
  3. @smoser smoser revised this gist Oct 7, 2014. 1 changed file with 109 additions and 0 deletions.
    109 changes: 109 additions & 0 deletions mdserv-maas
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,109 @@
    #!/usr/bin/python
    """
    To use this to mimic a MAAS metadata service, run it like:
    sudo ./mdserv 9999
    Then:
    python cloudinit/sources/DataSourceMAAS.py crawl \
    http://localhost:9999/latest/
    """

    import sys
    import BaseHTTPServer


    PUBLIC_KEYS = (
    'ssh-rsa AAAAB3NzaC1y...oxPm+vX ubuntu@maas-dev\n'
    'ssh-rsa AAAAB3NzaC1y...jpa7rHD smoser@kurhah\r\n'
    )

    MD_VERSION = "2012-03-01"

    USER_DATA = """#!/bin/sh
    echo Hi World
    """
    md = {
    'instance-id': 'node-0acfa70c-486c-11e4-8415-00163eabcee6',
    'local-hostname': 'myhost.maas',
    'public-keys': PUBLIC_KEYS,
    }

    MD_TREE = {
    MD_VERSION: {'meta-data': md, 'user-data': USER_DATA},
    'latest': {'meta-data': md, 'user-data': USER_DATA},
    }


    class myRequestHandler(BaseHTTPServer.BaseHTTPRequestHandler):
    def do_GET(self):
    # set 'path' to "normalized" path, ie without leading
    # or trailing '/' and without double /
    toks = [i for i in self.path.split("/") if i != ""]
    path = '/'.join(toks)

    cur = MD_TREE
    for tok in toks:
    if isinstance(cur, str):
    cur = None
    break
    cur = cur.get(tok, None)
    if cur is None:
    break

    if cur is None:
    output = None
    elif isinstance(cur, str):
    output = cur
    else:
    mlist = []
    for k in sorted(cur.keys()):
    if isinstance(cur[k], str):
    mlist.append(k)
    else:
    mlist.append("%s/" % k)

    output = "\n".join(mlist)

    if cur:
    self.send_response(200)
    self.end_headers()
    self.wfile.write(output)
    else:
    self.send_response(404)
    self.end_headers()

    return

    def do_POST(self):
    return


    def run_while_true(server_class=BaseHTTPServer.HTTPServer,
    handler_class=BaseHTTPServer.BaseHTTPRequestHandler,
    port=8001, ipaddr=''):
    """
    This assumes that keep_running() is a function of no arguments which
    is tested initially and after each request. If its return value
    is true, the server continues.
    """
    server_address = (ipaddr, int(port))
    httpd = server_class(server_address, handler_class)
    httpd.serve_forever()


    args = {
    'handler_class': myRequestHandler, 'port': 8000, 'ipaddr': = '',
    }

    if len(sys.argv) == 2:
    toks = sys.argv[1].split(":")
    if len(toks) == 1:
    # port only
    args['port'] = sys.argv[1]
    if len(toks) == 2:
    # host:port
    (args['ipaddr'], args['port']) = toks

    print "listening on %s:%s" % (args['ipaddr'], args['port'])
    run_while_true(**args)

    # vi: ts=4 expandtab
  4. @smoser smoser revised this gist Dec 3, 2012. 1 changed file with 0 additions and 0 deletions.
    Empty file modified mdserv
    100644 → 100755
    Empty file.
  5. @smoser smoser revised this gist Dec 19, 2011. 1 changed file with 1 addition and 1 deletion.
    2 changes: 1 addition & 1 deletion mdserv
    Original file line number Diff line number Diff line change
    @@ -2,7 +2,7 @@
    """
    To use this to mimic the EC2 metadata service entirely, run it like:
    # where 'eth0' is *some* interface. if i used 'lo:0' i got 5 second or so delays on response.
    sudo ifconfig eth0:0 up 169.254.169.254
    sudo ifconfig eth0:0 169.254.169.254 netmask 255.255.255.255
    sudo ./mdserv 169.254.169.254:80
    Then:
  6. @smoser smoser revised this gist Dec 19, 2011. 1 changed file with 3 additions and 1 deletion.
    4 changes: 3 additions & 1 deletion mdserv
    Original file line number Diff line number Diff line change
    @@ -1,7 +1,9 @@
    #!/usr/bin/python
    """
    To use this to mimic the EC2 metadata service entirely, run it like:
    sudo ifconfig eth0 up 169.254.169.254
    # where 'eth0' is *some* interface. if i used 'lo:0' i got 5 second or so delays on response.
    sudo ifconfig eth0:0 up 169.254.169.254
    sudo ./mdserv 169.254.169.254:80
    Then:
    wget -q http://169.254.169.254/latest/meta-data/instance-id -O -; echo
  7. @smoser smoser revised this gist Dec 19, 2011. 1 changed file with 9 additions and 0 deletions.
    9 changes: 9 additions & 0 deletions mdserv
    Original file line number Diff line number Diff line change
    @@ -1,4 +1,13 @@
    #!/usr/bin/python
    """
    To use this to mimic the EC2 metadata service entirely, run it like:
    sudo ifconfig eth0 up 169.254.169.254
    sudo ./mdserv 169.254.169.254:80
    Then:
    wget -q http://169.254.169.254/latest/meta-data/instance-id -O -; echo
    curl --silent http://169.254.169.254/latest/meta-data/instance-id ; echo
    ec2metadata --instance-id
    """

    import sys
    import BaseHTTPServer
  8. @smoser smoser revised this gist Oct 20, 2011. 1 changed file with 2 additions and 0 deletions.
    2 changes: 2 additions & 0 deletions mdserv
    Original file line number Diff line number Diff line change
    @@ -53,6 +53,8 @@ echo Hi World

    MD_TREE = {
    'latest' : { 'user-data' : ud, 'meta-data': md },
    '2009-04-04' : { 'user-data' : ud, 'meta-data': md },
    '2011-01-01' : { 'user-data' : ud, 'meta-data': md },
    }

    def fixup_pubkeys(pk_dict, listing):
  9. @smoser smoser revised this gist Oct 20, 2011. 1 changed file with 12 additions and 3 deletions.
    15 changes: 12 additions & 3 deletions mdserv
    Original file line number Diff line number Diff line change
    @@ -123,20 +123,29 @@ class myRequestHandler(BaseHTTPServer.BaseHTTPRequestHandler):

    def run_while_true(server_class=BaseHTTPServer.HTTPServer,
    handler_class=BaseHTTPServer.BaseHTTPRequestHandler,
    port=8001):
    port=8001, ipaddr=''):
    """
    This assumes that keep_running() is a function of no arguments which
    is tested initially and after each request. If its return value
    is true, the server continues.
    """
    server_address = ('', int(port))
    server_address = (ipaddr, int(port))
    httpd = server_class(server_address, handler_class)
    httpd.serve_forever()

    args = { }
    args['handler_class'] = myRequestHandler
    args['port'] = 8000
    args['ipaddr'] = ''
    if len(sys.argv) == 2:
    args['port'] = sys.argv[1]
    toks = sys.argv[1].split(":")
    if len(toks) == 1:
    # port only
    args['port'] = sys.argv[1]
    if len(toks) == 2:
    # host:port
    (args['ipaddr'],args['port']) = toks

    print "listening on %s:%s" % (args['ipaddr'], args['port'])
    run_while_true(**args)
    # vi: ts=4 noexpandtab
  10. @smoser smoser created this gist Oct 11, 2011.
    142 changes: 142 additions & 0 deletions mdserv
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,142 @@
    #!/usr/bin/python

    import sys
    import BaseHTTPServer

    # output of: python -c 'import boto.utils; boto.utils.get_instance_metadata()'
    md = {
    'ami-id': 'ami-3dd11d54',
    'ami-launch-index': '0',
    'ami-manifest-path': '(unknown)',
    'block-device-mapping': {'ami': '/dev/sda1',
    'ephemeral0': '/dev/sdb',
    'root': '/dev/sda1'},
    'hostname': 'ip-10-127-107-239.ec2.internal',
    'instance-action': 'none',
    'instance-id': 'i-a2547ac2',
    'instance-type': 't1.micro',
    'kernel-id': 'aki-825ea7eb',
    'local-hostname': 'ip-10-127-107-239.ec2.internal',
    'local-ipv4': '10.127.107.239',
    'mac': '12:31:38:10:88:01',
    'network': {
    'interfaces': {
    'macs': {
    '12:31:38:10:88:01': {
    'local-hostname': 'ip-10-127-107-239.ec2.internal',
    'local-ipv4s': '10.127.107.239',
    'mac': '12:31:38:10:88:01',
    'public-hostname': 'ec2-50-19-60-80.compute-1.amazonaws.com',
    'public-ipv4s': '50.19.60.80',
    'security-groups': 'default'
    }
    }
    }
    },
    'placement': {'availability-zone': 'us-east-1d'},
    'profile': 'default-paravirtual',
    'public-hostname': 'ec2-50-19-60-80.compute-1.amazonaws.com',
    'public-ipv4': '50.19.60.80',
    'public-keys': {
    'brickies': [
    'ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEA3I7VUf2l5gSn5uavROsc5HRDpZdQueUq5ozemNSj8T7enqKHOEaFoU2VoPgGEWC9RyzSQVeyD6s7APMcE82EtmW4skVEgEGSbDc1pvxzxtchBj78hJP6Cf5TCMFSXw+Fz5rF1dR23QDbN1mkHs7adr8GW4kSWqU7Q7NDwfIrJJtO7Hi42GyXtvEONHbiRPOe8stqUly7MvUoN+5kfjBM8Qqpfl2+FNhTYWpMfYdPUnE7u536WqzFmsaqJctz3gBxH9Ex7dFtrxR4qiqEr9Qtlu3xGn7Bw07/+i1D+ey3ONkZLN+LQ714cgj8fRS4Hj29SCmXp5Kt5/82cD/VN3NtHw== brickies',
    ''
    ]
    },
    'reservation-id': 'r-50258f3e',
    'security-groups': 'default'
    }

    ud = """#!/bin/sh
    echo Hi World
    """

    MD_TREE = {
    'latest' : { 'user-data' : ud, 'meta-data': md },
    }

    def fixup_pubkeys(pk_dict, listing):
    # if pk_dict is a public-keys dictionary as returned by boto
    # listing is boolean indicating if this is a listing or a item
    #
    # public-keys is messed up. a list of /latest/meta-data/public-keys/
    # shows something like: '0=brickies'
    # but a GET to /latest/meta-data/public-keys/0=brickies will fail
    # you have to know to get '/latest/meta-data/public-keys/0', then
    # from there you get a 'openssh-key', which you can get.
    # this hunk of code just re-works the object for that.
    i = -1
    mod_cur = {}
    for k in sorted(pk_dict.keys()):
    i = i+1
    if listing:
    mod_cur["%d=%s" % (i, k)] = ""
    else:
    mod_cur["%d" % i] = { "openssh-key": '\n'.join(pk_dict[k]) }
    return(mod_cur)

    class myRequestHandler(BaseHTTPServer.BaseHTTPRequestHandler):
    def do_GET(self):

    # set 'path' to "normalized" path, ie without leading
    # or trailing '/' and without double /
    toks = [i for i in self.path.split("/") if i != "" ]
    path = '/'.join(toks)

    cur = MD_TREE
    for tok in toks:
    if isinstance(cur, str):
    cur = None
    break
    cur = cur.get(tok, None)
    if cur == None:
    break
    if tok == "public-keys":
    cur = fixup_pubkeys(cur, toks[-1] == "public-keys")

    if cur == None:
    output = None
    elif isinstance(cur,str):
    output = cur
    else:
    mlist = []
    for k in sorted(cur.keys()):
    if isinstance(cur[k], str):
    mlist.append(k)
    else:
    mlist.append("%s/" % k)

    output = "\n".join(mlist)

    if cur:
    self.send_response(200)
    self.end_headers()
    self.wfile.write(output)
    else:
    self.send_response(404)
    self.end_headers()

    return

    def do_POST(self):
    return

    def run_while_true(server_class=BaseHTTPServer.HTTPServer,
    handler_class=BaseHTTPServer.BaseHTTPRequestHandler,
    port=8001):
    """
    This assumes that keep_running() is a function of no arguments which
    is tested initially and after each request. If its return value
    is true, the server continues.
    """
    server_address = ('', int(port))
    httpd = server_class(server_address, handler_class)
    httpd.serve_forever()

    args = { }
    args['handler_class'] = myRequestHandler
    if len(sys.argv) == 2:
    args['port'] = sys.argv[1]

    run_while_true(**args)
    # vi: ts=4 noexpandtab