import os from flask import Flask, request from flask_restful import Resource, Api from ucloud.config import etcd_client, config, vm_pool app = Flask(__name__) api = Api(app) def get_vm_entry(mac_addr): return next(filter(lambda vm: mac_addr in list(zip(*vm.network))[1], vm_pool.vms), None) # https://stackoverflow.com/questions/37140846/how-to-convert-ipv6-link-local-address-to-mac-address-in-python def ipv62mac(ipv6): # remove subnet info if given subnet_index = ipv6.find('/') if subnet_index != -1: ipv6 = ipv6[:subnet_index] ipv6_parts = ipv6.split(':') mac_parts = list() for ipv6_part in ipv6_parts[-4:]: while len(ipv6_part) < 4: ipv6_part = '0' + ipv6_part mac_parts.append(ipv6_part[:2]) mac_parts.append(ipv6_part[-2:]) # modify parts to match MAC value mac_parts[0] = '%02x' % (int(mac_parts[0], 16) ^ 2) del mac_parts[4] del mac_parts[3] return ':'.join(mac_parts) class Root(Resource): @staticmethod def get(): data = get_vm_entry(ipv62mac(request.remote_addr)) if not data: return {'message': 'Metadata for such VM does not exists.'}, 404 else: etcd_key = os.path.join(config['etcd']['user_prefix'], data.value['owner_realm'], data.value['owner'], 'key') etcd_entry = etcd_client.get_prefix(etcd_key, value_in_json=True) user_personal_ssh_keys = [key.value for key in etcd_entry] data.value['metadata']['ssh-keys'] += user_personal_ssh_keys return data.value['metadata'], 200 @staticmethod def post(): return {'message': 'Previous Implementation is deprecated.'} # data = etcd_client.get("/v1/metadata/{}".format(request.remote_addr), value_in_json=True) # print(data) # if data: # for k in request.json: # if k not in data.value: # data.value[k] = request.json[k] # if k.endswith("-list"): # data.value[k] = [request.json[k]] # else: # if k.endswith("-list"): # data.value[k].append(request.json[k]) # else: # data.value[k] = request.json[k] # etcd_client.put("/v1/metadata/{}".format(request.remote_addr), # data.value, value_in_json=True) # else: # data = {} # for k in request.json: # data[k] = request.json[k] # if k.endswith("-list"): # data[k] = [request.json[k]] # etcd_client.put("/v1/metadata/{}".format(request.remote_addr), # data, value_in_json=True) api.add_resource(Root, '/') def main(): app.run(debug=True, host="::", port="80") if __name__ == '__main__': main()