add first levels, begin class based view

This commit is contained in:
Nico Schottelius 2019-05-26 00:21:37 +02:00
parent de768b2ae7
commit 64a5bc57d7
3 changed files with 122 additions and 19 deletions

View File

@ -6,14 +6,25 @@ import ipaddress
import random import random
import sys import sys
import etcd import etcd
import ungleichapi
import json
import datetime
from flask import Flask from flask import Flask, abort, request, Response
from flask_restful import Resource, Api from flask_restful import Resource, Api
from flask_restful import reqparse from flask_restful import reqparse
app = Flask(__name__) app = Flask(__name__)
api = Api(app) api = Api(app)
def get_random_ip(network):
net = ipaddress.IPv6Network(network)
addr_offset = random.randrange(2**64)
addr = net[0] + addr_offset
return addr
class Level(Resource): class Level(Resource):
points = 0 points = 0
@ -29,35 +40,115 @@ class Ping6(Level):
ping6 -c3 ping6 -c3
""" """
class Game(Resource): class Game(object):
def get(self): def __init__(self, name):
return {'hello': 'list of levels'} self.client = etcd.Client(port=2379)
self.app = Flask(name)
self.app.add_url_rule('/', 'highscore', self.highscore)
def highscore(self):
return Response("A lof of points")
api.add_resource(Game, '/game')
@app.route("/") @app.route("/")
def high_score(): def high_score():
return "High score!" return "High score!"
@app.route("/register", methods=['POST'])
def register():
parser = reqparse.RequestParser()
parser.add_argument('network', required=True)
parser.add_argument('user', required=True)
args = parser.parse_args()
# Needs to be fixed with ungleich-otp
username=args['user']
try:
net = ipaddress.IPv6Network(args['network'])
network = args['network']
except Exception as e:
return Response(status=400, response="Cannot register network {}: {}".format(network, e))
if not net.prefixlen == 64:
return Response(status=400, response="{} mask is not /64 - please use a /64 network".format(net))
client = etcd.Client(port=2379)
client.write("/ungleichgame/v1/{}/network".format(username), network)
data = client.read("/ungleichgame/v1/{}/network".format(username))
return json.dumps("All good, go to /level/1 to start with level 1! - {}".format(data.value))
@app.route("/level/1", methods=['GET', 'POST']) # post for username
def get_ip_address():
parser = reqparse.RequestParser()
parser.add_argument('user', required=True)
args = parser.parse_args()
# Needs to be fixed with ungleich-otp
username=args['user']
if request.method == 'GET':
return Response("""
This is an easy level - just register any /64 network
that you fully control. After submission the game server will generate
a random IPv6 address in this network.
""")
client = etcd.Client(port=2379)
try:
data = client.read("/ungleichgame/v1/{}/network".format(username))
# FIXME: differentiate keynotfound and other errors
except Exception as e:
return Response(status=400, response="Cannot read your network, try registering first (error: {})".format(e))
return Response("data={}".format(data.value))
address = get_random_ip(data.value)
# FIXME: catch errors
client.write("/ungleichgame/v1/{}/address".format(username), address)
return Response("Your IPv6 address for this game is {}. Make it pingable and post to /level/1/result".format(address))
@app.route("/level/2", methods=['GET', 'POST']) # post for username
def pingme():
parser = reqparse.RequestParser()
parser.add_argument('user', required=True)
args = parser.parse_args()
# Needs to be fixed with ungleich-otp
username=args['user']
if request.method == 'GET':
return Response("""
Proof that you can really control the network that you submitted:
- Setup the IPv6 address to be ping6 able globally
- POST to this address when it is configured
""")
if request.method == 'POST':
try:
data = client.read("/ungleichgame/v1/{}/address".format(username), address)
except Exception as e:
return Response(status=400,
response="""
You need to register a network before trying to be reachable.
Please go back to Level 1 for registering your network.
""")
return Response("something good")
if __name__ == '__main__': if __name__ == '__main__':
net_base = "2a0a:e5c1:{:x}::/64" net_base = "2a0a:e5c1:{:x}::/64"
net_offset = random.randrange(0xffff) net_offset = random.randrange(0xffff)
net = ipaddress.IPv6Network(net_base.format(net_offset)) net = ipaddress.IPv6Network(net_base.format(net_offset))
name = 'nico{}'.format(net_offset) username = 'nico{}'.format(net_offset)
print(net) print("{} has {}".format(username, net))
print(n) g = Game(__name__)
g.app.run(port='5002')
addr_offset = random.randrange(0, 2**64)
addr = net[0] + addr_offset
a = Address('nico{}'.format(net_offset), str(addr))
print(a)
sys.exit(0)
app.run(port='5002') app.run(port='5002')

View File

@ -10,16 +10,21 @@ some_vm['network']['ipv6'].append("2a0a:e5c0:4::42/64")
some_vm['network']['ipv6'].append("2a0a:e5c0:1::42/64") some_vm['network']['ipv6'].append("2a0a:e5c0:1::42/64")
#for node in range(20000): #for node in range(200):
# client.delete('/nodes/n{}'.format(node)) # client.delete('/nodes/n{}'.format(node))
for node in range(200): for node in range(10):
ip = some_vm['network']['ipv6'].append("2a0a:e5c0:3::{}/64".format(node)) ip = some_vm['network']['ipv6'].append("2a0a:e5c0:3::{}/64".format(node))
j = json.dumps(some_vm) j = json.dumps(some_vm)
client.write('/nodes/n{}'.format(node), j) client.write('/nodes/n{}'.format(node), j)
for node in range(10):
x = client.write("/dir/name", "value", append=True)
print("generated key: " + x.key)
print("stored value: " + x.value)
result = client.read('/nodes', recursive=True, sorted=True) result = client.read('/nodes', recursive=True, sorted=True)
print(result) print(result)
for child in result.children: for child in result.children:

View File

@ -5,4 +5,11 @@ ungleich_api = {}
class ungleichAPI(object): class ungleichAPI(object):
def __init__(self, version='v1'): def __init__(self, version='v1'):
pass self.version = version
def create_vm(self, id):
vm = {}
vm['ipv6'] = []
def create_user(self):
user = {}