This commit is contained in:
matthewalanpenning 2023-10-24 05:28:27 -04:00
parent a51b003a2a
commit 287d28fb10
67 changed files with 2208 additions and 9124 deletions

View file

@ -1,3 +1,10 @@
# 0.4.0
- Upgraded Bootstrap from version 4 to version 5
- Converted containers and virtual-machines endpoints to instances endpoint
- Combined containers and virtual-machines pages to instances page
- Datatable errors now display on console.log rather than the default alert
- Handled 404 Error on new virtual machine without logs
# 0.3.0
- Improved Dockerfile for quicker builds
- Added version specific flask and werkzeug to requirements due to build error in dependencies

View file

@ -5,8 +5,8 @@ from . import certificates
from . import cluster_groups
from . import cluster_members
from . import images
from . import container
from . import containers
from . import instance
from . import instances
from . import network
from . import networks
from . import network_acl
@ -18,8 +18,6 @@ from . import projects
from . import simplestreams
from . import storage_pools
from . import storage_volumes
from . import virtual_machine
from . import virtual_machines
from . import users
from . import groups
@ -32,8 +30,8 @@ api = Blueprint('api', __name__, url_prefix='/api')
# URLs are prefixed with /api...
api.add_url_rule('/container/<endpoint>', view_func=container.api_container_endpoint, methods=['GET', 'POST'])
api.add_url_rule('/containers/<endpoint>', view_func=containers.api_containers_endpoint, methods=['GET', 'POST'])
api.add_url_rule('/instance/<endpoint>', view_func=instance.api_instance_endpoint, methods=['GET', 'POST'])
api.add_url_rule('/instances/<endpoint>', view_func=instances.api_instances_endpoint, methods=['GET', 'POST'])
api.add_url_rule('/servers/<endpoint>', view_func=servers.api_servers_endpoint, methods=['GET', 'POST'])
api.add_url_rule('/server/<endpoint>', view_func=server.api_server_endpoint)
api.add_url_rule('/certificates/<endpoint>', view_func=certificates.api_certificates_endpoint, methods=['GET', 'POST'])
@ -51,8 +49,6 @@ api.add_url_rule('/projects/<endpoint>', view_func=projects.api_projects_endpoin
api.add_url_rule('/simplestreams/<endpoint>', view_func=simplestreams.api_simplestreams_endpoint, methods=['GET', 'POST'])
api.add_url_rule('/storage-pools/<endpoint>', view_func=storage_pools.api_storage_pools_endpoint, methods=['GET', 'POST'])
api.add_url_rule('/storage-volumes/<endpoint>', view_func=storage_volumes.api_storage_volumes_endpoint, methods=['GET', 'POST'])
api.add_url_rule('/virtual-machine/<endpoint>', view_func=virtual_machine.api_virtual_machine_endpoint, methods=['GET', 'POST'])
api.add_url_rule('/virtual-machines/<endpoint>', view_func=virtual_machines.api_virtual_machines_endpoint, methods=['GET', 'POST'])
api.add_url_rule('/users/<endpoint>', view_func=users.api_users_endpoint, methods=['GET', 'POST'])
api.add_url_rule('/groups/<endpoint>', view_func=groups.api_groups_endpoint, methods=['GET', 'POST'])

File diff suppressed because it is too large Load diff

View file

@ -17,7 +17,7 @@ def get_client_key():
return 'certs/client.key'
@login_required
def api_virtual_machine_endpoint(endpoint):
def api_instance_endpoint(endpoint):
if not privilege_check(endpoint, request.args.get('id')):
return jsonify({'data': [], 'metadata':[], 'error': 'not authorized', 'error_code': 403})
@ -28,7 +28,7 @@ def api_virtual_machine_endpoint(endpoint):
project = request.args.get('project')
instance = request.args.get('instance')
server = Server.query.filter_by(id=id).first()
url = 'https://' + server.addr + ':' + str(server.port) + '/1.0/virtual-machines/' + instance + '?project=' + project
url = 'https://' + server.addr + ':' + str(server.port) + '/1.0/instances/' + instance + '?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))
@ -72,7 +72,7 @@ def api_virtual_machine_endpoint(endpoint):
project = request.args.get('project')
instance = request.args.get('instance')
server = Server.query.filter_by(id=id).first()
url = 'https://' + server.addr + ':' + str(server.port) + '/1.0/virtual-machines/' + instance + '?project=' + project
url = 'https://' + server.addr + ':' + str(server.port) + '/1.0/instances/' + instance + '?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))
@ -108,7 +108,7 @@ def api_virtual_machine_endpoint(endpoint):
project = request.args.get('project')
instance = request.args.get('instance')
server = Server.query.filter_by(id=id).first()
url = 'https://' + server.addr + ':' + str(server.port) + '/1.0/virtual-machines/' + instance + '?project=' + project
url = 'https://' + server.addr + ':' + str(server.port) + '/1.0/instances/' + instance + '?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))
@ -172,7 +172,7 @@ def api_virtual_machine_endpoint(endpoint):
project = request.args.get('project')
instance = request.args.get('instance')
server = Server.query.filter_by(id=id).first()
url = 'https://' + server.addr + ':' + str(server.port) + '/1.0/virtual-machines/' + instance + '?project=' + project
url = 'https://' + server.addr + ':' + str(server.port) + '/1.0/instances/' + instance + '?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))
@ -208,7 +208,7 @@ def api_virtual_machine_endpoint(endpoint):
project = request.args.get('project')
instance = request.args.get('instance')
server = Server.query.filter_by(id=id).first()
url = 'https://' + server.addr + ':' + str(server.port) + '/1.0/virtual-machines/' + instance + '?project=' + project
url = 'https://' + server.addr + ':' + str(server.port) + '/1.0/instances/' + instance + '?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))
@ -235,14 +235,14 @@ def api_virtual_machine_endpoint(endpoint):
data.update({'devices': devices})
results = requests.patch(url, verify=server.ssl_verify, cert=(client_cert, client_key), json=data)
return jsonify(results.json())
if endpoint == 'add_instance_usb_device':
id = request.args.get('id')
project = request.args.get('project')
instance = request.args.get('instance')
server = Server.query.filter_by(id=id).first()
url = 'https://' + server.addr + ':' + str(server.port) + '/1.0/virtual-machines/' + instance + '?project=' + project
url = 'https://' + server.addr + ':' + str(server.port) + '/1.0/instances/' + instance + '?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))
@ -267,12 +267,13 @@ def api_virtual_machine_endpoint(endpoint):
results = requests.patch(url, verify=server.ssl_verify, cert=(client_cert, client_key), json=data)
return jsonify(results.json())
if endpoint == 'attach_instance_profile':
id = request.args.get('id')
project = request.args.get('project')
instance = request.args.get('instance')
server = Server.query.filter_by(id=id).first()
url = 'https://' + server.addr + ':' + str(server.port) + '/1.0/virtual-machines/' + instance + '?project=' + project
url = 'https://' + server.addr + ':' + str(server.port) + '/1.0/instances/' + instance + '?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))
@ -296,7 +297,7 @@ def api_virtual_machine_endpoint(endpoint):
action = request.form.get('action')
force = request.form.get('force')
server = Server.query.filter_by(id=id).first()
url = 'https://' + server.addr + ':' + str(server.port) + '/1.0/virtual-machines/' + instance + '/state?project=' + project
url = 'https://' + server.addr + ':' + str(server.port) + '/1.0/instances/' + instance + '/state?project=' + project
client_cert = get_client_crt()
client_key = get_client_key()
if force == 'true':
@ -315,9 +316,9 @@ def api_virtual_machine_endpoint(endpoint):
location = request.args.get('location')
#Target location is needed for clustered servers and not allowed on non-clustered servers
if location == 'none':
url = 'https://' + server.addr + ':' + str(server.port) + '/1.0/virtual-machines?project=' + project
url = 'https://' + server.addr + ':' + str(server.port) + '/1.0/instances?project=' + project
else:
url = 'https://' + server.addr + ':' + str(server.port) + '/1.0/virtual-machines?target='+location+'&project=' + project
url = 'https://' + server.addr + ':' + str(server.port) + '/1.0/instances?target='+location+'&project=' + project
client_cert = get_client_crt()
client_key = get_client_key()
data = {}
@ -336,7 +337,7 @@ def api_virtual_machine_endpoint(endpoint):
project = request.args.get('project')
instance = request.args.get('instance')
server = Server.query.filter_by(id=id).first()
url = 'https://' + server.addr + ':' + str(server.port) + '/1.0/virtual-machines/' + instance + '/backups?project=' + project
url = 'https://' + server.addr + ':' + str(server.port) + '/1.0/instances/' + instance + '/backups?project=' + project
client_cert = get_client_crt()
client_key = get_client_key()
@ -372,14 +373,14 @@ def api_virtual_machine_endpoint(endpoint):
data.update({'compression_algorithm': request.form.get('compression_algorithm')}) if request.form.get('compression_algorithm') else False
results = requests.post(url, verify=server.ssl_verify, cert=(client_cert, client_key), json=data)
return jsonify(results.json())
if endpoint == 'create_instance_snapshot':
id = request.args.get('id')
project = request.args.get('project')
instance = request.args.get('instance')
server = Server.query.filter_by(id=id).first()
url = 'https://' + server.addr + ':' + str(server.port) + '/1.0/virtual-machines/' + instance + '/snapshots?project=' + project
url = 'https://' + server.addr + ':' + str(server.port) + '/1.0/instances/' + instance + '/snapshots?project=' + project
client_cert = get_client_crt()
client_key = get_client_key()
data = {}
@ -400,9 +401,9 @@ def api_virtual_machine_endpoint(endpoint):
location = request.args.get('location')
#Target location is needed for clustered servers and not allowed on non-clustered servers
if location == 'none':
url = 'https://' + server.addr + ':' + str(server.port) + '/1.0/virtual-machines?project=' + project
url = 'https://' + server.addr + ':' + str(server.port) + '/1.0/instances?project=' + project
else:
url = 'https://' + server.addr + ':' + str(server.port) + '/1.0/virtual-machines?target='+location+'&project=' + project
url = 'https://' + server.addr + ':' + str(server.port) + '/1.0/instances?target='+location+'&project=' + project
client_cert = get_client_crt()
client_key = get_client_key()
data = {}
@ -423,7 +424,7 @@ def api_virtual_machine_endpoint(endpoint):
instance = request.args.get('instance')
backup = request.args.get('backup')
server = Server.query.filter_by(id=id).first()
url = 'https://' + server.addr + ':' + str(server.port) + '/1.0/virtual-machines/' + instance + '/backups/' + backup + '?project=' + project
url = 'https://' + server.addr + ':' + str(server.port) + '/1.0/instances/' + instance + '/backups/' + backup + '?project=' + project
client_cert = get_client_crt()
client_key = get_client_key()
if os.path.isfile('backups/' + str(server.id) + '/' + project + '/' + instance + '/' + backup):
@ -438,7 +439,7 @@ def api_virtual_machine_endpoint(endpoint):
instance = request.args.get('instance')
device = request.args.get('device')
server = Server.query.filter_by(id=id).first()
url = 'https://' + server.addr + ':' + str(server.port) + '/1.0/virtual-machines/' + instance + '?project=' + project
url = 'https://' + server.addr + ':' + str(server.port) + '/1.0/instances/' + instance + '?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))
@ -455,7 +456,7 @@ def api_virtual_machine_endpoint(endpoint):
project = request.args.get('project')
instance = request.form.get('instance')
server = Server.query.filter_by(id=id).first()
url = 'https://' + server.addr + ':' + str(server.port) + '/1.0/virtual-machines/' + instance + '?project=' + project
url = 'https://' + server.addr + ':' + str(server.port) + '/1.0/instances/' + instance + '?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))
@ -480,7 +481,7 @@ def api_virtual_machine_endpoint(endpoint):
instance = request.args.get('instance')
snapshot = request.args.get('snapshot')
server = Server.query.filter_by(id=id).first()
url = 'https://' + server.addr + ':' + str(server.port) + '/1.0/virtual-machines/' + instance + '/snapshots/' + snapshot + '?project=' + project
url = 'https://' + server.addr + ':' + str(server.port) + '/1.0/instances/' + instance + '/snapshots/' + snapshot + '?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))
@ -493,7 +494,7 @@ def api_virtual_machine_endpoint(endpoint):
instance = request.args.get('instance')
profile = request.args.get('profile')
server = Server.query.filter_by(id=id).first()
url = 'https://' + server.addr + ':' + str(server.port) + '/1.0/virtual-machines/' + instance + '?project=' + project
url = 'https://' + server.addr + ':' + str(server.port) + '/1.0/instances/' + instance + '?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))
@ -520,14 +521,14 @@ def api_virtual_machine_endpoint(endpoint):
client_key = get_client_key()
results = requests.get(url, verify=server.ssl_verify, cert=(client_cert, client_key))
return results.text
if endpoint == 'establish_instance_console_websocket':
id = request.args.get('id')
project = request.args.get('project')
instance = request.args.get('instance')
server = Server.query.filter_by(id=id).first()
url = 'https://' + server.addr + ':' + str(server.port) + '/1.0/virtual-machines/' + instance + '/console?project=' + project
url = 'https://' + server.addr + ':' + str(server.port) + '/1.0/instances/' + instance + '/console?project=' + project
client_cert = get_client_crt()
client_key = get_client_key()
data = {}
@ -550,7 +551,7 @@ def api_virtual_machine_endpoint(endpoint):
project = request.args.get('project')
instance = request.args.get('instance')
server = Server.query.filter_by(id=id).first()
url = 'https://' + server.addr + ':' + str(server.port) + '/1.0/virtual-machines/' + instance + '/exec?project=' + project
url = 'https://' + server.addr + ':' + str(server.port) + '/1.0/instances/' + instance + '/exec?project=' + project
client_cert = get_client_crt()
client_key = get_client_key()
data = {}
@ -576,7 +577,7 @@ def api_virtual_machine_endpoint(endpoint):
control = str(results['metadata']['metadata']['fds']['control']) if str(results['metadata']['metadata']['fds']['control']) else ''
return jsonify({'operation': operation, 'secret': secret, 'control': control})
if endpoint == 'export_instance_backup':
id = request.args.get('id')
@ -584,7 +585,7 @@ def api_virtual_machine_endpoint(endpoint):
server = Server.query.filter_by(id=id).first()
instance = request.args.get('instance')
backup = request.args.get('backup')
url = 'https://' + server.addr + ':' + str(server.port) + '/1.0/virtual-machines/' + instance + '/backups/' + backup + '/export?project=' + project
url = 'https://' + server.addr + ':' + str(server.port) + '/1.0/instances/' + instance + '/backups/' + backup + '/export?project=' + project
client_cert = get_client_crt()
client_key = get_client_key()
os.system('mkdir -p backups/' + str(server.id) + '/' + project + '/' + instance)
@ -604,15 +605,15 @@ def api_virtual_machine_endpoint(endpoint):
name = request.args.get('name')
recursion = request.args.get('recursion')
if recursion == '1':
url = 'https://' + server.addr + ':' + str(server.port) + '/1.0/virtual-machines/' + name + '?recursion=1&project=' + project
url = 'https://' + server.addr + ':' + str(server.port) + '/1.0/instances/' + name + '?recursion=1&project=' + project
else:
url = 'https://' + server.addr + ':' + str(server.port) + '/1.0/virtual-machines/' + name + '?project=' + project
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())
# Virtual Machine only
if endpoint == 'get_instance_cpu_percentage':
id = request.args.get('id')
project = request.args.get('project')
@ -629,7 +630,7 @@ def api_virtual_machine_endpoint(endpoint):
# Unable to read /proc/stat directly on virtual machines use lxd files api...getting an EOF error
# So we will copy /proc/stat to /tmp/stat and then read that file as a work around
data = {}
data.update({'command': ['cp', '/proc/stat', '/tmp/stat']})
data.update({'command': ['cp', '/proc/stat', '/tmp/stat1']})
data.update({'wait-for-websocket': False})
data.update({'interactive': False})
data.update({'width': 80 })
@ -640,14 +641,14 @@ def api_virtual_machine_endpoint(endpoint):
data.update({'record-output': False })
data.update({'environment': {} })
url = 'https://' + server.addr + ':' + str(server.port) + '/1.0/virtual-machines/' + name + '/exec?project=' + project
url = 'https://' + server.addr + ':' + str(server.port) + '/1.0/instances/' + name + '/exec?project=' + project
results = requests.post(url, verify=server.ssl_verify, cert=(client_cert, client_key), json=data)
# Sleep to allow time for copy to complete
time.sleep(.5)
#Get first /proc/stat information but from /tmp/stat
url = 'https://' + server.addr + ':' + str(server.port) + '/1.0/virtual-machines/' + name + '/files?project=' + project + '&path=/tmp/stat'
url = 'https://' + server.addr + ':' + str(server.port) + '/1.0/instances/' + name + '/files?project=' + project + '&path=/tmp/stat1'
results = requests.get(url, verify=server.ssl_verify, cert=(client_cert, client_key))
if 'cpu' in results.text:
results = results.text.split('\n')
@ -665,7 +666,7 @@ def api_virtual_machine_endpoint(endpoint):
# Copy /proc/stat to /tmp/stat and then read that file as a work around
data = {}
data.update({'command': ['cp', '/proc/stat', '/tmp/stat']})
data.update({'command': ['cp', '/proc/stat', '/tmp/stat2']})
data.update({'wait-for-websocket': False})
data.update({'interactive': False})
data.update({'width': 80 })
@ -676,14 +677,14 @@ def api_virtual_machine_endpoint(endpoint):
data.update({'record-output': False })
data.update({'environment': {} })
url = 'https://' + server.addr + ':' + str(server.port) + '/1.0/virtual-machines/' + name + '/exec?project=' + project
url = 'https://' + server.addr + ':' + str(server.port) + '/1.0/instances/' + name + '/exec?project=' + project
results = requests.post(url, verify=server.ssl_verify, cert=(client_cert, client_key), json=data)
# Sleep to allow time for copy to complete
time.sleep(.5)
#Get second /proc/stat information
url = 'https://' + server.addr + ':' + str(server.port) + '/1.0/virtual-machines/' + name + '/files?project=' + project + '&path=/tmp/stat'
url = 'https://' + server.addr + ':' + str(server.port) + '/1.0/instances/' + name + '/files?project=' + project + '&path=/tmp/stat2'
results = requests.get(url, verify=server.ssl_verify, cert=(client_cert, client_key))
if 'cpu' in results.text:
results = results.text.split('\n')
@ -703,6 +704,53 @@ def api_virtual_machine_endpoint(endpoint):
return jsonify({'percentage': 0, 'cpu1': first_cpu_time, 'cpu2': second_cpu_time, 'idle1': first_idle_time, 'idle2': second_idle_time})
percentage = 100 * (1 - idle_time / total_time)
return jsonify({'percentage': percentage, 'cpu1': first_cpu_time, 'cpu2': second_cpu_time, 'idle1': first_idle_time, 'idle2': second_idle_time})
if endpoint == 'get_instance_cpu_usage':
id = request.args.get('id')
project = request.args.get('project')
server = Server.query.filter_by(id=id).first()
name = request.args.get('name')
client_cert = get_client_crt()
client_key = get_client_key()
#Get instance state to retrieve instance cpu usage
url = 'https://' + server.addr + ':' + str(server.port) + '/1.0/instances/' + name + '/state?project=' + project
results = requests.get(url, verify=server.ssl_verify, cert=(client_cert, client_key))
results = json.dumps(results.json())
results = json.loads(results)
#Get cpu usage
if 'cpu' in results['metadata']:
if 'usage' in results['metadata']['cpu']:
#Usage is reported in nanoseconds
instance_cpu_time = int(results['metadata']['cpu']['usage'])
else:
instance_cpu_time = 0
else:
instance_cpu_time = 0
#Get /proc/stat information
url = 'https://' + server.addr + ':' + str(server.port) + '/1.0/instances/' + name + '/files?project=' + project + '&path=/proc/stat'
results = requests.get(url, verify=server.ssl_verify, cert=(client_cert, client_key))
if 'cpu' in results.text:
results = results.text.split('\n')
for result in results:
stats = result.split()
if stats[0] == 'cpu':
#0 = 'cpu'
#1 = <user time>
#2 = <nice time>
#3 = <system time>
#4 = <idle time>
user_time = int(stats[1])
system_time= int(stats[3])
idle_time = int(stats[4])
host_cpu_time = user_time + system_time + idle_time
return jsonify({'instance_cpu_time':instance_cpu_time,'host_cpu_time': host_cpu_time})
return jsonify({'instance_cpu_time':0,'host_cpu_time': 0})
if endpoint == 'get_instance_disk_devices':
@ -712,9 +760,9 @@ def api_virtual_machine_endpoint(endpoint):
name = request.args.get('name')
recursion = request.args.get('recursion')
if recursion == '1':
url = 'https://' + server.addr + ':' + str(server.port) + '/1.0/virtual-machines/' + name + '?recursion=1&project=' + project
url = 'https://' + server.addr + ':' + str(server.port) + '/1.0/instances/' + name + '?recursion=1&project=' + project
else:
url = 'https://' + server.addr + ':' + str(server.port) + '/1.0/virtual-machines/' + name + '?project=' + project
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))
@ -722,7 +770,7 @@ def api_virtual_machine_endpoint(endpoint):
instance = json.loads(instance)
expanded_devices = instance['metadata']['expanded_devices']
devices = []
instance_state_url = 'https://' + server.addr + ':' + str(server.port) + '/1.0/virtual-machines/' + name + '/state?project=' + project
instance_state_url = 'https://' + server.addr + ':' + str(server.port) + '/1.0/instances/' + name + '/state?project=' + project
instance_state = requests.get(instance_state_url, verify=server.ssl_verify, cert=(client_cert, client_key))
instance_state = json.dumps(instance_state.json())
instance_state = json.loads(instance_state)
@ -751,9 +799,9 @@ def api_virtual_machine_endpoint(endpoint):
name = request.args.get('name')
recursion = request.args.get('recursion')
if recursion == '1':
url = 'https://' + server.addr + ':' + str(server.port) + '/1.0/virtual-machines/' + name + '?recursion=1&project=' + project
url = 'https://' + server.addr + ':' + str(server.port) + '/1.0/instances/' + name + '?recursion=1&project=' + project
else:
url = 'https://' + server.addr + ':' + str(server.port) + '/1.0/virtual-machines/' + name + '?project=' + project
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))
@ -798,9 +846,9 @@ def api_virtual_machine_endpoint(endpoint):
name = request.args.get('name')
recursion = request.args.get('recursion')
if recursion == '1':
url = 'https://' + server.addr + ':' + str(server.port) + '/1.0/virtual-machines/' + name + '/state?recursion=1&project=' + project
url = 'https://' + server.addr + ':' + str(server.port) + '/1.0/instances/' + name + '/state?recursion=1&project=' + project
else:
url = 'https://' + server.addr + ':' + str(server.port) + '/1.0/virtual-machines/' + name + '/state?project=' + project
url = 'https://' + server.addr + ':' + str(server.port) + '/1.0/instances/' + name + '/state?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))
@ -827,7 +875,7 @@ def api_virtual_machine_endpoint(endpoint):
interfaces.append(interface)
return jsonify({ 'data': interfaces })
# Virtual Machine only
if endpoint == 'get_instance_memory_percentage':
id = request.args.get('id')
project = request.args.get('project')
@ -854,14 +902,14 @@ def api_virtual_machine_endpoint(endpoint):
data.update({'record-output': False })
data.update({'environment': {} })
url = 'https://' + server.addr + ':' + str(server.port) + '/1.0/virtual-machines/' + name + '/exec?project=' + project
url = 'https://' + server.addr + ':' + str(server.port) + '/1.0/instances/' + name + '/exec?project=' + project
results = requests.post(url, verify=server.ssl_verify, cert=(client_cert, client_key), json=data)
# Sleep a second to give time to copy file
time.sleep(1)
#Get /proc/meminfo information but from /tmp/meminfo
url = 'https://' + server.addr + ':' + str(server.port) + '/1.0/virtual-machines/' + name + '/files?project=' + project + '&path=/tmp/meminfo'
url = 'https://' + server.addr + ':' + str(server.port) + '/1.0/instances/' + name + '/files?project=' + project + '&path=/tmp/meminfo'
results = requests.get(url, verify=server.ssl_verify, cert=(client_cert, client_key))
if 'MemTotal' in results.text:
results = results.text.split('\n')
@ -879,9 +927,9 @@ def api_virtual_machine_endpoint(endpoint):
name = request.args.get('name')
recursion = request.args.get('recursion')
if recursion == '1':
url = 'https://' + server.addr + ':' + str(server.port) + '/1.0/virtual-machines/' + name + '?recursion=1&project=' + project
url = 'https://' + server.addr + ':' + str(server.port) + '/1.0/instances/' + name + '?recursion=1&project=' + project
else:
url = 'https://' + server.addr + ':' + str(server.port) + '/1.0/virtual-machines/' + name + '?project=' + project
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))
@ -914,9 +962,9 @@ def api_virtual_machine_endpoint(endpoint):
name = request.args.get('name')
recursion = request.args.get('recursion')
if recursion == '1':
url = 'https://' + server.addr + ':' + str(server.port) + '/1.0/virtual-machines/' + name + '?recursion=1&project=' + project
url = 'https://' + server.addr + ':' + str(server.port) + '/1.0/instances/' + name + '?recursion=1&project=' + project
else:
url = 'https://' + server.addr + ':' + str(server.port) + '/1.0/virtual-machines/' + name + '?project=' + project
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))
@ -945,14 +993,57 @@ def api_virtual_machine_endpoint(endpoint):
name = request.args.get('name')
recursion = request.args.get('recursion')
if recursion == '1':
url = 'https://' + server.addr + ':' + str(server.port) + '/1.0/virtual-machines/' + name + '/state?recursion=1&project=' + project
url = 'https://' + server.addr + ':' + str(server.port) + '/1.0/instances/' + name + '/state?recursion=1&project=' + project
else:
url = 'https://' + server.addr + ':' + str(server.port) + '/1.0/virtual-machines/' + name + '/state?project=' + project
url = 'https://' + server.addr + ':' + str(server.port) + '/1.0/instances/' + name + '/state?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())
# Container only
if endpoint == 'get_instance_unix_devices':
id = request.args.get('id')
project = request.args.get('project')
server = Server.query.filter_by(id=id).first()
name = request.args.get('name')
recursion = request.args.get('recursion')
if recursion == '1':
url = 'https://' + server.addr + ':' + str(server.port) + '/1.0/instances/' + name + '?recursion=1&project=' + project
else:
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))
instance = json.dumps(results.json())
instance = json.loads(instance)
expanded_devices = instance['metadata']['expanded_devices']
devices = []
if expanded_devices:
for expanded_device in expanded_devices:
if expanded_devices[expanded_device]['type'] == 'unix-block' or expanded_devices[expanded_device]['type'] == 'unix-char':
device = {}
device.update({ 'device': expanded_device })
device.update({ 'type': expanded_devices[expanded_device]['type'] })
if 'source' in expanded_devices[expanded_device]:
device.update({ 'source': expanded_devices[expanded_device]['source'] })
if 'path' in expanded_devices[expanded_device]:
device.update({ 'path': expanded_devices[expanded_device]['path'] })
if 'major' in expanded_devices[expanded_device]:
device.update({ 'major': expanded_devices[expanded_device]['major'] })
if 'minor' in expanded_devices[expanded_device]:
device.update({ 'minor': expanded_devices[expanded_device]['minor'] })
if 'uid' in expanded_devices[expanded_device]:
device.update({ 'uid': expanded_devices[expanded_device]['uid'] })
if 'gid' in expanded_devices[expanded_device]:
device.update({ 'gid': expanded_devices[expanded_device]['gid'] })
if 'mode' in expanded_devices[expanded_device]:
device.update({ 'mode': expanded_devices[expanded_device]['mode'] })
if 'required' in expanded_devices[expanded_device]:
device.update({ 'required': expanded_devices[expanded_device]['required'] })
devices.append(device)
return jsonify({ 'data': devices })
if endpoint == 'get_instance_usb_devices':
id = request.args.get('id')
@ -961,9 +1052,9 @@ def api_virtual_machine_endpoint(endpoint):
name = request.args.get('name')
recursion = request.args.get('recursion')
if recursion == '1':
url = 'https://' + server.addr + ':' + str(server.port) + '/1.0/virtual-machines/' + name + '?recursion=1&project=' + project
url = 'https://' + server.addr + ':' + str(server.port) + '/1.0/instances/' + name + '?recursion=1&project=' + project
else:
url = 'https://' + server.addr + ':' + str(server.port) + '/1.0/virtual-machines/' + name + '?project=' + project
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))
@ -997,7 +1088,7 @@ def api_virtual_machine_endpoint(endpoint):
id = request.args.get('id')
server = Server.query.filter_by(id=id).first()
return jsonify({ 'addr': server.addr, 'port': server.port, 'proxy': server.proxy })
if endpoint == 'list_instance_backups':
id = request.args.get('id')
@ -1006,9 +1097,9 @@ def api_virtual_machine_endpoint(endpoint):
name = request.args.get('name')
recursion = request.args.get('recursion')
if recursion == '1':
url = 'https://' + server.addr + ':' + str(server.port) + '/1.0/virtual-machines/' + name + '/backups?recursion=1&project=' + project
url = 'https://' + server.addr + ':' + str(server.port) + '/1.0/instances/' + name + '/backups?recursion=1&project=' + project
else:
url = 'https://' + server.addr + ':' + str(server.port) + '/1.0/virtual-machines/' + name + '/backups?project=' + project
url = 'https://' + server.addr + ':' + str(server.port) + '/1.0/instances/' + name + '/backups?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))
@ -1034,13 +1125,19 @@ def api_virtual_machine_endpoint(endpoint):
name = request.args.get('name')
recursion = request.args.get('recursion')
if recursion == '1':
url = 'https://' + server.addr + ':' + str(server.port) + '/1.0/virtual-machines/' + name + '/logs?recursion=1&project=' + project
url = 'https://' + server.addr + ':' + str(server.port) + '/1.0/instances/' + name + '/logs?recursion=1&project=' + project
else:
url = 'https://' + server.addr + ':' + str(server.port) + '/1.0/virtual-machines/' + name + '/logs?project=' + project
url = 'https://' + server.addr + ':' + str(server.port) + '/1.0/instances/' + name + '/logs?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())
# Newly created VMs will not have logs until it starts, causing a 404 error
results = json.dumps(results.json())
results = json.loads(results)
if results['metadata'] is None:
return jsonify({"metadata":[]})
return jsonify(results)
if endpoint == 'list_instance_snapshots':
@ -1050,14 +1147,14 @@ def api_virtual_machine_endpoint(endpoint):
name = request.args.get('name')
recursion = request.args.get('recursion')
if recursion == '1':
url = 'https://' + server.addr + ':' + str(server.port) + '/1.0/virtual-machines/' + name + '/snapshots?recursion=1&project=' + project
url = 'https://' + server.addr + ':' + str(server.port) + '/1.0/instances/' + name + '/snapshots?recursion=1&project=' + project
else:
url = 'https://' + server.addr + ':' + str(server.port) + '/1.0/virtual-machines/' + name + '/snapshots?project=' + project
url = 'https://' + server.addr + ':' + str(server.port) + '/1.0/instances/' + name + '/snapshots?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 == 'migrate_instance':
id = request.args.get('id')
@ -1065,7 +1162,7 @@ def api_virtual_machine_endpoint(endpoint):
instance = request.args.get('instance')
server = Server.query.filter_by(id=id).first()
location = request.args.get('location')
url = 'https://' + server.addr + ':' + str(server.port) + '/1.0/virtual-machines/' + instance + '?target='+location+'&project=' + project
url = 'https://' + server.addr + ':' + str(server.port) + '/1.0/instances/' + instance + '?target='+location+'&project=' + project
client_cert = get_client_crt()
client_key = get_client_key()
data = {}
@ -1134,7 +1231,7 @@ def api_virtual_machine_endpoint(endpoint):
project = request.args.get('project')
instance = request.args.get('instance')
server = Server.query.filter_by(id=id).first()
url = 'https://' + server.addr + ':' + str(server.port) + '/1.0/virtual-machines/' + instance + '?project=' + project
url = 'https://' + server.addr + ':' + str(server.port) + '/1.0/instances/' + instance + '?project=' + project
client_cert = get_client_crt()
client_key = get_client_key()
data = {}
@ -1148,7 +1245,7 @@ def api_virtual_machine_endpoint(endpoint):
project = request.args.get('project')
instance = request.args.get('instance')
server = Server.query.filter_by(id=id).first()
url = 'https://' + server.addr + ':' + str(server.port) + '/1.0/virtual-machines/' + instance + '?project=' + project
url = 'https://' + server.addr + ':' + str(server.port) + '/1.0/instances/' + instance + '?project=' + project
client_cert = get_client_crt()
client_key = get_client_key()
@ -1164,7 +1261,7 @@ def api_virtual_machine_endpoint(endpoint):
project = request.args.get('project')
instance = request.args.get('instance')
server = Server.query.filter_by(id=id).first()
url = 'https://' + server.addr + ':' + str(server.port) + '/1.0/virtual-machines/' + instance + '?project=' + project
url = 'https://' + server.addr + ':' + str(server.port) + '/1.0/instances/' + instance + '?project=' + project
client_cert = get_client_crt()
client_key = get_client_key()

View file

@ -13,7 +13,7 @@ def get_client_key():
return 'certs/client.key'
@login_required
def api_containers_endpoint(endpoint):
def api_instances_endpoint(endpoint):
if not privilege_check(endpoint, request.args.get('id')):
return jsonify({'data': [], 'metadata':[], 'error': 'not authorized', 'error_code': 403})
@ -25,9 +25,9 @@ def api_containers_endpoint(endpoint):
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/containers?project=' + project
url = 'https://' + server.addr + ':' + str(server.port) + '/1.0/instances?project=' + project
else:
url = 'https://' + server.addr + ':' + str(server.port) + '/1.0/containers?target=' + location + '&project=' + project
url = 'https://' + server.addr + ':' + str(server.port) + '/1.0/instances?target=' + location + '&project=' + project
client_cert = get_client_crt()
client_key = get_client_key()
@ -40,7 +40,7 @@ def api_containers_endpoint(endpoint):
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({'type': request.form.get('type')})
data.update({'instance_type': request.form.get('instance_type')})
profiles = []
profiles.append(request.form.get('profiles'))
@ -56,48 +56,51 @@ def api_containers_endpoint(endpoint):
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.disk.priority': request.form.get('limits.disk.priority')}) if request.form.get('limits.disk.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': request.form.get('limits.memory')}) if request.form.get('limits.memory') 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.network.priority': request.form.get('limits.network.priority')}) if request.form.get('limits.network.priority') 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({'cluster.evacuate': request.form.get('cluster.evacuate')}) if request.form.get('cluster.evacuate') else False
config.update({'linux.kernel_modules': request.form.get('linux.kernel_modules')}) if request.form.get('linux.kernel_modules') else False
config.update({'raw.apparmor': request.form.get('raw.apparmor')}) if request.form.get('raw.apparmor') 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
@ -107,7 +110,6 @@ def api_containers_endpoint(endpoint):
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
@ -120,12 +122,15 @@ def api_containers_endpoint(endpoint):
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
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
#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)
@ -137,7 +142,7 @@ def api_containers_endpoint(endpoint):
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/containers/' + name + '?project=' + project
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))
@ -149,12 +154,20 @@ def api_containers_endpoint(endpoint):
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/containers?recursion=1&project=' + project
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/containers?recursion=2&project=' + project
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/containers?project=' + project
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))
@ -211,7 +224,7 @@ def api_containers_endpoint(endpoint):
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/containers/' + name + '?project=' + project
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))
@ -237,7 +250,7 @@ def api_containers_endpoint(endpoint):
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/containers/' + name + '?project=' + project
url = 'https://' + server.addr + ':' + str(server.port) + '/1.0/instances/' + name + '?project=' + project
client_cert = get_client_crt()
client_key = get_client_key()

View file

@ -1,217 +0,0 @@
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_virtual_machines_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/virtual-machines?project=' + project
else:
url = 'https://' + server.addr + ':' + str(server.port) + '/1.0/virtual-machines?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 = {}
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({'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.memory.hugepages': request.form.get('limits.memory.hugepages')}) if request.form.get('limits.memory.hugepages') else False
config.update({'limits.network.priority': request.form.get('limits.network.priority')}) if request.form.get('limits.network.priority') else False
config.update({'migration.stateful': request.form.get('migration.stateful')}) if request.form.get('migration.stateful') else False
config.update({'cluster.evacuate': request.form.get('cluster.evacuate')}) if request.form.get('cluster.evacuate') else False
config.update({'raw.apparmor': request.form.get('raw.apparmor')}) if request.form.get('raw.apparmor') 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.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({'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
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
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/virtual-machines/' + 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 recursion == '1':
url = 'https://' + server.addr + ':' + str(server.port) + '/1.0/virtual-machines?recursion=1&project=' + project
elif recursion == '2':
url = 'https://' + server.addr + ':' + str(server.port) + '/1.0/virtual-machines?recursion=2&project=' + project
else:
url = 'https://' + server.addr + ':' + str(server.port) + '/1.0/virtual-machines?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/virtual-machines/' + 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/virtual-machines/' + 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())

View file

@ -59,21 +59,16 @@ def cluster_groups():
def cluster_members():
return render_template('cluster-members.html', page_title='Cluster Members', page_user_id=current_user.id, page_username=current_user.username,)
@app.route("/container")
@login_required
def container():
return render_template('container.html', page_title='Container: ', page_user_id=current_user.id, page_username=current_user.username,)
@app.route("/containers")
@login_required
def containers():
return render_template('containers.html', page_title='Containers', page_user_id=current_user.id, page_username=current_user.username,)
@app.route("/images")
@login_required
def images():
return render_template('images.html', page_title='Images', page_user_id=current_user.id, page_username=current_user.username,)
@app.route("/instance")
@login_required
def instance():
return render_template('instance.html', page_title='Instance', page_user_id=current_user.id, page_username=current_user.username,)
@app.route("/instances")
@login_required
def instances():
@ -144,17 +139,6 @@ def storage_pools():
def storage_volumes():
return render_template('storage-volumes.html', page_title='Storage Volumes', page_user_id=current_user.id, page_username=current_user.username,)
@app.route("/virtual-machine")
@login_required
def virtual_machine():
return render_template('virtual-machine.html', page_title='Virtual Machine: ', page_user_id=current_user.id, page_username=current_user.username,)
@app.route("/virtual-machines")
@login_required
def virtual_machines():
return render_template('virtual-machines.html', page_title='Virtual Machines', page_user_id=current_user.id, page_username=current_user.username,)
@app.route("/backups/<serverId>/<project>/<instance>/<filename>")
@login_required
def backups(serverId, project, instance, filename):

File diff suppressed because one or more lines are too long

View file

@ -68,7 +68,12 @@ td.details-control {
color:#007bff ;
cursor: pointer;
}
tr.shown td.details-control {
text-align:center;
color:#ff0000 ;
}
}
.table-hover tbody tr:hover td, .table-hover tbody tr:hover th {
background-color: #fefefe;
}

View file

@ -53,8 +53,7 @@ function populateNavbarLinks(){
}
function applySidebarLinks() {
$("#containersLinkSidebar").attr("href", "containers?id=" + encodeURI(serverId) + "&project=" + encodeURI(project));
$("#virtualMachinesLinkSidebar").attr("href", "virtual-machines?id=" + encodeURI(serverId) + "&project=" + encodeURI(project));
$("#instancesLinkSidebar").attr("href", "instances?id=" + encodeURI(serverId) + "&project=" + encodeURI(project));
$("#imagesLinkSidebar").attr("href", "images?id=" + encodeURI(serverId) + "&project=" + encodeURI(project));
$("#profilesLinkSidebar").attr("href", "profiles?id=" + encodeURI(serverId) + "&project=" + encodeURI(project));
@ -71,9 +70,9 @@ function applySidebarLinks() {
}
function applySidebarStyles() {
if (location.pathname == "/containers" || location.pathname == "/container"){
$('#containersSpan').css('color','#fff');
$('#containersIcon').css('color','#fff');
if (location.pathname == "/instances" || location.pathname == "/instance"){
$('#instancesSpan').css('color','#fff');
$('#instancesIcon').css('color','#fff');
}
if (location.pathname == "/images"){
$('#imagesSpan').css('color','#fff');

View file

@ -6,9 +6,9 @@
<h1>{{ page_title | safe }}</h1>
</div>
<div class="col-sm-6">
<a class="btn btn-outline-primary float-sm-right mr-4" href="#" data-toggle="modal" data-target="#addModal" title="Add Access Control" aria-hidden="true">
<button class="btn btn-outline-primary float-sm-right mr-4" data-bs-toggle="modal" data-bs-target="#addModal" title="Add Access Control" aria-hidden="true">
<i class="fas fa-plus fa-sm fa-fw"></i> Access Control
</a>
</button>
</div>
</div>
{% endblock header %}
@ -59,7 +59,10 @@
url: "../api/access-controls/list_access_controls",
dataType: "json",
dataSrc: "data",
contentType: "application/json"
contentType: "application/json",
error: function (xhr, error, code) {
console.log(xhr, code);
}
},
columns: [
{ title: "Id", data: function (row, type, set) {

View file

@ -6,9 +6,9 @@
<h1>{{ page_title | safe }}</h1>
</div>
<div class="col-sm-6">
<a class="btn btn-outline-primary float-sm-right mr-4" href="#" data-toggle="modal" data-target="#addModal" title="Add Certificate" aria-hidden="true">
<button class="btn btn-outline-primary float-sm-right mr-4" data-bs-toggle="modal" data-bs-target="#addModal" title="Add Certificate" aria-hidden="true">
<i class="fas fa-plus fa-sm fa-fw"></i> Certificate
</a>
</button>
</div>
</div>
{% endblock header %}
@ -98,7 +98,10 @@
url: "../api/certificates/list_certificates?id="+serverId+"&project=" + project + "&recursion=1",
dataType: "json",
dataSrc: "metadata",
contentType: "application/json"
contentType: "application/json",
error: function (xhr, error, code) {
console.log(xhr, code);
}
},
columns: [
{ title: "Name", data: function (row, type, set) {

View file

@ -6,9 +6,9 @@
<h1>{{ page_title | safe }}</h1>
</div>
<div class="col-sm-6">
<a class="btn btn-outline-primary float-sm-right mr-4" href="#" data-toggle="modal" data-target="#addModal" title="Add Cluster Group" aria-hidden="true">
<button class="btn btn-outline-primary float-sm-right mr-4" data-bs-toggle="modal" data-bs-target="#addModal" title="Add Cluster Group" aria-hidden="true">
<i class="fas fa-plus fa-sm fa-fw"></i> Cluster Group
</a>
</button>
</div>
</div>
{% endblock header %}
@ -98,7 +98,10 @@
url: "../api/cluster-groups/list_cluster_groups?id="+serverId+"&project=" + project + "&recursion=1",
dataType: "json",
dataSrc: "metadata",
contentType: "application/json"
contentType: "application/json",
error: function (xhr, error, code) {
console.log(xhr, code);
}
},
columns: [
{ title: "Name", data: function (row, type, set) {

View file

@ -7,9 +7,9 @@
</div>
<!--
<div class="col-sm-6">
<a class="btn btn-outline-primary float-sm-right mr-4" href="#" data-toggle="modal" data-target="#addModal" title="Add Cluster Member" aria-hidden="true">
<button class="btn btn-outline-primary float-sm-right mr-4" data-bs-toggle="modal" data-bs-target="#addModal" title="Add Cluster Member" aria-hidden="true">
<i class="fas fa-plus fa-sm fa-fw"></i> Cluster Member
</a>
</button>
</div>
-->
</div>
@ -100,7 +100,10 @@
url: "../api/cluster-members/list_cluster_members?id="+serverId+"&project=" + project + "&recursion=1",
dataType: "json",
dataSrc: "metadata",
contentType: "application/json"
contentType: "application/json",
error: function (xhr, error, code) {
console.log(xhr, code);
}
},
columns: [
{ title: "Server Name", data: function (row, type, set) {

View file

@ -1,332 +0,0 @@
{% extends "main.html" %}
{% block header %}
<div class="row mb-2">
<div class="col-sm-6">
<h1>{{ page_title | safe }}</h1>
</div>
<div class="col-sm-6">
<a class="btn btn-outline-primary float-sm-right mr-4" href="#" data-toggle="modal" data-target="#addModal" title="Add Container" aria-hidden="true">
<i class="fas fa-plus fa-sm fa-fw"></i> Container
</a>
</div>
</div>
{% endblock header %}
{% block content %}
<div class="col-12">
<div class="card">
<div class="card-header">
<h3 class="card-title">Containers</h3>
<div class="card-tools">
<button type="button" class="btn btn-tool" onclick="reloadPageContent()" title="Refresh">
<i class="fas fa-sync"></i>
</button>
</div>
</div>
<div class="card-body">
<table class="table table-hover" id="myDataTable" width="100%" cellspacing="0">
</table>
</div>
</div>
</div>
{% endblock content %}
{% block modal %}
{% include 'modals/containers.html' %}
{% endblock modal %}
{% block script %}
<script>
var reloadTime = 10000;
const queryString = window.location.search;
const urlParams = new URLSearchParams(queryString);
const serverId = urlParams.get('id');
const project = urlParams.get('project');
var editedContainer = ''
applySidebarStyles();
applySidebarLinks();
populateSidebarLinks();
populateNavbarLinks();
function reloadPageContent() {
//Clear the automatic page reload
clearTimeout(pageReloadTimeout);
//Reload the datatables content
$('#myDataTable').DataTable().ajax.reload(null, false);
//Set the automatic page reload
pageReloadTimeout = setTimeout(() => { reloadPageContent(); }, reloadTime);
}
function loadPageContent(){
//Display the current project
$("#selectedProject").text(project);
//Populate the Server dropdown
$.getJSON("../api/servers/list_servers?id="+serverId, function (data) {
data = data.data
for (var index = 0; index < data.length; index++) {
if (data[index].name == '')
optionText = data[index].addr
else
optionText = data[index].name
if (data[index].id == serverId)
$('#serverListNav').append('<option value="' + data[index].id + '" selected="selected">' + optionText + '</option>');
else
$('#serverListNav').append('<option value="' + data[index].id + '">' + optionText + '</option>');
}
})
//Populate the Project dropdown
$.getJSON("../api/projects/list_projects?id="+serverId+"&project="+project, function (data) {
data = data.metadata
for (var index = 0; index < data.length; index++) {
optionText = data[index].replace('/1.0/projects/','');
if (optionText == project)
$('#projectListNav').append('<option value="' + optionText + '" selected="selected">' + optionText + '</option>');
else
$('#projectListNav').append('<option value="' + optionText + '">' + optionText + '</option>');
}
})
//Populate the modal Profile dropdown
$.getJSON("../api/profiles/list_profiles?id="+serverId+"&project="+project, function (data) {
data = data.metadata
for (var index = 0; index < data.length; index++) {
//When using projects other than default and no recursion, it gets like URL variable with "?"
optionText = data[index].split("?")
optionText = optionText[0].replace('/1.0/profiles/','');
if (optionText == 'default') {
$('#containerProfileInput').append('<option value="' + optionText + '" selected="selected">' + optionText + '</option>');
}
else {
$('#containerProfileInput').append('<option value="' + optionText + '">' + optionText + '</option>');
}
}
})
//Populate the modal Location dropdown
$.getJSON("../api/cluster-members/list_cluster_members?id="+serverId+"&project="+project, function (data) {
data = data.metadata
for (var index = 0; index < data.length; index++) {
optionText = data[index].replace('/1.0/cluster/members/','');
$('#containerLocationInput').append('<option value="' + optionText + '">' + optionText + '</option>');
}
})
$.getJSON("../api/cluster-groups/list_cluster_groups?id="+serverId+"&project="+project, function (data) {
data = data.metadata
for (var index = 0; index < data.length; index++) {
optionText = data[index].replace('/1.0/cluster/groups/','');
$('#containerLocationInput').append('<option value="@' + optionText + '">@' + optionText + '</option>');
}
})
//Populate the modal Image dropdown
$.getJSON("../api/images/list_images?id="+serverId+"&project="+project+"&recursion=1", function (data) {
data = data.metadata
for (var index = 0; index < data.length; index++) {
// Earlier versions of LXD did not have type property. These only supported container type instances
if (data[index].hasOwnProperty('type')) {
if(data[index].type == 'container'){
$('#containerImageInput').append('<option value="' + data[index].fingerprint + '">' + data[index].properties.description + '</option>');
}
}
else {
$('#containerImageInput').append('<option value="' + data[index].fingerprint + '">' + data[index].properties.description + '</option>');
}
}
})
// Configure Datatable
$('#myDataTable').DataTable({
ajax: {
url: "../api/containers/list_instances?id="+serverId+"&project=" + project + "&recursion=2",
dataType: "json",
dataSrc: "metadata",
contentType: "application/json"
},
columns: [
{ title: "Name", data: function (row, type, set) {
if (row.hasOwnProperty('name')) {
if (row.name)
return '<a href="../container?id=' + serverId + '&project=' + project + '&instance=' + row.name + '">' + row.name + '</a>';
}
return '-'
},
},
{ title: "OS", data: function (row, type, set) {
if (row.hasOwnProperty('expanded_config')) {
if (row.expanded_config.hasOwnProperty('image.os')) {
if (row.expanded_config['image.os']){
return row.expanded_config['image.os']
}
}
}
return '-'
},
},
{ title: "Location", data: function (row, type, set) {
if (row.hasOwnProperty('location')) {
if (row.location){
return row.location
}
}
return '-'
},
},
{ title: "IPv4", data: function (row, type, set) {
if (row.hasOwnProperty('ipv4_addresses')) {
if (row.ipv4_addresses.length > 0){
return row.ipv4_addresses.join(', <br />')
}
}
return '-'
},
},
{ title: "IPv6", data: function (row, type, set) {
if (row.hasOwnProperty('ipv6_addresses')) {
if (row.ipv6_addresses.length > 0){
return row.ipv6_addresses.join(', <br />')
}
}
return '-'
},
},
{ title: "Memory", data: function (row, type, set) {
if (row.hasOwnProperty('memory')) {
if (row.memory){
if (type === 'display'){
return (row.memory / 1024 / 1024).toFixed(2) + ' MiB'
}
return row.memory
}
}
return '-'
},
},
{ title: "Root Disk", data: function (row, type, set) {
if (row.hasOwnProperty('disk')) {
if (row.disk){
if (type === 'display'){
return (row.disk / 1024 / 1024).toFixed(2) + ' MiB'
}
return row.disk
}
}
return '-'
},
},
{ title: "Status", data: function (row, type, set) {
if (row.hasOwnProperty('status')) {
if (row.status){
return row.status
}
}
return '-'
},
},
{ title: "Actions", data: function (row, type, set) {
links = ''
if (row.hasOwnProperty('name') && row.hasOwnProperty('status')) {
if (row.name && row.status){
if (row.status == 'Frozen')
links += '<a href="#" onclick=changeItemState(\''+row.name+'\',\'unfreeze\')><i class="fas fa-pause fa-lg" style="color:#ddd" title="Edit" aria-hidden="true"></i></a>'
else if (row.status == 'Stopped')
links += '<a href="#" onclick=changeItemState(\''+row.name+'\',\'start\')><i class="fas fa-play fa-lg" style="color:#ddd" title="Edit" aria-hidden="true"></i></a>'
else if (row.status == 'Running')
links += '<a href="#" onclick=changeItemState(\''+row.name+'\',\'stop\')><i class="fas fa-stop fa-lg" style="color:#ddd" title="Edit" aria-hidden="true"></i></a>'
links += '&nbsp' + '&nbsp'
links += '<a href="#" onclick=deleteInstance(\''+row.name+'\')><i class="fas fa-trash-alt fa-lg" style="color:#ddd" title="Delete" aria-hidden="true"></i></a>'
}
}
return links
},
},
],
order: [],
});
//Set reload page content
pageReloadTimeout = setTimeout(() => { reloadPageContent(); }, reloadTime);
}
// Change state start/stop of instance
function changeItemState(name, action){
console.log("Info: starting container " + name);
$.post("../api/containers/change_instance_state?id=" + serverId + "&project=" + project, { name: name, action: action }, function (data) {
console.log(data);
if (data.error_code >= 400){
alert(data.error);
}
//Async type
setTimeout(() => { reloadPageContent(); }, 2000);
operationStatusCheck()
});
}
// Add instance
function addItem(){
console.log("Info: adding new container");
data = $('#addForm').serialize();
$.post("../api/containers/add_instance?id="+serverId+"&project="+project, data, function (data) {
console.log(data);
if (data.error_code >= 400){
alert(data.error);
}
//Aync type
setTimeout(() => { reloadPageContent(); }, 2000);
operationStatusCheck()
});
}
// Delete instance
function deleteInstance(name){
console.log("Info: confirming deletion of container " + name);
if (confirm("Are you sure you want to delete container " + name + "?") == true) {
console.log("Info: deleting container " + name);
$.post("../api/containers/delete_instance?id=" + serverId + "&project=" + project, { name: name }, function (data) {
console.log(data);
if (data.error_code >= 400){
alert(data.error);
}
//Async type
setTimeout(() => { reloadPageContent(); }, 2000);
operationStatusCheck()
});
}
}
// Create instance from JSON
function createItemUsingJSON(){
var json = $("#jsonCreateInput").val();
console.log("Info: adding new instance");
$.post("../api/containers/add_instance?id="+serverId+"&project="+project, { json: json }, function (data) {
console.log(data);
if (data.error_code >= 400){
alert(data.error);
}
//Async type
setTimeout(() => { reloadPageContent(); }, 2000);
operationStatusCheck()
});
}
$(document).ready(function(){
//If id or project variables are missing redirect to servers page
if (!serverId || !project) {
window.location.href = 'servers';
}
else {
loadPageContent()
operationStatusCheck()
}
});
</script>
{% endblock script %}

View file

@ -6,9 +6,9 @@
<h1>{{ page_title | safe }}</h1>
</div>
<div class="col-sm-6">
<a class="btn btn-outline-primary float-sm-right mr-4" href="#" data-toggle="modal" data-target="#addModal" title="Add Group" aria-hidden="true">
<button class="btn btn-outline-primary float-sm-right mr-4" data-bs-toggle="modal" data-bs-target="#addModal" title="Add Group" aria-hidden="true">
<i class="fas fa-plus fa-sm fa-fw"></i> Group
</a>
</button>
</div>
</div>
{% endblock header %}
@ -59,7 +59,10 @@
url: "../api/groups/list_groups",
dataType: "json",
dataSrc: "data",
contentType: "application/json"
contentType: "application/json",
error: function (xhr, error, code) {
console.log(xhr, code);
}
},
columns: [
{ title: "Name", data: function (row, type, set) {

View file

@ -10,10 +10,11 @@
<!-- Font Awesome -->
<link rel="stylesheet" href="../static/plugins/fontawesome-free/css/all.min.css">
<!-- DataTables -->
<link rel="stylesheet" href="../static/plugins/datatables-bs4/css/dataTables.bootstrap4.min.css">
<link rel="stylesheet" href="../static/plugins/datatables-responsive/css/responsive.bootstrap4.min.css">
<link rel="stylesheet" href="../static/plugins/datatables-buttons/css/buttons.bootstrap4.min.css">
<!-- Datatables Bootstrap 5 - https://cdn.datatables.net/1.13.6/css/dataTables.bootstrap5.min.css -->
<link rel="stylesheet" href="../static/css/datatables/dataTables.bootstrap5.min.css">
<!-- Bootstrap 5 - https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/5.2.3/css/bootstrap.min.css -->
<link rel="stylesheet" href="../static/css/bootstrap/bootstrap-5.2.3.min.css">
<!-- Xterm.js style -->
<link rel="stylesheet" href="../static/css/xterm/xterm.css"/>
@ -24,11 +25,6 @@
<!-- LXD Dashboard style -->
<link rel="stylesheet" href="../static/css/styles.css">
<!-- Bootstrap 5 - https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/5.2.3/css/bootstrap.min.css -->
<!-- <link rel="stylesheet" href="../static/css/bootstrap/bootstrap-5.2.3.min.css"> -->
<!-- Datatables Bootstrap 5 - https://cdn.datatables.net/1.13.6/css/dataTables.bootstrap5.min.css -->
<!--<link rel="stylesheet" href="../static/css/datatables/dataTables.bootstrap5.min.css">-->
</head>

View file

@ -6,9 +6,9 @@
<h1>{{ page_title | safe }}</h1>
</div>
<div class="col-sm-6">
<a class="btn btn-outline-primary float-sm-right mr-4" href="#" data-toggle="modal" data-target="#addModal" title="Add Image" aria-hidden="true">
<button class="btn btn-outline-primary float-sm-right mr-4" data-bs-toggle="modal" data-bs-target="#addModal" title="Add Image" aria-hidden="true">
<i class="fas fa-plus fa-sm fa-fw"></i> Image
</a>
</button>
</div>
</div>
{% endblock header %}
@ -98,7 +98,10 @@
url: "../api/images/list_images?id="+serverId + "&project=" + project + "&recursion=1",
dataType: "json",
dataSrc: "metadata",
contentType: "application/json"
contentType: "application/json",
error: function (xhr, error, code) {
console.log(xhr, code);
}
},
columns: [
{ title: "Alias", data: function (row, type, set) {

View file

@ -0,0 +1,632 @@
{% extends "main.html" %}
{% block header %}
<div class="row mb-2">
<div class="col-sm-6">
<h1>{{ page_title | safe }}</h1>
</div>
<div class="col-sm-6">
<button class="btn btn-outline-primary float-sm-right mr-4" data-bs-toggle="modal" data-bs-target="#addModal" title="Add Instance" aria-hidden="true">
<i class="fas fa-plus fa-sm fa-fw"></i> Instance
</button>
</div>
</div>
{% endblock header %}
{% block content %}
<div class="col-12">
<nav>
<div class="nav nav-tabs" id="nav-page-tab" role="tablist">
<button class="nav-link active" id="nav-containers-tab" data-bs-toggle="tab" data-bs-target="#nav-containers" type="button" role="tab" aria-controls="nav-containers" aria-selected="true">Containers</button>
<button class="nav-link" id="nav-virtual-machines-tab" data-bs-toggle="tab" data-bs-target="#nav-virtual-machines" type="button" role="tab" aria-controls="nav-virtual-machines" aria-selected="false">Virtual-Machines</button>
</div>
</nav>
<div class="tab-content" id="nav-page-content">
<div class="tab-pane fade show active" id="nav-containers" role="tabpanel" aria-labelledby="nav-containers-tab">
<br />
<div class="card">
<div class="card-header">
<h3 class="card-title">Containers</h3>
<div class="card-tools">
<button type="button" class="btn btn-tool" onclick="reloadPageContent()" title="Refresh">
<i class="fas fa-sync"></i>
</button>
</div>
</div>
<div class="card-body">
<table class="table table-hover" id="containerDataTable" width="100%" cellspacing="0">
</table>
</div>
</div>
</div>
<div class="tab-pane fade" id="nav-virtual-machines" role="tabpanel" aria-labelledby="nav-virtual-machines-tab">
<br />
<div class="card">
<div class="card-header">
<h3 class="card-title">Virtual Machines</h3>
<div class="card-tools">
<button type="button" class="btn btn-tool" onclick="reloadPageContent()" title="Refresh">
<i class="fas fa-sync"></i>
</button>
</div>
</div>
<div class="card-body">
<table class="table table-hover" id="virtualMachineDataTable" width="100%" cellspacing="0">
</table>
</div>
</div>
</div>
</div>
</div>
{% endblock content %}
{% block modal %}
{% include 'modals/instances.html' %}
{% endblock modal %}
{% block script %}
<script>
var reloadTime = 10000;
const queryString = window.location.search;
const urlParams = new URLSearchParams(queryString);
const serverId = urlParams.get('id');
const project = urlParams.get('project');
applySidebarStyles();
applySidebarLinks();
populateSidebarLinks();
populateNavbarLinks();
function reloadPageContent() {
//Clear the automatic page reload
clearTimeout(pageReloadTimeout);
//Reload the datatables content
loadContainersTable()
loadVirtualMachinesTable()
//Set the automatic page reload
pageReloadTimeout = setTimeout(() => { reloadPageContent(); }, reloadTime);
}
function loadPageContent(){
//Display the current project
$("#selectedProject").text(project);
//Populate the Server dropdown
$.getJSON("../api/servers/list_servers?id="+serverId, function (data) {
data = data.data
for (var index = 0; index < data.length; index++) {
if (data[index].name == '')
optionText = data[index].addr
else
optionText = data[index].name
if (data[index].id == serverId)
$('#serverListNav').append('<option value="' + data[index].id + '" selected="selected">' + optionText + '</option>');
else
$('#serverListNav').append('<option value="' + data[index].id + '">' + optionText + '</option>');
}
})
//Populate the Project dropdown
$.getJSON("../api/projects/list_projects?id="+serverId+"&project="+project, function (data) {
data = data.metadata
for (var index = 0; index < data.length; index++) {
optionText = data[index].replace('/1.0/projects/','');
if (optionText == project)
$('#projectListNav').append('<option value="' + optionText + '" selected="selected">' + optionText + '</option>');
else
$('#projectListNav').append('<option value="' + optionText + '">' + optionText + '</option>');
}
})
//Populate the modal Profile dropdown
$.getJSON("../api/profiles/list_profiles?id="+serverId+"&project="+project, function (data) {
data = data.metadata
for (var index = 0; index < data.length; index++) {
//When using projects other than default and no recursion, it gets like URL variable with "?"
optionText = data[index].split("?")
optionText = optionText[0].replace('/1.0/profiles/','');
if (optionText == 'default') {
$('#instanceProfileInput').append('<option value="' + optionText + '" selected="selected">' + optionText + '</option>');
}
else {
$('#instanceProfileInput').append('<option value="' + optionText + '">' + optionText + '</option>');
}
}
})
//Populate the modal Location dropdown
$.getJSON("../api/cluster-members/list_cluster_members?id="+serverId+"&project="+project, function (data) {
data = data.metadata
for (var index = 0; index < data.length; index++) {
optionText = data[index].replace('/1.0/cluster/members/','');
$('#instanceLocationInput').append('<option value="' + optionText + '">' + optionText + '</option>');
}
})
$.getJSON("../api/cluster-groups/list_cluster_groups?id="+serverId+"&project="+project, function (data) {
data = data.metadata
for (var index = 0; index < data.length; index++) {
optionText = data[index].replace('/1.0/cluster/groups/','');
$('#instanceLocationInput').append('<option value="@' + optionText + '">@' + optionText + '</option>');
}
})
loadContainersTable()
loadVirtualMachinesTable()
changeInstanceModalTypeOptions()
//Set reload page content
pageReloadTimeout = setTimeout(() => { reloadPageContent(); }, reloadTime);
}
function populateContainerImages() {
$("#instanceImageInput").empty().append('<option value="none">none</option>');
//Populate the modal Image dropdown
$.getJSON("../api/images/list_images?id="+serverId+"&project="+project+"&recursion=1", function (data) {
data = data.metadata
for (var index = 0; index < data.length; index++) {
// Earlier versions of LXD did not have type property. These only supported container type instances
if (data[index].hasOwnProperty('type')) {
if(data[index].type == 'container'){
$('#instanceImageInput').append('<option value="' + data[index].fingerprint + '">' + data[index].properties.description + '</option>');
}
}
else {
$('#instanceImageInput').append('<option value="' + data[index].fingerprint + '">' + data[index].properties.description + '</option>');
}
}
})
}
function populateVirtualMachineImages() {
$("#instanceImageInput").empty().append('<option value="none">none</option>');
//Populate the modal Image dropdown
$.getJSON("../api/images/list_images?id="+serverId+"&project="+project+"&recursion=1", function (data) {
data = data.metadata
for (var index = 0; index < data.length; index++) {
// Earlier versions of LXD did not have type property. These only supported container type instances
if (data[index].hasOwnProperty('type')) {
if(data[index].type == 'virtual-machine'){
$('#instanceImageInput').append('<option value="' + data[index].fingerprint + '">' + data[index].properties.description + '</option>');
}
}
else {
$('#instanceImageInput').append('<option value="' + data[index].fingerprint + '">' + data[index].properties.description + '</option>');
}
}
})
}
function loadContainersTable() {
if ( ! $.fn.DataTable.isDataTable( '#containerDataTable' ) ) {
// Configure Containers Datatable
$('#containerDataTable').DataTable({
ajax: {
url: "../api/instances/list_instances?id=" + serverId + "&filter=container" + "&project=" + project + "&recursion=2",
dataType: "json",
dataSrc: "metadata",
contentType: "application/json",
error: function (xhr, error, code) {
console.log(xhr, code);
}
},
columns: [
{ title: "Name", data: function (row, type, set) {
if (row.hasOwnProperty('name')) {
if (row.name)
return '<a href="../instance?id=' + serverId + '&project=' + project + '&instance=' + row.name + '&type=container">' + row.name + '</a>';
}
return '-'
},
},
{ title: "OS", data: function (row, type, set) {
if (row.hasOwnProperty('expanded_config')) {
if (row.expanded_config.hasOwnProperty('image.os')) {
if (row.expanded_config['image.os']){
return row.expanded_config['image.os']
}
}
}
return '-'
},
},
{ title: "Location", data: function (row, type, set) {
if (row.hasOwnProperty('location')) {
if (row.location){
return row.location
}
}
return '-'
},
},
{ title: "IPv4", data: function (row, type, set) {
if (row.hasOwnProperty('ipv4_addresses')) {
if (row.ipv4_addresses.length > 0){
return row.ipv4_addresses.join(', <br />')
}
}
return '-'
},
},
{ title: "IPv6", data: function (row, type, set) {
if (row.hasOwnProperty('ipv6_addresses')) {
if (row.ipv6_addresses.length > 0){
return row.ipv6_addresses.join(', <br />')
}
}
return '-'
},
},
{ title: "Memory", data: function (row, type, set) {
if (row.hasOwnProperty('memory')) {
if (row.memory){
if (type === 'display'){
return (row.memory / 1024 / 1024).toFixed(2) + ' MiB'
}
return row.memory
}
}
return '-'
},
},
{ title: "Root Disk", data: function (row, type, set) {
if (row.hasOwnProperty('disk')) {
if (row.disk){
if (type === 'display'){
return (row.disk / 1024 / 1024).toFixed(2) + ' MiB'
}
return row.disk
}
}
return '-'
},
},
{ title: "Status", data: function (row, type, set) {
if (row.hasOwnProperty('status')) {
if (row.status){
return row.status
}
}
return '-'
},
},
{ title: "Actions", data: function (row, type, set) {
links = ''
if (row.hasOwnProperty('name') && row.hasOwnProperty('status')) {
if (row.name && row.status){
if (row.status == 'Frozen')
links += '<a href="#" onclick=changeItemState(\''+row.name+'\',\'unfreeze\')><i class="fas fa-pause fa-lg" style="color:#ddd" title="Edit" aria-hidden="true"></i></a>'
else if (row.status == 'Stopped')
links += '<a href="#" onclick=changeItemState(\''+row.name+'\',\'start\')><i class="fas fa-play fa-lg" style="color:#ddd" title="Edit" aria-hidden="true"></i></a>'
else if (row.status == 'Running')
links += '<a href="#" onclick=changeItemState(\''+row.name+'\',\'stop\')><i class="fas fa-stop fa-lg" style="color:#ddd" title="Edit" aria-hidden="true"></i></a>'
links += '&nbsp' + '&nbsp'
links += '<a href="#" onclick=deleteInstance(\''+row.name+'\')><i class="fas fa-trash-alt fa-lg" style="color:#ddd" title="Delete" aria-hidden="true"></i></a>'
}
}
return links
},
},
],
order: [],
});
}
else {
$('#containerDataTable').DataTable().ajax.reload(null, false);
}
}
function loadVirtualMachinesTable() {
if ( ! $.fn.DataTable.isDataTable( '#virtualMachineDataTable' ) ) {
// Configure Datatable
$('#virtualMachineDataTable').DataTable({
ajax: {
url: "../api/instances/list_instances?id=" + serverId + "&filter=virtual-machine" + "&project=" + project + "&recursion=2",
dataType: "json",
dataSrc: "metadata",
contentType: "application/json",
error: function (xhr, error, code) {
console.log(xhr, code);
}
},
columns: [
{ title: "Name", data: function (row, type, set) {
if (row.hasOwnProperty('name')) {
if (row.name)
return '<a href="../instance?id=' + serverId + '&project=' + project + '&instance=' + row.name + '&type=virtual-machine">' + row.name + '</a>';
}
return '-'
},
},
{ title: "OS", data: function (row, type, set) {
if (row.hasOwnProperty('expanded_config')) {
if (row.expanded_config.hasOwnProperty('image.os')) {
if (row.expanded_config['image.os']){
return row.expanded_config['image.os']
}
}
}
return '-'
},
},
{ title: "Location", data: function (row, type, set) {
if (row.hasOwnProperty('location')) {
if (row.location){
return row.location
}
}
return '-'
},
},
{ title: "IPv4", data: function (row, type, set) {
if (row.hasOwnProperty('ipv4_addresses')) {
if (row.ipv4_addresses.length > 0){
return row.ipv4_addresses.join(', <br />')
}
}
return '-'
},
},
{ title: "IPv6", data: function (row, type, set) {
if (row.hasOwnProperty('ipv6_addresses')) {
if (row.ipv6_addresses.length > 0){
return row.ipv6_addresses.join(', <br />')
}
}
return '-'
},
},
{ title: "Memory", data: function (row, type, set) {
if (row.hasOwnProperty('memory')) {
if (row.memory){
if (type === 'display'){
return (row.memory / 1024 / 1024).toFixed(2) + ' MiB'
}
return row.memory
}
}
return '-'
},
},
{ title: "Root Disk", data: function (row, type, set) {
if (row.hasOwnProperty('disk')) {
if (row.disk){
if (type === 'display'){
return (row.disk / 1024 / 1024).toFixed(2) + ' MiB'
}
return row.disk
}
}
return '-'
},
},
{ title: "Status", data: function (row, type, set) {
if (row.hasOwnProperty('status')) {
if (row.status){
return row.status
}
}
return '-'
},
},
{ title: "Actions", data: function (row, type, set) {
links = ''
if (row.hasOwnProperty('name') && row.hasOwnProperty('status')) {
if (row.name && row.status){
if (row.status == 'Frozen')
links += '<a href="#" onclick=changeItemState(\''+row.name+'\',\'unfreeze\')><i class="fas fa-pause fa-lg" style="color:#ddd" title="Edit" aria-hidden="true"></i></a>'
else if (row.status == 'Stopped')
links += '<a href="#" onclick=changeItemState(\''+row.name+'\',\'start\')><i class="fas fa-play fa-lg" style="color:#ddd" title="Edit" aria-hidden="true"></i></a>'
else if (row.status == 'Running')
links += '<a href="#" onclick=changeItemState(\''+row.name+'\',\'stop\')><i class="fas fa-stop fa-lg" style="color:#ddd" title="Edit" aria-hidden="true"></i></a>'
links += '&nbsp' + '&nbsp'
links += '<a href="#" onclick=deleteInstance(\''+row.name+'\')><i class="fas fa-trash-alt fa-lg" style="color:#ddd" title="Delete" aria-hidden="true"></i></a>'
}
}
return links
},
},
],
order: [],
});
}
else {
$('#virtualMachineDataTable').DataTable().ajax.reload(null, false);
}
}
// Change state start/stop of instance
function changeItemState(name, action){
console.log("Info: starting instance " + name);
$.post("../api/instances/change_instance_state?id=" + serverId + "&project=" + project, { name: name, action: action }, function (data) {
console.log(data);
if (data.error_code >= 400){
alert(data.error);
}
//Async type
setTimeout(() => { reloadPageContent(); }, 2000);
operationStatusCheck()
});
}
// Add instance
function addItem(){
console.log("Info: adding new instance");
data = $('#addForm').serialize();
$.post("../api/instances/add_instance?id="+serverId+"&project="+project, data, function (data) {
console.log(data);
if (data.error_code >= 400){
alert(data.error);
}
//Aync type
setTimeout(() => { reloadPageContent(); }, 2000);
operationStatusCheck()
});
}
// Delete instance
function deleteInstance(name){
console.log("Info: confirming deletion of instance " + name);
if (confirm("Are you sure you want to delete instance " + name + "?") == true) {
console.log("Info: deleting instance " + name);
$.post("../api/instances/delete_instance?id=" + serverId + "&project=" + project, { name: name }, function (data) {
console.log(data);
if (data.error_code >= 400){
alert(data.error);
}
//Async type
setTimeout(() => { reloadPageContent(); }, 2000);
operationStatusCheck()
});
}
}
// Create instance from JSON
function createItemUsingJSON(){
var json = $("#jsonCreateInput").val();
console.log("Info: adding new instance");
$.post("../api/instances/add_instance?id="+serverId+"&project="+project, { json: json }, function (data) {
console.log(data);
if (data.error_code >= 400){
alert(data.error);
}
//Async type
setTimeout(() => { reloadPageContent(); }, 2000);
operationStatusCheck()
});
}
// Change properties options while adding network device
function changeInstanceModalTypeOptions(){
var instanceTypeInput = $("#instanceTypeInput").val()
if (instanceTypeInput == "container"){
populateContainerImages()
//Container options
$("#limitsCpuAllowance").attr("disabled", false);
$("#limitsCpuPriority").attr("disabled", false);
$("#limitsHugepages64KB").attr("disabled", false);
$("#limitsHugepages1MB").attr("disabled", false);
$("#limitsHugepages2MB").attr("disabled", false);
$("#limitsHugepages1GB").attr("disabled", false);
$("#limitsMemoryEnforce").attr("disabled", false);
$("#limitsMemorySwapPriority").attr("disabled", false);
$("#limitsMemorySwap").attr("disabled", false);
$("#limitsProcesses").attr("disabled", false);
$("#linuxKernel_modules").attr("disabled", false);
$("#migrationIncrementalMemory").attr("disabled", false);
$("#migrationIncrementalMemoryGoal").attr("disabled", false);
$("#migrationIncrementalMemoryIterations").attr("disabled", false);
$("#nvidiaDriverCapabilities").attr("disabled", false);
$("#nvidiaRuntime").attr("disabled", false);
$("#nvidiaRequireCuda").attr("disabled", false);
$("#nvidiaRequireDriver").attr("disabled", false);
$("#rawIdmap").attr("disabled", false);
$("#rawLxc").attr("disabled", false);
$("#rawSeccomp").attr("disabled", false);
$("#securityDevlxd").attr("disabled", false);
$("#securityDevlxdImages").attr("disabled", false);
$("#securityIdmapBase").attr("disabled", false);
$("#securityIdmapIsolated").attr("disabled", false);
$("#securityIdmapSize").attr("disabled", false);
$("#securityNesting").attr("disabled", false);
$("#securityPrivileged").attr("disabled", false);
$("#securityProtectionDelete").attr("disabled", false);
$("#securityProtectionShift").attr("disabled", false);
$("#securitySyscallsAllow").attr("disabled", false);
$("#securitySyscallsDeny").attr("disabled", false);
$("#securitySyscallsDeny_compat").attr("disabled", false);
$("#securitySyscallsDeny_default").attr("disabled", false);
$("#securitySyscallsInterceptBpf").attr("disabled", false);
$("#securitySyscallsInterceptBpfDevices").attr("disabled", false);
$("#securitySyscallsInterceptMknod").attr("disabled", false);
$("#securitySyscallsInterceptMount").attr("disabled", false);
$("#securitySyscallsInterceptMountAllowed").attr("disabled", false);
$("#securitySyscallsInterceptMountFuse").attr("disabled", false);
$("#securitySyscallsInterceptMountShift").attr("disabled", false);
$("#securitySyscallsInterceptSetxattr").attr("disabled", false);
//Virtual-machine options
$("#limitsMemoryHugepages").attr("disabled", true); $("#limitsMemoryHugepages").val('');
$("#migrationStateful").attr("disabled", true); $("#migrationStateful").val('');
$("#rawQemu").attr("disabled", true); $("#rawQemu").val('');
$("#rawQemuConf").attr("disabled", true); $("#rawQemuConf").val('');
$("#securityAgentMetrics").attr("disabled", true); $("#securityAgentMetrics").val('');
$("#securitySecureboot").attr("disabled", true); $("#securitySecureboot").val('');
}
if (instanceTypeInput == "virtual-machine"){
populateVirtualMachineImages()
//Container options
$("#limitsCpuAllowance").attr("disabled", true); $("#limitsCpuAllowance").val('');
$("#limitsCpuPriority").attr("disabled", true); $("#limitsCpuPriority").val('');
$("#limitsHugepages64KB").attr("disabled", true); $("#limitsHugepages64KB").val('');
$("#limitsHugepages1MB").attr("disabled", true); $("#limitsHugepages1MB").val('');
$("#limitsHugepages2MB").attr("disabled", true); $("#limitsHugepages2MB").val('');
$("#limitsHugepages1GB").attr("disabled", true); $("#limitsHugepages1GB").val('');
$("#limitsMemoryEnforce").attr("disabled", true); $("#limitsMemoryEnforce").val('');
$("#limitsMemorySwapPriority").attr("disabled", true); $("#limitsMemorySwapPriority").val('');
$("#limitsMemorySwap").attr("disabled", true); $("#limitsMemorySwap").val('');
$("#limitsProcesses").attr("disabled", true); $("#limitsProcesses").val('');
$("#linuxKernel_modules").attr("disabled", true); $("#linuxKernel_modules").val('');
$("#migrationIncrementalMemory").attr("disabled", true); $("#migrationIncrementalMemory").val('');
$("#migrationIncrementalMemoryGoal").attr("disabled", true); $("#migrationIncrementalMemoryGoal").val('');
$("#migrationIncrementalMemoryIterations").attr("disabled", true); $("#migrationIncrementalMemoryIterations").val('');
$("#nvidiaDriverCapabilities").attr("disabled", true); $("#nvidiaDriverCapabilities").val('');
$("#nvidiaRuntime").attr("disabled", true); $("#nvidiaRuntime").val('');
$("#nvidiaRequireCuda").attr("disabled", true); $("#nvidiaRequireCuda").val('');
$("#nvidiaRequireDriver").attr("disabled", true); $("#nvidiaRequireDriver").val('');
$("#rawIdmap").attr("disabled", true); $("#rawIdmap").val('');
$("#rawLxc").attr("disabled", true); $("#rawLxc").val('');
$("#rawSeccomp").attr("disabled", true); $("#rawSeccomp").val('');
$("#securityDevlxd").attr("disabled", true); $("#securityDevlxd").val('');
$("#securityDevlxdImages").attr("disabled", true); $("#securityDevlxdImages").val('');
$("#securityIdmapBase").attr("disabled", true); $("#securityIdmapBase").val('');
$("#securityIdmapIsolated").attr("disabled", true); $("#securityIdmapIsolated").val('');
$("#securityIdmapSize").attr("disabled", true); $("#securityIdmapSize").val('');
$("#securityNesting").attr("disabled", true); $("#securityNesting").val('');
$("#securityPrivileged").attr("disabled", true); $("#securityPrivileged").val('');
$("#securityProtectionDelete").attr("disabled", true); $("#securityProtectionDelete").val('');
$("#securityProtectionShift").attr("disabled", true); $("#securityProtectionShift").val('');
$("#securitySyscallsAllow").attr("disabled", true); $("#securitySyscallsAllow").val('');
$("#securitySyscallsDeny").attr("disabled", true); $("#securitySyscallsDeny").val('');
$("#securitySyscallsDeny_compat").attr("disabled", true); $("#securitySyscallsDeny_compat").val('');
$("#securitySyscallsDeny_default").attr("disabled", true); $("#securitySyscallsDeny_default").val('');
$("#securitySyscallsInterceptBpf").attr("disabled", true); $("#securitySyscallsInterceptBpf").val('');
$("#securitySyscallsInterceptBpfDevices").attr("disabled", true); $("#securitySyscallsInterceptBpfDevices").val('');
$("#securitySyscallsInterceptMknod").attr("disabled", true); $("#securitySyscallsInterceptMknod").val('');
$("#securitySyscallsInterceptMount").attr("disabled", true); $("#securitySyscallsInterceptMount").val('');
$("#securitySyscallsInterceptMountAllowed").attr("disabled", true); $("#securitySyscallsInterceptMountAllowed").val('');
$("#securitySyscallsInterceptMountFuse").attr("disabled", true); $("#securitySyscallsInterceptMountFuse").val('');
$("#securitySyscallsInterceptMountShift").attr("disabled", true); $("#securitySyscallsInterceptMountShift").val('');
$("#securitySyscallsInterceptSetxattr").attr("disabled", true); $("#securitySyscallsInterceptSetxattr").val('');
//Virtual-machine options
$("#limitsMemoryHugepages").attr("disabled", false);
$("#migrationStateful").attr("disabled", false);
$("#rawQemu").attr("disabled", false);
$("#rawQemuConf").attr("disabled", false);
$("#securityAgentMetrics").attr("disabled", false);
$("#securitySecureboot").attr("disabled", false);
}
}
$(document).ready(function(){
//If id or project variables are missing redirect to servers page
if (!serverId || !project) {
window.location.href = 'servers';
}
else {
loadPageContent()
operationStatusCheck()
}
});
</script>
{% endblock script %}

View file

@ -54,7 +54,10 @@
url: "../api/logs/list_logs",
dataType: "json",
dataSrc: "data",
contentType: "application/json"
contentType: "application/json",
error: function (xhr, error, code) {
console.log(xhr, code);
}
},
columns: [
{ title: "Id", data: function (row, type, set) {

View file

@ -3,7 +3,7 @@
{% include 'head.html' %}
<!-- Add dark-mode class to body for dark theme-->
<body class="hold-transition sidebar-mini">
<body class="hold-transition sidebar-mini layout-fixed layout-navbar-fixed">
<script>0</script>
<div class="wrapper">
@ -40,7 +40,7 @@
<footer class="main-footer">
<div class="float-right d-none d-sm-block">
Version 0.3.0
Version 0.4.0
</div>
Copyright &copy; 2020-Present <a href="https://penninglabs.com">Penning Labs</a>. All rights reserved.
</footer>
@ -51,20 +51,15 @@
<!-- jQuery - https://code.jquery.com/jquery-3.7.1.js -->
<script src="../static/js/jquery/jquery-3.7.1.js"></script>
<!-- Bootstrap 5 - https://cdn.jsdelivr.net/npm/bootstrap@5.2.3/dist/js/bootstrap.bundle.min.js -->
<script src="../static/js/bootstrap/bootstrap-5.2.3.bundle.min.js.js"></script>
<!-- jQuery Datatables - https://cdn.datatables.net/1.13.6/js/jquery.dataTables.min.js -->
<!-- <script src="../static/js/datatables/jquery.dataTables-1.13.6.min.js"></script> -->
<script src="../static/js/datatables/jquery.dataTables-1.13.6.min.js"></script>
<!-- Datatables Bootstrap 5 - https://cdn.datatables.net/1.13.6/js/dataTables.bootstrap5.min.js -->
<!-- <script src="../static/js/datatables/dataTables.bootstrap5.min.js"></script> -->
<script src="../static/js/datatables/dataTables.bootstrap5.min.js"></script>
<!-- Bootstrap 4 -->
<script src="../static/plugins/bootstrap/js/bootstrap.bundle.min.js"></script>
<!-- DataTables & Plugins -->
<script src="../static/plugins/datatables/jquery.dataTables.min.js"></script>
<script src="../static/plugins/datatables-bs4/js/dataTables.bootstrap4.min.js"></script>
<script src="../static/plugins/datatables-responsive/js/dataTables.responsive.min.js"></script>
<script src="../static/plugins/datatables-responsive/js/responsive.bootstrap4.min.js"></script>
<script src="../static/plugins/jquery-knob/jquery.knob.min.js"></script>
<!-- AdminLTE App -->

View file

@ -4,7 +4,7 @@
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title" id="exampleModalLabel">Create Access Control</h5>
<button class="close" type="button" data-dismiss="modal" aria-label="Close">
<button class="close" type="button" data-bs-dismiss="modal" aria-label="Close">
<span aria-hidden="true">×</span>
</button>
</div>
@ -16,7 +16,7 @@
<label class="col-3 col-form-label text-right">Group: <span class="text-danger">*</span></label>
<div class="col-7">
<div class="form-group">
<select id="groupInput" onchange="" class="form-control" name="group_id">
<select id="groupInput" onchange="" class="form-select" name="group_id">
<option value="">(not set)</option>
</select>
</div>
@ -30,7 +30,7 @@
<label class="col-3 col-form-label text-right">Role: <span class="text-danger">*</span></label>
<div class="col-7">
<div class="form-group">
<select id="roleInput" onchange="" class="form-control" name="role_id">
<select id="roleInput" onchange="" class="form-select" name="role_id">
<option value="">(not set)</option>
</select>
</div>
@ -44,7 +44,7 @@
<label class="col-3 col-form-label text-right">Scope: </label>
<div class="col-7">
<div class="form-group">
<select id="scopeInput" class="form-control" name="scope">
<select id="scopeInput" class="form-select" name="scope">
<option value="global">global</option>
</select>
</div>
@ -58,7 +58,7 @@
<label class="col-3 col-form-label text-right">Server: </label>
<div class="col-7">
<div class="form-group">
<select id="serverInput" onchange="" class="form-control" name="server_id">
<select id="serverInput" onchange="" class="form-select" name="server_id">
<option value="">(not set)</option>
</select>
</div>
@ -84,8 +84,8 @@
</div> <!-- End Modal Body-->
<div class="modal-footer">
<button class="btn btn-secondary" type="button" data-dismiss="modal">Cancel</button>
<a class="btn btn-primary" href="#" onclick="addAccessControl()" data-dismiss="modal">Submit</a>
<button class="btn btn-secondary" type="button" data-bs-dismiss="modal">Cancel</button>
<a class="btn btn-primary" href="#" onclick="addAccessControl()" data-bs-dismiss="modal">Submit</a>
</div>
</div>
</div>
@ -98,7 +98,7 @@
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title" id="exampleModalLabel">Edit Access Control</h5>
<button class="close" type="button" data-dismiss="modal" aria-label="Close">
<button class="close" type="button" data-bs-dismiss="modal" aria-label="Close">
<span aria-hidden="true">×</span>
</button>
</div>
@ -110,7 +110,7 @@
<label class="col-3 col-form-label text-right">Group: <span class="text-danger">*</span></label>
<div class="col-7">
<div class="form-group">
<select id="groupEditInput" onchange="" class="form-control" name="group_id">
<select id="groupEditInput" onchange="" class="form-select" name="group_id">
<option value="">(not set)</option>
</select>
</div>
@ -124,7 +124,7 @@
<label class="col-3 col-form-label text-right">Role: <span class="text-danger">*</span></label>
<div class="col-7">
<div class="form-group">
<select id="roleEditInput" onchange="" class="form-control" name="role_id">
<select id="roleEditInput" onchange="" class="form-select" name="role_id">
<option value="">(not set)</option>
</select>
</div>
@ -138,7 +138,7 @@
<label class="col-3 col-form-label text-right">Scope: </label>
<div class="col-7">
<div class="form-group">
<select id="scopeEditInput" class="form-control" name="scope">
<select id="scopeEditInput" class="form-select" name="scope">
<option value="global">global</option>
</select>
</div>
@ -152,7 +152,7 @@
<label class="col-3 col-form-label text-right">Server: </label>
<div class="col-7">
<div class="form-group">
<select id="serverEditInput" onchange="" class="form-control" name="server_id">
<select id="serverEditInput" onchange="" class="form-select" name="server_id">
<option value="">(not set)</option>
</select>
</div>
@ -179,8 +179,8 @@
</div> <!-- End Modal Body-->
<div class="modal-footer">
<button class="btn btn-secondary" type="button" data-dismiss="modal">Cancel</button>
<a class="btn btn-primary" href="#" onclick="updateAccessControl()" data-dismiss="modal">Submit</a>
<button class="btn btn-secondary" type="button" data-bs-dismiss="modal">Cancel</button>
<a class="btn btn-primary" href="#" onclick="updateAccessControl()" data-bs-dismiss="modal">Submit</a>
</div>
</div>
</div>

View file

@ -4,17 +4,17 @@
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title" id="exampleModalLabel">Add Certificate</h5>
<button class="close" type="button" data-dismiss="modal" aria-label="Close">
<button class="close" type="button" data-bs-dismiss="modal" aria-label="Close">
<span aria-hidden="true">×</span>
</button>
</div>
<div class="modal-body">
<ul class="nav nav-tabs" id="myTab" role="tablist">
<li class="nav-item">
<a class="nav-link active" id="form-tab" data-toggle="tab" href="#form" role="tab" aria-controls="form" aria-selected="true">Form</a>
<a class="nav-link active" id="form-tab" data-bs-toggle="tab" href="#form" role="tab" aria-controls="form" aria-selected="true">Form</a>
</li>
<li class="nav-item">
<a class="nav-link" id="json-tab" data-toggle="tab" href="#json" role="tab" aria-controls="json" aria-selected="false">JSON</a>
<a class="nav-link" id="json-tab" data-bs-toggle="tab" href="#json" role="tab" aria-controls="json" aria-selected="false">JSON</a>
</li>
</ul>
<div class="tab-content" id="myTabContent">
@ -58,8 +58,8 @@
</div>
</form>
<div class="modal-footer">
<button class="btn btn-secondary" type="button" data-dismiss="modal">Cancel</button>
<a class="btn btn-primary" href="#" onclick="addItem()" data-dismiss="modal">Submit</a>
<button class="btn btn-secondary" type="button" data-bs-dismiss="modal">Cancel</button>
<a class="btn btn-primary" href="#" onclick="addItem()" data-bs-dismiss="modal">Submit</a>
</div>
</div>
<div class="tab-pane fade" id="json" role="tabpanel" aria-labelledby="json-tab">
@ -74,8 +74,8 @@
</div>
</div>
<div class="modal-footer">
<button class="btn btn-secondary" type="button" data-dismiss="modal">Cancel</button>
<a class="btn btn-primary" href="#" onclick="createItemUsingJSON()" data-dismiss="modal">Submit</a>
<button class="btn btn-secondary" type="button" data-bs-dismiss="modal">Cancel</button>
<a class="btn btn-primary" href="#" onclick="createItemUsingJSON()" data-bs-dismiss="modal">Submit</a>
</div>
</div>
</div>
@ -90,7 +90,7 @@
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title" id="exampleModalLabel">Edit Certificate</h5>
<button class="close" type="button" data-dismiss="modal" aria-label="Close">
<button class="close" type="button" data-bs-dismiss="modal" aria-label="Close">
<span aria-hidden="true">×</span>
</button>
</div>
@ -107,8 +107,8 @@
</div>
</div>
<div class="modal-footer">
<button class="btn btn-secondary" type="button" data-dismiss="modal">Cancel</button>
<a class="btn btn-primary" href="#" onclick="updateItem()" data-dismiss="modal">Submit</a>
<button class="btn btn-secondary" type="button" data-bs-dismiss="modal">Cancel</button>
<a class="btn btn-primary" href="#" onclick="updateItem()" data-bs-dismiss="modal">Submit</a>
</div>
</div>
</div>

View file

@ -4,17 +4,17 @@
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title" id="exampleModalLabel">Add Cluster Group</h5>
<button class="close" type="button" data-dismiss="modal" aria-label="Close">
<button class="close" type="button" data-bs-dismiss="modal" aria-label="Close">
<span aria-hidden="true">×</span>
</button>
</div>
<div class="modal-body">
<ul class="nav nav-tabs" id="myTab" role="tablist">
<li class="nav-item">
<a class="nav-link active" id="form-tab" data-toggle="tab" href="#form" role="tab" aria-controls="form" aria-selected="true">Form</a>
<a class="nav-link active" id="form-tab" data-bs-toggle="tab" href="#form" role="tab" aria-controls="form" aria-selected="true">Form</a>
</li>
<li class="nav-item">
<a class="nav-link" id="json-tab" data-toggle="tab" href="#json" role="tab" aria-controls="json" aria-selected="false">JSON</a>
<a class="nav-link" id="json-tab" data-bs-toggle="tab" href="#json" role="tab" aria-controls="json" aria-selected="false">JSON</a>
</li>
</ul>
<div class="tab-content" id="myTabContent">
@ -47,7 +47,7 @@
<label class="col-3 col-form-label text-right">Cluster Members: </label>
<div class="col-7">
<div class="form-group">
<select id="clusterMembersInput" class="select form-control" multiple name="members">
<select id="clusterMembersInput" class="select form-select" multiple name="members">
</select>
</div>
</div>
@ -57,8 +57,8 @@
</div>
</form>
<div class="modal-footer">
<button class="btn btn-secondary" type="button" data-dismiss="modal">Cancel</button>
<a class="btn btn-primary" href="#" onclick="addItem()" data-dismiss="modal">Submit</a>
<button class="btn btn-secondary" type="button" data-bs-dismiss="modal">Cancel</button>
<a class="btn btn-primary" href="#" onclick="addItem()" data-bs-dismiss="modal">Submit</a>
</div>
</div>
<div class="tab-pane fade" id="json" role="tabpanel" aria-labelledby="json-tab">
@ -73,8 +73,8 @@
</div>
</div>
<div class="modal-footer">
<button class="btn btn-secondary" type="button" data-dismiss="modal">Cancel</button>
<a class="btn btn-primary" href="#" onclick="createItemUsingJSON()" data-dismiss="modal">Submit</a>
<button class="btn btn-secondary" type="button" data-bs-dismiss="modal">Cancel</button>
<a class="btn btn-primary" href="#" onclick="createItemUsingJSON()" data-bs-dismiss="modal">Submit</a>
</div>
</div>
</div>
@ -89,17 +89,17 @@
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title" id="exampleModalLabel">Edit Cluster Group</h5>
<button class="close" type="button" data-dismiss="modal" aria-label="Close">
<button class="close" type="button" data-bs-dismiss="modal" aria-label="Close">
<span aria-hidden="true">×</span>
</button>
</div>
<div class="modal-body">
<ul class="nav nav-tabs" id="myTab" role="tablist">
<li class="nav-item">
<a class="nav-link active" id="json-edit-tab" data-toggle="tab" href="#json-edit" role="tab" aria-controls="json-edit" aria-selected="false">JSON</a>
<a class="nav-link active" id="json-edit-tab" data-bs-toggle="tab" href="#json-edit" role="tab" aria-controls="json-edit" aria-selected="false">JSON</a>
</li>
<li class="nav-item">
<a class="nav-link" id="rename-edit-tab" data-toggle="tab" href="#rename-edit" role="tab" aria-controls="rename-edit" aria-selected="true">Rename</a>
<a class="nav-link" id="rename-edit-tab" data-bs-toggle="tab" href="#rename-edit" role="tab" aria-controls="rename-edit" aria-selected="true">Rename</a>
</li>
</ul>
<div class="tab-content" id="myTabContent">
@ -116,8 +116,8 @@
</div>
</div>
<div class="modal-footer">
<button class="btn btn-secondary" type="button" data-dismiss="modal">Cancel</button>
<a class="btn btn-primary" href="#" onclick="updateItem()" data-dismiss="modal">Submit</a>
<button class="btn btn-secondary" type="button" data-bs-dismiss="modal">Cancel</button>
<a class="btn btn-primary" href="#" onclick="updateItem()" data-bs-dismiss="modal">Submit</a>
</div>
</div>
<div class="tab-pane fade" id="rename-edit" role="tabpanel" aria-labelledby="rename-edit-tab">
@ -136,8 +136,8 @@
</div>
</form>
<div class="modal-footer">
<button class="btn btn-secondary" type="button" data-dismiss="modal">Cancel</button>
<a class="btn btn-primary" href="#" onclick="renameItem()" data-dismiss="modal">Submit</a>
<button class="btn btn-secondary" type="button" data-bs-dismiss="modal">Cancel</button>
<a class="btn btn-primary" href="#" onclick="renameItem()" data-bs-dismiss="modal">Submit</a>
</div>
</div>
</div>
@ -152,7 +152,7 @@
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title" id="exampleModalLabel">Delete Cluster Group</h5>
<button class="close" type="button" data-dismiss="modal" aria-label="Close">
<button class="close" type="button" data-bs-dismiss="modal" aria-label="Close">
<span aria-hidden="true">×</span>
</button>
</div>
@ -163,8 +163,8 @@
<input type="hidden" id="clusterGroup" class="form-control" name="server_name">
</div>
<div class="modal-footer">
<button class="btn btn-secondary" type="button" data-dismiss="modal">Cancel</button>
<a class="btn btn-primary" href="#" onclick="deleteItem()" data-dismiss="modal">Yes</a>
<button class="btn btn-secondary" type="button" data-bs-dismiss="modal">Cancel</button>
<a class="btn btn-primary" href="#" onclick="deleteItem()" data-bs-dismiss="modal">Yes</a>
</div>
</div>
</div>

View file

@ -4,17 +4,17 @@
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title" id="exampleModalLabel">Add Cluster Member</h5>
<button class="close" type="button" data-dismiss="modal" aria-label="Close">
<button class="close" type="button" data-bs-dismiss="modal" aria-label="Close">
<span aria-hidden="true">×</span>
</button>
</div>
<div class="modal-body">
<ul class="nav nav-tabs" id="myTab" role="tablist">
<li class="nav-item">
<a class="nav-link active" id="form-tab" data-toggle="tab" href="#form" role="tab" aria-controls="form" aria-selected="true">Form</a>
<a class="nav-link active" id="form-tab" data-bs-toggle="tab" href="#form" role="tab" aria-controls="form" aria-selected="true">Form</a>
</li>
<li class="nav-item">
<a class="nav-link" id="json-tab" data-toggle="tab" href="#json" role="tab" aria-controls="json" aria-selected="false">JSON</a>
<a class="nav-link" id="json-tab" data-bs-toggle="tab" href="#json" role="tab" aria-controls="json" aria-selected="false">JSON</a>
</li>
</ul>
<div class="tab-content" id="myTabContent">
@ -45,8 +45,8 @@
</div>
</form>
<div class="modal-footer">
<button class="btn btn-secondary" type="button" data-dismiss="modal">Cancel</button>
<a class="btn btn-primary" href="#" onclick="addItem()" data-dismiss="modal">Submit</a>
<button class="btn btn-secondary" type="button" data-bs-dismiss="modal">Cancel</button>
<a class="btn btn-primary" href="#" onclick="addItem()" data-bs-dismiss="modal">Submit</a>
</div>
</div>
<div class="tab-pane fade" id="json" role="tabpanel" aria-labelledby="json-tab">
@ -61,8 +61,8 @@
</div>
</div>
<div class="modal-footer">
<button class="btn btn-secondary" type="button" data-dismiss="modal">Cancel</button>
<a class="btn btn-primary" href="#" onclick="createItemUsingJSON()" data-dismiss="modal">Submit</a>
<button class="btn btn-secondary" type="button" data-bs-dismiss="modal">Cancel</button>
<a class="btn btn-primary" href="#" onclick="createItemUsingJSON()" data-bs-dismiss="modal">Submit</a>
</div>
</div>
</div>
@ -77,17 +77,17 @@
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title" id="exampleModalLabel">Edit Cluster Member</h5>
<button class="close" type="button" data-dismiss="modal" aria-label="Close">
<button class="close" type="button" data-bs-dismiss="modal" aria-label="Close">
<span aria-hidden="true">×</span>
</button>
</div>
<div class="modal-body">
<ul class="nav nav-tabs" id="myTab" role="tablist">
<li class="nav-item">
<a class="nav-link active" id="json-edit-tab" data-toggle="tab" href="#json-edit" role="tab" aria-controls="json-edit" aria-selected="false">JSON</a>
<a class="nav-link active" id="json-edit-tab" data-bs-toggle="tab" href="#json-edit" role="tab" aria-controls="json-edit" aria-selected="false">JSON</a>
</li>
<li class="nav-item">
<a class="nav-link" id="rename-edit-tab" data-toggle="tab" href="#rename-edit" role="tab" aria-controls="rename-edit" aria-selected="true">Rename</a>
<a class="nav-link" id="rename-edit-tab" data-bs-toggle="tab" href="#rename-edit" role="tab" aria-controls="rename-edit" aria-selected="true">Rename</a>
</li>
</ul>
<div class="tab-content" id="myTabContent">
@ -104,8 +104,8 @@
</div>
</div>
<div class="modal-footer">
<button class="btn btn-secondary" type="button" data-dismiss="modal">Cancel</button>
<a class="btn btn-primary" href="#" onclick="updateItem()" data-dismiss="modal">Submit</a>
<button class="btn btn-secondary" type="button" data-bs-dismiss="modal">Cancel</button>
<a class="btn btn-primary" href="#" onclick="updateItem()" data-bs-dismiss="modal">Submit</a>
</div>
</div>
<div class="tab-pane fade" id="rename-edit" role="tabpanel" aria-labelledby="rename-edit-tab">
@ -125,8 +125,8 @@
</div>
</form>
<div class="modal-footer">
<button class="btn btn-secondary" type="button" data-dismiss="modal">Cancel</button>
<a class="btn btn-primary" href="#" onclick="renameItem()" data-dismiss="modal">Submit</a>
<button class="btn btn-secondary" type="button" data-bs-dismiss="modal">Cancel</button>
<a class="btn btn-primary" href="#" onclick="renameItem()" data-bs-dismiss="modal">Submit</a>
</div>
</div>
</div>
@ -141,7 +141,7 @@
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title" id="exampleModalLabel">Delete Cluster Member</h5>
<button class="close" type="button" data-dismiss="modal" aria-label="Close">
<button class="close" type="button" data-bs-dismiss="modal" aria-label="Close">
<span aria-hidden="true">×</span>
</button>
</div>
@ -158,8 +158,8 @@
<input type="hidden" id="clusterMember" class="form-control" name="server_name">
</div>
<div class="modal-footer">
<button class="btn btn-secondary" type="button" data-dismiss="modal">Cancel</button>
<a class="btn btn-primary" href="#" onclick="deleteItem()" data-dismiss="modal">Yes</a>
<button class="btn btn-secondary" type="button" data-bs-dismiss="modal">Cancel</button>
<a class="btn btn-primary" href="#" onclick="deleteItem()" data-bs-dismiss="modal">Yes</a>
</div>
</div>
</div>

View file

@ -4,7 +4,7 @@
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title" id="exampleModalLabel">Create Group</h5>
<button class="close" type="button" data-dismiss="modal" aria-label="Close">
<button class="close" type="button" data-bs-dismiss="modal" aria-label="Close">
<span aria-hidden="true">×</span>
</button>
</div>
@ -39,8 +39,8 @@
</div> <!-- End Modal Body-->
<div class="modal-footer">
<button class="btn btn-secondary" type="button" data-dismiss="modal">Cancel</button>
<a class="btn btn-primary" href="#" onclick="addGroup()" data-dismiss="modal">Submit</a>
<button class="btn btn-secondary" type="button" data-bs-dismiss="modal">Cancel</button>
<a class="btn btn-primary" href="#" onclick="addGroup()" data-bs-dismiss="modal">Submit</a>
</div>
</div>
</div>
@ -53,7 +53,7 @@
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title" id="exampleModalLabel">Edit Group</h5>
<button class="close" type="button" data-dismiss="modal" aria-label="Close">
<button class="close" type="button" data-bs-dismiss="modal" aria-label="Close">
<span aria-hidden="true">×</span>
</button>
</div>
@ -89,8 +89,8 @@
</div> <!-- End Modal Body-->
<div class="modal-footer">
<button class="btn btn-secondary" type="button" data-dismiss="modal">Cancel</button>
<a class="btn btn-primary" href="#" onclick="updateGroup()" data-dismiss="modal">Submit</a>
<button class="btn btn-secondary" type="button" data-bs-dismiss="modal">Cancel</button>
<a class="btn btn-primary" href="#" onclick="updateGroup()" data-bs-dismiss="modal">Submit</a>
</div>
</div>
</div>

View file

@ -4,17 +4,17 @@
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title" id="exampleModalLabel">Download Image</h5>
<button class="close" type="button" data-dismiss="modal" aria-label="Close">
<button class="close" type="button" data-bs-dismiss="modal" aria-label="Close">
<span aria-hidden="true">×</span>
</button>
</div>
<div class="modal-body">
<ul class="nav nav-tabs" id="myTab" role="tablist">
<li class="nav-item">
<a class="nav-link active" id="catalog-tab" data-toggle="tab" href="#catalog" role="tab" aria-controls="catalog" aria-selected="true">Catalog</a>
<a class="nav-link active" id="catalog-tab" data-bs-toggle="tab" href="#catalog" role="tab" aria-controls="catalog" aria-selected="true">Catalog</a>
</li>
<li class="nav-item">
<a class="nav-link" id="form-tab" data-toggle="tab" href="#form" role="tab" aria-controls="form" aria-selected="false">Form</a>
<a class="nav-link" id="form-tab" data-bs-toggle="tab" href="#form" role="tab" aria-controls="form" aria-selected="false">Form</a>
</li>
</ul>
<div class="tab-content" id="myTabContent">
@ -24,7 +24,7 @@
<label class="col-3 col-form-label text-right">Operating System: </label>
<div class="col-7">
<div class="form-group">
<select id="operatingSystem" onchange="updateOSVersion()" class="form-control" name="operating_system">
<select id="operatingSystem" onchange="updateOSVersion()" class="form-select" name="operating_system">
<option value="">unavailable</option>
</select>
</div>
@ -38,7 +38,7 @@
<label class="col-3 col-form-label text-right">OS Version: </label>
<div class="col-7">
<div class="form-group">
<select id="operatingSystemVersion" onchange="" class="form-control" name="version">
<select id="operatingSystemVersion" onchange="" class="form-select" name="version">
<option value="">unavailable</option>
</select>
</div>
@ -52,7 +52,7 @@
<label class="col-3 col-form-label text-right">Image Variant: </label>
<div class="col-7">
<div class="form-group">
<select id="operatingSystemVariant" onchange="" class="form-control" name="variant">
<select id="operatingSystemVariant" onchange="" class="form-select" name="variant">
<option value="">unavailable</option>
</select>
</div>
@ -66,7 +66,7 @@
<label class="col-3 col-form-label text-right">Image Type: </label>
<div class="col-7">
<div class="form-group">
<select id="operatingSystemType" onchange="" class="form-control" name="type">
<select id="operatingSystemType" onchange="" class="form-select" name="type">
<option value="container">container</option>
<option value="virtual-machine">virtual-machine</option>
</select>
@ -78,8 +78,8 @@
</div>
<div class="modal-footer">
<button class="btn btn-secondary" type="button" data-dismiss="modal">Cancel</button>
<a class="btn btn-primary" href="#" onclick="addCatalogImage()" data-dismiss="modal">Ok</a>
<button class="btn btn-secondary" type="button" data-bs-dismiss="modal">Cancel</button>
<a class="btn btn-primary" href="#" onclick="addCatalogImage()" data-bs-dismiss="modal">Ok</a>
</div>
</div>
@ -94,13 +94,13 @@
</div>
</div>
<div class="col-1">
<i class="far fa-sm fa-question-circle" data-toggle="tooltip" data-html="true" title='(Required) - Enter in the repository specific name. For example, ubuntu/20.04 would be used for the images repository and simply 20.04 would be used for the ubuntu repositories.'></i>
<i class="far fa-sm fa-question-circle" data-bs-toggle="tooltip" data-html="true" title='(Required) - Enter in the repository specific name. For example, ubuntu/20.04 would be used for the images repository and simply 20.04 would be used for the ubuntu repositories.'></i>
</div>
<label class="col-2 col-form-label text-right">Repository: </label>
<div class="col-8">
<div class="form-group">
<select id="selectRepoInput" class="form-control" name="simplestreams_id">
<select id="selectRepoInput" class="form-select" name="simplestreams_id">
</select>
</div>
</div>
@ -111,7 +111,7 @@
<label class="col-2 col-form-label text-right">Image Type:</label>
<div class="col-8 text-right">
<div class="form-group">
<select class="form-control" name="image_type">
<select class="form-select" name="image_type">
<option value="container" selected>container</option>
<option value="virtual-machine">virtual-machine</option>
</select>
@ -124,14 +124,14 @@
</div>
</form>
<div class="modal-footer">
<button class="btn btn-secondary" type="button" data-dismiss="modal">Cancel</button>
<a class="btn btn-primary" href="#" onclick="addItem()" data-dismiss="modal">Ok</a>
<button class="btn btn-secondary" type="button" data-bs-dismiss="modal">Cancel</button>
<a class="btn btn-primary" href="#" onclick="addItem()" data-bs-dismiss="modal">Ok</a>
</div>
</div>
</div>
</div>
<div class="modal-footer text-center">
<!--<a href="#" data-toggle="modal" data-target="#trademarkNotices" title="Download Image" aria-hidden="true">Trademark notices</a>-->
<!--<a href="#" data-bs-toggle="modal" data-bs-target="#trademarkNotices" title="Download Image" aria-hidden="true">Trademark notices</a>-->
</div>
</div>
</div>
@ -143,7 +143,7 @@
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title" id="exampleModalLabel">Edit Image</h5>
<button class="close" type="button" data-dismiss="modal" aria-label="Close">
<button class="close" type="button" data-bs-dismiss="modal" aria-label="Close">
<span aria-hidden="true">×</span>
</button>
</div>
@ -160,8 +160,8 @@
</div>
</div>
<div class="modal-footer">
<button class="btn btn-secondary" type="button" data-dismiss="modal">Cancel</button>
<a class="btn btn-primary" href="#" onclick="updateImage()" data-dismiss="modal">Submit</a>
<button class="btn btn-secondary" type="button" data-bs-dismiss="modal">Cancel</button>
<a class="btn btn-primary" href="#" onclick="updateImage()" data-bs-dismiss="modal">Submit</a>
</div>
</div>
</div>

View file

@ -3,18 +3,18 @@
<div class="modal-dialog modal-lg" role="document">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title" id="exampleModalLabel">Create Container</h5>
<button class="close" type="button" data-dismiss="modal" aria-label="Close">
<h5 class="modal-title" id="exampleModalLabel">Create Instance</h5>
<button class="close" type="button" data-bs-dismiss="modal" aria-label="Close">
<span aria-hidden="true">×</span>
</button>
</div>
<div class="modal-body">
<ul class="nav nav-tabs" id="myTab" role="tablist">
<li class="nav-item">
<a class="nav-link active" id="form-tab" data-toggle="tab" href="#form" role="tab" aria-controls="form" aria-selected="true">Form</a>
<a class="nav-link active" id="form-tab" data-bs-toggle="tab" href="#form" role="tab" aria-controls="form" aria-selected="true">Form</a>
</li>
<li class="nav-item">
<a class="nav-link" id="json-tab" data-toggle="tab" href="#json" role="tab" aria-controls="json" aria-selected="false">JSON</a>
<a class="nav-link" id="json-tab" data-bs-toggle="tab" href="#json" role="tab" aria-controls="json" aria-selected="false">JSON</a>
</li>
</ul>
<div class="tab-content" id="myTabContent">
@ -30,7 +30,7 @@
</div>
</div>
<div class="col-1">
<i class="far fa-sm fa-question-circle" title='Enter in a name for this container'></i>
<i class="far fa-sm fa-question-circle" title='Enter in a name for this instance'></i>
</div>
</div>
<div class="row">
@ -41,39 +41,53 @@
</div>
</div>
<div class="col-1">
<i class="far fa-sm fa-question-circle" title='Enter in a description for this container'></i>
<i class="far fa-sm fa-question-circle" title='Enter in a description for this instance'></i>
</div>
</div>
<div class="row">
<label class="col-3 col-form-label text-right">Type: </label>
<div class="col-7">
<div class="form-group">
<select id="instanceTypeInput" onchange="changeInstanceModalTypeOptions()" class="form-select" name="type">
<option value="container">container</option>
<option value="virtual-machine">virtual-machine</option>
</select>
</div>
</div>
<div class="col-1">
<i class="far fa-sm fa-question-circle" title='Choose either a traditional container or virtual-machine'></i>
</div>
</div>
<div class="row">
<label class="col-3 col-form-label text-right">Image: </label>
<div class="col-7">
<div class="form-group">
<select id="containerImageInput" class="form-control" name="image">
<select id="instanceImageInput" class="form-select" name="image">
<option value="none">none</option>
</select>
</div>
</div>
<div class="col-1">
<i class="far fa-sm fa-question-circle" title='Select a downloaded image to use to build the container'></i>
<i class="far fa-sm fa-question-circle" title='Select a downloaded image to use to build the instance'></i>
</div>
</div>
<div class="row">
<label class="col-3 col-form-label text-right">Profiles: </label>
<div class="col-7">
<div class="form-group">
<select id="containerProfileInput" class="form-control" name="profiles">
<select id="instanceProfileInput" class="form-select" name="profiles">
</select>
</div>
</div>
<div class="col-1">
<i class="far fa-sm fa-question-circle" title='Select the initial profile to attach to this container. Additional profiles can be attached after the container is created. Default: default'></i>
<i class="far fa-sm fa-question-circle" title='Select the initial profile to attach to this instance. Additional profiles can be attached after the instance is created. Default: default'></i>
</div>
</div>
<div class="row">
<label class="col-3 col-form-label text-right">Instance Type: </label>
<div class="col-7">
<div class="form-group">
<select class="form-control" name="instance_type">
<select class="form-select" name="instance_type">
<option value="" selected>(not set)</option>
<option disabled>--- AWS Instance Types ---</option>
<option value="aws:c1.medium">c1.medium</option>
@ -243,7 +257,7 @@
</div>
</div>
<div class="col-1">
<i class="far fa-sm fa-question-circle" title='Select from a variety of preconfigured container configurations. Default: (not set)'></i>
<i class="far fa-sm fa-question-circle" title='Select from a variety of preconfigured instance configurations. Default: (not set)'></i>
</div>
</div>
@ -251,28 +265,28 @@
<label class="col-3 col-form-label text-right">Location: </label>
<div class="col-7">
<div class="form-group">
<select id="containerLocationInput" class="form-control" name="location">
<select id="instanceLocationInput" class="form-select" name="location">
<option value="none">none</option>
</select>
</div>
</div>
<div class="col-1">
<i class="far fa-sm fa-question-circle" title='Select the LXD cluster member or @group to deploy this container on. Default: none'></i>
<i class="far fa-sm fa-question-circle" title='Select the LXD cluster member or @group to deploy this instance on. Default: none'></i>
</div>
</div>
<hr class="mb-2">
<nav>
<div class="nav nav-pills justify-content-center" id="nav-tab" role="tablist">
<a class="nav-link active" id="nav-boot-tab" data-toggle="tab" href="#nav-boot" role="tab" aria-controls="nav-boot" aria-selected="true">Boot</a>
<a class="nav-link" id="nav-cloud-init-tab" data-toggle="tab" href="#nav-cloud-init" role="tab" aria-controls="nav-cloud-init" aria-selected="true">Cloud-init</a>
<a class="nav-link" id="nav-limits-tab" data-toggle="tab" href="#nav-limits" role="tab" aria-controls="nav-limits" aria-selected="false">Limits</a>
<a class="nav-link" id="nav-migration-tab" data-toggle="tab" href="#nav-migration" role="tab" aria-controls="nav-migration" aria-selected="false">Migration</a>
<a class="nav-link" id="nav-nvidia-tab" data-toggle="tab" href="#nav-nvidia" role="tab" aria-controls="nav-nvidia" aria-selected="false">Nvidia</a>
<a class="nav-link" id="nav-other-tab" data-toggle="tab" href="#nav-other" role="tab" aria-controls="nav-other" aria-selected="false">Other</a>
<a class="nav-link" id="nav-raw-tab" data-toggle="tab" href="#nav-raw" role="tab" aria-controls="nav-raw" aria-selected="false">Raw</a>
<a class="nav-link" id="nav-security-tab" data-toggle="tab" href="#nav-security" role="tab" aria-controls="nav-security" aria-selected="false">Security</a>
<a class="nav-link" id="nav-snapshots-tab" data-toggle="tab" href="#nav-snapshots" role="tab" aria-controls="nav-snapshots" aria-selected="false">Snapshots</a>
<a class="nav-link active" id="nav-boot-tab" data-bs-toggle="tab" href="#nav-boot" role="tab" aria-controls="nav-boot" aria-selected="true">Boot</a>
<a class="nav-link" id="nav-cloud-init-tab" data-bs-toggle="tab" href="#nav-cloud-init" role="tab" aria-controls="nav-cloud-init" aria-selected="true">Cloud-init</a>
<a class="nav-link" id="nav-limits-tab" data-bs-toggle="tab" href="#nav-limits" role="tab" aria-controls="nav-limits" aria-selected="false">Limits</a>
<a class="nav-link" id="nav-migration-tab" data-bs-toggle="tab" href="#nav-migration" role="tab" aria-controls="nav-migration" aria-selected="false">Migration</a>
<a class="nav-link" id="nav-nvidia-tab" data-bs-toggle="tab" href="#nav-nvidia" role="tab" aria-controls="nav-nvidia" aria-selected="false">Nvidia</a>
<a class="nav-link" id="nav-other-tab" data-bs-toggle="tab" href="#nav-other" role="tab" aria-controls="nav-other" aria-selected="false">Other</a>
<a class="nav-link" id="nav-raw-tab" data-bs-toggle="tab" href="#nav-raw" role="tab" aria-controls="nav-raw" aria-selected="false">Raw</a>
<a class="nav-link" id="nav-security-tab" data-bs-toggle="tab" href="#nav-security" role="tab" aria-controls="nav-security" aria-selected="false">Security</a>
<a class="nav-link" id="nav-snapshots-tab" data-bs-toggle="tab" href="#nav-snapshots" role="tab" aria-controls="nav-snapshots" aria-selected="false">Snapshots</a>
</div>
</nav>
<hr class="mt-2">
@ -283,7 +297,7 @@
<label class="col-4 col-form-label text-right">Autostart: </label>
<div class="col-6">
<div class="form-group">
<select class="form-control" name="boot.autostart">
<select class="form-select" name="boot.autostart">
<option value="">(not set)</option>
<option value="true">true</option>
<option value="false">false</option>
@ -291,7 +305,7 @@
</div>
</div>
<div class="col-1">
<i class="far fa-sm fa-question-circle" title='Select whether to automatically start the container with LXD starts. If not set, defaults to container last state.'></i>
<i class="far fa-sm fa-question-circle" title='Select whether to automatically start the instance when LXD starts. If not set, defaults to instance last state.'></i>
</div>
</div>
<div class="row">
@ -302,7 +316,7 @@
</div>
</div>
<div class="col-1">
<i class="far fa-sm fa-question-circle" title='Enter in the number of seconds to wait after the container starts to boot up the next container. Default: 0.'></i>
<i class="far fa-sm fa-question-circle" title='Enter in the number of seconds to wait after the instance starts to boot up the next instance. Default: 0.'></i>
</div>
</div>
<div class="row">
@ -313,7 +327,7 @@
</div>
</div>
<div class="col-1">
<i class="far fa-sm fa-question-circle" title='Enter in a number to determine the order the container boots, higher numbers being first. Default: 0.'></i>
<i class="far fa-sm fa-question-circle" title='Enter in a number to determine the order the instance boots, higher numbers being first. Default: 0.'></i>
</div>
</div>
<div class="row">
@ -324,7 +338,7 @@
</div>
</div>
<div class="col-1">
<i class="far fa-sm fa-question-circle" title='Enter in a the number of seconds to wait on host shutdown before forcefull shutdown of container. Default: 30.'></i>
<i class="far fa-sm fa-question-circle" title='Enter in a the number of seconds to wait on host shutdown before forcefull shutdown of instance. Default: 30.'></i>
</div>
</div>
<div class="row">
@ -335,7 +349,7 @@
</div>
</div>
<div class="col-1">
<i class="far fa-sm fa-question-circle" title='Enter in a number to determine the order the container shutsdown, higher numbers being first. Default: 0.'></i>
<i class="far fa-sm fa-question-circle" title='Enter in a number to determine the order the instance shutsdown, higher numbers being first. Default: 0.'></i>
</div>
</div>
</div>
@ -385,29 +399,29 @@
</div>
</div>
<div class="col-1">
<i class="far fa-sm fa-question-circle" title='Enter in the number or range of CPUs to expose to the container.'></i>
<i class="far fa-sm fa-question-circle" title='Enter in the number or range of CPUs to expose to the instance.'></i>
</div>
</div>
<div class="row">
<label class="col-4 col-form-label text-right">CPU Allowance: </label>
<div class="col-6">
<div class="form-group">
<input type="text" class="form-control" name="limits.cpu.allowance">
<input type="text" class="form-control" id="limitsCpuAllowance" name="limits.cpu.allowance">
</div>
</div>
<div class="col-1">
<i class="far fa-sm fa-question-circle" title='Enter in the amount of Host CPU allowed to the container. This can be a percentage or a chunk of time. For example, 50% or 25ms/100ms. Default: 100%) '></i>
<i class="far fa-sm fa-question-circle" title='Enter in the amount of Host CPU allowed to the instance. This can be a percentage or a chunk of time. For example, 50% or 25ms/100ms. Default: 100%) '></i>
</div>
</div>
<div class="row">
<label class="col-4 col-form-label text-right">CPU Priority: </label>
<div class="col-6">
<div class="form-group">
<input type="number" class="form-control" name="limits.cpu.priority">
<input type="number" class="form-control" id="limitsCpuPriority" name="limits.cpu.priority">
</div>
</div>
<div class="col-1">
<i class="far fa-sm fa-question-circle" title='Enter in an integer between 0 (min) and 10 (max) to schedule the CPU priority compared to other containers. Default: 10.'></i>
<i class="far fa-sm fa-question-circle" title='Enter in an integer between 0 (min) and 10 (max) to schedule the CPU priority compared to other instances. Default: 10.'></i>
</div>
</div>
<div class="row">
@ -418,14 +432,14 @@
</div>
</div>
<div class="col-1">
<i class="far fa-sm fa-question-circle" title='Enter in an integer between 0 (min) and 10 (max) to schedule disk I/O request priority compared to other containers. Default: 5.'></i>
<i class="far fa-sm fa-question-circle" title='Enter in an integer between 0 (min) and 10 (max) to schedule disk I/O request priority compared to other instances. Default: 5.'></i>
</div>
</div>
<div class="row">
<label class="col-4 col-form-label text-right">Hugepages - 64KB: </label>
<div class="col-6">
<div class="form-group">
<input type="number" class="form-control" name="limits.hugepages.64KB">
<input type="number" class="form-control" id="limitsHugepages64KB" name="limits.hugepages.64KB">
</div>
</div>
<div class="col-1">
@ -436,7 +450,7 @@
<label class="col-4 col-form-label text-right">Hugepages - 1MB: </label>
<div class="col-6">
<div class="form-group">
<input type="number" class="form-control" name="limits.hugepages.1MB">
<input type="number" class="form-control" id="limitsHugepages1MB" name="limits.hugepages.1MB">
</div>
</div>
<div class="col-1">
@ -447,7 +461,7 @@
<label class="col-4 col-form-label text-right">Hugepages - 2MB: </label>
<div class="col-6">
<div class="form-group">
<input type="number" class="form-control" name="limits.hugepages.2MB">
<input type="number" class="form-control" id="limitsHugepages2MB" name="limits.hugepages.2MB">
</div>
</div>
<div class="col-1">
@ -458,7 +472,7 @@
<label class="col-4 col-form-label text-right">Hugepages - 1GB: </label>
<div class="col-6">
<div class="form-group">
<input type="number" class="form-control" name="limits.hugepages.1GB">
<input type="number" class="form-control" id="limitsHugepages1GB" name="limits.hugepages.1GB">
</div>
</div>
<div class="col-1">
@ -480,7 +494,7 @@
<label class="col-4 col-form-label text-right">Memory Enforce: </label>
<div class="col-6">
<div class="form-group">
<select class="form-control" name="limits.memory.enforce">
<select class="form-select" id="limitsMemoryEnforce" name="limits.memory.enforce">
<option value="">(not set)</option>
<option value="hard">hard</option>
<option value="soft">soft</option>
@ -492,10 +506,10 @@
</div>
</div>
<div class="row">
<label class="col-4 col-form-label text-right">Memory Swap: </label>
<label class="col-4 col-form-label text-right">Memory Hugepages: </label>
<div class="col-6">
<div class="form-group">
<select class="form-control" name="limits.memory.swap">
<select class="form-select" id="limitsMemoryHugepages" name="limits.memory.hugepages">
<option value="">(not set)</option>
<option value="true">true</option>
<option value="false">false</option>
@ -503,18 +517,33 @@
</div>
</div>
<div class="col-1">
<i class="far fa-sm fa-question-circle" title="Select whether to encorage swapping less used pages for the container. Default: true."></i>
<i class="far fa-sm fa-question-circle" title="Select whether to back the instance using hugepages rather than regular system memory. Default: false."></i>
</div>
</div>
<div class="row">
<label class="col-4 col-form-label text-right">Memory Swap: </label>
<div class="col-6">
<div class="form-group">
<select class="form-select" id="limitsMemorySwap" name="limits.memory.swap">
<option value="">(not set)</option>
<option value="true">true</option>
<option value="false">false</option>
</select>
</div>
</div>
<div class="col-1">
<i class="far fa-sm fa-question-circle" title="Select whether to encorage swapping less used pages for the instance. Default: true."></i>
</div>
</div>
<div class="row">
<label class="col-4 col-form-label text-right">Memory Swap Priority: </label>
<div class="col-6">
<div class="form-group">
<input type="number" class="form-control" name="limits.memory.swap.priority">
<input type="number" class="form-control" id="limitsMemorySwapPriority" name="limits.memory.swap.priority">
</div>
</div>
<div class="col-1">
<i class="far fa-sm fa-question-circle" title="Enter in the priority that the container will be less likely to swap to disk, with 10 being the maxium less likeliness. Default 10."></i>
<i class="far fa-sm fa-question-circle" title="Enter in the priority that the instance will be less likely to swap to disk, with 10 being the maxium less likeliness. Default 10."></i>
</div>
</div>
<div class="row">
@ -525,18 +554,18 @@
</div>
</div>
<div class="col-1">
<i class="far fa-sm fa-question-circle" title="Enter in the priority for the container network when the host is under, with 10 being the priority. Default 0."></i>
<i class="far fa-sm fa-question-circle" title="Enter in the priority for the instance network when the host is under, with 10 being the priority. Default 0."></i>
</div>
</div>
<div class="row">
<label class="col-4 col-form-label text-right">Processes: </label>
<div class="col-6">
<div class="form-group">
<input type="number" class="form-control" name="limits.processes">
<input type="number" class="form-control" id="limitsProcesses" name="limits.processes">
</div>
</div>
<div class="col-1">
<i class="far fa-sm fa-question-circle" title="Enter in the maximum number of processes that can run in an container. Default (not set)."></i>
<i class="far fa-sm fa-question-circle" title="Enter in the maximum number of processes that can run in an instance. Default (not set)."></i>
</div>
</div>
</div>
@ -546,7 +575,7 @@
<label class="col-4 col-form-label text-right">Incremental Memory: </label>
<div class="col-6">
<div class="form-group">
<select class="form-control" name="migration.incremental.memory">
<select class="form-select" id="migrationIncrementalMemory" name="migration.incremental.memory">
<option value="">(not set)</option>
<option value="true">true</option>
<option value="false">false</option>
@ -554,29 +583,44 @@
</div>
</div>
<div class="col-1">
<i class="far fa-sm fa-question-circle" title="Select whether to allow incremental memory transfer of the container's memory to reduce downtime. Default: false."></i>
<i class="far fa-sm fa-question-circle" title="Select whether to allow incremental memory transfer of the instance's memory to reduce downtime. Default: false."></i>
</div>
</div>
<div class="row">
<label class="col-4 col-form-label text-right">Incremental Memory Goal: </label>
<div class="col-6">
<div class="form-group">
<input type="number" class="form-control"name="migration.incremental.memory.goal">
<input type="number" class="form-control" id="migrationIncrementalMemoryGoal" name="migration.incremental.memory.goal">
</div>
</div>
<div class="col-1">
<i class="far fa-sm fa-question-circle" title="Enter in the percentage number of memory to have in sync before stopping the container. Default: 70."></i>
<i class="far fa-sm fa-question-circle" title="Enter in the percentage number of memory to have in sync before stopping the instance. Default: 70."></i>
</div>
</div>
<div class="row">
<label class="col-4 col-form-label text-right">Incremental Memory Iterations: </label>
<div class="col-6">
<div class="form-group">
<input type="number" class="form-control" name="migration.incremental.memory.iterations">
<input type="number" class="form-control" id="migrationIncrementalMemoryIterations" name="migration.incremental.memory.iterations">
</div>
</div>
<div class="col-1">
<i class="far fa-sm fa-question-circle" title="Enter in the maximum number of transfer operations to go through before stopping the container. Default: 10."></i>
<i class="far fa-sm fa-question-circle" title="Enter in the maximum number of transfer operations to go through before stopping the instance. Default: 10."></i>
</div>
</div>
<div class="row">
<label class="col-4 col-form-label text-right">Stateful: </label>
<div class="col-6">
<div class="form-group">
<select class="form-select" id="migrationStateful" name="migration.stateful">
<option value="">(not set)</option>
<option value="true">true</option>
<option value="false">false</option>
</select>
</div>
</div>
<div class="col-1">
<i class="far fa-sm fa-question-circle" title="Select whether to allow for stateful stop/start and snapshots. This will prevent the use of some features that are incompatible with it. Default: false."></i>
</div>
</div>
</div>
@ -586,18 +630,18 @@
<label class="col-4 col-form-label text-right">Driver Capabilities: </label>
<div class="col-6">
<div class="form-group">
<input type="text" class="form-control" name="nvidia.driver.capabilities">
<input type="text" class="form-control" id="nvidiaDriverCapabilities" name="nvidia.driver.capabilities">
</div>
</div>
<div class="col-1">
<i class="far fa-sm fa-question-circle" title="Enter in what driver capabilities the container needs (sets libnvidia-container NVIDIA_DRIVER_CAPABILITIES). Default: compute,utility."></i>
<i class="far fa-sm fa-question-circle" title="Enter in what driver capabilities the instance needs (sets libnvidia-container NVIDIA_DRIVER_CAPABILITIES). Default: compute,utility."></i>
</div>
</div>
<div class="row">
<label class="col-4 col-form-label text-right">Runtime: </label>
<div class="col-6">
<div class="form-group">
<select class="form-control" name="nvidia.runtime">
<select class="form-select" id="nvidiaRuntime" name="nvidia.runtime">
<option value="">(not set)</option>
<option value="true">true</option>
<option value="false">false</option>
@ -605,14 +649,14 @@
</div>
</div>
<div class="col-1">
<i class="far fa-sm fa-question-circle" title="Select whether to pass the host NVIDIA and CUDA runtime libraries into the container. Default: false."></i>
<i class="far fa-sm fa-question-circle" title="Select whether to pass the host NVIDIA and CUDA runtime libraries into the instance. Default: false."></i>
</div>
</div>
<div class="row">
<label class="col-4 col-form-label text-right">Require Cuda: </label>
<div class="col-6">
<div class="form-group">
<input type="text" class="form-control" name="nvidia.require.cuda">
<input type="text" class="form-control" id="nvidiaRequireCuda" name="nvidia.require.cuda">
</div>
</div>
<div class="col-1">
@ -623,7 +667,7 @@
<label class="col-4 col-form-label text-right">Require Driver: </label>
<div class="col-6">
<div class="form-group">
<input type="text" class="form-control" name="nvidia.require.driver">
<input type="text" class="form-control" id="nvidiaRequireDriver" name="nvidia.require.driver">
</div>
</div>
<div class="col-1">
@ -637,7 +681,7 @@
<label class="col-4 col-form-label text-right">Cluster Evacuate: </label>
<div class="col-6">
<div class="form-group">
<select class="form-control" name="cluster.evacuate">
<select class="form-select" name="cluster.evacuate">
<option value="">(not set)</option>
<option value="auto">auto</option>
<option value="migrate">migrate</option>
@ -646,18 +690,18 @@
</div>
</div>
<div class="col-1">
<i class="far fa-sm fa-question-circle" title='Select what to do when evacuating the container. Default: auto'></i>
<i class="far fa-sm fa-question-circle" title='Select what to do when evacuating the instance. Default: auto'></i>
</div>
</div>
<div class="row">
<label class="col-4 col-form-label text-right">Kernel Modules: </label>
<div class="col-6">
<div class="form-group">
<input type="text" class="form-control" name="linux.kernel_modules">
<input type="text" class="form-control" id="linuxKernel_modules" name="linux.kernel_modules">
</div>
</div>
<div class="col-1">
<i class="far fa-sm fa-question-circle" title="Enter in a comma separated list of kernel modules to load before starting the container. Default (not set)."></i>
<i class="far fa-sm fa-question-circle" title="Enter in a comma separated list of kernel modules to load before starting the instance. Default (not set)."></i>
</div>
</div>
</div>
@ -678,7 +722,7 @@
<label class="col-4 col-form-label text-right">Idmap: </label>
<div class="col-6">
<div class="form-group">
<input type="text" class="form-control" name="raw.idmap">
<input type="text" class="form-control" id="rawIdmap" name="raw.idmap">
</div>
</div>
<div class="col-1">
@ -689,7 +733,7 @@
<label class="col-4 col-form-label text-right">Lxc: </label>
<div class="col-6">
<div class="form-group">
<input type="text" class="form-control" name="raw.lxc">
<input type="text" class="form-control" id="rawLxc" name="raw.lxc">
</div>
</div>
<div class="col-1">
@ -700,21 +744,43 @@
<label class="col-4 col-form-label text-right">Seccomp: </label>
<div class="col-6">
<div class="form-group">
<input type="text" class="form-control" name="raw.seccomp">
<input type="text" class="form-control" id="rawSeccomp" name="raw.seccomp">
</div>
</div>
<div class="col-1">
<i class="far fa-sm fa-question-circle" title="Enter in a raw Seccomp configuration. Default: (not set)."></i>
</div>
</div>
<div class="row">
<label class="col-4 col-form-label text-right">Qemu: </label>
<div class="col-6">
<div class="form-group">
<input type="text" class="form-control" id="rawQemu" name="raw.qemu">
</div>
</div>
<div class="col-1">
<i class="far fa-sm fa-question-circle" title="Enter raw QEMU configuration to be appended to the generated command line. Default: (not set)."></i>
</div>
</div>
<div class="row">
<label class="col-4 col-form-label text-right">Qemu.conf: </label>
<div class="col-6">
<div class="form-group">
<input type="text" class="form-control" id="rawQemuConf" name="raw.qemu.conf">
</div>
</div>
<div class="col-1">
<i class="far fa-sm fa-question-circle" title="Enter in addition/override to the generated qemu.conf file. Default: (not set)."></i>
</div>
</div>
</div>
<div class="tab-pane fade" id="nav-security" role="tabpanel" aria-labelledby="nav-security-tab">
<br>
<div class="row">
<label class="col-4 col-form-label text-right">Devlxd: </label>
<label class="col-4 col-form-label text-right">Agent Metrics: </label>
<div class="col-6">
<div class="form-group">
<select class="form-control" name="security.devlxd">
<select class="form-select" id="securityAgentMetrics" name="security.agent.metrics">
<option value="">(not set)</option>
<option value="true">true</option>
<option value="false">false</option>
@ -722,14 +788,29 @@
</div>
</div>
<div class="col-1">
<i class="far fa-sm fa-question-circle" title="Select whether to control the presence of /dev/lxd in the container. Default: true."></i>
<i class="far fa-sm fa-question-circle" title="Select whether the lxd-agent is queried for state information and metrics. Default: true."></i>
</div>
</div>
<div class="row">
<label class="col-4 col-form-label text-right">Devlxd: </label>
<div class="col-6">
<div class="form-group">
<select class="form-select" id="securityDevlxd" name="security.devlxd">
<option value="">(not set)</option>
<option value="true">true</option>
<option value="false">false</option>
</select>
</div>
</div>
<div class="col-1">
<i class="far fa-sm fa-question-circle" title="Select whether to control the presence of /dev/lxd in the instance. Default: true."></i>
</div>
</div>
<div class="row">
<label class="col-4 col-form-label text-right">Devlxd Images: </label>
<div class="col-6">
<div class="form-group">
<select class="form-control" name="security.devlxd.images">
<select class="form-select" id="securityDevlxdImages" name="security.devlxd.images">
<option value="">(not set)</option>
<option value="true">true</option>
<option value="false">false</option>
@ -744,7 +825,7 @@
<label class="col-4 col-form-label text-right">Idmap Base: </label>
<div class="col-6">
<div class="form-group">
<input type="number" class="form-control" name="security.idmap.base">
<input type="number" class="form-control" id="securityIdmapBase" name="security.idmap.base">
</div>
</div>
<div class="col-1">
@ -755,7 +836,7 @@
<label class="col-4 col-form-label text-right">Idmap Isolated: </label>
<div class="col-6">
<div class="form-group">
<select class="form-control" name="security.idmap.isolated">
<select class="form-select" id="securityIdmapIsolated" name="security.idmap.isolated">
<option value="">(not set)</option>
<option value="true">true</option>
<option value="false">false</option>
@ -763,14 +844,14 @@
</div>
</div>
<div class="col-1">
<i class="far fa-sm fa-question-circle" title="Select whether to use an idmap for the container that is unique amoung containers with isolate enabled. Default: false."></i>
<i class="far fa-sm fa-question-circle" title="Select whether to use an idmap for the instance that is unique amoung instances with isolate enabled. Default: false."></i>
</div>
</div>
<div class="row">
<label class="col-4 col-form-label text-right">Idmap Size: </label>
<div class="col-6">
<div class="form-group">
<input type="number" class="form-control" name="security.idmap.size">
<input type="number" class="form-control" id="securityIdmapSize" name="security.idmap.size">
</div>
</div>
<div class="col-1">
@ -781,7 +862,7 @@
<label class="col-4 col-form-label text-right">Nesting: </label>
<div class="col-6">
<div class="form-group">
<select class="form-control" name="security.nesting">
<select class="form-select" id="securityNesting" name="security.nesting">
<option value="">(not set)</option>
<option value="true">true</option>
<option value="false">false</option>
@ -789,14 +870,14 @@
</div>
</div>
<div class="col-1">
<i class="far fa-sm fa-question-circle" title="Select whether to support running LXD inside the container. Default: false."></i>
<i class="far fa-sm fa-question-circle" title="Select whether to support running LXD inside the instance. Default: false."></i>
</div>
</div>
<div class="row">
<label class="col-4 col-form-label text-right">Privileged: </label>
<div class="col-6">
<div class="form-group">
<select class="form-control" name="security.privileged">
<select class="form-select" id="securityPrivileged" name="security.privileged">
<option value="">(not set)</option>
<option value="true">true</option>
<option value="false">false</option>
@ -804,14 +885,14 @@
</div>
</div>
<div class="col-1">
<i class="far fa-sm fa-question-circle" title="Select whether to run the container in privileged mode. Default: false."></i>
<i class="far fa-sm fa-question-circle" title="Select whether to run the instance in privileged mode. Default: false."></i>
</div>
</div>
<div class="row">
<label class="col-4 col-form-label text-right">Protection Delete: </label>
<div class="col-6">
<div class="form-group">
<select class="form-control" name="security.protection.delete">
<select class="form-select" id="securityProtectionDelete" name="security.protection.delete">
<option value="">(not set)</option>
<option value="true">true</option>
<option value="false">false</option>
@ -819,14 +900,14 @@
</div>
</div>
<div class="col-1">
<i class="far fa-sm fa-question-circle" title="Select whether to prevent the container from being deleted. Default: false."></i>
<i class="far fa-sm fa-question-circle" title="Select whether to prevent the instance from being deleted. Default: false."></i>
</div>
</div>
<div class="row">
<label class="col-4 col-form-label text-right">Protection Shift: </label>
<div class="col-6">
<div class="form-group">
<select class="form-control" name="security.protection.shift">
<select class="form-select" id="securityProtectionShift" name="security.protection.shift">
<option value="">(not set)</option>
<option value="true">true</option>
<option value="false">false</option>
@ -834,14 +915,29 @@
</div>
</div>
<div class="col-1">
<i class="far fa-sm fa-question-circle" title="Select whether to prevent the container filesystem from being uid/gid shifted on startup. Default: false."></i>
<i class="far fa-sm fa-question-circle" title="Select whether to prevent the instance filesystem from being uid/gid shifted on startup. Default: false."></i>
</div>
</div>
<div class="row">
<label class="col-4 col-form-label text-right">Secureboot: </label>
<div class="col-6">
<div class="form-group">
<select class="form-select" id="securitySecureboot" name="security.secureboot">
<option value="">(not set)</option>
<option value="true">true</option>
<option value="false">false</option>
</select>
</div>
</div>
<div class="col-1">
<i class="far fa-sm fa-question-circle" title="Select whether whether UEFI secure boot is enabled with the default Microsoft keys. Default: true."></i>
</div>
</div>
<div class="row">
<label class="col-4 col-form-label text-right">Syscalls Allow: </label>
<div class="col-6">
<div class="form-group">
<input type="text" class="form-control" name="security.syscalls.allow">
<input type="text" class="form-control" id="securitySyscallsAllow" name="security.syscalls.allow">
</div>
</div>
<div class="col-1">
@ -852,7 +948,7 @@
<label class="col-4 col-form-label text-right">Syscalls Deny: </label>
<div class="col-6">
<div class="form-group">
<input type="text" class="form-control" name="security.syscalls.deny">
<input type="text" class="form-control" id="securitySyscallsDeny" name="security.syscalls.deny">
</div>
</div>
<div class="col-1">
@ -863,7 +959,7 @@
<label class="col-4 col-form-label text-right">Syscalls Deny Compat: </label>
<div class="col-6">
<div class="form-group">
<select class="form-control" name="security.syscalls.deny_compat">
<select class="form-select" id="securitySyscallsDeny_compat" name="security.syscalls.deny_compat">
<option value="">(not set)</option>
<option value="true">true</option>
<option value="false">false</option>
@ -878,7 +974,7 @@
<label class="col-4 col-form-label text-right">Syscalls Deny Default: </label>
<div class="col-6">
<div class="form-group">
<select class="form-control" name="security.syscalls.deny_default">
<select class="form-select" id="securitySyscallsDeny_default" name="security.syscalls.deny_default">
<option value="">(not set)</option>
<option value="true">true</option>
<option value="false">false</option>
@ -893,7 +989,7 @@
<label class="col-4 col-form-label text-right">Syscalls Intercept Bpf: </label>
<div class="col-6">
<div class="form-group">
<select class="form-control" name="security.syscalls.intercept.bpf">
<select class="form-select" id="securitySyscallsInterceptBpf" name="security.syscalls.intercept.bpf">
<option value="">(not set)</option>
<option value="true">true</option>
<option value="false">false</option>
@ -908,7 +1004,7 @@
<label class="col-4 col-form-label text-right">Syscalls Intercept Bpf Devices: </label>
<div class="col-6">
<div class="form-group">
<select class="form-control" name="security.syscalls.intercept.bpf.devices">
<select class="form-select" id="securitySyscallsInterceptBpfDevices" name="security.syscalls.intercept.bpf.devices">
<option value="">(not set)</option>
<option value="true">true</option>
<option value="false">false</option>
@ -923,7 +1019,7 @@
<label class="col-4 col-form-label text-right">Syscalls Intercept Mknod: </label>
<div class="col-6">
<div class="form-group">
<select class="form-control" name="security.syscalls.intercept.mknod">
<select class="form-select" id="securitySyscallsInterceptMknod" name="security.syscalls.intercept.mknod">
<option value="">(not set)</option>
<option value="true">true</option>
<option value="false">false</option>
@ -938,7 +1034,7 @@
<label class="col-4 col-form-label text-right">Syscalls Intercept Mount: </label>
<div class="col-6">
<div class="form-group">
<select class="form-control" name="security.syscalls.intercept.mount">
<select class="form-select" id="securitySyscallsInterceptMount" name="security.syscalls.intercept.mount">
<option value="">(not set)</option>
<option value="true">true</option>
<option value="false">false</option>
@ -953,18 +1049,18 @@
<label class="col-4 col-form-label text-right">Syscalls Intercept Mount Allowed: </label>
<div class="col-6">
<div class="form-group">
<input type="text" class="form-control" name="security.syscalls.intercept.mount.allowed">
<input type="text" class="form-control" id="securitySyscallsInterceptMountAllowed" name="security.syscalls.intercept.mount.allowed">
</div>
</div>
<div class="col-1">
<i class="far fa-sm fa-question-circle" title="Enter in a comma-separated list of filesystems that are safe to mount for processes within the container. Default: (not set)."></i>
<i class="far fa-sm fa-question-circle" title="Enter in a comma-separated list of filesystems that are safe to mount for processes within the instance. Default: (not set)."></i>
</div>
</div>
<div class="row">
<label class="col-4 col-form-label text-right">Syscalls Intercept Mount Fuse: </label>
<div class="col-6">
<div class="form-group">
<input type="text" class="form-control" name="security.syscalls.intercept.mount.fuse">
<input type="text" class="form-control" id="securitySyscallsInterceptMountFuse" name="security.syscalls.intercept.mount.fuse">
</div>
</div>
<div class="col-1">
@ -975,7 +1071,7 @@
<label class="col-4 col-form-label text-right">Syscalls Intercept Mount Shift: </label>
<div class="col-6">
<div class="form-group">
<select class="form-control" name="security.syscalls.intercept.mount.shift">
<select class="form-select" id="securitySyscallsInterceptMountShift" name="security.syscalls.intercept.mount.shift">
<option value="">(not set)</option>
<option value="true">true</option>
<option value="false">false</option>
@ -990,7 +1086,7 @@
<label class="col-4 col-form-label text-right">Syscalls Intercept Setxattr: </label>
<div class="col-6">
<div class="form-group">
<select class="form-control" name="security.syscalls.intercept.setxattr">
<select class="form-select" id="securitySyscallsInterceptSetxattr" name="security.syscalls.intercept.setxattr">
<option value="">(not set)</option>
<option value="true">true</option>
<option value="false">false</option>
@ -1019,7 +1115,7 @@
<label class="col-4 col-form-label text-right">Schedule Stopped: </label>
<div class="col-6">
<div class="form-group">
<select class="form-control" name="snapshots.schedule.stopped">
<select class="form-select" name="snapshots.schedule.stopped">
<option value="">(not set)</option>
<option value="true">true</option>
<option value="false">false</option>
@ -1027,7 +1123,7 @@
</div>
</div>
<div class="col-1">
<i class="far fa-sm fa-question-circle" title="Select whether stopped containers are to be snapshoted automatically. Default: false."></i>
<i class="far fa-sm fa-question-circle" title="Select whether stopped instances are to be snapshoted automatically. Default: false."></i>
</div>
</div>
<div class="row">
@ -1058,8 +1154,8 @@
</form>
<div class="modal-footer">
<button class="btn btn-secondary" type="button" data-dismiss="modal">Cancel</button>
<a class="btn btn-primary" href="#" onclick="addItem()" data-dismiss="modal">Submit</a>
<button class="btn btn-secondary" type="button" data-bs-dismiss="modal">Cancel</button>
<a class="btn btn-primary" href="#" onclick="addItem()" data-bs-dismiss="modal">Submit</a>
</div>
</div>
<div class="tab-pane fade" id="json" role="tabpanel" aria-labelledby="json-tab">
@ -1074,8 +1170,8 @@
</div>
</div>
<div class="modal-footer">
<button class="btn btn-secondary" type="button" data-dismiss="modal">Cancel</button>
<a class="btn btn-primary" href="#" onclick="createItemUsingJSON()" data-dismiss="modal">Submit</a>
<button class="btn btn-secondary" type="button" data-bs-dismiss="modal">Cancel</button>
<a class="btn btn-primary" href="#" onclick="createItemUsingJSON()" data-bs-dismiss="modal">Submit</a>
</div>
</div>
</div>

View file

@ -4,7 +4,7 @@
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title" id="exampleModalLabel">About lxconsole</h5>
<button class="close" type="button" data-dismiss="modal" aria-label="Close">
<button class="close" type="button" data-bs-dismiss="modal" aria-label="Close">
<span aria-hidden="true">×</span>
</button>
</div>
@ -13,7 +13,7 @@
<div class="col-12">
<p>Lxconsole is an open source management console providing a web-based user interface capable of managing multiple LXD servers from a single location.</p>
<p>
<strong>Version</strong>: <span id="versionNumber">v0.3.0</span> <br />
<strong>Version</strong>: <span id="versionNumber">v0.4.0</span> <br />
<strong>License</strong>: AGPL-3.0 <br />
<strong>URL</strong>: https://lxconsole.com <br />
</p>
@ -21,7 +21,7 @@
</div>
</div>
<div class="modal-footer">
<button class="btn btn-secondary" type="button" data-dismiss="modal">Dismiss</button>
<button class="btn btn-secondary" type="button" data-bs-dismiss="modal">Dismiss</button>
</div>
</div>
</div>
@ -33,7 +33,7 @@
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title" id="exampleModalLabel">User Account</h5>
<button class="close" type="button" data-dismiss="modal" aria-label="Close">
<button class="close" type="button" data-bs-dismiss="modal" aria-label="Close">
<span aria-hidden="true">×</span>
</button>
</div>
@ -103,8 +103,8 @@
</div>
<div class="modal-footer">
<button class="btn btn-secondary" type="button" data-dismiss="modal">Dismiss</button>
<a class="btn btn-primary" href="#" onclick="updateAccount()" data-dismiss="modal">Update</a>
<button class="btn btn-secondary" type="button" data-bs-dismiss="modal">Dismiss</button>
<a class="btn btn-primary" href="#" onclick="updateAccount()" data-bs-dismiss="modal">Update</a>
</div>
</div>
</div>

View file

@ -4,17 +4,17 @@
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title" id="exampleModalLabel">Add Network ACL Rule</h5>
<button class="close" type="button" data-dismiss="modal" aria-label="Close">
<button class="close" type="button" data-bs-dismiss="modal" aria-label="Close">
<span aria-hidden="true">×</span>
</button>
</div>
<div class="modal-body">
<ul class="nav nav-tabs" id="myTab" role="tablist">
<li class="nav-item">
<a class="nav-link active" id="form-tab" data-toggle="tab" href="#form" role="tab" aria-controls="form" aria-selected="true">Form</a>
<a class="nav-link active" id="form-tab" data-bs-toggle="tab" href="#form" role="tab" aria-controls="form" aria-selected="true">Form</a>
</li>
<li class="nav-item">
<a class="nav-link" id="json-tab" data-toggle="tab" href="#json" role="tab" aria-controls="json" aria-selected="false">JSON</a>
<a class="nav-link" id="json-tab" data-bs-toggle="tab" href="#json" role="tab" aria-controls="json" aria-selected="false">JSON</a>
</li>
</ul>
<div class="tab-content" id="myTabContent">
@ -25,7 +25,7 @@
<label class="col-3 col-form-label text-right">Type: <span class="text-danger">*</span></label>
<div class="col-7">
<div class="form-group">
<select onchange="" class="form-control" name="type">
<select onchange="" class="form-select" name="type">
<option value="ingress">ingress</option>
<option value="egress">egress</option>
</select>
@ -39,7 +39,7 @@
<label class="col-3 col-form-label text-right">Action: <span class="text-danger">*</span></label>
<div class="col-7">
<div class="form-group">
<select onchange="" class="form-control" name="action">
<select onchange="" class="form-select" name="action">
<option value="allow">allow</option>
<option value="reject">reject</option>
<option value="drop">drop</option>
@ -54,7 +54,7 @@
<label class="col-3 col-form-label text-right">State: <span class="text-danger">*</span></label>
<div class="col-7">
<div class="form-group">
<select onchange="" class="form-control" name="state">
<select onchange="" class="form-select" name="state">
<option value="enabled">enabled</option>
<option value="disabled">disabled</option>
<option value="logged">logged</option>
@ -102,7 +102,7 @@
<label class="col-3 col-form-label text-right">Protocol: </label>
<div class="col-7">
<div class="form-group">
<select onchange="" class="form-control" name="protocol">
<select onchange="" class="form-select" name="protocol">
<option value="">(not set)</option>
<option value="icmp4">icmp4</option>
<option value="icmp6">icmp6</option>
@ -161,8 +161,8 @@
</div>
</form>
<div class="modal-footer">
<button class="btn btn-secondary" type="button" data-dismiss="modal">Cancel</button>
<a class="btn btn-primary" href="#" onclick="addItem()" data-dismiss="modal">Submit</a>
<button class="btn btn-secondary" type="button" data-bs-dismiss="modal">Cancel</button>
<a class="btn btn-primary" href="#" onclick="addItem()" data-bs-dismiss="modal">Submit</a>
</div>
</div>
<div class="tab-pane fade" id="json" role="tabpanel" aria-labelledby="json-tab">
@ -177,8 +177,8 @@
</div>
</div>
<div class="modal-footer">
<button class="btn btn-secondary" type="button" data-dismiss="modal">Cancel</button>
<a class="btn btn-primary" href="#" onclick="createItemUsingJSON()" data-dismiss="modal">Submit</a>
<button class="btn btn-secondary" type="button" data-bs-dismiss="modal">Cancel</button>
<a class="btn btn-primary" href="#" onclick="createItemUsingJSON()" data-bs-dismiss="modal">Submit</a>
</div>
</div>
</div>

View file

@ -4,17 +4,17 @@
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title" id="exampleModalLabel">Add Network ACL</h5>
<button class="close" type="button" data-dismiss="modal" aria-label="Close">
<button class="close" type="button" data-bs-dismiss="modal" aria-label="Close">
<span aria-hidden="true">×</span>
</button>
</div>
<div class="modal-body">
<ul class="nav nav-tabs" id="myTab" role="tablist">
<li class="nav-item">
<a class="nav-link active" id="form-tab" data-toggle="tab" href="#form" role="tab" aria-controls="form" aria-selected="true">Form</a>
<a class="nav-link active" id="form-tab" data-bs-toggle="tab" href="#form" role="tab" aria-controls="form" aria-selected="true">Form</a>
</li>
<li class="nav-item">
<a class="nav-link" id="json-tab" data-toggle="tab" href="#json" role="tab" aria-controls="json" aria-selected="false">JSON</a>
<a class="nav-link" id="json-tab" data-bs-toggle="tab" href="#json" role="tab" aria-controls="json" aria-selected="false">JSON</a>
</li>
</ul>
<div class="tab-content" id="myTabContent">
@ -46,8 +46,8 @@
<p class="text-center pt-2">Egress and Ingress rules can be defined once the Network ACL is created.</p>
</form>
<div class="modal-footer">
<button class="btn btn-secondary" type="button" data-dismiss="modal">Cancel</button>
<a class="btn btn-primary" href="#" onclick="addItem()" data-dismiss="modal">Submit</a>
<button class="btn btn-secondary" type="button" data-bs-dismiss="modal">Cancel</button>
<a class="btn btn-primary" href="#" onclick="addItem()" data-bs-dismiss="modal">Submit</a>
</div>
</div>
<div class="tab-pane fade" id="json" role="tabpanel" aria-labelledby="json-tab">
@ -62,8 +62,8 @@
</div>
</div>
<div class="modal-footer">
<button class="btn btn-secondary" type="button" data-dismiss="modal">Cancel</button>
<a class="btn btn-primary" href="#" onclick="createItemUsingJSON()" data-dismiss="modal">Submit</a>
<button class="btn btn-secondary" type="button" data-bs-dismiss="modal">Cancel</button>
<a class="btn btn-primary" href="#" onclick="createItemUsingJSON()" data-bs-dismiss="modal">Submit</a>
</div>
</div>
</div>
@ -78,7 +78,7 @@
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title" id="exampleModalLabel">Edit Network ACL</h5>
<button class="close" type="button" data-dismiss="modal" aria-label="Close">
<button class="close" type="button" data-bs-dismiss="modal" aria-label="Close">
<span aria-hidden="true">×</span>
</button>
</div>
@ -95,8 +95,8 @@
</div>
</div>
<div class="modal-footer">
<button class="btn btn-secondary" type="button" data-dismiss="modal">Cancel</button>
<a class="btn btn-primary" href="#" onclick="updateItem()" data-dismiss="modal">Submit</a>
<button class="btn btn-secondary" type="button" data-bs-dismiss="modal">Cancel</button>
<a class="btn btn-primary" href="#" onclick="updateItem()" data-bs-dismiss="modal">Submit</a>
</div>
</div>
</div>
@ -108,7 +108,7 @@
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title" id="renameItemModalLabel">Rename Network ACL</h5>
<button class="close" type="button" data-dismiss="modal" aria-label="Close">
<button class="close" type="button" data-bs-dismiss="modal" aria-label="Close">
<span aria-hidden="true">×</span>
</button>
</div>
@ -127,8 +127,8 @@
<input type="hidden" id ="networkACLToRename">
</div>
<div class="modal-footer">
<button class="btn btn-secondary" type="button" data-dismiss="modal">Cancel</button>
<a class="btn btn-primary" href="#" onclick="updateItemName()" data-dismiss="modal">Ok</a>
<button class="btn btn-secondary" type="button" data-bs-dismiss="modal">Cancel</button>
<a class="btn btn-primary" href="#" onclick="updateItemName()" data-bs-dismiss="modal">Ok</a>
</div>
</div>
</div>

View file

@ -4,17 +4,17 @@
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title" id="exampleModalLabel">Add Network Zone</h5>
<button class="close" type="button" data-dismiss="modal" aria-label="Close">
<button class="close" type="button" data-bs-dismiss="modal" aria-label="Close">
<span aria-hidden="true">×</span>
</button>
</div>
<div class="modal-body">
<ul class="nav nav-tabs" id="myTab" role="tablist">
<li class="nav-item">
<a class="nav-link active" id="form-tab" data-toggle="tab" href="#form" role="tab" aria-controls="form" aria-selected="true">Form</a>
<a class="nav-link active" id="form-tab" data-bs-toggle="tab" href="#form" role="tab" aria-controls="form" aria-selected="true">Form</a>
</li>
<li class="nav-item">
<a class="nav-link" id="json-tab" data-toggle="tab" href="#json" role="tab" aria-controls="json" aria-selected="false">JSON</a>
<a class="nav-link" id="json-tab" data-bs-toggle="tab" href="#json" role="tab" aria-controls="json" aria-selected="false">JSON</a>
</li>
</ul>
<div class="tab-content" id="myTabContent">
@ -46,8 +46,8 @@
</form>
<div class="modal-footer">
<button class="btn btn-secondary" type="button" data-dismiss="modal">Cancel</button>
<a class="btn btn-primary" href="#" onclick="addItem()" data-dismiss="modal">Submit</a>
<button class="btn btn-secondary" type="button" data-bs-dismiss="modal">Cancel</button>
<a class="btn btn-primary" href="#" onclick="addItem()" data-bs-dismiss="modal">Submit</a>
</div>
</div>
<div class="tab-pane fade" id="json" role="tabpanel" aria-labelledby="json-tab">
@ -62,8 +62,8 @@
</div>
</div>
<div class="modal-footer">
<button class="btn btn-secondary" type="button" data-dismiss="modal">Cancel</button>
<a class="btn btn-primary" href="#" onclick="createItemUsingJSON()" data-dismiss="modal">Submit</a>
<button class="btn btn-secondary" type="button" data-bs-dismiss="modal">Cancel</button>
<a class="btn btn-primary" href="#" onclick="createItemUsingJSON()" data-bs-dismiss="modal">Submit</a>
</div>
</div>
</div>
@ -78,17 +78,17 @@
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title" id="exampleModalLabel">Edit Network Zone</h5>
<button class="close" type="button" data-dismiss="modal" aria-label="Close">
<button class="close" type="button" data-bs-dismiss="modal" aria-label="Close">
<span aria-hidden="true">×</span>
</button>
</div>
<div class="modal-body">
<ul class="nav nav-tabs" id="myTab" role="tablist">
<li class="nav-item">
<a class="nav-link active" id="json-edit-tab" data-toggle="tab" href="#json-edit" role="tab" aria-controls="json-edit" aria-selected="false">JSON</a>
<a class="nav-link active" id="json-edit-tab" data-bs-toggle="tab" href="#json-edit" role="tab" aria-controls="json-edit" aria-selected="false">JSON</a>
</li>
<!-- <li class="nav-item">
<a class="nav-link" id="rename-edit-tab" data-toggle="tab" href="#rename-edit" role="tab" aria-controls="rename-edit" aria-selected="true">Rename</a>
<a class="nav-link" id="rename-edit-tab" data-bs-toggle="tab" href="#rename-edit" role="tab" aria-controls="rename-edit" aria-selected="true">Rename</a>
</li> -->
</ul>
<div class="tab-content" id="myTabContent">
@ -105,8 +105,8 @@
</div>
</div>
<div class="modal-footer">
<button class="btn btn-secondary" type="button" data-dismiss="modal">Cancel</button>
<a class="btn btn-primary" href="#" onclick="updateItem()" data-dismiss="modal">Submit</a>
<button class="btn btn-secondary" type="button" data-bs-dismiss="modal">Cancel</button>
<a class="btn btn-primary" href="#" onclick="updateItem()" data-bs-dismiss="modal">Submit</a>
</div>
</div>
<div class="tab-pane fade" id="rename-edit" role="tabpanel" aria-labelledby="rename-edit-tab">
@ -125,8 +125,8 @@
</div>
</form>
<div class="modal-footer">
<button class="btn btn-secondary" type="button" data-dismiss="modal">Cancel</button>
<a class="btn btn-primary" href="#" onclick="renameItem()" data-dismiss="modal">Submit</a>
<button class="btn btn-secondary" type="button" data-bs-dismiss="modal">Cancel</button>
<a class="btn btn-primary" href="#" onclick="renameItem()" data-bs-dismiss="modal">Submit</a>
</div>
</div>
</div>
@ -141,7 +141,7 @@
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title" id="exampleModalLabel">Delete Network Zone</h5>
<button class="close" type="button" data-dismiss="modal" aria-label="Close">
<button class="close" type="button" data-bs-dismiss="modal" aria-label="Close">
<span aria-hidden="true">×</span>
</button>
</div>
@ -152,8 +152,8 @@
<input type="hidden" id="networkZone" class="form-control" name="server_name">
</div>
<div class="modal-footer">
<button class="btn btn-secondary" type="button" data-dismiss="modal">Cancel</button>
<a class="btn btn-primary" href="#" onclick="deleteItem()" data-dismiss="modal">Yes</a>
<button class="btn btn-secondary" type="button" data-bs-dismiss="modal">Cancel</button>
<a class="btn btn-primary" href="#" onclick="deleteItem()" data-bs-dismiss="modal">Yes</a>
</div>
</div>
</div>

View file

@ -4,17 +4,17 @@
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title" id="exampleModalLabel">Add Network Forward</h5>
<button class="close" type="button" data-dismiss="modal" aria-label="Close">
<button class="close" type="button" data-bs-dismiss="modal" aria-label="Close">
<span aria-hidden="true">×</span>
</button>
</div>
<div class="modal-body">
<ul class="nav nav-tabs" id="myTab" role="tablist">
<li class="nav-item">
<a class="nav-link active" id="add-forward-form-tab" data-toggle="tab" href="#addForwardform" role="tab" aria-controls="add-forward-form-tab" aria-selected="true">Form</a>
<a class="nav-link active" id="add-forward-form-tab" data-bs-toggle="tab" href="#addForwardform" role="tab" aria-controls="add-forward-form-tab" aria-selected="true">Form</a>
</li>
<li class="nav-item">
<a class="nav-link" id="add-forward-json-tab" data-toggle="tab" href="#addForwardJson" role="tab" aria-controls="add-forward-json-tab" aria-selected="false">JSON</a>
<a class="nav-link" id="add-forward-json-tab" data-bs-toggle="tab" href="#addForwardJson" role="tab" aria-controls="add-forward-json-tab" aria-selected="false">JSON</a>
</li>
</ul>
<div class="tab-content" id="myTabContent">
@ -73,7 +73,7 @@
<label class="col-3 col-form-label text-right">Protocol: </label>
<div class="col-7">
<div class="form-group">
<select class="form-control" name="port_protocol">
<select class="form-select" name="port_protocol">
<option value="tcp">TCP</option>
<option value="udp">UDP</option>
</select>
@ -111,8 +111,8 @@
</form>
<div class="modal-footer">
<button class="btn btn-secondary" type="button" data-dismiss="modal">Cancel</button>
<a class="btn btn-primary" href="#" onclick="addItem('forward')" data-dismiss="modal">Submit</a>
<button class="btn btn-secondary" type="button" data-bs-dismiss="modal">Cancel</button>
<a class="btn btn-primary" href="#" onclick="addItem('forward')" data-bs-dismiss="modal">Submit</a>
</div>
</div>
<div class="tab-pane fade" id="addForwardJson" role="tabpanel" aria-labelledby="json-tab">
@ -127,8 +127,8 @@
</div>
</div>
<div class="modal-footer">
<button class="btn btn-secondary" type="button" data-dismiss="modal">Cancel</button>
<a class="btn btn-primary" href="#" onclick="createItemUsingJSON('forward')" data-dismiss="modal">Submit</a>
<button class="btn btn-secondary" type="button" data-bs-dismiss="modal">Cancel</button>
<a class="btn btn-primary" href="#" onclick="createItemUsingJSON('forward')" data-bs-dismiss="modal">Submit</a>
</div>
</div>
</div>
@ -143,17 +143,17 @@
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title" id="exampleModalLabel">Add Network Load Balancer</h5>
<button class="close" type="button" data-dismiss="modal" aria-label="Close">
<button class="close" type="button" data-bs-dismiss="modal" aria-label="Close">
<span aria-hidden="true">×</span>
</button>
</div>
<div class="modal-body">
<ul class="nav nav-tabs" id="myTab" role="tablist">
<li class="nav-item">
<a class="nav-link active" id="form-tab" data-toggle="tab" href="#form" role="tab" aria-controls="form" aria-selected="true">Form</a>
<a class="nav-link active" id="form-tab" data-bs-toggle="tab" href="#form" role="tab" aria-controls="form" aria-selected="true">Form</a>
</li>
<li class="nav-item">
<a class="nav-link" id="json-tab" data-toggle="tab" href="#json" role="tab" aria-controls="json" aria-selected="false">JSON</a>
<a class="nav-link" id="json-tab" data-bs-toggle="tab" href="#json" role="tab" aria-controls="json" aria-selected="false">JSON</a>
</li>
</ul>
<div class="tab-content" id="myTabContent">
@ -263,7 +263,7 @@
<label class="col-3 col-form-label text-right">Protocol: </label>
<div class="col-7">
<div class="form-group">
<select class="form-control" name="port_protocol">
<select class="form-select" name="port_protocol">
<option value="tcp">TCP</option>
<option value="udp">UDP</option>
</select>
@ -288,8 +288,8 @@
</form>
<div class="modal-footer">
<button class="btn btn-secondary" type="button" data-dismiss="modal">Cancel</button>
<a class="btn btn-primary" href="#" onclick="addItem('load_balancer')" data-dismiss="modal">Submit</a>
<button class="btn btn-secondary" type="button" data-bs-dismiss="modal">Cancel</button>
<a class="btn btn-primary" href="#" onclick="addItem('load_balancer')" data-bs-dismiss="modal">Submit</a>
</div>
</div>
<div class="tab-pane fade" id="json" role="tabpanel" aria-labelledby="json-tab">
@ -304,8 +304,8 @@
</div>
</div>
<div class="modal-footer">
<button class="btn btn-secondary" type="button" data-dismiss="modal">Cancel</button>
<a class="btn btn-primary" href="#" onclick="createItemUsingJSON('load_balancer')" data-dismiss="modal">Submit</a>
<button class="btn btn-secondary" type="button" data-bs-dismiss="modal">Cancel</button>
<a class="btn btn-primary" href="#" onclick="createItemUsingJSON('load_balancer')" data-bs-dismiss="modal">Submit</a>
</div>
</div>
</div>
@ -320,17 +320,17 @@
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title" id="exampleModalLabel">Add Network Peer</h5>
<button class="close" type="button" data-dismiss="modal" aria-label="Close">
<button class="close" type="button" data-bs-dismiss="modal" aria-label="Close">
<span aria-hidden="true">×</span>
</button>
</div>
<div class="modal-body">
<ul class="nav nav-tabs" id="myTab" role="tablist">
<li class="nav-item">
<a class="nav-link active" id="add-peer-form-tab" data-toggle="tab" href="#addPeerform" role="tab" aria-controls="add-peer-form-tab" aria-selected="true">Form</a>
<a class="nav-link active" id="add-peer-form-tab" data-bs-toggle="tab" href="#addPeerform" role="tab" aria-controls="add-peer-form-tab" aria-selected="true">Form</a>
</li>
<li class="nav-item">
<a class="nav-link" id="add-peer-json-tab" data-toggle="tab" href="#addPeerJson" role="tab" aria-controls="add-peer-json-tab" aria-selected="false">JSON</a>
<a class="nav-link" id="add-peer-json-tab" data-bs-toggle="tab" href="#addPeerJson" role="tab" aria-controls="add-peer-json-tab" aria-selected="false">JSON</a>
</li>
</ul>
<div class="tab-content" id="myTabContent">
@ -384,8 +384,8 @@
</form>
<div class="modal-footer">
<button class="btn btn-secondary" type="button" data-dismiss="modal">Cancel</button>
<a class="btn btn-primary" href="#" onclick="addItem('peer')" data-dismiss="modal">Submit</a>
<button class="btn btn-secondary" type="button" data-bs-dismiss="modal">Cancel</button>
<a class="btn btn-primary" href="#" onclick="addItem('peer')" data-bs-dismiss="modal">Submit</a>
</div>
</div>
<div class="tab-pane fade" id="addPeerJson" role="tabpanel" aria-labelledby="json-tab">
@ -400,8 +400,8 @@
</div>
</div>
<div class="modal-footer">
<button class="btn btn-secondary" type="button" data-dismiss="modal">Cancel</button>
<a class="btn btn-primary" href="#" onclick="createItemUsingJSON('peer')" data-dismiss="modal">Submit</a>
<button class="btn btn-secondary" type="button" data-bs-dismiss="modal">Cancel</button>
<a class="btn btn-primary" href="#" onclick="createItemUsingJSON('peer')" data-bs-dismiss="modal">Submit</a>
</div>
</div>
</div>
@ -417,14 +417,14 @@
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title" id="exampleModalLabel">Edit Network Forward</h5>
<button class="close" type="button" data-dismiss="modal" aria-label="Close">
<button class="close" type="button" data-bs-dismiss="modal" aria-label="Close">
<span aria-hidden="true">×</span>
</button>
</div>
<div class="modal-body">
<ul class="nav nav-tabs" id="myTab" role="tablist">
<li class="nav-item">
<a class="nav-link active" id="json-edit-tab" data-toggle="tab" href="#json-edit" role="tab" aria-controls="json-edit" aria-selected="false">JSON</a>
<a class="nav-link active" id="json-edit-tab" data-bs-toggle="tab" href="#json-edit" role="tab" aria-controls="json-edit" aria-selected="false">JSON</a>
</li>
</ul>
<div class="tab-content" id="myTabContent">
@ -442,8 +442,8 @@
</div>
</div>
<div class="modal-footer">
<button class="btn btn-secondary" type="button" data-dismiss="modal">Cancel</button>
<a class="btn btn-primary" href="#" onclick="updateForward()" data-dismiss="modal">Submit</a>
<button class="btn btn-secondary" type="button" data-bs-dismiss="modal">Cancel</button>
<a class="btn btn-primary" href="#" onclick="updateForward()" data-bs-dismiss="modal">Submit</a>
</div>
</div>
</div>
@ -458,14 +458,14 @@
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title" id="exampleModalLabel">Edit Network Load Balancer</h5>
<button class="close" type="button" data-dismiss="modal" aria-label="Close">
<button class="close" type="button" data-bs-dismiss="modal" aria-label="Close">
<span aria-hidden="true">×</span>
</button>
</div>
<div class="modal-body">
<ul class="nav nav-tabs" id="myTab" role="tablist">
<li class="nav-item">
<a class="nav-link active" id="json-edit-tab" data-toggle="tab" href="#json-edit" role="tab" aria-controls="json-edit" aria-selected="false">JSON</a>
<a class="nav-link active" id="json-edit-tab" data-bs-toggle="tab" href="#json-edit" role="tab" aria-controls="json-edit" aria-selected="false">JSON</a>
</li>
</ul>
<div class="tab-content" id="myTabContent">
@ -483,8 +483,8 @@
</div>
</div>
<div class="modal-footer">
<button class="btn btn-secondary" type="button" data-dismiss="modal">Cancel</button>
<a class="btn btn-primary" href="#" onclick="updateLoadBalancer()" data-dismiss="modal">Submit</a>
<button class="btn btn-secondary" type="button" data-bs-dismiss="modal">Cancel</button>
<a class="btn btn-primary" href="#" onclick="updateLoadBalancer()" data-bs-dismiss="modal">Submit</a>
</div>
</div>
</div>
@ -499,14 +499,14 @@
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title" id="exampleModalLabel">Edit Network Peer</h5>
<button class="close" type="button" data-dismiss="modal" aria-label="Close">
<button class="close" type="button" data-bs-dismiss="modal" aria-label="Close">
<span aria-hidden="true">×</span>
</button>
</div>
<div class="modal-body">
<ul class="nav nav-tabs" id="myTab" role="tablist">
<li class="nav-item">
<a class="nav-link active" id="json-edit-tab" data-toggle="tab" href="#json-edit" role="tab" aria-controls="json-edit" aria-selected="false">JSON</a>
<a class="nav-link active" id="json-edit-tab" data-bs-toggle="tab" href="#json-edit" role="tab" aria-controls="json-edit" aria-selected="false">JSON</a>
</li>
</ul>
<div class="tab-content" id="myTabContent">
@ -524,8 +524,8 @@
</div>
</div>
<div class="modal-footer">
<button class="btn btn-secondary" type="button" data-dismiss="modal">Cancel</button>
<a class="btn btn-primary" href="#" onclick="updatePeer()" data-dismiss="modal">Submit</a>
<button class="btn btn-secondary" type="button" data-bs-dismiss="modal">Cancel</button>
<a class="btn btn-primary" href="#" onclick="updatePeer()" data-bs-dismiss="modal">Submit</a>
</div>
</div>
</div>

View file

@ -4,17 +4,17 @@
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title" id="exampleModalLabel">Create Network</h5>
<button class="close" type="button" data-dismiss="modal" aria-label="Close">
<button class="close" type="button" data-bs-dismiss="modal" aria-label="Close">
<span aria-hidden="true">×</span>
</button>
</div>
<div class="modal-body">
<ul class="nav nav-tabs" id="myTab" role="tablist">
<li class="nav-item">
<a class="nav-link active" id="form-tab" data-toggle="tab" href="#form" role="tab" aria-controls="form" aria-selected="true">Form</a>
<a class="nav-link active" id="form-tab" data-bs-toggle="tab" href="#form" role="tab" aria-controls="form" aria-selected="true">Form</a>
</li>
<li class="nav-item">
<a class="nav-link" id="json-tab" data-toggle="tab" href="#json" role="tab" aria-controls="json" aria-selected="false">JSON</a>
<a class="nav-link" id="json-tab" data-bs-toggle="tab" href="#json" role="tab" aria-controls="json" aria-selected="false">JSON</a>
</li>
</ul>
<div class="tab-content" id="myTabContent">
@ -36,7 +36,7 @@
<label class="col-3 col-form-label text-right">Network Type: <span class="text-danger">*</span></label>
<div class="col-7">
<div class="form-group">
<select id="networkTypeInput" onchange="changeNetworkTypeInput()" class="form-control" name="type">
<select id="networkTypeInput" onchange="changeNetworkTypeInput()" class="form-select" name="type">
<option value="bridge">bridge</option>
<option value="macvlan">macvlan</option>
<option value="ovn">ovn</option>
@ -53,7 +53,7 @@
<label class="col-3 col-form-label text-right">Parent: <span class="text-danger">*</span></label>
<div class="col-7">
<div class="form-group">
<select id="networkParentInput" onchange="" class="form-control" name="parent">
<select id="networkParentInput" onchange="" class="form-select" name="parent">
</select>
</div>
</div>
@ -65,7 +65,7 @@
<label class="col-3 col-form-label text-right">Network: <span class="text-danger">*</span></label>
<div class="col-7">
<div class="form-group">
<select id="networkNetworkInput" onchange="" class="form-control" name="network">
<select id="networkNetworkInput" onchange="" class="form-select" name="network">
</select>
</div>
</div>
@ -87,7 +87,7 @@
<hr>
<div id="accordionConfigurationProperties">
<h2>
<button class="btn btn-link collapsed" type="button" data-toggle="collapse" data-target="#configurationProperties" aria-expanded="false" aria-controls="configurationProperties">
<button class="btn btn-link collapsed" type="button" data-bs-toggle="collapse" data-bs-target="#configurationProperties" aria-expanded="false" aria-controls="configurationProperties">
Configuration Properties
</button>
</h2>
@ -129,7 +129,7 @@
<label class="col-3 col-form-label text-right">Bridge Driver: </label>
<div class="col-7">
<div class="form-group">
<select onchange="" class="form-control" name="bridge.driver">
<select onchange="" class="form-select" name="bridge.driver">
<option value="">(not set)</option>
<option value="native">native</option>
<option value="openvswitch">openvswitch</option>
@ -166,7 +166,7 @@
<label class="col-3 col-form-label text-right">Bridge Mode: </label>
<div class="col-7">
<div class="form-group">
<select onchange="" class="form-control" name="bridge.mode">
<select onchange="" class="form-select" name="bridge.mode">
<option value="">(not set)</option>
<option value="fan">fan</option>
<option value="standard">standard</option>
@ -203,7 +203,7 @@
<label class="col-3 col-form-label text-right">DNS Mode: </label>
<div class="col-7">
<div class="form-group">
<select onchange="" class="form-control" name="dns.mode">
<select onchange="" class="form-select" name="dns.mode">
<option value="">(not set)</option>
<option value="dynamic">dynamic</option>
<option value="managed">managed</option>
@ -241,7 +241,7 @@
<label class="col-3 col-form-label text-right">Fan Type: </label>
<div class="col-7">
<div class="form-group">
<select onchange="" class="form-control" name="fan.type">
<select onchange="" class="form-select" name="fan.type">
<option value="">(not set)</option>
<option value="ipip">ipip</option>
<option value="vxlan">vxlan</option>
@ -278,7 +278,7 @@
<label class="col-3 col-form-label text-right">IPv4 DHCP: </label>
<div class="col-7">
<div class="form-group">
<select onchange="" class="form-control" name="ipv4.dhcp">
<select onchange="" class="form-select" name="ipv4.dhcp">
<option value="">(not set)</option>
<option value="true">true</option>
<option value="false">false</option>
@ -326,7 +326,7 @@
<label class="col-3 col-form-label text-right">IPv4 Firewall: </label>
<div class="col-7">
<div class="form-group">
<select onchange="" class="form-control" name="ipv4.firewall">
<select onchange="" class="form-select" name="ipv4.firewall">
<option value="">(not set)</option>
<option value="true">true</option>
<option value="false">false</option>
@ -352,7 +352,7 @@
<label class="col-3 col-form-label text-right">IPv4 NAT: </label>
<div class="col-7">
<div class="form-group">
<select onchange="" class="form-control" name="ipv4.nat">
<select onchange="" class="form-select" name="ipv4.nat">
<option value="">(not set)</option>
<option value="true">true</option>
<option value="false">false</option>
@ -367,7 +367,7 @@
<label class="col-3 col-form-label text-right">IPv4 NAT Order: </label>
<div class="col-7">
<div class="form-group">
<select onchange="" class="form-control" name="ipv4.nat.order">
<select onchange="" class="form-select" name="ipv4.nat.order">
<option value="">(not set)</option>
<option value="after">after</option>
<option value="before">before</option>
@ -404,7 +404,7 @@
<label class="col-3 col-form-label text-right">IPv4 Routes Anycast: </label>
<div class="col-7">
<div class="form-group">
<select onchange="" class="form-control" name="ipv4.routes.anycast">
<select onchange="" class="form-select" name="ipv4.routes.anycast">
<option value="">(not set)</option>
<option value="true">true</option>
<option value="false">false</option>
@ -430,7 +430,7 @@
<label class="col-3 col-form-label text-right">IPv4 Routing: </label>
<div class="col-7">
<div class="form-group">
<select onchange="" class="form-control" name="ipv4.routing">
<select onchange="" class="form-select" name="ipv4.routing">
<option value="">(not set)</option>
<option value="true">true</option>
<option value="false">false</option>
@ -456,7 +456,7 @@
<label class="col-3 col-form-label text-right">IPv6 DHCP: </label>
<div class="col-7">
<div class="form-group">
<select onchange="" class="form-control" name="ipv6.dhcp">
<select onchange="" class="form-select" name="ipv6.dhcp">
<option value="">(not set)</option>
<option value="true">true</option>
<option value="false">false</option>
@ -493,7 +493,7 @@
<label class="col-3 col-form-label text-right">IPv6 DHCP Stateful: </label>
<div class="col-7">
<div class="form-group">
<select onchange="" class="form-control" name="ipv6.dhcp.stateful">
<select onchange="" class="form-select" name="ipv6.dhcp.stateful">
<option value="">(not set)</option>
<option value="true">true</option>
<option value="false">false</option>
@ -508,7 +508,7 @@
<label class="col-3 col-form-label text-right">IPv6 Firewall: </label>
<div class="col-7">
<div class="form-group">
<select onchange="" class="form-control" name="ipv6.firewall">
<select onchange="" class="form-select" name="ipv6.firewall">
<option value="">(not set)</option>
<option value="true">true</option>
<option value="false">false</option>
@ -534,7 +534,7 @@
<label class="col-3 col-form-label text-right">IPv6 NAT: </label>
<div class="col-7">
<div class="form-group">
<select onchange="" class="form-control" name="ipv6.nat">
<select onchange="" class="form-select" name="ipv6.nat">
<option value="">(not set)</option>
<option value="true">true</option>
<option value="false">false</option>
@ -549,7 +549,7 @@
<label class="col-3 col-form-label text-right">IPv6 NAT Order: </label>
<div class="col-7">
<div class="form-group">
<select onchange="" class="form-control" name="ipv6.nat.order">
<select onchange="" class="form-select" name="ipv6.nat.order">
<option value="">(not set)</option>
<option value="after">after</option>
<option value="before">before</option>
@ -586,7 +586,7 @@
<label class="col-3 col-form-label text-right">IPv6 Routes Anycast: </label>
<div class="col-7">
<div class="form-group">
<select onchange="" class="form-control" name="ipv6.routes.anycast">
<select onchange="" class="form-select" name="ipv6.routes.anycast">
<option value="">(not set)</option>
<option value="true">true</option>
<option value="false">false</option>
@ -612,7 +612,7 @@
<label class="col-3 col-form-label text-right">IPv6 Routing: </label>
<div class="col-7">
<div class="form-group">
<select onchange="" class="form-control" name="ipv6.routing">
<select onchange="" class="form-select" name="ipv6.routing">
<option value="">(not set)</option>
<option value="true">true</option>
<option value="false">false</option>
@ -660,7 +660,7 @@
<label class="col-3 col-form-label text-right">OVN Ingress Mode: </label>
<div class="col-7">
<div class="form-group">
<select onchange="" class="form-control" name="ovn.ingress.mode">
<select onchange="" class="form-select" name="ovn.ingress.mode">
<option value="">(not set)</option>
<option value="l2proxy">l2proxy</option>
<option value="routed">routed</option>
@ -676,8 +676,8 @@
</form>
</div>
<div class="modal-footer">
<button class="btn btn-secondary" type="button" data-dismiss="modal">Cancel</button>
<a class="btn btn-primary" href="#" onclick="addItem()" data-dismiss="modal">Submit</a>
<button class="btn btn-secondary" type="button" data-bs-dismiss="modal">Cancel</button>
<a class="btn btn-primary" href="#" onclick="addItem()" data-bs-dismiss="modal">Submit</a>
</div>
</div>
<div class="tab-pane fade" id="json" role="tabpanel" aria-labelledby="json-tab">
@ -692,8 +692,8 @@
</div>
</div>
<div class="modal-footer">
<button class="btn btn-secondary" type="button" data-dismiss="modal">Cancel</button>
<a class="btn btn-primary" href="#" onclick="createNetworkUsingJSON()" data-dismiss="modal">Submit</a>
<button class="btn btn-secondary" type="button" data-bs-dismiss="modal">Cancel</button>
<a class="btn btn-primary" href="#" onclick="createNetworkUsingJSON()" data-bs-dismiss="modal">Submit</a>
</div>
</div>
</div>
@ -708,7 +708,7 @@
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title" id="exampleModalLabel">Edit Network</h5>
<button class="close" type="button" data-dismiss="modal" aria-label="Close">
<button class="close" type="button" data-bs-dismiss="modal" aria-label="Close">
<span aria-hidden="true">×</span>
</button>
</div>
@ -725,8 +725,8 @@
</div>
</div>
<div class="modal-footer">
<button class="btn btn-secondary" type="button" data-dismiss="modal">Cancel</button>
<a class="btn btn-primary" href="#" onclick="updateNetwork()" data-dismiss="modal">Submit</a>
<button class="btn btn-secondary" type="button" data-bs-dismiss="modal">Cancel</button>
<a class="btn btn-primary" href="#" onclick="updateNetwork()" data-bs-dismiss="modal">Submit</a>
</div>
</div>
</div>
@ -738,7 +738,7 @@
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title" id="renameNetworkModalLabel">Rename Network</h5>
<button class="close" type="button" data-dismiss="modal" aria-label="Close">
<button class="close" type="button" data-bs-dismiss="modal" aria-label="Close">
<span aria-hidden="true">×</span>
</button>
</div>
@ -757,8 +757,8 @@
<input type="hidden" id ="networkToRename" name="networkToRename">
</div>
<div class="modal-footer">
<button class="btn btn-secondary" type="button" data-dismiss="modal">Cancel</button>
<a class="btn btn-primary" href="#" onclick="updateNetworkName()" data-dismiss="modal">Ok</a>
<button class="btn btn-secondary" type="button" data-bs-dismiss="modal">Cancel</button>
<a class="btn btn-primary" href="#" onclick="updateNetworkName()" data-bs-dismiss="modal">Ok</a>
</div>
</div>
</div>

View file

@ -4,7 +4,7 @@
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title" id="exampleModalLabel">View Operation</h5>
<button class="close" type="button" data-dismiss="modal" aria-label="Close">
<button class="close" type="button" data-bs-dismiss="modal" aria-label="Close">
<span aria-hidden="true">×</span>
</button>
</div>
@ -21,7 +21,7 @@
</div>
</div>
<div class="modal-footer">
<button class="btn btn-secondary" type="button" data-dismiss="modal">Close</button>
<button class="btn btn-secondary" type="button" data-bs-dismiss="modal">Close</button>
</div>
</div>
</div>

View file

@ -4,17 +4,17 @@
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title" id="exampleModalLabel">Create Profile</h5>
<button class="close" type="button" data-dismiss="modal" aria-label="Close">
<button class="close" type="button" data-bs-dismiss="modal" aria-label="Close">
<span aria-hidden="true">×</span>
</button>
</div>
<div class="modal-body">
<ul class="nav nav-tabs" id="myTab" role="tablist">
<li class="nav-item">
<a class="nav-link active" id="form-tab" data-toggle="tab" href="#form" role="tab" aria-controls="form" aria-selected="true">Form</a>
<a class="nav-link active" id="form-tab" data-bs-toggle="tab" href="#form" role="tab" aria-controls="form" aria-selected="true">Form</a>
</li>
<li class="nav-item">
<a class="nav-link" id="json-tab" data-toggle="tab" href="#json" role="tab" aria-controls="json" aria-selected="false">JSON</a>
<a class="nav-link" id="json-tab" data-bs-toggle="tab" href="#json" role="tab" aria-controls="json" aria-selected="false">JSON</a>
</li>
</ul>
<div class="tab-content" id="myTabContent">
@ -45,8 +45,8 @@
</div>
</form>
<div class="modal-footer">
<button class="btn btn-secondary" type="button" data-dismiss="modal">Cancel</button>
<a class="btn btn-primary" href="#" onclick="addItem()" data-dismiss="modal">Submit</a>
<button class="btn btn-secondary" type="button" data-bs-dismiss="modal">Cancel</button>
<a class="btn btn-primary" href="#" onclick="addItem()" data-bs-dismiss="modal">Submit</a>
</div>
</div>
<div class="tab-pane fade" id="json" role="tabpanel" aria-labelledby="json-tab">
@ -61,8 +61,8 @@
</div>
</div>
<div class="modal-footer">
<button class="btn btn-secondary" type="button" data-dismiss="modal">Cancel</button>
<a class="btn btn-primary" href="#" onclick="createItemUsingJSON()" data-dismiss="modal">Submit</a>
<button class="btn btn-secondary" type="button" data-bs-dismiss="modal">Cancel</button>
<a class="btn btn-primary" href="#" onclick="createItemUsingJSON()" data-bs-dismiss="modal">Submit</a>
</div>
</div>
</div>
@ -77,7 +77,7 @@
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title" id="exampleModalLabel">Edit Profile</h5>
<button class="close" type="button" data-dismiss="modal" aria-label="Close">
<button class="close" type="button" data-bs-dismiss="modal" aria-label="Close">
<span aria-hidden="true">×</span>
</button>
</div>
@ -94,8 +94,8 @@
</div>
</div>
<div class="modal-footer">
<button class="btn btn-secondary" type="button" data-dismiss="modal">Cancel</button>
<a class="btn btn-primary" href="#" onclick="updateItem()" data-dismiss="modal">Submit</a>
<button class="btn btn-secondary" type="button" data-bs-dismiss="modal">Cancel</button>
<a class="btn btn-primary" href="#" onclick="updateItem()" data-bs-dismiss="modal">Submit</a>
</div>
</div>
</div>
@ -107,7 +107,7 @@
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title" id="renameItemModalLabel">Rename Profile</h5>
<button class="close" type="button" data-dismiss="modal" aria-label="Close">
<button class="close" type="button" data-bs-dismiss="modal" aria-label="Close">
<span aria-hidden="true">×</span>
</button>
</div>
@ -126,8 +126,8 @@
<input type="hidden" id="profileToRename" name="profileToRename">
</div>
<div class="modal-footer">
<button class="btn btn-secondary" type="button" data-dismiss="modal">Cancel</button>
<a class="btn btn-primary" href="#" onclick="updateItemName()" data-dismiss="modal">Ok</a>
<button class="btn btn-secondary" type="button" data-bs-dismiss="modal">Cancel</button>
<a class="btn btn-primary" href="#" onclick="updateItemName()" data-bs-dismiss="modal">Ok</a>
</div>
</div>
</div>

View file

@ -4,17 +4,17 @@
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title" id="exampleModalLabel">Add Project</h5>
<button class="close" type="button" data-dismiss="modal" aria-label="Close">
<button class="close" type="button" data-bs-dismiss="modal" aria-label="Close">
<span aria-hidden="true">×</span>
</button>
</div>
<div class="modal-body">
<ul class="nav nav-tabs" id="myTab" role="tablist">
<li class="nav-item">
<a class="nav-link active" id="form-tab" data-toggle="tab" href="#form" role="tab" aria-controls="form" aria-selected="true">Form</a>
<a class="nav-link active" id="form-tab" data-bs-toggle="tab" href="#form" role="tab" aria-controls="form" aria-selected="true">Form</a>
</li>
<li class="nav-item">
<a class="nav-link" id="json-tab" data-toggle="tab" href="#json" role="tab" aria-controls="json" aria-selected="false">JSON</a>
<a class="nav-link" id="json-tab" data-bs-toggle="tab" href="#json" role="tab" aria-controls="json" aria-selected="false">JSON</a>
</li>
</ul>
<div class="tab-content" id="myTabContent">
@ -47,7 +47,7 @@
<label class="col-3 col-form-label text-right">features.images: </label>
<div class="col-7">
<div class="form-group">
<select onchange="" class="form-control" name="features.images">
<select onchange="" class="form-select" name="features.images">
<option value="">(not set)</option>
<option value="true">true</option>
<option value="false">false</option>
@ -62,7 +62,7 @@
<label class="col-3 col-form-label text-right">features.networks: </label>
<div class="col-7">
<div class="form-group">
<select onchange="" class="form-control" name="features.networks">
<select onchange="" class="form-select" name="features.networks">
<option value="">(not set)</option>
<option value="true">true</option>
<option value="false">false</option>
@ -77,7 +77,7 @@
<label class="col-3 col-form-label text-right">features.profiles: </label>
<div class="col-7">
<div class="form-group">
<select onchange="" class="form-control" name="features.profiles">
<select onchange="" class="form-select" name="features.profiles">
<option value="">(not set)</option>
<option value="true">true</option>
<option value="false">false</option>
@ -92,7 +92,7 @@
<label class="col-3 col-form-label text-right">features.storage.volumes: </label>
<div class="col-7">
<div class="form-group">
<select onchange="" class="form-control" name="features.storage.volumes">
<select onchange="" class="form-select" name="features.storage.volumes">
<option value="">(not set)</option>
<option value="true">true</option>
<option value="false">false</option>
@ -107,7 +107,7 @@
<label class="col-3 col-form-label text-right">features.storage.buckets: </label>
<div class="col-7">
<div class="form-group">
<select onchange="" class="form-control" name="features.storage.buckets">
<select onchange="" class="form-select" name="features.storage.buckets">
<option value="">(not set)</option>
<option value="true">true</option>
<option value="false">false</option>
@ -121,7 +121,7 @@
<hr>
<div id="accordionConfigurationProperties">
<h2>
<button class="btn btn-link collapsed" type="button" data-toggle="collapse" data-target="#configurationProperties" aria-expanded="false" aria-controls="configurationProperties">
<button class="btn btn-link collapsed" type="button" data-bs-toggle="collapse" data-bs-target="#configurationProperties" aria-expanded="false" aria-controls="configurationProperties">
Additional Configuration Properties
</button>
</h2>
@ -130,7 +130,7 @@
<label class="col-4 col-form-label text-right">backups.compression_algorithm: </label>
<div class="col-6">
<div class="form-group">
<select onchange="" class="form-control" name="features.backups.compression_algorithm">
<select onchange="" class="form-select" name="features.backups.compression_algorithm">
<option value="">(not set)</option>
<option value="bzip2">bzip2</option>
<option value="gzip">gzip</option>
@ -148,7 +148,7 @@
<label class="col-4 col-form-label text-right">images.auto_update_cached: </label>
<div class="col-6">
<div class="form-group">
<select onchange="" class="form-control" name="features.images.auto_update_cached">
<select onchange="" class="form-select" name="features.images.auto_update_cached">
<option value="">(not set)</option>
<option value="true">true</option>
<option value="false">false</option>
@ -174,7 +174,7 @@
<label class="col-4 col-form-label text-right">images.compression_algorithm: </label>
<div class="col-6">
<div class="form-group">
<select onchange="" class="form-control" name="features.images.compression_algorithm">
<select onchange="" class="form-select" name="features.images.compression_algorithm">
<option value="">(not set)</option>
<option value="bzip2">bzip2</option>
<option value="gzip">gzip</option>
@ -302,7 +302,7 @@
<label class="col-4 col-form-label text-right">restricted: </label>
<div class="col-6">
<div class="form-group">
<select id="addModalRestrictedInput" onchange="changeRestrictedOptionsDisplay()" class="form-control" name="restricted">
<select id="addModalRestrictedInput" onchange="changeRestrictedOptionsDisplay()" class="form-select" name="restricted">
<option value="">(not set)</option>
<option value="true">true</option>
<option value="false">false</option>
@ -317,7 +317,7 @@
<label class="col-4 col-form-label text-right">restricted.backups: </label>
<div class="col-6">
<div class="form-group">
<select onchange="" class="form-control" name="restricted.backups">
<select onchange="" class="form-select" name="restricted.backups">
<option value="">(not set)</option>
<option value="allow">allow</option>
<option value="block">block</option>
@ -332,7 +332,7 @@
<label class="col-4 col-form-label text-right">restricted.cluster.target: </label>
<div class="col-6">
<div class="form-group">
<select onchange="" class="form-control" name="restricted.cluster.target">
<select onchange="" class="form-select" name="restricted.cluster.target">
<option value="">(not set)</option>
<option value="allow">allow</option>
<option value="block">block</option>
@ -347,7 +347,7 @@
<label class="col-4 col-form-label text-right">restricted.containers.lowlevel: </label>
<div class="col-6">
<div class="form-group">
<select onchange="" class="form-control" name="restricted.containers.lowlevel">
<select onchange="" class="form-select" name="restricted.containers.lowlevel">
<option value="">(not set)</option>
<option value="allow">allow</option>
<option value="block">block</option>
@ -362,7 +362,7 @@
<label class="col-4 col-form-label text-right">restricted.containers.nesting: </label>
<div class="col-6">
<div class="form-group">
<select onchange="" class="form-control" name="restricted.containers.nesting">
<select onchange="" class="form-select" name="restricted.containers.nesting">
<option value="">(not set)</option>
<option value="allow">allow</option>
<option value="block">block</option>
@ -377,7 +377,7 @@
<label class="col-4 col-form-label text-right">restricted.containers.privilege: </label>
<div class="col-6">
<div class="form-group">
<select onchange="" class="form-control" name="restricted.containers.privilege">
<select onchange="" class="form-select" name="restricted.containers.privilege">
<option value="">(not set)</option>
<option value="allow">allow</option>
<option value="isolated">isolated</option>
@ -393,7 +393,7 @@
<label class="col-4 col-form-label text-right">restricted.devices.disk: </label>
<div class="col-6">
<div class="form-group">
<select onchange="" class="form-control" name="restricted.devices.disk">
<select onchange="" class="form-select" name="restricted.devices.disk">
<option value="">(not set)</option>
<option value="allow">allow</option>
<option value="block">block</option>
@ -409,7 +409,7 @@
<label class="col-4 col-form-label text-right">restricted.devices.gpu: </label>
<div class="col-6">
<div class="form-group">
<select onchange="" class="form-control" name="restricted.devices.gpu">
<select onchange="" class="form-select" name="restricted.devices.gpu">
<option value="">(not set)</option>
<option value="allow">allow</option>
<option value="block">block</option>
@ -424,7 +424,7 @@
<label class="col-4 col-form-label text-right">restricted.devices.infiniband: </label>
<div class="col-6">
<div class="form-group">
<select onchange="" class="form-control" name="restricted.devices.infiniband">
<select onchange="" class="form-select" name="restricted.devices.infiniband">
<option value="">(not set)</option>
<option value="allow">allow</option>
<option value="block">block</option>
@ -439,7 +439,7 @@
<label class="col-4 col-form-label text-right">restricted.devices.nic: </label>
<div class="col-6">
<div class="form-group">
<select onchange="" class="form-control" name="restricted.devices.nic">
<select onchange="" class="form-select" name="restricted.devices.nic">
<option value="">(not set)</option>
<option value="allow">allow</option>
<option value="block">block</option>
@ -455,7 +455,7 @@
<label class="col-4 col-form-label text-right">restricted.devices.pci: </label>
<div class="col-6">
<div class="form-group">
<select onchange="" class="form-control" name="restricted.devices.pci">
<select onchange="" class="form-select" name="restricted.devices.pci">
<option value="">(not set)</option>
<option value="allow">allow</option>
<option value="block">block</option>
@ -470,7 +470,7 @@
<label class="col-4 col-form-label text-right">restricted.devices.proxy: </label>
<div class="col-6">
<div class="form-group">
<select onchange="" class="form-control" name="restricted.devices.proxy">
<select onchange="" class="form-select" name="restricted.devices.proxy">
<option value="">(not set)</option>
<option value="allow">allow</option>
<option value="block">block</option>
@ -485,7 +485,7 @@
<label class="col-4 col-form-label text-right">restricted.devices.unix-block: </label>
<div class="col-6">
<div class="form-group">
<select onchange="" class="form-control" name="restricted.devices.unix-block">
<select onchange="" class="form-select" name="restricted.devices.unix-block">
<option value="">(not set)</option>
<option value="allow">allow</option>
<option value="block">block</option>
@ -500,7 +500,7 @@
<label class="col-4 col-form-label text-right">restricted.devices.unix-char: </label>
<div class="col-6">
<div class="form-group">
<select onchange="" class="form-control" name="restricted.devices.unix-char">
<select onchange="" class="form-select" name="restricted.devices.unix-char">
<option value="">(not set)</option>
<option value="allow">allow</option>
<option value="block">block</option>
@ -515,7 +515,7 @@
<label class="col-4 col-form-label text-right">restricted.devices.unix-hotplug: </label>
<div class="col-6">
<div class="form-group">
<select onchange="" class="form-control" name="restricted.devices.unix-hotplug">
<select onchange="" class="form-select" name="restricted.devices.unix-hotplug">
<option value="">(not set)</option>
<option value="allow">allow</option>
<option value="block">block</option>
@ -530,7 +530,7 @@
<label class="col-4 col-form-label text-right">restricted.devices.usb: </label>
<div class="col-6">
<div class="form-group">
<select onchange="" class="form-control" name="restricted.devices.usb">
<select onchange="" class="form-select" name="restricted.devices.usb">
<option value="">(not set)</option>
<option value="allow">allow</option>
<option value="block">block</option>
@ -567,7 +567,7 @@
<label class="col-4 col-form-label text-right">restricted.snapshots: </label>
<div class="col-6">
<div class="form-group">
<select onchange="" class="form-control" name="restricted.snapshots">
<select onchange="" class="form-select" name="restricted.snapshots">
<option value="">(not set)</option>
<option value="allow">allow</option>
<option value="block">block</option>
@ -582,7 +582,7 @@
<label class="col-4 col-form-label text-right">restricted.virtual-machines.lowlevel: </label>
<div class="col-6">
<div class="form-group">
<select onchange="" class="form-control" name="restricted.virtual-machines.lowlevel">
<select onchange="" class="form-select" name="restricted.virtual-machines.lowlevel">
<option value="">(not set)</option>
<option value="allow">allow</option>
<option value="block">block</option>
@ -596,8 +596,8 @@
</div>
</div>
<div class="modal-footer">
<button class="btn btn-secondary" type="button" data-dismiss="modal">Cancel</button>
<a class="btn btn-primary" onclick="addItem()" href="#" data-dismiss="modal">Submit</a>
<button class="btn btn-secondary" type="button" data-bs-dismiss="modal">Cancel</button>
<a class="btn btn-primary" onclick="addItem()" href="#" data-bs-dismiss="modal">Submit</a>
</div>
</form>
</div>
@ -613,8 +613,8 @@
</div>
</div>
<div class="modal-footer">
<button class="btn btn-secondary" type="button" data-dismiss="modal">Cancel</button>
<a class="btn btn-primary" href="#" onclick="createProjectUsingJSON()" data-dismiss="modal">Submit</a>
<button class="btn btn-secondary" type="button" data-bs-dismiss="modal">Cancel</button>
<a class="btn btn-primary" href="#" onclick="createProjectUsingJSON()" data-bs-dismiss="modal">Submit</a>
</div>
</div>
</div>
@ -629,7 +629,7 @@
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title" id="exampleModalLabel">Edit Project</h5>
<button class="close" type="button" data-dismiss="modal" aria-label="Close">
<button class="close" type="button" data-bs-dismiss="modal" aria-label="Close">
<span aria-hidden="true">×</span>
</button>
</div>
@ -646,8 +646,8 @@
</div>
</div>
<div class="modal-footer">
<button class="btn btn-secondary" type="button" data-dismiss="modal">Cancel</button>
<a class="btn btn-primary" href="#" onclick="updateProject()" data-dismiss="modal">Submit</a>
<button class="btn btn-secondary" type="button" data-bs-dismiss="modal">Cancel</button>
<a class="btn btn-primary" href="#" onclick="updateProject()" data-bs-dismiss="modal">Submit</a>
</div>
</div>
</div>
@ -659,7 +659,7 @@
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title" id="renameProjectModalLabel">Rename Project</h5>
<button class="close" type="button" data-dismiss="modal" aria-label="Close">
<button class="close" type="button" data-bs-dismiss="modal" aria-label="Close">
<span aria-hidden="true">×</span>
</button>
</div>
@ -678,8 +678,8 @@
<input type="hidden" id ="projectToRename" name="projectToRename">
</div>
<div class="modal-footer">
<button class="btn btn-secondary" type="button" data-dismiss="modal">Cancel</button>
<a class="btn btn-primary" href="#" onclick="updateProjectName()" data-dismiss="modal">Ok</a>
<button class="btn btn-secondary" type="button" data-bs-dismiss="modal">Cancel</button>
<a class="btn btn-primary" href="#" onclick="updateProjectName()" data-bs-dismiss="modal">Ok</a>
</div>
</div>
</div>

View file

@ -4,7 +4,7 @@
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title" id="exampleModalLabel">Add Role</h5>
<button class="close" type="button" data-dismiss="modal" aria-label="Close">
<button class="close" type="button" data-bs-dismiss="modal" aria-label="Close">
<span aria-hidden="true">×</span>
</button>
</div>
@ -14,7 +14,7 @@
<label class="col-3 col-form-label text-right">Role:</label>
<div class="col-7 text-right">
<div class="form-group">
<select id="roleIdForAddRoleInput" class="form-control" name="roleIdForAddRoleInput">
<select id="roleIdForAddRoleInput" class="form-select" name="roleIdForAddRoleInput">
</select>
</div>
</div>
@ -27,8 +27,8 @@
</div> <!-- End Modal Body-->
<div class="modal-footer">
<button class="btn btn-secondary" type="button" data-dismiss="modal">Cancel</button>
<a class="btn btn-primary" href="#" onclick="addRole()" data-dismiss="modal">Submit</a>
<button class="btn btn-secondary" type="button" data-bs-dismiss="modal">Cancel</button>
<a class="btn btn-primary" href="#" onclick="addRole()" data-bs-dismiss="modal">Submit</a>
</div>
</div>
</div>

View file

@ -4,7 +4,7 @@
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title" id="exampleModalLabel">Add LXD Server</h5>
<button class="close" type="button" data-dismiss="modal" aria-label="Close">
<button class="close" type="button" data-bs-dismiss="modal" aria-label="Close">
<span aria-hidden="true">×</span>
</button>
</div>
@ -54,7 +54,7 @@
<label class="col-3 col-form-label text-right">SSL Verify: </label>
<div class="col-7">
<div class="form-group">
<select id="addModalSSLVerifyInput" class="form-control" name="addModalSSLVerifyInput">
<select id="addModalSSLVerifyInput" class="form-select" name="addModalSSLVerifyInput">
<option value="true">True</option>
<option value="false" selected>False</option>
</select>
@ -67,8 +67,8 @@
</div> <!-- End Modal Body-->
<div class="modal-footer">
<button class="btn btn-secondary" type="button" data-dismiss="modal">Cancel</button>
<a class="btn btn-primary" href="#" onclick="addServer()" data-dismiss="modal">Submit</a>
<button class="btn btn-secondary" type="button" data-bs-dismiss="modal">Cancel</button>
<a class="btn btn-primary" href="#" onclick="addServer()" data-bs-dismiss="modal">Submit</a>
</div>
</div>
</div>
@ -80,7 +80,7 @@
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title" id="exampleModalLabel">Edit Server</h5>
<button class="close" type="button" data-dismiss="modal" aria-label="Close">
<button class="close" type="button" data-bs-dismiss="modal" aria-label="Close">
<span aria-hidden="true">×</span>
</button>
</div>
@ -126,7 +126,7 @@
<label class="col-3 col-form-label text-right">SSL Verify: </label>
<div class="col-7">
<div class="form-group">
<select id="editModalSSLVerifyInput" class="form-control" name="editModalSSLVerifyInput">
<select id="editModalSSLVerifyInput" class="form-select" name="editModalSSLVerifyInput">
<option value="true">True</option>
<option value="false" selected>False</option>
</select>
@ -141,8 +141,8 @@
</div> <!-- End Modal Body-->
<div class="modal-footer">
<button class="btn btn-secondary" type="button" data-dismiss="modal">Cancel</button>
<a class="btn btn-primary" href="#" onclick="updateServer()" data-dismiss="modal">Submit</a>
<button class="btn btn-secondary" type="button" data-bs-dismiss="modal">Cancel</button>
<a class="btn btn-primary" href="#" onclick="updateServer()" data-bs-dismiss="modal">Submit</a>
</div>
</div>
</div>
@ -154,7 +154,7 @@
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title" id="exampleModalLabel">Instructions</h5>
<button class="close" type="button" data-dismiss="modal" aria-label="Close">
<button class="close" type="button" data-bs-dismiss="modal" aria-label="Close">
<span aria-hidden="true">×</span>
</button>
</div>
@ -177,7 +177,7 @@
</div>
</div>
<div class="modal-footer">
<button class="btn btn-secondary" type="button" data-dismiss="modal">Dismiss</button>
<button class="btn btn-secondary" type="button" data-bs-dismiss="modal">Dismiss</button>
</div>
</div>
</div>
@ -189,7 +189,7 @@
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title" id="exampleModalLabel">LXD Client Certificate</h5>
<button class="close" type="button" data-dismiss="modal" aria-label="Close">
<button class="close" type="button" data-bs-dismiss="modal" aria-label="Close">
<span aria-hidden="true">×</span>
</button>
</div>
@ -201,7 +201,7 @@
</div>
</div>
<div class="modal-footer">
<button class="btn btn-secondary" type="button" data-dismiss="modal">Dismiss</button>
<button class="btn btn-secondary" type="button" data-bs-dismiss="modal">Dismiss</button>
</div>
</div>
</div>
@ -213,14 +213,14 @@
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title" id="exampleModalLabel">Remove Server</h5>
<button class="close" type="button" data-dismiss="modal" aria-label="Close">
<button class="close" type="button" data-bs-dismiss="modal" aria-label="Close">
<span aria-hidden="true">×</span>
</button>
</div>
<div class="modal-body">Are you sure you want to remove this server?</div>
<div class="modal-footer">
<button class="btn btn-secondary" type="button" data-dismiss="modal">Cancel</button>
<a class="btn btn-primary" href="#" onclick="deleteServer()" data-dismiss="modal">Yes</a>
<button class="btn btn-secondary" type="button" data-bs-dismiss="modal">Cancel</button>
<a class="btn btn-primary" href="#" onclick="deleteServer()" data-bs-dismiss="modal">Yes</a>
</div>
</div>
</div>

View file

@ -4,7 +4,7 @@
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title" id="exampleModalLabel">Add Simplestreams Host</h5>
<button class="close" type="button" data-dismiss="modal" aria-label="Close">
<button class="close" type="button" data-bs-dismiss="modal" aria-label="Close">
<span aria-hidden="true">×</span>
</button>
</div>
@ -38,8 +38,8 @@
</div> <!-- End Modal Body-->
<div class="modal-footer">
<button class="btn btn-secondary" type="button" data-dismiss="modal">Cancel</button>
<a class="btn btn-primary" href="#" onclick="addItem()" data-dismiss="modal">Submit</a>
<button class="btn btn-secondary" type="button" data-bs-dismiss="modal">Cancel</button>
<a class="btn btn-primary" href="#" onclick="addItem()" data-bs-dismiss="modal">Submit</a>
</div>
</div>
</div>

View file

@ -4,17 +4,17 @@
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title" id="exampleModalLabel">Create Storage Pool</h5>
<button class="close" type="button" data-dismiss="modal" aria-label="Close">
<button class="close" type="button" data-bs-dismiss="modal" aria-label="Close">
<span aria-hidden="true">×</span>
</button>
</div>
<div class="modal-body">
<ul class="nav nav-tabs" id="myTab" role="tablist">
<li class="nav-item">
<a class="nav-link active" id="form-tab" data-toggle="tab" href="#form" role="tab" aria-controls="form" aria-selected="true">Form</a>
<a class="nav-link active" id="form-tab" data-bs-toggle="tab" href="#form" role="tab" aria-controls="form" aria-selected="true">Form</a>
</li>
<li class="nav-item">
<a class="nav-link" id="json-tab" data-toggle="tab" href="#json" role="tab" aria-controls="json" aria-selected="false">JSON</a>
<a class="nav-link" id="json-tab" data-bs-toggle="tab" href="#json" role="tab" aria-controls="json" aria-selected="false">JSON</a>
</li>
</ul>
<div class="tab-content" id="myTabContent">
@ -47,7 +47,7 @@
<label class="col-3 col-form-label text-right">Driver: <span class="text-danger">*</span></label>
<div class="col-7">
<div class="form-group">
<select id="storagePoolDriverInput" class="form-control" onclick="changeStoragePoolDriverInput()" name="driver">
<select id="storagePoolDriverInput" class="form-select" onclick="changeStoragePoolDriverInput()" name="driver">
<option value="btrfs">btrfs</option>
<option value="ceph">ceph</option>
<option value="cephfs">cephfs</option>
@ -86,7 +86,7 @@
<hr>
<div id="accordionConfigurationProperties">
<h2>
<button class="btn btn-link collapsed" type="button" data-toggle="collapse" data-target="#configurationProperties" aria-expanded="false" aria-controls="configurationProperties">
<button class="btn btn-link collapsed" type="button" data-bs-toggle="collapse" data-bs-target="#configurationProperties" aria-expanded="false" aria-controls="configurationProperties">
Configuration Properties
</button>
</h2>
@ -118,7 +118,7 @@
<label class="col-4 col-form-label text-right">ceph.osd.force_reuse: </label>
<div class="col-6">
<div class="form-group">
<select onchange="" class="form-control" name="ceph.osd.force_reuse">
<select onchange="" class="form-select" name="ceph.osd.force_reuse">
<option value="">(not set)</option>
<option value="true">true</option>
<option value="false">false</option>
@ -166,7 +166,7 @@
<label class="col-4 col-form-label text-right">ceph.rbd.clone_copy: </label>
<div class="col-6">
<div class="form-group">
<select onchange="" class="form-control" name="ceph.rbd.clone_copy">
<select onchange="" class="form-select" name="ceph.rbd.clone_copy">
<option value="">(not set)</option>
<option value="true">true</option>
<option value="false">false</option>
@ -247,7 +247,7 @@
<label class="col-4 col-form-label text-right">lvm.use_thinpool: </label>
<div class="col-6">
<div class="form-group">
<select onchange="" class="form-control" name="lvm.use_thinpool">
<select onchange="" class="form-select" name="lvm.use_thinpool">
<option value="">(not set)</option>
<option value="true">true</option>
<option value="false">false</option>
@ -273,7 +273,7 @@
<label class="col-4 col-form-label text-right">lvm.vg.force_reuse: </label>
<div class="col-6">
<div class="form-group">
<select onchange="" class="form-control" name="lvm.vg.force_reuse">
<select onchange="" class="form-select" name="lvm.vg.force_reuse">
<option value="">(not set)</option>
<option value="true">true</option>
<option value="false">false</option>
@ -321,7 +321,7 @@
<label class="col-4 col-form-label text-right">rsync.compression: </label>
<div class="col-6">
<div class="form-group">
<select onchange="" class="form-control" name="rsync.compression">
<select onchange="" class="form-select" name="rsync.compression">
<option value="">(not set)</option>
<option value="true">true</option>
<option value="false">false</option>
@ -347,7 +347,7 @@
<label class="col-4 col-form-label text-right">volatile.pool.pristine: </label>
<div class="col-6">
<div class="form-group">
<select onchange="" class="form-control" name="volatile.pool.pristine">
<select onchange="" class="form-select" name="volatile.pool.pristine">
<option value="">(not set)</option>
<option value="true">true</option>
<option value="false">false</option>
@ -395,7 +395,7 @@
<label class="col-4 col-form-label text-right">volume.zfs.remove_snapshots: </label>
<div class="col-6">
<div class="form-group">
<select onchange="" class="form-control" name="volume.zfs.remove_snapshots">
<select onchange="" class="form-select" name="volume.zfs.remove_snapshots">
<option value="">(not set)</option>
<option value="true">true</option>
<option value="false">false</option>
@ -410,7 +410,7 @@
<label class="col-4 col-form-label text-right">volume.zfs.use_refquota: </label>
<div class="col-6">
<div class="form-group">
<select onchange="" class="form-control" name="volume.zfs.use_refquota ">
<select onchange="" class="form-select" name="volume.zfs.use_refquota ">
<option value="">(not set)</option>
<option value="true">true</option>
<option value="false">false</option>
@ -425,7 +425,7 @@
<label class="col-4 col-form-label text-right">zfs.clone_copy: </label>
<div class="col-6">
<div class="form-group">
<select onchange="" class="form-control" name="zfs.clone_copy">
<select onchange="" class="form-select" name="zfs.clone_copy">
<option value="">(not set)</option>
<option value="true">true</option>
<option value="false">false</option>
@ -452,8 +452,8 @@
</div>
</form>
<div class="modal-footer">
<button class="btn btn-secondary" type="button" data-dismiss="modal">Cancel</button>
<a class="btn btn-primary" href="#" onclick="addItem()" data-dismiss="modal">Submit</a>
<button class="btn btn-secondary" type="button" data-bs-dismiss="modal">Cancel</button>
<a class="btn btn-primary" href="#" onclick="addItem()" data-bs-dismiss="modal">Submit</a>
</div>
</div>
<div class="tab-pane fade" id="json" role="tabpanel" aria-labelledby="json-tab">
@ -468,8 +468,8 @@
</div>
</div>
<div class="modal-footer">
<button class="btn btn-secondary" type="button" data-dismiss="modal">Cancel</button>
<a class="btn btn-primary" href="#" onclick="createStoragePoolUsingJSON()" data-dismiss="modal">Submit</a>
<button class="btn btn-secondary" type="button" data-bs-dismiss="modal">Cancel</button>
<a class="btn btn-primary" href="#" onclick="createStoragePoolUsingJSON()" data-bs-dismiss="modal">Submit</a>
</div>
</div>
</div>
@ -484,7 +484,7 @@
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title" id="exampleModalLabel">Edit Storage Pool</h5>
<button class="close" type="button" data-dismiss="modal" aria-label="Close">
<button class="close" type="button" data-bs-dismiss="modal" aria-label="Close">
<span aria-hidden="true">×</span>
</button>
</div>
@ -501,8 +501,8 @@
</div>
</div>
<div class="modal-footer">
<button class="btn btn-secondary" type="button" data-dismiss="modal">Cancel</button>
<a class="btn btn-primary" href="#" onclick="updateStoragePool()" data-dismiss="modal">Submit</a>
<button class="btn btn-secondary" type="button" data-bs-dismiss="modal">Cancel</button>
<a class="btn btn-primary" href="#" onclick="updateStoragePool()" data-bs-dismiss="modal">Submit</a>
</div>
</div>
</div>

View file

@ -4,17 +4,17 @@
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title" id="exampleModalLabel">Create Storage Volume</h5>
<button class="close" type="button" data-dismiss="modal" aria-label="Close">
<button class="close" type="button" data-bs-dismiss="modal" aria-label="Close">
<span aria-hidden="true">×</span>
</button>
</div>
<div class="modal-body">
<ul class="nav nav-tabs" id="myTab" role="tablist">
<li class="nav-item">
<a class="nav-link active" id="form-tab" data-toggle="tab" href="#form" role="tab" aria-controls="form" aria-selected="true">Form</a>
<a class="nav-link active" id="form-tab" data-bs-toggle="tab" href="#form" role="tab" aria-controls="form" aria-selected="true">Form</a>
</li>
<li class="nav-item">
<a class="nav-link" id="json-tab" data-toggle="tab" href="#json" role="tab" aria-controls="json" aria-selected="false">JSON</a>
<a class="nav-link" id="json-tab" data-bs-toggle="tab" href="#json" role="tab" aria-controls="json" aria-selected="false">JSON</a>
</li>
</ul>
<div class="tab-content" id="myTabContent">
@ -47,7 +47,7 @@
<label class="col-3 col-form-label text-right">Type: <span class="text-danger">*</span></label>
<div class="col-7">
<div class="form-group">
<select id="storageVolumeContentTypeInput" class="form-control" name="type">
<select id="storageVolumeContentTypeInput" class="form-select" name="type">
<option value="custom" selected>custom</option>
</select>
</div>
@ -60,7 +60,7 @@
<label class="col-3 col-form-label text-right">Content Type: <span class="text-danger">*</span></label>
<div class="col-7">
<div class="form-group">
<select id="storageVolumeContentTypeInput" class="form-control" name="content_type">
<select id="storageVolumeContentTypeInput" class="form-select" name="content_type">
<option value="block" selected>block</option>
<option value="filesystem">filesystem</option>
</select>
@ -84,7 +84,7 @@
<hr>
<div id="accordionConfigurationProperties">
<h2>
<button class="btn btn-link collapsed" type="button" data-toggle="collapse" data-target="#configurationProperties" aria-expanded="false" aria-controls="configurationProperties">
<button class="btn btn-link collapsed" type="button" data-bs-toggle="collapse" data-bs-target="#configurationProperties" aria-expanded="false" aria-controls="configurationProperties">
Configuration Properties
</button>
</h2>
@ -115,7 +115,7 @@
<label class="col-4 col-form-label text-right">security.shifted: </label>
<div class="col-6">
<div class="form-group">
<select onchange="" class="form-control" name="security.shifted">
<select onchange="" class="form-select" name="security.shifted">
<option value="">(not set)</option>
<option value="true">true</option>
<option value="false">false</option>
@ -130,7 +130,7 @@
<label class="col-4 col-form-label text-right">security.unmapped: </label>
<div class="col-6">
<div class="form-group">
<select onchange="" class="form-control" name="security.unmapped">
<select onchange="" class="form-select" name="security.unmapped">
<option value="">(not set)</option>
<option value="true">true</option>
<option value="false">false</option>
@ -200,7 +200,7 @@
<label class="col-4 col-form-label text-right">zfs.remove_snapshots: </label>
<div class="col-6">
<div class="form-group">
<select onchange="" class="form-control" name="zfs.remove_snapshots">
<select onchange="" class="form-select" name="zfs.remove_snapshots">
<option value="">(not set)</option>
<option value="true">true</option>
<option value="false">false</option>
@ -215,7 +215,7 @@
<label class="col-4 col-form-label text-right">zfs.use_refquota: </label>
<div class="col-6">
<div class="form-group">
<select onchange="" class="form-control" name="zfs.use_refquota">
<select onchange="" class="form-select" name="zfs.use_refquota">
<option value="">(not set)</option>
<option value="true">true</option>
<option value="false">false</option>
@ -231,8 +231,8 @@
</form>
<div class="modal-footer">
<button class="btn btn-secondary" type="button" data-dismiss="modal">Cancel</button>
<a class="btn btn-primary" href="#" onclick="addItem()" data-dismiss="modal">Submit</a>
<button class="btn btn-secondary" type="button" data-bs-dismiss="modal">Cancel</button>
<a class="btn btn-primary" href="#" onclick="addItem()" data-bs-dismiss="modal">Submit</a>
</div>
</div>
<div class="tab-pane fade" id="json" role="tabpanel" aria-labelledby="json-tab">
@ -247,8 +247,8 @@
</div>
</div>
<div class="modal-footer">
<button class="btn btn-secondary" type="button" data-dismiss="modal">Cancel</button>
<a class="btn btn-primary" href="#" onclick="createStorageVolumeUsingJSON()" data-dismiss="modal">Submit</a>
<button class="btn btn-secondary" type="button" data-bs-dismiss="modal">Cancel</button>
<a class="btn btn-primary" href="#" onclick="createStorageVolumeUsingJSON()" data-bs-dismiss="modal">Submit</a>
</div>
</div>
</div>
@ -263,7 +263,7 @@
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title" id="exampleModalLabel">Edit Storage Volume</h5>
<button class="close" type="button" data-dismiss="modal" aria-label="Close">
<button class="close" type="button" data-bs-dismiss="modal" aria-label="Close">
<span aria-hidden="true">×</span>
</button>
</div>
@ -280,8 +280,8 @@
</div>
</div>
<div class="modal-footer">
<button class="btn btn-secondary" type="button" data-dismiss="modal">Cancel</button>
<a class="btn btn-primary" href="#" onclick="updateStorageVolume()" data-dismiss="modal">Submit</a>
<button class="btn btn-secondary" type="button" data-bs-dismiss="modal">Cancel</button>
<a class="btn btn-primary" href="#" onclick="updateStorageVolume()" data-bs-dismiss="modal">Submit</a>
</div>
</div>
</div>

View file

@ -4,7 +4,7 @@
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title" id="exampleModalLabel">Create User</h5>
<button class="close" type="button" data-dismiss="modal" aria-label="Close">
<button class="close" type="button" data-bs-dismiss="modal" aria-label="Close">
<span aria-hidden="true">×</span>
</button>
</div>
@ -75,7 +75,7 @@
<label class="col-3 col-form-label text-right">Group: </label>
<div class="col-7">
<div class="form-group">
<select id="groupInput" class="form-control" required="required" name="group_id">
<select id="groupInput" class="form-select" required="required" name="group_id">
<option value="4">Auditor</option>
</select>
</div>
@ -89,8 +89,8 @@
</div> <!-- End Modal Body-->
<div class="modal-footer">
<button class="btn btn-secondary" type="button" data-dismiss="modal">Cancel</button>
<a class="btn btn-primary" href="#" onclick="addUser()" data-dismiss="modal">Submit</a>
<button class="btn btn-secondary" type="button" data-bs-dismiss="modal">Cancel</button>
<a class="btn btn-primary" href="#" onclick="addUser()" data-bs-dismiss="modal">Submit</a>
</div>
</div>
</div>
@ -102,20 +102,20 @@
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title" id="exampleModalLabel">Edit User</h5>
<button class="close" type="button" data-dismiss="modal" aria-label="Close">
<button class="close" type="button" data-bs-dismiss="modal" aria-label="Close">
<span aria-hidden="true">×</span>
</button>
</div>
<div class="modal-body">
<ul class="nav nav-tabs" id="myTab" role="tablist">
<li class="nav-item">
<a class="nav-link active" id="user-tab" data-toggle="tab" href="#user-profile" role="tab" aria-controls="user-profile" aria-selected="true">Profile</a>
<a class="nav-link active" id="user-tab" data-bs-toggle="tab" href="#user-profile" role="tab" aria-controls="user-profile" aria-selected="true">Profile</a>
</li>
<li class="nav-item">
<a class="nav-link" id="group-tab" data-toggle="tab" href="#user-group" role="tab" aria-controls="user-group" aria-selected="false">Groups</a>
<a class="nav-link" id="group-tab" data-bs-toggle="tab" href="#user-group" role="tab" aria-controls="user-group" aria-selected="false">Groups</a>
</li>
<li class="nav-item">
<a class="nav-link" id="password-tab" data-toggle="tab" href="#user-password" role="tab" aria-controls="user-password" aria-selected="false">Password</a>
<a class="nav-link" id="password-tab" data-bs-toggle="tab" href="#user-password" role="tab" aria-controls="user-password" aria-selected="false">Password</a>
</li>
</ul>
<div class="tab-content" id="myTabContent">
@ -175,8 +175,8 @@
<input type="hidden" id="idEditInput" name="id">
</form>
<div class="modal-footer">
<button class="btn btn-secondary" type="button" data-dismiss="modal">Cancel</button>
<a class="btn btn-primary" href="#" onclick="updateUser()" data-dismiss="modal">Update Profile</a>
<button class="btn btn-secondary" type="button" data-bs-dismiss="modal">Cancel</button>
<a class="btn btn-primary" href="#" onclick="updateUser()" data-bs-dismiss="modal">Update Profile</a>
</div>
</div>
@ -188,7 +188,7 @@
<label class="col-3 col-form-label text-right">Action: </label>
<div class="col-7">
<div class="form-group">
<select id="actionEditInput" onchange="changeActionInput()" class="form-control" required="required" name="action">
<select id="actionEditInput" onchange="changeActionInput()" class="form-select" required="required" name="action">
<option value="add">Add</option>
<option value="remove">Remove</option>
</select>
@ -203,7 +203,7 @@
<label class="col-3 col-form-label text-right">Group: </label>
<div class="col-7">
<div class="form-group">
<select id="addGroupEditInput" class="form-control" required="required" name="add_group">
<select id="addGroupEditInput" class="form-select" required="required" name="add_group">
</select>
</div>
</div>
@ -216,7 +216,7 @@
<label class="col-3 col-form-label text-right">Group: </label>
<div class="col-7">
<div class="form-group">
<select id="removeGroupEditInput" class="form-control" required="required" name="remove_group">
<select id="removeGroupEditInput" class="form-select" required="required" name="remove_group">
</select>
</div>
</div>
@ -229,8 +229,8 @@
</form>
<div class="modal-footer">
<button class="btn btn-secondary" type="button" data-dismiss="modal">Cancel</button>
<a class="btn btn-primary" href="#" onclick="updateUserGroup()" data-dismiss="modal">Update Group</a>
<button class="btn btn-secondary" type="button" data-bs-dismiss="modal">Cancel</button>
<a class="btn btn-primary" href="#" onclick="updateUserGroup()" data-bs-dismiss="modal">Update Group</a>
</div>
</div>
@ -265,8 +265,8 @@
</form>
<div class="modal-footer">
<button class="btn btn-secondary" type="button" data-dismiss="modal">Cancel</button>
<a class="btn btn-primary" href="#" onclick="updateUserPassword()" data-dismiss="modal">Update Password</a>
<button class="btn btn-secondary" type="button" data-bs-dismiss="modal">Cancel</button>
<a class="btn btn-primary" href="#" onclick="updateUserPassword()" data-bs-dismiss="modal">Update Password</a>
</div>
</div>

File diff suppressed because it is too large Load diff

View file

@ -1,655 +0,0 @@
<!-- Add Modal-->
<div class="modal fade" id="addModal" tabindex="-1" role="dialog" aria-labelledby="exampleModalLabel" aria-hidden="true">
<div class="modal-dialog modal-lg" role="document">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title" id="exampleModalLabel">Create Virtual Machine</h5>
<button class="close" type="button" data-dismiss="modal" aria-label="Close">
<span aria-hidden="true">×</span>
</button>
</div>
<div class="modal-body">
<ul class="nav nav-tabs" id="myTab" role="tablist">
<li class="nav-item">
<a class="nav-link active" id="form-tab" data-toggle="tab" href="#form" role="tab" aria-controls="form" aria-selected="true">Form</a>
</li>
<li class="nav-item">
<a class="nav-link" id="json-tab" data-toggle="tab" href="#json" role="tab" aria-controls="json" aria-selected="false">JSON</a>
</li>
</ul>
<div class="tab-content" id="myTabContent">
<div class="tab-pane fade show active" id="form" role="tabpanel" aria-labelledby="form-tab">
<br />
<form id="addForm">
<div class="row">
<label class="col-3 col-form-label text-right">Name: <span class="text-danger">*</span> </label>
<div class="col-7">
<div class="form-group">
<input type="text" class="form-control" required="required" name="name">
</div>
</div>
<div class="col-1">
<i class="far fa-sm fa-question-circle" title='Enter in a name for this instance'></i>
</div>
</div>
<div class="row">
<label class="col-3 col-form-label text-right">Description: </label>
<div class="col-7">
<div class="form-group">
<input type="text" class="form-control" required="required" name="description">
</div>
</div>
<div class="col-1">
<i class="far fa-sm fa-question-circle" title='Enter in a description for this instance'></i>
</div>
</div>
<div class="row">
<label class="col-3 col-form-label text-right">Image: </label>
<div class="col-7">
<div class="form-group">
<select id="virtualMachineImageInput" class="form-control" name="image">
<option value="none">none</option>
</select>
</div>
</div>
<div class="col-1">
<i class="far fa-sm fa-question-circle" title='Select a downloaded image to use to build the instance'></i>
</div>
</div>
<div class="row">
<label class="col-3 col-form-label text-right">Profiles: </label>
<div class="col-7">
<div class="form-group">
<select id="virtualMachineProfileInput" class="form-control" name="profiles">
</select>
</div>
</div>
<div class="col-1">
<i class="far fa-sm fa-question-circle" title='Select the initial profile to attach to this instance. Additional profiles can be attached after the instance is created. Default: default'></i>
</div>
</div>
<div class="row">
<label class="col-3 col-form-label text-right">Instance Type: </label>
<div class="col-7">
<div class="form-group">
<select class="form-control" name="instance_type">
<option value="" selected>(not set)</option>
<option disabled>--- AWS Instance Types ---</option>
<option value="aws:c1.medium">c1.medium</option>
<option value="aws:c1.xlarge">c1.xlarge</option>
<option value="aws:c3.2xlarge">c3.2xlarge</option>
<option value="aws:c3.4xlarge">c3.4xlarge</option>
<option value="aws:c3.8xlarge">c3.8xlarge</option>
<option value="aws:c3.large">c3.large</option>
<option value="aws:c3.xlarge">c3.xlarge</option>
<option value="aws:c4.2xlarge">c4.2xlarge</option>
<option value="aws:c4.4xlarge">c4.4xlarge</option>
<option value="aws:c4.8xlarge">c4.8xlarge</option>
<option value="aws:c4.large">c4.large</option>
<option value="aws:c4.xlarge">c4.xlarge</option>
<option value="aws:c5.large">c5.large</option>
<option value="aws:c5.xlarge">c5.xlarge</option>
<option value="aws:c5.2xlarge">c5.2xlarge</option>
<option value="aws:c5.4xlarge">c5.4xlarge</option>
<option value="aws:c5.9xlarge">c5.9xlarge</option>
<option value="aws:c5.18xlarge">c5.18xlarge</option>
<option value="aws:cc2.8xlarge">cc2.8xlarge</option>
<option value="aws:cg1.4xlarge">cg1.4xlarge</option>
<option value="aws:cr1.8xlarge">cr1.8xlarge</option>
<option value="aws:d2.xlarge">d2.xlarge</option>
<option value="aws:d2.2xlarge">d2.2xlarge</option>
<option value="aws:d2.4xlarge">d2.4xlarge</option>
<option value="aws:d2.8xlarge">d2.8xlarge</option>
<option value="aws:f1.2xlarge">f1.2xlarge</option>
<option value="aws:f1.16xlarge">f1.16xlarge</option>
<option value="aws:g2.2xlarge">g2.2xlarge</option>
<option value="aws:g2.8xlarge">g2.8xlarge</option>
<option value="aws:g3.4xlarge">g3.4xlarge</option>
<option value="aws:g3.8xlarge">g3.8xlarge</option>
<option value="aws:g3.16xlarge">g3.16xlarge</option>
<option value="aws:hi1.4xlarge">hi1.4xlarge</option>
<option value="aws:hs1.8xlarge">hs1.8xlarge</option>
<option value="aws:i2.xlarge">i2.xlarge</option>
<option value="aws:i2.2xlarge">i2.2xlarge</option>
<option value="aws:i2.4xlarge">i2.4xlarge</option>
<option value="aws:i2.8xlarge">i2.8xlarge</option>
<option value="aws:i3.large">i3.large</option>
<option value="aws:i3.xlarge">i3.xlarge</option>
<option value="aws:i3.2xlarge">i3.2xlarge</option>
<option value="aws:i3.4xlarge">i3.4xlarge</option>
<option value="aws:i3.8xlarge">i3.8xlarge</option>
<option value="aws:i3.16xlarge">i3.16xlarge</option>
<option value="aws:m1.small">m1.small</option>
<option value="aws:m1.medium">m1.medium</option>
<option value="aws:m1.large">m1.large</option>
<option value="aws:m1.xlarge">m1.xlarge</option>
<option value="aws:m2.xlarge">m2.xlarge</option>
<option value="aws:m2.2xlarge">m2.2xlarge</option>
<option value="aws:m2.4xlarge">m2.4xlarge</option>
<option value="aws:m3.medium">m3.medium</option>
<option value="aws:m3.large">m3.large</option>
<option value="aws:m3.xlarge">m3.xlarge</option>
<option value="aws:m3.2xlarge">m3.2xlarge</option>
<option value="aws:m4.large">m4.large</option>
<option value="aws:m4.xlarge">m4.xlarge</option>
<option value="aws:m4.2xlarge">m4.2xlarge</option>
<option value="aws:m4.4xlarge">m4.4xlarge</option>
<option value="aws:m4.10xlarge">m4.10xlarge</option>
<option value="aws:m4.16xlarge">m4.16xlarge</option>
<option value="aws:p2.xlarge">p2.xlarge</option>
<option value="aws:p2.8xlarge">p2.8xlarge</option>
<option value="aws:p2.16xlarge">p2.16xlarge</option>
<option value="aws:r3.large">r3.large</option>
<option value="aws:r3.xlarge">r3.xlarge</option>
<option value="aws:r3.2xlarge">r3.2xlarge</option>
<option value="aws:r3.4xlarge">r3.4xlarge</option>
<option value="aws:r3.8xlarge">r3.8xlarge</option>
<option value="aws:r4.large">r4.large</option>
<option value="aws:r4.xlarge">r4.xlarge</option>
<option value="aws:r4.2xlarge">r4.2xlarge</option>
<option value="aws:r4.4xlarge">r4.4xlarge</option>
<option value="aws:r4.8xlarge">r4.8xlarge</option>
<option value="aws:r4.16xlarge">r4.16xlarge</option>
<option value="aws:t1.micro">t1.micro</option>
<option value="aws:t2.nano">t2.nano</option>
<option value="aws:t2.micro">t2.micro</option>
<option value="aws:t2.small">t2.small</option>
<option value="aws:t2.medium">t2.medium</option>
<option value="aws:t2.large">t2.large</option>
<option value="aws:t2.xlarge">t2.xlarge</option>
<option value="aws:t2.2xlarge">t2.2xlarge</option>
<option value="aws:t3.nano">t3.nano</option>
<option value="aws:t3.micro">t3.micro</option>
<option value="aws:t3.small">t3.small</option>
<option value="aws:t3.medium">t3.medium</option>
<option value="aws:t3.large">t3.large</option>
<option value="aws:t3.xlarge">t3.xlarge</option>
<option value="aws:t3.2xlarge">t3.2xlarge</option>
<option value="aws:x1.16xlarge">x1.16xlarge</option>
<option value="aws:x1.32xlarge">x1.32xlarge</option>
<option disabled>--- Azure Instance Types ---</option>
<option value="azure:A5">A5</option>
<option value="azure:A6">A6</option>
<option value="azure:A7">A7</option>
<option value="azure:A8">A8</option>
<option value="azure:A9">A9</option>
<option value="azure:A10">A10</option>
<option value="azure:A11">A11</option>
<option value="azure:ExtraSmall">ExtraSmall</option>
<option value="azure:Small">Small</option>
<option value="azure:Medium">Medium</option>
<option value="azure:Large">Large</option>
<option value="azure:ExtraLarge">ExtraLarge</option>
<option value="azure:Standard_A1_v2">Standard_A1_v2</option>
<option value="azure:Standard_A2m_v2">Standard_A2m_v2</option>
<option value="azure:Standard_A2_v2">Standard_A2_v2</option>
<option value="azure:Standard_A4m_v2">Standard_A4m_v2</option>
<option value="azure:Standard_A4_v2">Standard_A4_v2</option>
<option value="azure:Standard_A8m_v2">Standard_A8m_v2</option>
<option value="azure:Standard_A8_v2">Standard_A8_v2</option>
<option value="azure:Standard_D1">Standard_D1</option>
<option value="azure:Standard_D1_v2">Standard_D1_v2</option>
<option value="azure:Standard_D2">Standard_D2</option>
<option value="azure:Standard_D2_v2">Standard_D2_v2</option>
<option value="azure:Standard_D3">Standard_D3</option>
<option value="azure:Standard_D3_v2">Standard_D3_v2</option>
<option value="azure:Standard_D4">Standard_D4</option>
<option value="azure:Standard_D4_v2">Standard_D4_v2</option>
<option value="azure:Standard_D5_v2">Standard_D5_v2</option>
<option value="azure:Standard_D11">Standard_D11</option>
<option value="azure:Standard_D11_v2">Standard_D11_v2</option>
<option value="azure:Standard_D12">Standard_D12</option>
<option value="azure:Standard_D12_v2">Standard_D12_v2</option>
<option value="azure:Standard_D13">Standard_D13</option>
<option value="azure:Standard_D13_v2">Standard_D13_v2</option>
<option value="azure:Standard_D14">Standard_D14</option>
<option value="azure:Standard_D14_v2">Standard_D14_v2</option>
<option value="azure:Standard_D15_v2">Standard_D15_v2</option>
<option value="azure:Standard_G1">Standard_G1</option>
<option value="azure:Standard_G2">Standard_G2</option>
<option value="azure:Standard_G3">Standard_G3</option>
<option value="azure:Standard_G4">Standard_G4</option>
<option value="azure:Standard_G5">Standard_G5</option>
<option value="azure:Standard_H8">Standard_H8</option>
<option value="azure:Standard_H8m">Standard_H8m</option>
<option value="azure:Standard_H16">Standard_H16</option>
<option value="azure:Standard_H16m">Standard_H16m</option>
<option value="azure:Standard_H16mr">Standard_H16mr</option>
<option value="azure:Standard_H16r">Standard_H16r</option>
<option disabled>--- GCE Instance Types ---</option>
<option value="gce:f1-micro">f1-micro</option>
<option value="gce:g1-small">g1-small</option>
<option value="gce:n1-highcpu-2">n1-highcpu-2</option>
<option value="gce:n1-highcpu-4">n1-highcpu-4</option>
<option value="gce:n1-highcpu-8">n1-highcpu-8</option>
<option value="gce:n1-highcpu-16">n1-highcpu-16</option>
<option value="gce:n1-highcpu-32">n1-highcpu-32</option>
<option value="gce:n1-highcpu-64">n1-highcpu-64</option>
<option value="gce:n1-highmem-2">n1-highmem-2</option>
<option value="gce:n1-highmem-4">n1-highmem-4</option>
<option value="gce:n1-highmem-8">n1-highmem-8</option>
<option value="gce:n1-highmem-16">n1-highmem-16</option>
<option value="gce:n1-highmem-32">n1-highmem-32</option>
<option value="gce:n1-highmem-64">n1-highmem-64</option>
<option value="gce:n1-standard-1">n1-standard-1</option>
<option value="gce:n1-standard-2">n1-standard-2</option>
<option value="gce:n1-standard-4">n1-standard-4</option>
<option value="gce:n1-standard-8">n1-standard-8</option>
<option value="gce:n1-standard-16">n1-standard-16</option>
<option value="gce:n1-standard-32">n1-standard-32</option>
<option value="gce:n1-standard-64">n1-standard-64</option>
</select>
</div>
</div>
<div class="col-1">
<i class="far fa-sm fa-question-circle" title='Select from a variety of preconfigured instance configurations. Default: (not set)'></i>
</div>
</div>
<div class="row">
<label class="col-3 col-form-label text-right">Location: </label>
<div class="col-7">
<div class="form-group">
<select id="virtualMachineLocationInput" class="form-control" name="location">
<option value="none">none</option>
</select>
</div>
</div>
<div class="col-1">
<i class="far fa-sm fa-question-circle" title='Select the LXD cluster member or @group to deploy this virtual machine on. Default: none'></i>
</div>
</div>
<hr class="mb-2">
<nav>
<div class="nav nav-pills justify-content-center" id="nav-tab" role="tablist">
<a class="nav-link active" id="nav-boot-tab" data-toggle="tab" href="#nav-boot" role="tab" aria-controls="nav-boot" aria-selected="true">Boot</a>
<a class="nav-link" id="nav-cloud-init-tab" data-toggle="tab" href="#nav-cloud-init" role="tab" aria-controls="nav-cloud-init" aria-selected="true">Cloud-init</a>
<a class="nav-link" id="nav-limits-tab" data-toggle="tab" href="#nav-limits" role="tab" aria-controls="nav-limits" aria-selected="false">Limits</a>
<a class="nav-link" id="nav-migration-tab" data-toggle="tab" href="#nav-migration" role="tab" aria-controls="nav-migration" aria-selected="false">Migration</a>
<a class="nav-link" id="nav-other-tab" data-toggle="tab" href="#nav-other" role="tab" aria-controls="nav-other" aria-selected="false">Other</a>
<a class="nav-link" id="nav-raw-tab" data-toggle="tab" href="#nav-raw" role="tab" aria-controls="nav-raw" aria-selected="false">Raw</a>
<a class="nav-link" id="nav-security-tab" data-toggle="tab" href="#nav-security" role="tab" aria-controls="nav-security" aria-selected="false">Security</a>
<a class="nav-link" id="nav-snapshots-tab" data-toggle="tab" href="#nav-snapshots" role="tab" aria-controls="nav-snapshots" aria-selected="false">Snapshots</a>
</div>
</nav>
<hr class="mt-2">
<div class="tab-content" id="nav-tabContent">
<div class="tab-pane fade show active" id="nav-boot" role="tabpanel" aria-labelledby="nav-boot-tab">
<br>
<div class="row">
<label class="col-4 col-form-label text-right">Autostart: </label>
<div class="col-6">
<div class="form-group">
<select class="form-control" name="boot.autostart">
<option value="">(not set)</option>
<option value="true">true</option>
<option value="false">false</option>
</select>
</div>
</div>
<div class="col-1">
<i class="far fa-sm fa-question-circle" title='Select whether to automatically start the instance with LXD starts. If not set, defaults to instance last state.'></i>
</div>
</div>
<div class="row">
<label class="col-4 col-form-label text-right">Autostart Delay: </label>
<div class="col-6">
<div class="form-group">
<input type="number" class="form-control" name="boot.autostart.delay">
</div>
</div>
<div class="col-1">
<i class="far fa-sm fa-question-circle" title='Enter in the number of seconds to wait after the instance starts to boot up the next instance. Default: 0.'></i>
</div>
</div>
<div class="row">
<label class="col-4 col-form-label text-right">Autostart Priority: </label>
<div class="col-6">
<div class="form-group">
<input type="number" class="form-control" name="boot.autostart.priority">
</div>
</div>
<div class="col-1">
<i class="far fa-sm fa-question-circle" title='Enter in a number to determine the order the instance boots, higher numbers being first. Default: 0.'></i>
</div>
</div>
<div class="row">
<label class="col-4 col-form-label text-right">Host Shutdown Timeout: </label>
<div class="col-6">
<div class="form-group">
<input type="number" class="form-control" name="boot.host_shutdown_timeout">
</div>
</div>
<div class="col-1">
<i class="far fa-sm fa-question-circle" title='Enter in a the number of seconds to wait on host shutdown before forcefull shutdown of instance. Default: 30.'></i>
</div>
</div>
<div class="row">
<label class="col-4 col-form-label text-right">Stop Priority: </label>
<div class="col-6">
<div class="form-group">
<input type="number" class="form-control" name="boot.stop.priority">
</div>
</div>
<div class="col-1">
<i class="far fa-sm fa-question-circle" title='Enter in a number to determine the order the instance shutsdown, higher numbers being first. Default: 0.'></i>
</div>
</div>
</div>
<div class="tab-pane fade" id="nav-cloud-init" role="tabpanel" aria-labelledby="nav-cloud-init-tab">
<br>
<div class="row">
<label class="col-4 col-form-label text-right">Network Config: </label>
<div class="col-6">
<div class="form-group">
<textarea class="form-control" name="cloud-init.network-config"></textarea>
</div>
</div>
<div class="col-1">
<i class="far fa-sm fa-question-circle" title='Support for this option depends on the instance image. Enter in network configuration. Default: not set.'></i>
</div>
</div>
<div class="row">
<label class="col-4 col-form-label text-right">User Data: </label>
<div class="col-6">
<div class="form-group">
<textarea class="form-control" name="cloud-init.user-data"></textarea>
</div>
</div>
<div class="col-1">
<i class="far fa-sm fa-question-circle" title='Support for this option depends on the instance image. Enter in user data configuration. If both cloud-init.user-data and cloud-init.vendor-data exist, the contents of both are merged. Default: not set.'></i>
</div>
</div>
<div class="row">
<label class="col-4 col-form-label text-right">Vendor Data: </label>
<div class="col-6">
<div class="form-group">
<textarea class="form-control" name="cloud-init.vendor-data"></textarea>
</div>
</div>
<div class="col-1">
<i class="far fa-sm fa-question-circle" title='Support for this option depends on the instance image. Enter in vendor data configuration. If both cloud-init.user-data and cloud-init.vendor-data exist, the contents of both are merged. Default: not set.'></i>
</div>
</div>
</div>
<div class="tab-pane fade" id="nav-limits" role="tabpanel" aria-labelledby="nav-limits-tab">
<br>
<div class="row">
<label class="col-4 col-form-label text-right">CPU: </label>
<div class="col-6">
<div class="form-group">
<input type="text" class="form-control" name="limits.cpu">
</div>
</div>
<div class="col-1">
<i class="far fa-sm fa-question-circle" title='Enter in the number or range of CPUs to expose to the instance.'></i>
</div>
</div>
<div class="row">
<label class="col-4 col-form-label text-right">Disk Priority: </label>
<div class="col-6">
<div class="form-group">
<input type="number" class="form-control" name="limits.disk.priority">
</div>
</div>
<div class="col-1">
<i class="far fa-sm fa-question-circle" title='Enter in an integer between 0 (min) and 10 (max) to schedule disk I/O request priority compared to other instances. Default: 5.'></i>
</div>
</div>
<div class="row">
<label class="col-4 col-form-label text-right">Memory: </label>
<div class="col-6">
<div class="form-group">
<input type="text" class="form-control" name="limits.memory">
</div>
</div>
<div class="col-1">
<i class="far fa-sm fa-question-circle" title="Enter in a percentage of the host's memory or enter in a fixed value of bytes."></i>
</div>
</div>
<div class="row">
<label class="col-4 col-form-label text-right">Memory Hugepages: </label>
<div class="col-6">
<div class="form-group">
<select class="form-control" name="limits.memory.hugepages">
<option value="">(not set)</option>
<option value="true">true</option>
<option value="false">false</option>
</select>
</div>
</div>
<div class="col-1">
<i class="far fa-sm fa-question-circle" title="Select whether to back the instance using hugepages rather than regular system memory. Default: false."></i>
</div>
</div>
<div class="row">
<label class="col-4 col-form-label text-right">Network Priority: </label>
<div class="col-6">
<div class="form-group">
<input type="number" class="form-control" name="limits.network.priority">
</div>
</div>
<div class="col-1">
<i class="far fa-sm fa-question-circle" title="Enter in the priority for the instance network when the host is under, with 10 being the priority. Default 0."></i>
</div>
</div>
</div>
<div class="tab-pane fade" id="nav-migration" role="tabpanel" aria-labelledby="nav-migration-tab">
<br>
<div class="row">
<label class="col-4 col-form-label text-right">Stateful: </label>
<div class="col-6">
<div class="form-group">
<select class="form-control" name="migration.stateful">
<option value="">(not set)</option>
<option value="true">true</option>
<option value="false">false</option>
</select>
</div>
</div>
<div class="col-1">
<i class="far fa-sm fa-question-circle" title="Select whether to allow for stateful stop/start and snapshots. This will prevent the use of some features that are incompatible with it. Default: false."></i>
</div>
</div>
</div>
<div class="tab-pane fade" id="nav-other" role="tabpanel" aria-labelledby="nav-other-tab">
<br>
<div class="row">
<label class="col-4 col-form-label text-right">Cluster Evacuate: </label>
<div class="col-6">
<div class="form-group">
<select class="form-control" name="cluster.evacuate">
<option value="">(not set)</option>
<option value="auto">auto</option>
<option value="migrate">migrate</option>
<option value="stop">stop</option>
</select>
</div>
</div>
<div class="col-1">
<i class="far fa-sm fa-question-circle" title='Select what to do when evacuating the instance. Default: auto'></i>
</div>
</div>
</div>
<div class="tab-pane fade" id="nav-raw" role="tabpanel" aria-labelledby="nav-raw-tab">
<br>
<div class="row">
<label class="col-4 col-form-label text-right">Apparmor: </label>
<div class="col-6">
<div class="form-group">
<input type="text" class="form-control" name="raw.apparmor">
</div>
</div>
<div class="col-1">
<i class="far fa-sm fa-question-circle" title="Enter in apparmor profile entries to be appended to the profile. Default: (not set)."></i>
</div>
</div>
<div class="row">
<label class="col-4 col-form-label text-right">Qemu: </label>
<div class="col-6">
<div class="form-group">
<input type="text" class="form-control" name="raw.qemu">
</div>
</div>
<div class="col-1">
<i class="far fa-sm fa-question-circle" title="Enter raw QEMU configuration to be appended to the generated command line. Default: (not set)."></i>
</div>
</div>
<div class="row">
<label class="col-4 col-form-label text-right">Qemu.conf: </label>
<div class="col-6">
<div class="form-group">
<input type="text" class="form-control" name="raw.qemu.conf">
</div>
</div>
<div class="col-1">
<i class="far fa-sm fa-question-circle" title="Enter in addition/override to the generated qemu.conf file. Default: (not set)."></i>
</div>
</div>
</div>
<div class="tab-pane fade" id="nav-security" role="tabpanel" aria-labelledby="nav-security-tab">
<br>
<div class="row">
<label class="col-4 col-form-label text-right">Devlxd: </label>
<div class="col-6">
<div class="form-group">
<select class="form-control" name="security.devlxd">
<option value="">(not set)</option>
<option value="true">true</option>
<option value="false">false</option>
</select>
</div>
</div>
<div class="col-1">
<i class="far fa-sm fa-question-circle" title="Select whether to control the presence of /dev/lxd in the instance. Default: true."></i>
</div>
</div>
<div class="row">
<label class="col-4 col-form-label text-right">Protection Delete: </label>
<div class="col-6">
<div class="form-group">
<select class="form-control" name="security.protection.delete">
<option value="">(not set)</option>
<option value="true">true</option>
<option value="false">false</option>
</select>
</div>
</div>
<div class="col-1">
<i class="far fa-sm fa-question-circle" title="Select whether to prevent the instance from being deleted. Default: false."></i>
</div>
</div>
<div class="row">
<label class="col-4 col-form-label text-right">Agent Metrics: </label>
<div class="col-6">
<div class="form-group">
<select class="form-control" name="security.agent.metrics">
<option value="">(not set)</option>
<option value="true">true</option>
<option value="false">false</option>
</select>
</div>
</div>
<div class="col-1">
<i class="far fa-sm fa-question-circle" title="Select whether the lxd-agent is queried for state information and metrics. Default: true."></i>
</div>
</div>
<div class="row">
<label class="col-4 col-form-label text-right">Secureboot: </label>
<div class="col-6">
<div class="form-group">
<select class="form-control" name="security.secureboot">
<option value="">(not set)</option>
<option value="true">true</option>
<option value="false">false</option>
</select>
</div>
</div>
<div class="col-1">
<i class="far fa-sm fa-question-circle" title="Select whether whether UEFI secure boot is enabled with the default Microsoft keys. Default: true."></i>
</div>
</div>
</div>
<div class="tab-pane fade" id="nav-snapshots" role="tabpanel" aria-labelledby="nav-snapshots-tab">
<br>
<div class="row">
<label class="col-4 col-form-label text-right">Schedule: </label>
<div class="col-6">
<div class="form-group">
<input type="text" class="form-control" name="snapshots.schedule">
</div>
</div>
<div class="col-1">
<i class="far fa-sm fa-question-circle" title="Enter in a cron expression (<minute> <hour> <dom> <month> <dow>), or a comma separated list of schedule aliases <@hourly> <@daily> <@midnight> <@weekly> <@monthly> <@annually> <@yearly> <@startup>. Default: (not set)."></i>
</div>
</div>
<div class="row">
<label class="col-4 col-form-label text-right">Schedule Stopped: </label>
<div class="col-6">
<div class="form-group">
<select class="form-control" name="snapshots.schedule.stopped">
<option value="">(not set)</option>
<option value="true">true</option>
<option value="false">false</option>
</select>
</div>
</div>
<div class="col-1">
<i class="far fa-sm fa-question-circle" title="Select whether stopped instances are to be snapshoted automatically. Default: false."></i>
</div>
</div>
<div class="row">
<label class="col-4 col-form-label text-right">Pattern: </label>
<div class="col-6">
<div class="form-group">
<input type="text" class="form-control" name="snapshots.pattern'">
</div>
</div>
<div class="col-1">
<i class="far fa-sm fa-question-circle" title="Enter in a pongo2 template string representing the snapshot name. Default: snap%d."></i>
</div>
</div>
<div class="row">
<label class="col-4 col-form-label text-right">Expiry: </label>
<div class="col-6">
<div class="form-group">
<input type="text" class="form-control" name="snapshots.expiry">
</div>
</div>
<div class="col-1">
<i class="far fa-sm fa-question-circle" title="Enter in time controls when snapshots are to be deleted (expects expressions like 1M 2H 3d 4w 5m 6y). Default: (not set)."></i>
</div>
</div>
</div>
</div>
</form>
<div class="modal-footer">
<button class="btn btn-secondary" type="button" data-dismiss="modal">Cancel</button>
<a class="btn btn-primary" href="#" onclick="addItem()" data-dismiss="modal">Submit</a>
</div>
</div>
<div class="tab-pane fade" id="json" role="tabpanel" aria-labelledby="json-tab">
<br />
<div class="row">
<div class="col-12">
<div class="form-group text-right">
<pre>
<textarea name="json" class="form-control" id="jsonCreateInput" rows="16" placeholder="Enter JSON data"></textarea>
</pre>
</div>
</div>
</div>
<div class="modal-footer">
<button class="btn btn-secondary" type="button" data-dismiss="modal">Cancel</button>
<a class="btn btn-primary" href="#" onclick="createItemUsingJSON()" data-dismiss="modal">Submit</a>
</div>
</div>
</div>
</div>
</div>
</div>
</div>

View file

@ -20,7 +20,7 @@
</li>
<li id="serverNavbarSelect" class="nav-item" style="display: none;">
<div class="input-group">
<select class="form-control" id="serverListNav" style="width:150px;" onchange="changeServer(this.value)">
<select class="form-select" id="serverListNav" style="width:150px;" onchange="changeServer(this.value)">
</select>
</div>
</li>
@ -31,19 +31,19 @@
</li>
<li id="projectNavbarSelect" class="nav-item" style="display: none;">
<div class="input-group">
<select class="form-control" id="projectListNav" style="width:150px;" onchange="changeProject(this.value)">
<select class="form-select" id="projectListNav" style="width:150px;" onchange="changeProject(this.value)">
</select>
</div>
</li>
<!-- Nav Item - User Information -->
<li class="nav-item dropdown">
<a class="nav-link" href="#" id="userDropdown" data-toggle="dropdown" aria-expanded="false">
<li class="nav-item dropdown border-start ml-3">
<a class="nav-link" href="#" id="userDropdown" data-bs-toggle="dropdown" aria-expanded="false">
<i class="fas fa-user-circle"></i>
<span id="username">{{ page_username }}</span>
</a>
<!-- Dropdown - User Information -->
<div class="dropdown-menu dropdown-menu-right" aria-labelledby="userDropdown">
<div class="dropdown-menu dropdown-menu-end" aria-labelledby="userDropdown">
<a class="dropdown-item" href="#" onclick="loadAccountModal()">
<i class="fas fa-user-circle fa-sm fa-fw mr-2"></i>
Account
@ -68,7 +68,7 @@
<i class="fas fa-history fa-sm fa-fw mr-2"></i>
Logs
</a> -->
<a class="dropdown-item" href="#" data-toggle="modal" data-target="#aboutModal">
<a class="dropdown-item" href="#" data-bs-toggle="modal" data-bs-target="#aboutModal">
<i class="fas fa-info-circle fa-sm fa-fw mr-2"></i>
About
</a>

View file

@ -6,9 +6,9 @@
<h1>{{ page_title | safe }}</h1>
</div>
<div class="col-sm-6">
<a class="btn btn-outline-primary float-sm-right mr-4" href="#" data-toggle="modal" data-target="#addModal" title="Add Network ACL Rule" aria-hidden="true">
<button class="btn btn-outline-primary float-sm-right mr-4" data-bs-toggle="modal" data-bs-target="#addModal" title="Add Network ACL Rule" aria-hidden="true">
<i class="fas fa-plus fa-sm fa-fw"></i> Network ACL Rule
</a>
</button>
</div>
</div>
{% endblock header %}
@ -17,10 +17,10 @@
<div class="col-12">
<ul class="nav nav-tabs" id="myTab" role="tablist">
<li class="nav-item">
<a class="nav-link active" id="ingress-tab" data-toggle="tab" href="#ingress" role="tab" aria-controls="ingress" aria-selected="true">Ingress</a>
<a class="nav-link active" id="ingress-tab" data-bs-toggle="tab" href="#ingress" role="tab" aria-controls="ingress" aria-selected="true">Ingress</a>
</li>
<li class="nav-item">
<a class="nav-link" id="egress-tab" data-toggle="tab" href="#egress" role="tab" aria-controls="egress" aria-selected="false">Egress</a>
<a class="nav-link" id="egress-tab" data-bs-toggle="tab" href="#egress" role="tab" aria-controls="egress" aria-selected="false">Egress</a>
</li>
</ul>
@ -136,7 +136,10 @@
url: "../api/network-acl/list_network_acls?id="+serverId+"&project=" + project + "&acl=" + acl,
dataType: "json",
dataSrc: "metadata.ingress",
contentType: "application/json"
contentType: "application/json",
error: function (xhr, error, code) {
console.log(xhr, code);
}
},
columns: [
{ title: "Index", data: function (row, type, set) {
@ -237,7 +240,10 @@
url: "../api/network-acl/list_network_acls?id="+serverId+"&project=" + project + "&acl=" + acl,
dataType: "json",
dataSrc: "metadata.egress",
contentType: "application/json"
contentType: "application/json",
error: function (xhr, error, code) {
console.log(xhr, code);
}
},
columns: [
{ title: "Index", data: function (row, type, set) {

View file

@ -6,9 +6,9 @@
<h1>{{ page_title | safe }}</h1>
</div>
<div class="col-sm-6">
<a class="btn btn-outline-primary float-sm-right mr-4" href="#" data-toggle="modal" data-target="#addModal" title="Add Network ACL" aria-hidden="true">
<button class="btn btn-outline-primary float-sm-right mr-4" data-bs-toggle="modal" data-bs-target="#addModal" title="Add Network ACL" aria-hidden="true">
<i class="fas fa-plus fa-sm fa-fw"></i> Network ACL
</a>
</button>
</div>
</div>
{% endblock header %}
@ -98,7 +98,10 @@
url: "../api/network-acls/list_network_acls?id="+serverId+"&project=" + project + "&recursion=1",
dataType: "json",
dataSrc: "metadata",
contentType: "application/json"
contentType: "application/json",
error: function (xhr, error, code) {
console.log(xhr, code);
}
},
columns: [
{ title: "Name", data: function (row, type, set) {

View file

@ -6,9 +6,9 @@
<h1>{{ page_title | safe }}</h1>
</div>
<div class="col-sm-6">
<a class="btn btn-outline-primary float-sm-right mr-4" href="#" data-toggle="modal" data-target="#addModal" title="Add Network Zone" aria-hidden="true">
<button class="btn btn-outline-primary float-sm-right mr-4" data-bs-toggle="modal" data-bs-target="#addModal" title="Add Network Zone" aria-hidden="true">
<i class="fas fa-plus fa-sm fa-fw"></i> Network Zone
</a>
</button>
</div>
</div>
{% endblock header %}
@ -98,7 +98,10 @@
url: "../api/network-zones/list_network_zones?id="+serverId+"&project=" + project + "&recursion=1",
dataType: "json",
dataSrc: "metadata",
contentType: "application/json"
contentType: "application/json",
error: function (xhr, error, code) {
console.log(xhr, code);
}
},
columns: [
{ title: "Name", data: function (row, type, set) {

View file

@ -6,14 +6,13 @@
<h1>{{ page_title | safe }} <span id="network_title"></span></h1>
</div>
<div class="col-sm-6">
<a class="btn btn-outline-primary dropdown-toggle float-sm-right ml-2 mr-4" href="#" role="button" id="dropdownMenuLink" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false" title="Actions">
<button class="btn btn-outline-primary dropdown-toggle float-sm-right ml-2 mr-4" type="button" id="dropdownMenuLink" data-bs-toggle="dropdown" aria-expanded="false" title="Actions">
Network Actions
</a>
</button>
<div class="dropdown-menu dropdown-menu-right shadow animated--fade-in" aria-labelledby="dropdownMenuLink">
<a class="dropdown-item text-primary" href="#" data-toggle="modal" data-target="#addLoadBalancerModal" id="addLoadBalancer"><i class="fas fa-save fa-sm fa-fw mr-2"></i>Add Load Balancer</a>
<a class="dropdown-item text-primary" href="#" data-toggle="modal" data-target="#addForwardModal" id="addForward"><i class="fas fa-save fa-sm fa-fw mr-2"></i>Add Forward</a>
<a class="dropdown-item text-primary" href="#" data-toggle="modal" data-target="#addPeerModal" id="addPeer"><i class="fas fa-save fa-sm fa-fw mr-2"></i>Add Peer</a>
<a class="dropdown-item text-primary" href="#" data-bs-toggle="modal" data-bs-target="#addLoadBalancerModal" id="addLoadBalancer"><i class="fas fa-save fa-sm fa-fw mr-2"></i>Add Load Balancer</a>
<a class="dropdown-item text-primary" href="#" data-bs-toggle="modal" data-bs-target="#addForwardModal" id="addForward"><i class="fas fa-save fa-sm fa-fw mr-2"></i>Add Forward</a>
<a class="dropdown-item text-primary" href="#" data-bs-toggle="modal" data-bs-target="#addPeerModal" id="addPeer"><i class="fas fa-save fa-sm fa-fw mr-2"></i>Add Peer</a>
</div>
</div>
@ -25,10 +24,10 @@
<nav>
<div class="nav nav-tabs" id="nav-page-tab" role="tablist">
<a class="nav-item nav-link active" id="nav-home-tab" data-toggle="tab" href="#nav-home" role="tab" aria-controls="nav-home" aria-selected="true">Home</a>
<a class="nav-item nav-link" id="nav-forwards-tab" data-toggle="tab" href="#nav-forwards" role="tab" aria-controls="nav-forwards" aria-selected="false">Forwards</a>
<a class="nav-item nav-link" id="nav-load-balancers-tab" data-toggle="tab" href="#nav-load-balancers" role="tab" aria-controls="nav-load-balancers" aria-selected="false">Load Balancers</a>
<a class="nav-item nav-link" id="nav-peers-tab" data-toggle="tab" href="#nav-peers" role="tab" aria-controls="nav-peers" aria-selected="false">Peers</a>
<button class="nav-link active" id="nav-home-tab" data-bs-toggle="tab" data-bs-target="#nav-home" type="button" role="tab" aria-controls="nav-home" aria-selected="true">Home</button>
<button class="nav-link" id="nav-forwards-tab" data-bs-toggle="tab" data-bs-target="#nav-forwards" type="button" role="tab" aria-controls="nav-forwards" aria-selected="false">Forwards</button>
<button class="nav-link" id="nav-load-balancers-tab" data-bs-toggle="tab" data-bs-target="#nav-load-balancers" type="button" role="tab" aria-controls="nav-load-balancers" aria-selected="false">Load Balancers</button>
<button class="nav-link" id="nav-peers-tab" data-bs-toggle="tab" data-bs-target="#nav-peers" type="button" role="tab" aria-controls="nav-peers" aria-selected="false">Peers</button>
</div>
</nav>
<div class="tab-content" id="nav-page-content">
@ -142,11 +141,11 @@
</h3>
<div class="card-tools">
<button type="button" class="btn btn-tool" data-card-widget="collapse"><i class="fas fa-minus"></i></button>
<button type="button" class="btn btn-tool" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
<button type="button" class="btn btn-tool" data-bs-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
<i class="fa fa-bars"></i>
</button>
<div class="dropdown-menu dropdown-menu-right">
<a href="#" class="dropdown-item" data-toggle="modal" data-target="#addForwardModal" title="Create Forward">Create Forward</a>
<a href="#" class="dropdown-item" data-bs-toggle="modal" data-bs-target="#addForwardModal" title="Create Forward">Create Forward</a>
</div>
</div>
</div>
@ -171,11 +170,11 @@
</h3>
<div class="card-tools">
<button type="button" class="btn btn-tool" data-card-widget="collapse"><i class="fas fa-minus"></i></button>
<button type="button" class="btn btn-tool" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
<button type="button" class="btn btn-tool" data-bs-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
<i class="fa fa-bars"></i>
</button>
<div class="dropdown-menu dropdown-menu-right">
<a href="#" class="dropdown-item" data-toggle="modal" data-target="#addLoadBalancerModal" title="Create Load Balancer">Create Load Balancer</a>
<a href="#" class="dropdown-item" data-bs-toggle="modal" data-bs-target="#addLoadBalancerModal" title="Create Load Balancer">Create Load Balancer</a>
</div>
</div>
</div>
@ -200,11 +199,11 @@
</h3>
<div class="card-tools">
<button type="button" class="btn btn-tool" data-card-widget="collapse"><i class="fas fa-plus"></i></button>
<button type="button" class="btn btn-tool" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
<button type="button" class="btn btn-tool" data-bs-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
<i class="fa fa-bars"></i>
</button>
<div class="dropdown-menu dropdown-menu-right">
<a href="#" class="dropdown-item" data-toggle="modal" data-target="#addPeerModal" title="Create Peer">Create Peer</a>
<a href="#" class="dropdown-item" data-bs-toggle="modal" data-bs-target="#addPeerModal" title="Create Peer">Create Peer</a>
</div>
</div>
</div>
@ -351,7 +350,10 @@
url: "../api/network/list_network_leases?id="+serverId+"&project="+project+"&name="+network,
dataType: "json",
dataSrc: "metadata",
contentType: "application/json"
contentType: "application/json",
error: function (xhr, error, code) {
console.log(xhr, code);
}
},
rowId: 'id',
stateSave: true,
@ -413,7 +415,10 @@
url: "../api/network/list_network_load_balancers?id="+serverId+"&project="+project+"&name="+network+"&recursion=1",
dataType: "json",
dataSrc: "metadata",
contentType: "application/json"
contentType: "application/json",
error: function (xhr, error, code) {
console.log(xhr, code);
}
},
stateSave: true,
columns: [
@ -470,7 +475,10 @@
url: "../api/network/list_network_forwards?id="+serverId+"&project="+project+"&name="+network+"&recursion=1",
dataType: "json",
dataSrc: "metadata",
contentType: "application/json"
contentType: "application/json",
error: function (xhr, error, code) {
console.log(xhr, code);
}
},
stateSave: true,
columns: [
@ -527,7 +535,10 @@
url: "../api/network/list_network_peers?id="+serverId+"&project="+project+"&name="+network+"&recursion=1",
dataType: "json",
dataSrc: "metadata",
contentType: "application/json"
contentType: "application/json",
error: function (xhr, error, code) {
console.log(xhr, code);
}
},
rowId: 'id',
stateSave: true,

View file

@ -6,9 +6,9 @@
<h1>{{ page_title | safe }}</h1>
</div>
<div class="col-sm-6">
<a class="btn btn-outline-primary float-sm-right mr-4" href="#" data-toggle="modal" data-target="#addModal" title="Add Network" aria-hidden="true">
<button class="btn btn-outline-primary float-sm-right mr-4" data-bs-toggle="modal" data-bs-target="#addModal" title="Add Network" aria-hidden="true">
<i class="fas fa-plus fa-sm fa-fw"></i> Network
</a>
</button>
</div>
</div>
{% endblock header %}
@ -98,7 +98,10 @@
url: "../api/networks/list_networks?id="+serverId+"&project=" + project + "&recursion=1",
dataType: "json",
dataSrc: "metadata",
contentType: "application/json"
contentType: "application/json",
error: function (xhr, error, code) {
console.log(xhr, code);
}
},
columns: [
{ title: "Name", data: function (row, type, set) {

View file

@ -94,7 +94,10 @@
url: "../api/operations/list_operations?id="+serverId+"&project=" + project + "&recursion=1",
dataType: "json",
dataSrc: "metadata.running",
contentType: "application/json"
contentType: "application/json",
error: function (xhr, error, code) {
console.log(xhr, code);
}
},
columns: [
{ title: "ID", data: function (row, type, set) {

View file

@ -6,9 +6,9 @@
<h1>{{ page_title | safe }}</h1>
</div>
<div class="col-sm-6">
<a class="btn btn-outline-primary float-sm-right mr-4" href="#" data-toggle="modal" data-target="#addModal" title="Add Profile" aria-hidden="true">
<button class="btn btn-outline-primary float-sm-right mr-4" data-bs-toggle="modal" data-bs-target="#addModal" title="Add Profile" aria-hidden="true">
<i class="fas fa-plus fa-sm fa-fw"></i> Profile
</a>
</button>
</div>
</div>
{% endblock header %}
@ -98,7 +98,10 @@
url: "../api/profiles/list_profiles?id="+serverId+"&project=" + project + "&recursion=1",
dataType: "json",
dataSrc: "metadata",
contentType: "application/json"
contentType: "application/json",
error: function (xhr, error, code) {
console.log(xhr, code);
}
},
columns: [
{ title: "Name", data: function (row, type, set) {

View file

@ -6,9 +6,9 @@
<h1>{{ page_title | safe }}</h1>
</div>
<div class="col-sm-6">
<a class="btn btn-outline-primary float-sm-right mr-4" href="#" data-toggle="modal" data-target="#addModal" title="Add Project" aria-hidden="true">
<button class="btn btn-outline-primary float-sm-right mr-4" data-bs-toggle="modal" data-bs-target="#addModal" title="Add Project" aria-hidden="true">
<i class="fas fa-plus fa-sm fa-fw"></i> Project
</a>
</button>
</div>
</div>
{% endblock header %}
@ -98,7 +98,10 @@
url: "../api/projects/list_projects?id="+serverId+"&project="+project+"&recursion=1",
dataType: "json",
dataSrc: "metadata",
contentType: "application/json"
contentType: "application/json",
error: function (xhr, error, code) {
console.log(xhr, code);
}
},
columns: [
{ title: "Name", data: function (row, type, set) {

View file

@ -7,9 +7,9 @@
<h1>{{ page_title | safe }}</h1>
</div>
<div class="col-sm-6">
<a class="btn btn-outline-primary float-sm-right mr-4" href="#" data-toggle="modal" data-target="#addModal" title="Add Role" aria-hidden="true">
<button class="btn btn-outline-primary float-sm-right mr-4" data-bs-toggle="modal" data-bs-target="#addModal" title="Add Role" aria-hidden="true">
<i class="fas fa-plus fa-sm fa-fw"></i> Role
</a>
</button>
</div>
</div>
-->
@ -61,7 +61,10 @@
url: "../api/roles/list_roles",
dataType: "json",
dataSrc: "data",
contentType: "application/json"
contentType: "application/json",
error: function (xhr, error, code) {
console.log(xhr, code);
}
},
columns: [
{ title: "Name", data: function (row, type, set) {

View file

@ -9,7 +9,6 @@
<div class="col-12 mt-n3">
<div class="row">
<div class="col-md-3 col-sm-6 col-12">
<div class="info-box">
<a href="#" class="stretched-link" id="containersLink"></a>
@ -404,7 +403,7 @@
});
//Load Containers Info
$.getJSON("../api/containers/list_instances?id="+encodeURI(serverId)+'&project='+encodeURI(project)+'&recursion=1', function (data) {
$.getJSON("../api/instances/list_instances?id="+encodeURI(serverId)+'&project='+encodeURI(project)+'&filter=container'+'&recursion=1', function (data) {
data = data.metadata;
running_containers = 0
@ -430,7 +429,7 @@
});
// Load Virtual Machine Info
$.getJSON("../api/virtual-machines/list_instances?id="+encodeURI(serverId)+'&project='+encodeURI(project)+'&recursion=1', function (data) {
$.getJSON("../api/instances/list_instances?id="+encodeURI(serverId)+'&project='+encodeURI(project)+'&filter=virtual-machine'+'&recursion=1', function (data) {
data = data.metadata;
running_virtual_machines = 0
@ -516,8 +515,8 @@
});
//Set hyperlink references for cards
$("#containersLink").attr("href", "containers?id="+serverId+"&project="+project)
$("#virtualMachinesLink").attr("href", "virtual-machines?id="+serverId+"&project="+project)
$("#containersLink").attr("href", "instances?id="+serverId+"&project="+project)
$("#virtualMachinesLink").attr("href", "instances?id="+serverId+"&project="+project)
$("#clusterMembersLink").attr("href", "cluster-members?id="+serverId+"&project="+project)
$("#imagesLink").attr("href", "images?id="+serverId+"&project="+project)
$("#profilesLink").attr("href", "profiles?id="+serverId+"&project="+project)

View file

@ -6,9 +6,9 @@
<h1>{{ page_title | safe }}</h1>
</div>
<div class="col-sm-6">
<a class="btn btn-outline-primary float-sm-right mr-4" href="#" data-toggle="modal" data-target="#addModal" title="Add Server" aria-hidden="true">
<button class="btn btn-outline-primary float-sm-right mr-4" data-bs-toggle="modal" data-bs-target="#addModal" title="Add Server" aria-hidden="true">
<i class="fas fa-plus fa-sm fa-fw"></i> Server
</a>
</button>
</div>
</div>
{% endblock header %}
@ -59,7 +59,10 @@
url: "../api/servers/list_servers",
dataType: "json",
dataSrc: "data",
contentType: "application/json"
contentType: "application/json",
error: function (xhr, error, code) {
console.log(xhr, code);
}
},
columns: [
{ title: "Name", data: function (row, type, set) {

View file

@ -40,18 +40,10 @@
<ul id="instanceSidebarLinks" class="nav nav-pills nav-sidebar flex-column user-panel py-2" style="display: none;" data-widget="treeview" role="menu" data-accordion="false">
<li class="nav-item">
<a class="nav-link" id="containersLinkSidebar" href="containers">
<i id="containersIcon" class="nav-icon fas fa-cube"></i>
<p id="containersSpan">
Containers
</p>
</a>
</li>
<li class="nav-item">
<a class="nav-link" id="virtualMachinesLinkSidebar" href="virtual-machines">
<i id="virtualMachinesIcon" class="nav-icon fas fa-cube"></i>
<p id="virtualMachinesSpan">
Virtual Machines
<a class="nav-link" id="instancesLinkSidebar" href="instances">
<i id="instancesIcon" class="nav-icon fas fa-cube"></i>
<p id="instancesSpan">
Instances
</p>
</a>
</li>

View file

@ -6,9 +6,9 @@
<h1>{{ page_title | safe }}</h1>
</div>
<div class="col-sm-6">
<a class="btn btn-outline-primary float-sm-right mr-4" href="#" data-toggle="modal" data-target="#addModal" title="Add Simplestreams Repository" aria-hidden="true">
<button class="btn btn-outline-primary float-sm-right mr-4" data-bs-toggle="modal" data-bs-target="#addModal" title="Add Simplestreams Repository" aria-hidden="true">
<i class="fas fa-plus fa-sm fa-fw"></i> Simplestreams Repository
</a>
</button>
</div>
</div>
{% endblock header %}
@ -97,7 +97,10 @@
url: "../api/simplestreams/list_simplestreams",
dataType: "json",
dataSrc: "data",
contentType: "application/json"
contentType: "application/json",
error: function (xhr, error, code) {
console.log(xhr, code);
}
},
columns: [
{ title: "URL", data: function (row, type, set) {

View file

@ -6,9 +6,9 @@
<h1>{{ page_title | safe }}</h1>
</div>
<div class="col-sm-6">
<a class="btn btn-outline-primary float-sm-right mr-4" href="#" data-toggle="modal" data-target="#addModal" title="Add Storage Pool" aria-hidden="true">
<button class="btn btn-outline-primary float-sm-right mr-4" data-bs-toggle="modal" data-bs-target="#addModal" title="Add Storage Pool" aria-hidden="true">
<i class="fas fa-plus fa-sm fa-fw"></i> Storage Pool
</a>
</button>
</div>
</div>
{% endblock header %}
@ -98,7 +98,10 @@
url: "../api/storage-pools/list_storage_pools?id="+serverId+"&project=" + project + "&recursion=1",
dataType: "json",
dataSrc: "metadata",
contentType: "application/json"
contentType: "application/json",
error: function (xhr, error, code) {
console.log(xhr, code);
}
},
columns: [
{ title: "Name", data: function (row, type, set) {

View file

@ -6,9 +6,9 @@
<h1>{{ page_title | safe }}</h1>
</div>
<div class="col-sm-6">
<a class="btn btn-outline-primary float-sm-right mr-4" href="#" data-toggle="modal" data-target="#addModal" title="Add Storage Volume" aria-hidden="true">
<button class="btn btn-outline-primary float-sm-right mr-4" data-tbs-oggle="modal" data-bs-target="#addModal" title="Add Storage Volume" aria-hidden="true">
<i class="fas fa-plus fa-sm fa-fw"></i> Storage Volume
</a>
</button>
</div>
</div>
{% endblock header %}
@ -106,7 +106,10 @@
url: "../api/storage-volumes/list_storage_volumes?id="+serverId+"&project=" + project + "&recursion=1" + "&pool=" + pool,
dataType: "json",
dataSrc: "metadata",
contentType: "application/json"
contentType: "application/json",
error: function (xhr, error, code) {
console.log(xhr, code);
}
},
columns: [
{ title: "Name", data: function (row, type, set) {

View file

@ -6,9 +6,9 @@
<h1>{{ page_title | safe }}</h1>
</div>
<div class="col-sm-6">
<a class="btn btn-outline-primary float-sm-right mr-4" href="#" data-toggle="modal" data-target="#addModal" title="Add User" aria-hidden="true">
<button class="btn btn-outline-primary float-sm-right mr-4" data-bs-toggle="modal" data-bs-target="#addModal" title="Add User" aria-hidden="true">
<i class="fas fa-plus fa-sm fa-fw"></i> User
</a>
</button>
</div>
</div>
{% endblock header %}
@ -59,7 +59,10 @@
url: "../api/users/list_users",
dataType: "json",
dataSrc: "data",
contentType: "application/json"
contentType: "application/json",
error: function (xhr, error, code) {
console.log(xhr, code);
}
},
columns: [
{ title: "Username", data: function (row, type, set) {

File diff suppressed because it is too large Load diff

View file

@ -1,328 +0,0 @@
{% extends "main.html" %}
{% block header %}
<div class="row mb-2">
<div class="col-sm-6">
<h1>{{ page_title | safe }}</h1>
</div>
<div class="col-sm-6">
<a class="btn btn-outline-primary float-sm-right mr-4" href="#" data-toggle="modal" data-target="#addModal" title="Add Virtual Machine" aria-hidden="true">
<i class="fas fa-plus fa-sm fa-fw"></i> Virtual Machine
</a>
</div>
</div>
{% endblock header %}
{% block content %}
<div class="col-12">
<div class="card">
<div class="card-header">
<h3 class="card-title">Virtual Machines</h3>
<div class="card-tools">
<button type="button" class="btn btn-tool" onclick="reloadPageContent()" title="Refresh">
<i class="fas fa-sync"></i>
</button>
</div>
</div>
<div class="card-body">
<table class="table table-hover" id="myDataTable" width="100%" cellspacing="0">
</table>
</div>
</div>
</div>
{% endblock content %}
{% block modal %}
{% include 'modals/virtual-machines.html' %}
{% endblock modal %}
{% block script %}
<script>
var reloadTime = 10000;
const queryString = window.location.search;
const urlParams = new URLSearchParams(queryString);
const serverId = urlParams.get('id');
const project = urlParams.get('project');
var editedVirtualMachine = ''
applySidebarStyles();
applySidebarLinks();
populateSidebarLinks();
populateNavbarLinks();
function reloadPageContent() {
//Clear the automatic page reload
clearTimeout(pageReloadTimeout);
//Reload the datatables content
$('#myDataTable').DataTable().ajax.reload(null, false);
//Set the automatic page reload
pageReloadTimeout = setTimeout(() => { reloadPageContent(); }, reloadTime);
}
function loadPageContent(){
//Display the current project
$("#selectedProject").text(project);
//Populate the Server dropdown
$.getJSON("../api/servers/list_servers?id="+serverId, function (data) {
data = data.data
for (var index = 0; index < data.length; index++) {
if (data[index].name == '')
optionText = data[index].addr
else
optionText = data[index].name
if (data[index].id == serverId)
$('#serverListNav').append('<option value="' + data[index].id + '" selected="selected">' + optionText + '</option>');
else
$('#serverListNav').append('<option value="' + data[index].id + '">' + optionText + '</option>');
}
})
//Populate the Project dropdown
$.getJSON("../api/projects/list_projects?id="+serverId+"&project="+project, function (data) {
data = data.metadata
for (var index = 0; index < data.length; index++) {
optionText = data[index].replace('/1.0/projects/','');
if (optionText == project)
$('#projectListNav').append('<option value="' + optionText + '" selected="selected">' + optionText + '</option>');
else
$('#projectListNav').append('<option value="' + optionText + '">' + optionText + '</option>');
}
})
//Populate the modal Profile dropdown
$.getJSON("../api/profiles/list_profiles?id="+serverId+"&project="+project, function (data) {
data = data.metadata
for (var index = 0; index < data.length; index++) {
//When using projects other than default and no recursion, it gets like URL variable with "?"
optionText = data[index].split("?")
optionText = optionText[0].replace('/1.0/profiles/','');
if (optionText == 'default') {
$('#virtualMachineProfileInput').append('<option value="' + optionText + '" selected="selected">' + optionText + '</option>');
}
else {
$('#virtualMachineProfileInput').append('<option value="' + optionText + '">' + optionText + '</option>');
}
}
})
//Populate the modal Location dropdown
$.getJSON("../api/cluster-members/list_cluster_members?id="+serverId+"&project="+project, function (data) {
data = data.metadata
for (var index = 0; index < data.length; index++) {
optionText = data[index].replace('/1.0/cluster/members/','');
$('#virtualMachineLocationInput').append('<option value="' + optionText + '">' + optionText + '</option>');
}
})
$.getJSON("../api/cluster-groups/list_cluster_groups?id="+serverId+"&project="+project, function (data) {
data = data.metadata
for (var index = 0; index < data.length; index++) {
optionText = data[index].replace('/1.0/cluster/groups/','');
$('#containerLocationInput').append('<option value="@' + optionText + '">@' + optionText + '</option>');
}
})
//Populate the modal Image dropdown
$.getJSON("../api/images/list_images?id="+serverId+"&project="+project+"&recursion=1", function (data) {
data = data.metadata
for (var index = 0; index < data.length; index++) {
if (data[index].hasOwnProperty('type')) {
if(data[index].type == 'virtual-machine'){
$('#virtualMachineImageInput').append('<option value="' + data[index].fingerprint + '">' + data[index].properties.description + '</option>');
}
}
}
})
// Configure Datatable
$('#myDataTable').DataTable({
ajax: {
url: "../api/virtual-machines/list_instances?id="+serverId+"&project=" + project + "&recursion=2",
dataType: "json",
dataSrc: "metadata",
contentType: "application/json"
},
columns: [
{ title: "Name", data: function (row, type, set) {
if (row.hasOwnProperty('name')) {
if (row.name)
return '<a href="../virtual-machine?id=' + serverId + '&project=' + project + '&instance=' + row.name + '">' + row.name + '</a>';
}
return '-'
},
},
{ title: "OS", data: function (row, type, set) {
if (row.hasOwnProperty('expanded_config')) {
if (row.expanded_config.hasOwnProperty('image.os')) {
if (row.expanded_config['image.os']){
return row.expanded_config['image.os']
}
}
}
return '-'
},
},
{ title: "Location", data: function (row, type, set) {
if (row.hasOwnProperty('location')) {
if (row.location){
return row.location
}
}
return '-'
},
},
{ title: "IPv4", data: function (row, type, set) {
if (row.hasOwnProperty('ipv4_addresses')) {
if (row.ipv4_addresses.length > 0){
return row.ipv4_addresses.join(', <br />')
}
}
return '-'
},
},
{ title: "IPv6", data: function (row, type, set) {
if (row.hasOwnProperty('ipv6_addresses')) {
if (row.ipv6_addresses.length > 0){
return row.ipv6_addresses.join(', <br />')
}
}
return '-'
},
},
{ title: "Memory", data: function (row, type, set) {
if (row.hasOwnProperty('memory')) {
if (row.memory){
if (type === 'display'){
return (row.memory / 1024 / 1024).toFixed(2) + ' MiB'
}
return row.memory
}
}
return '-'
},
},
{ title: "Root Disk", data: function (row, type, set) {
if (row.hasOwnProperty('disk')) {
if (row.disk){
if (type === 'display'){
return (row.disk / 1024 / 1024).toFixed(2) + ' MiB'
}
return row.disk
}
}
return '-'
},
},
{ title: "Status", data: function (row, type, set) {
if (row.hasOwnProperty('status')) {
if (row.status){
return row.status
}
}
return '-'
},
},
{ title: "Actions", data: function (row, type, set) {
links = ''
if (row.hasOwnProperty('name') && row.hasOwnProperty('status')) {
if (row.name && row.status){
if (row.status == 'Frozen')
links += '<a href="#" onclick=changeItemState(\''+row.name+'\',\'unfreeze\')><i class="fas fa-pause fa-lg" style="color:#ddd" title="Edit" aria-hidden="true"></i></a>'
else if (row.status == 'Stopped')
links += '<a href="#" onclick=changeItemState(\''+row.name+'\',\'start\')><i class="fas fa-play fa-lg" style="color:#ddd" title="Edit" aria-hidden="true"></i></a>'
else if (row.status == 'Running')
links += '<a href="#" onclick=changeItemState(\''+row.name+'\',\'stop\')><i class="fas fa-stop fa-lg" style="color:#ddd" title="Edit" aria-hidden="true"></i></a>'
links += '&nbsp' + '&nbsp'
links += '<a href="#" onclick=deleteInstance(\''+row.name+'\')><i class="fas fa-trash-alt fa-lg" style="color:#ddd" title="Delete" aria-hidden="true"></i></a>'
}
}
return links
},
},
],
order: [],
});
//Set reload page content
pageReloadTimeout = setTimeout(() => { reloadPageContent(); }, reloadTime);
}
// Change state start/stop of instance
function changeItemState(name, action){
console.log("Info: starting container " + name);
$.post("../api/virtual-machines/change_instance_state?id=" + serverId + "&project=" + project, { name: name, action: action }, function (data) {
console.log(data);
if (data.error_code >= 400){
alert(data.error);
}
//Async type
setTimeout(() => { reloadPageContent(); }, 2000);
operationStatusCheck()
});
}
// Add instance
function addItem(){
console.log("Info: adding new virtual machine");
data = $('#addForm').serialize();
$.post("../api/virtual-machines/add_instance?id="+serverId+"&project="+project, data, function (data) {
console.log(data);
if (data.error_code >= 400){
alert(data.error);
}
//Aync type
setTimeout(() => { reloadPageContent(); }, 2000);
operationStatusCheck()
});
}
// Delete instance
function deleteInstance(name){
console.log("Info: confirming deletion of container " + name);
if (confirm("Are you sure you want to delete container " + name + "?") == true) {
console.log("Info: deleting container " + name);
$.post("../api/virtual-machines/delete_instance?id=" + serverId + "&project=" + project, { name: name }, function (data) {
console.log(data);
if (data.error_code >= 400){
alert(data.error);
}
//Async type
setTimeout(() => { reloadPageContent(); }, 2000);
operationStatusCheck()
});
}
}
// Create instance from JSON
function createItemUsingJSON(){
var json = $("#jsonCreateInput").val();
console.log("Info: adding new instance");
$.post("../api/virtual-machines/add_instance?id="+serverId+"&project="+project, { json: json }, function (data) {
console.log(data);
if (data.error_code >= 400){
alert(data.error);
}
//Async type
setTimeout(() => { reloadPageContent(); }, 2000);
operationStatusCheck()
});
}
$(document).ready(function(){
//If id or project variables are missing redirect to servers page
if (!serverId || !project) {
window.location.href = 'servers';
}
else {
loadPageContent()
operationStatusCheck()
}
});
</script>
{% endblock script %}

View file

@ -1,18 +1,17 @@
# 0.4.0
- Convert to bootstrap 5
# 0.5.0
- Add dark theme option
- Add bootstrap toast notifications
- Add warnings
# 0.5.0
# 0.6.0
- Add two factor authentication option
- Add password complexity requirements option
# 0.6.0
# 0.7.0
- Add support for MariaDB and Postgres database backends
- Add logs page
# 0.7.0
# 0.8.0
- Add offcanvas sidebars where appropriate for additional information
- Include rename tasks in tables with edit form on new tab