lxconsole/lxconsole/api/instances.py

266 lines
17 KiB
Python

from flask import jsonify, request
import json
import requests
from lxconsole import db
from lxconsole.models import Server
from flask_login import login_required
from lxconsole.api.access_controls import privilege_check
def get_client_crt():
return 'certs/client.crt'
def get_client_key():
return 'certs/client.key'
@login_required
def api_instances_endpoint(endpoint):
if not privilege_check(endpoint, request.args.get('id')):
return jsonify({'data': [], 'metadata':[], 'error': 'not authorized', 'error_code': 403})
if endpoint == 'add_instance':
id = request.args.get('id')
project = request.args.get('project')
server = Server.query.filter_by(id=id).first()
location = request.form.get('location')
if location == 'none':
url = 'https://' + server.addr + ':' + str(server.port) + '/1.0/instances?project=' + project
else:
url = 'https://' + server.addr + ':' + str(server.port) + '/1.0/instances?target=' + location + '&project=' + project
client_cert = get_client_crt()
client_key = get_client_key()
if request.form.get('json'):
data = request.form.get('json')
results = requests.post(url, verify=server.ssl_verify, cert=(client_cert, client_key), data=data)
return jsonify(results.json())
data = {}
data.update({'name': request.form.get('name')})
data.update({'description': request.form.get('description')})
data.update({'location': request.form.get('location')})
data.update({'type': request.form.get('type')})
data.update({'instance_type': request.form.get('instance_type')})
profiles = []
profiles.append(request.form.get('profiles'))
data.update({'profiles': profiles})
source = {}
if request.form.get('image') == 'none':
source.update({'type': request.form.get('image')})
data.update({'source': source})
else:
source.update({'type': 'image'})
source.update({'fingerprint': request.form.get('image')})
data.update({'source': source})
config = {}
#Options shared between containers and virtual machines
config.update({'boot.autostart': request.form.get('boot.autostart')}) if request.form.get('boot.autostart') else False
config.update({'boot.autostart.delay': request.form.get('boot.autostart.delay')}) if request.form.get('boot.autostart.delay') else False
config.update({'boot.autostart.priority': request.form.get('boot.autostart.priority')}) if request.form.get('boot.autostart.priority') else False
config.update({'boot.host_shutdown_timeout': request.form.get('boot.host_shutdown_timeout')}) if request.form.get('boot.host_shutdown_timeout') else False
config.update({'boot.stop.priority': request.form.get('boot.stop.priority')}) if request.form.get('boot.stop.priority') else False
config.update({'cloud-init.network-config': request.form.get('cloud-init.network-config')}) if request.form.get('cloud-init.network-config') else False
config.update({'cloud-init.user-data': request.form.get('cloud-init.user-data')}) if request.form.get('cloud-init.user-data') else False
config.update({'cloud-init.vendor-data': request.form.get('cloud-init.vendor-data')}) if request.form.get('cloud-init.vendor-data') else False
config.update({'cluster.evacuate': request.form.get('cluster.evacuate')}) if request.form.get('cluster.evacuate') else False
config.update({'limits.cpu': request.form.get('limits.cpu')}) if request.form.get('limits.cpu') else False
config.update({'limits.disk.priority': request.form.get('limits.disk.priority')}) if request.form.get('limits.disk.priority') else False
config.update({'limits.memory': request.form.get('limits.memory')}) if request.form.get('limits.memory') else False
config.update({'limits.network.priority': request.form.get('limits.network.priority')}) if request.form.get('limits.network.priority') else False
config.update({'raw.apparmor': request.form.get('raw.apparmor')}) if request.form.get('raw.apparmor') else False
config.update({'security.devlxd': request.form.get('security.devlxd')}) if request.form.get('security.devlxd') else False
config.update({'security.protection.shift': request.form.get('security.protection.shift')}) if request.form.get('security.protection.shift') else False
config.update({'snapshots.schedule': request.form.get('snapshots.schedule')}) if request.form.get('snapshots.schedule') else False
config.update({'snapshots.schedule.stopped': request.form.get('snapshots.schedule.stopped')}) if request.form.get('snapshots.schedule.stopped') else False
config.update({'snapshots.pattern': request.form.get('snapshots.pattern')}) if request.form.get('snapshots.pattern') else False
config.update({'snapshots.expiry': request.form.get('snapshots.expiry')}) if request.form.get('snapshots.expiry') else False
#Container only options
config.update({'limits.cpu.allowance': request.form.get('limits.cpu.allowance')}) if request.form.get('limits.cpu.allowance') else False
config.update({'limits.cpu.priority': request.form.get('limits.cpu.priority')}) if request.form.get('limits.cpu.priority') else False
config.update({'limits.hugepages.64KB': request.form.get('limits.hugepages.64KB')}) if request.form.get('limits.hugepages.64KB') else False
config.update({'limits.hugepages.1MB': request.form.get('limits.hugepages.1MB')}) if request.form.get('limits.hugepages.1MB') else False
config.update({'limits.hugepages.2MB': request.form.get('limits.hugepages.2MB')}) if request.form.get('limits.hugepages.2MB') else False
config.update({'limits.hugepages.1GB': request.form.get('limits.hugepages.1GB')}) if request.form.get('limits.hugepages.1GB') else False
config.update({'limits.memory.enforce': request.form.get('limits.memory.enforce')}) if request.form.get('limits.memory.enforce') else False
config.update({'limits.memory.swap.priority': request.form.get('limits.memory.swap.priority')}) if request.form.get('limits.memory.swap.priority') else False
config.update({'limits.memory.swap': request.form.get('limits.memory.swap')}) if request.form.get('limits.memory.swap') else False
config.update({'limits.processes': request.form.get('limits.processes')}) if request.form.get('limits.processes') else False
config.update({'linux.kernel_modules': request.form.get('linux.kernel_modules')}) if request.form.get('linux.kernel_modules') else False
config.update({'migration.incremental.memory': request.form.get('migration.incremental.memory')}) if request.form.get('migration.incremental.memory') else False
config.update({'migration.incremental.memory.goal': request.form.get('migration.incremental.memory.goal')}) if request.form.get('migration.incremental.memory.goal') else False
config.update({'migration.incremental.memory.iterations': request.form.get('migration.incremental.memory.iterations')}) if request.form.get('migration.incremental.memory.iterations') else False
config.update({'nvidia.driver.capabilities': request.form.get('nvidia.driver.capabilities')}) if request.form.get('nvidia.driver.capabilities') else False
config.update({'nvidia.runtime': request.form.get('nvidia.runtime')}) if request.form.get('nvidia.runtime') else False
config.update({'nvidia.require.cuda': request.form.get('nvidia.require.cuda')}) if request.form.get('nvidia.require.cuda') else False
config.update({'nvidia.require.driver': request.form.get('nvidia.require.driver')}) if request.form.get('nvidia.require.driver') else False
config.update({'raw.idmap': request.form.get('raw.idmap')}) if request.form.get('raw.idmap') else False
config.update({'raw.lxc': request.form.get('raw.lxc')}) if request.form.get('raw.lxc') else False
config.update({'raw.seccomp': request.form.get('raw.seccomp')}) if request.form.get('raw.seccomp') else False
config.update({'security.devlxd': request.form.get('security.devlxd')}) if request.form.get('security.devlxd') else False
config.update({'security.devlxd.images': request.form.get('security.devlxd.images')}) if request.form.get('security.devlxd.images') else False
config.update({'security.idmap.base': request.form.get('security.idmap.base')}) if request.form.get('security.idmap.base') else False
config.update({'security.idmap.isolated': request.form.get('security.idmap.isolated')}) if request.form.get('security.idmap.isolated') else False
config.update({'security.idmap.size': request.form.get('security.idmap.size')}) if request.form.get('security.idmap.size') else False
config.update({'security.nesting': request.form.get('security.nesting')}) if request.form.get('security.nesting') else False
config.update({'security.privileged': request.form.get('security.privileged')}) if request.form.get('security.privileged') else False
config.update({'security.protection.delete': request.form.get('security.protection.delete')}) if request.form.get('security.protection.delete') else False
config.update({'security.protection.shift': request.form.get('security.protection.shift')}) if request.form.get('security.protection.shift') else False
config.update({'security.syscalls.allow': request.form.get('security.syscalls.allow')}) if request.form.get('security.syscalls.allow') else False
config.update({'security.syscalls.deny': request.form.get('security.syscalls.deny')}) if request.form.get('security.syscalls.deny') else False
config.update({'security.syscalls.deny_compat': request.form.get('security.syscalls.deny_compat')}) if request.form.get('security.syscalls.deny_compat') else False
config.update({'security.syscalls.deny_default': request.form.get('security.syscalls.deny_default')}) if request.form.get('security.syscalls.deny_default') else False
config.update({'security.syscalls.intercept.bpf': request.form.get('security.syscalls.intercept.bpf')}) if request.form.get('security.syscalls.intercept.bpf') else False
config.update({'security.syscalls.intercept.bpf.devices': request.form.get('security.syscalls.intercept.bpf.devices')}) if request.form.get('security.syscalls.intercept.bpf.devices') else False
config.update({'security.syscalls.intercept.mknod': request.form.get('security.syscalls.intercept.mknod')}) if request.form.get('security.syscalls.intercept.mknod') else False
config.update({'security.syscalls.intercept.mount': request.form.get('security.syscalls.intercept.mount')}) if request.form.get('security.syscalls.intercept.mount') else False
config.update({'security.syscalls.intercept.mount.allowed': request.form.get('security.syscalls.intercept.mount.allowed')}) if request.form.get('security.syscalls.intercept.mount.allowed') else False
config.update({'security.syscalls.intercept.mount.fuse': request.form.get('security.syscalls.intercept.mount.fuse')}) if request.form.get('security.syscalls.intercept.mount.fuse') else False
config.update({'security.syscalls.intercept.mount.shift': request.form.get('security.syscalls.intercept.mount.shift')}) if request.form.get('security.syscalls.intercept.mount.shift') else False
config.update({'security.syscalls.intercept.setxattr': request.form.get('security.syscalls.intercept.setxattr')}) if request.form.get('security.syscalls.intercept.setxattr') else False
#Virtual Machine only options
config.update({'limits.memory.hugepages': request.form.get('limits.memory.hugepages')}) if request.form.get('limits.memory.hugepages') else False
config.update({'migration.stateful': request.form.get('migration.stateful')}) if request.form.get('migration.stateful') else False
config.update({'raw.qemu': request.form.get('raw.qemu')}) if request.form.get('raw.qemu') else False
config.update({'raw.qemu.conf': request.form.get('raw.qemu.conf')}) if request.form.get('raw.qemu.conf') else False
config.update({'security.agent.metrics': request.form.get('security.agent.metrics')}) if request.form.get('security.agent.metrics') else False
config.update({'security.secureboot': request.form.get('security.secureboot')}) if request.form.get('security.secureboot') else False
data.update({'config': config})
results = requests.post(url, verify=server.ssl_verify, cert=(client_cert, client_key), json=data)
return jsonify(results.json())
if endpoint == 'delete_instance':
id = request.args.get('id')
project = request.args.get('project')
name = request.form.get('name')
server = Server.query.filter_by(id=id).first()
url = 'https://' + server.addr + ':' + str(server.port) + '/1.0/instances/' + name + '?project=' + project
client_cert = get_client_crt()
client_key = get_client_key()
results = requests.delete(url, verify=server.ssl_verify, cert=(client_cert, client_key))
return jsonify(results.json())
if endpoint == 'list_instances':
id = request.args.get('id')
project = request.args.get('project')
server = Server.query.filter_by(id=id).first()
recursion = request.args.get('recursion')
if request.args.get('filter') == "container":
filter = "type+eq+container"
elif request.args.get('filter') == "virtual-machine":
filter = "type+eq+virtual-machine"
else:
filter = ""
if recursion == '1':
url = 'https://' + server.addr + ':' + str(server.port) + '/1.0/instances?filter=' + filter + '&recursion=1&project=' + project
elif recursion == '2':
url = 'https://' + server.addr + ':' + str(server.port) + '/1.0/instances?filter=' + filter + '&recursion=2&project=' + project
else:
url = 'https://' + server.addr + ':' + str(server.port) + '/1.0/instances?filter=' + filter + '&project=' + project
client_cert = get_client_crt()
client_key = get_client_key()
results = requests.get(url, verify=server.ssl_verify, cert=(client_cert, client_key))
instances = json.dumps(results.json())
instances = json.loads(instances)
if recursion == '0' or recursion == '1':
return jsonify(instances)
i = 0
for instance in instances['metadata']:
instances['metadata'][i]['memory'] = ''
instances['metadata'][i]['disk'] = ''
instances['metadata'][i]['ipv4_addresses'] = []
instances['metadata'][i]['ipv6_addresses'] = []
if 'state' in instance.keys():
# Set memory information if exists
if 'memory' in instance['state'].keys():
if 'usage' in instance['state']['memory'].keys():
memory = instance['state']['memory']['usage']
if memory:
instances['metadata'][i]['memory'] = memory
# Set disk information if exists
if 'disk' in instance['state'].keys():
if 'root' in instance['state']['disk'].keys():
if 'usage' in instance['state']['disk']['root'].keys():
disk = instance['state']['disk']['root']['usage']
if disk:
instances['metadata'][i]['disk'] = disk
# Set network information if exists
if 'network' in instance['state'].keys():
networks = instance['state']['network']
if networks:
instances['metadata'][i]['ipv4_addresses'] = []
for network in networks.keys():
addresses = networks[network]['addresses']
for address in addresses:
if address['family'] == 'inet' and address['scope'] == 'global':
instances['metadata'][i]['ipv4_addresses'] += [ address['address'] + ' (' + network + ')' ]
instances['metadata'][i]['ipv6_addresses'] = []
for network in networks.keys():
addresses = networks[network]['addresses']
for address in addresses:
if address['family'] == 'inet6' and address['scope'] == 'global':
instances['metadata'][i]['ipv6_addresses'] += [ address['address'] + ' (' + network + ')' ]
i += 1
return jsonify(instances)
if endpoint == 'load_instance':
id = request.args.get('id')
project = request.args.get('project')
name = request.form.get('name')
server = Server.query.filter_by(id=id).first()
url = 'https://' + server.addr + ':' + str(server.port) + '/1.0/instances/' + name + '?project=' + project
client_cert = get_client_crt()
client_key = get_client_key()
results = requests.get(url, verify=server.ssl_verify, cert=(client_cert, client_key))
return jsonify(results.json())
if endpoint == 'change_instance_state':
id = request.args.get('id')
project = request.args.get('project')
name = request.form.get('name')
action = request.form.get('action')
server = Server.query.filter_by(id=id).first()
url = 'https://' + server.addr + ':' + str(server.port) + '/1.0/instances/' + name + '/state?project=' + project
client_cert = get_client_crt()
client_key = get_client_key()
data = { 'action': action }
results = requests.put(url, verify=server.ssl_verify, cert=(client_cert, client_key), json=data)
return jsonify(results.json())
if endpoint == 'update_instance':
id = request.args.get('id')
project = request.args.get('project')
name = request.args.get('name')
server = Server.query.filter_by(id=id).first()
url = 'https://' + server.addr + ':' + str(server.port) + '/1.0/instances/' + name + '?project=' + project
client_cert = get_client_crt()
client_key = get_client_key()
if request.form.get('json'):
data = request.form.get('json')
results = requests.put(url, verify=server.ssl_verify, cert=(client_cert, client_key), data=data)
return jsonify(results.json())
data = {}
data.update({'name': request.form.get('name')})
results = requests.post(url, verify=server.ssl_verify, cert=(client_cert, client_key), json=data)
return jsonify(results.json())