91 lines
		
	
	
	
		
			3 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
			
		
		
	
	
			91 lines
		
	
	
	
		
			3 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
import os
 | 
						|
 | 
						|
from flask import Flask, request
 | 
						|
from flask_restful import Resource, Api
 | 
						|
 | 
						|
from ucloud.config import etcd_client, env_vars, 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:
 | 
						|
 | 
						|
            # {env_vars.get('USER_PREFIX')}/{realm}/{name}/key
 | 
						|
            etcd_key = os.path.join(env_vars.get('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()
 |