pvc/client-cli/pvc/cli_lib/provisioner.py

1699 lines
66 KiB
Python
Raw Normal View History

2020-01-02 11:18:46 -05:00
#!/usr/bin/env python3
# provisioner.py - PVC CLI client function library, Provisioner functions
# Part of the Parallel Virtual Cluster (PVC) system
#
2021-03-25 17:01:55 -04:00
# Copyright (C) 2018-2021 Joshua M. Boniface <joshua@boniface.me>
2020-01-02 11:18:46 -05:00
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, version 3.
2020-01-02 11:18:46 -05:00
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <https://www.gnu.org/licenses/>.
#
###############################################################################
from requests_toolbelt.multipart.encoder import MultipartEncoder, MultipartEncoderMonitor
from ast import literal_eval
import pvc.cli_lib.ansiprint as ansiprint
from pvc.cli_lib.common import UploadProgressBar, call_api
2020-01-02 11:18:46 -05:00
2020-01-02 11:18:46 -05:00
#
# Primary functions
#
def template_info(config, template, template_type):
"""
Get information about template
API endpoint: GET /api/v1/provisioner/template/{template_type}/{template}
API arguments:
2020-01-04 13:04:01 -05:00
API schema: {json_template_object}
2020-01-02 11:18:46 -05:00
"""
response = call_api(config, 'get', '/provisioner/template/{template_type}/{template}'.format(template_type=template_type, template=template))
2020-01-02 11:18:46 -05:00
if response.status_code == 200:
if isinstance(response.json(), list) and len(response.json()) != 1:
# No exact match; return not found
return False, "Template not found."
else:
# Return a single instance if the response is a list
if isinstance(response.json(), list):
return True, response.json()[0]
# This shouldn't happen, but is here just in case
else:
return True, response.json()
2020-01-02 11:18:46 -05:00
else:
2020-07-20 12:30:53 -04:00
return False, response.json().get('message', '')
2020-01-02 11:18:46 -05:00
2020-01-02 11:18:46 -05:00
def template_list(config, limit, template_type=None):
"""
Get list information about templates (limited by {limit})
API endpoint: GET /api/v1/provisioner/template/{template_type}
API arguments: limit={limit}
2020-01-04 13:04:01 -05:00
API schema: [{json_template_object},{json_template_object},etc.]
2020-01-02 11:18:46 -05:00
"""
params = dict()
if limit:
params['limit'] = limit
if template_type is not None:
response = call_api(config, 'get', '/provisioner/template/{template_type}'.format(template_type=template_type), params=params)
2020-01-02 11:18:46 -05:00
else:
response = call_api(config, 'get', '/provisioner/template', params=params)
2020-01-02 11:18:46 -05:00
if response.status_code == 200:
return True, response.json()
else:
2020-07-20 12:30:53 -04:00
return False, response.json().get('message', '')
2020-01-02 11:18:46 -05:00
2020-01-04 11:58:30 -05:00
def template_add(config, params, template_type=None):
"""
Add a new template of {template_type} with {params}
API endpoint: POST /api/v1/provisioner/template/{template_type}
API_arguments: args
API schema: {message}
"""
response = call_api(config, 'post', '/provisioner/template/{template_type}'.format(template_type=template_type), params=params)
2020-01-04 11:58:30 -05:00
if response.status_code == 200:
retvalue = True
else:
retvalue = False
2020-07-20 12:30:53 -04:00
return retvalue, response.json().get('message', '')
2020-01-04 11:58:30 -05:00
def template_modify(config, params, name, template_type):
"""
Modify an existing template of {template_type} with {params}
API endpoint: PUT /api/v1/provisioner/template/{template_type}/{name}
API_arguments: args
API schema: {message}
"""
response = call_api(config, 'put', '/provisioner/template/{template_type}/{name}'.format(template_type=template_type, name=name), params=params)
if response.status_code == 200:
retvalue = True
else:
retvalue = False
2020-07-20 12:30:53 -04:00
return retvalue, response.json().get('message', '')
def template_remove(config, name, template_type):
2020-01-04 11:58:30 -05:00
"""
2020-01-04 13:04:01 -05:00
Remove template {name} of {template_type}
2020-01-04 11:58:30 -05:00
API endpoint: DELETE /api/v1/provisioner/template/{template_type}/{name}
API_arguments:
API schema: {message}
"""
response = call_api(config, 'delete', '/provisioner/template/{template_type}/{name}'.format(template_type=template_type, name=name))
2020-01-04 11:58:30 -05:00
if response.status_code == 200:
retvalue = True
else:
retvalue = False
2020-07-20 12:30:53 -04:00
return retvalue, response.json().get('message', '')
2020-01-04 11:58:30 -05:00
2020-01-04 11:58:30 -05:00
def template_element_add(config, name, element_id, params, element_type=None, template_type=None):
"""
Add a new template element of {element_type} with {params} to template {name} of {template_type}
API endpoint: POST /api/v1/provisioner/template/{template_type}/{name}/{element_type}/{element_id}
API_arguments: args
API schema: {message}
"""
response = call_api(config, 'post', '/provisioner/template/{template_type}/{name}/{element_type}/{element_id}'.format(template_type=template_type, name=name, element_type=element_type, element_id=element_id), params=params)
2020-01-04 11:58:30 -05:00
if response.status_code == 200:
retvalue = True
else:
retvalue = False
2020-07-20 12:30:53 -04:00
return retvalue, response.json().get('message', '')
2020-01-04 11:58:30 -05:00
2020-01-04 11:58:30 -05:00
def template_element_remove(config, name, element_id, element_type=None, template_type=None):
"""
2020-01-04 13:04:01 -05:00
Remove template element {element_id} of {element_type} from template {name} of {template_type}
2020-01-04 11:58:30 -05:00
API endpoint: DELETE /api/v1/provisioner/template/{template_type}/{name}/{element_type}/{element_id}
API_arguments:
API schema: {message}
"""
response = call_api(config, 'delete', '/provisioner/template/{template_type}/{name}/{element_type}/{element_id}'.format(template_type=template_type, name=name, element_type=element_type, element_id=element_id))
2020-01-04 11:58:30 -05:00
if response.status_code == 200:
retvalue = True
else:
retvalue = False
2020-07-20 12:30:53 -04:00
return retvalue, response.json().get('message', '')
2020-01-04 11:58:30 -05:00
2020-01-04 13:04:01 -05:00
def userdata_info(config, userdata):
"""
Get information about userdata
API endpoint: GET /api/v1/provisioner/userdata/{userdata}
API arguments:
API schema: {json_data_object}
"""
response = call_api(config, 'get', '/provisioner/userdata/{userdata}'.format(userdata=userdata))
2020-01-04 13:04:01 -05:00
if response.status_code == 200:
if isinstance(response.json(), list) and len(response.json()) != 1:
# No exact match; return not found
return False, "Userdata not found."
else:
# Return a single instance if the response is a list
if isinstance(response.json(), list):
return True, response.json()[0]
# This shouldn't happen, but is here just in case
else:
return True, response.json()
2020-01-04 13:04:01 -05:00
else:
2020-07-20 12:30:53 -04:00
return False, response.json().get('message', '')
2020-01-04 13:04:01 -05:00
2020-01-04 13:04:01 -05:00
def userdata_list(config, limit):
"""
Get list information about userdatas (limited by {limit})
2020-01-04 14:06:36 -05:00
API endpoint: GET /api/v1/provisioner/userdata
2020-01-04 13:04:01 -05:00
API arguments: limit={limit}
API schema: [{json_data_object},{json_data_object},etc.]
"""
params = dict()
if limit:
params['limit'] = limit
response = call_api(config, 'get', '/provisioner/userdata', params=params)
2020-01-04 13:04:01 -05:00
if response.status_code == 200:
return True, response.json()
else:
2020-07-20 12:30:53 -04:00
return False, response.json().get('message', '')
2020-01-04 13:04:01 -05:00
def userdata_show(config, name):
"""
Get information about userdata name
API endpoint: GET /api/v1/provisioner/userdata/{name}
API arguments:
API schema: [{json_data_object},{json_data_object},etc.]
"""
response = call_api(config, 'get', '/provisioner/userdata/{}'.format(name))
if response.status_code == 200:
return True, response.json()[0]['userdata']
else:
2020-07-20 12:30:53 -04:00
return False, response.json().get('message', '')
2020-01-04 13:04:01 -05:00
def userdata_add(config, params):
"""
Add a new userdata with {params}
API endpoint: POST /api/v1/provisioner/userdata
API_arguments: args
API schema: {message}
"""
2020-01-06 23:28:06 -05:00
name = params.get('name')
userdata_data = params.get('data')
params = {
'name': name
}
data = {
'data': userdata_data
}
response = call_api(config, 'post', '/provisioner/userdata', params=params, data=data)
2020-01-04 13:04:01 -05:00
if response.status_code == 200:
retvalue = True
else:
retvalue = False
2020-07-20 12:30:53 -04:00
return retvalue, response.json().get('message', '')
2020-01-04 13:04:01 -05:00
2020-01-04 13:04:01 -05:00
def userdata_modify(config, name, params):
"""
Modify userdata {name} with {params}
API endpoint: PUT /api/v1/provisioner/userdata/{name}
API_arguments: args
API schema: {message}
"""
2020-01-06 23:28:06 -05:00
userdata_data = params.get('data')
params = {
'name': name
}
data = {
'data': userdata_data
}
response = call_api(config, 'put', '/provisioner/userdata/{name}'.format(name=name), params=params, data=data)
2020-01-04 13:04:01 -05:00
if response.status_code == 200:
retvalue = True
else:
retvalue = False
2020-07-20 12:30:53 -04:00
return retvalue, response.json().get('message', '')
2020-01-04 13:04:01 -05:00
2020-01-04 13:04:01 -05:00
def userdata_remove(config, name):
"""
Remove userdata {name}
API endpoint: DELETE /api/v1/provisioner/userdata/{name}
API_arguments:
API schema: {message}
"""
response = call_api(config, 'delete', '/provisioner/userdata/{name}'.format(name=name))
2020-01-04 13:04:01 -05:00
if response.status_code == 200:
retvalue = True
else:
retvalue = False
2020-07-20 12:30:53 -04:00
return retvalue, response.json().get('message', '')
2020-01-04 13:04:01 -05:00
2020-01-04 13:04:01 -05:00
def script_info(config, script):
"""
Get information about script
API endpoint: GET /api/v1/provisioner/script/{script}
API arguments:
API schema: {json_data_object}
"""
response = call_api(config, 'get', '/provisioner/script/{script}'.format(script=script))
2020-01-04 13:04:01 -05:00
if response.status_code == 200:
if isinstance(response.json(), list) and len(response.json()) != 1:
# No exact match; return not found
return False, "Script not found."
else:
# Return a single instance if the response is a list
if isinstance(response.json(), list):
return True, response.json()[0]
# This shouldn't happen, but is here just in case
else:
return True, response.json()
2020-01-04 13:04:01 -05:00
else:
2020-07-20 12:30:53 -04:00
return False, response.json().get('message', '')
2020-01-04 13:04:01 -05:00
2020-01-04 13:04:01 -05:00
def script_list(config, limit):
"""
Get list information about scripts (limited by {limit})
2020-01-04 14:06:36 -05:00
API endpoint: GET /api/v1/provisioner/script
2020-01-04 13:04:01 -05:00
API arguments: limit={limit}
API schema: [{json_data_object},{json_data_object},etc.]
"""
params = dict()
if limit:
params['limit'] = limit
response = call_api(config, 'get', '/provisioner/script', params=params)
2020-01-04 13:04:01 -05:00
if response.status_code == 200:
return True, response.json()
else:
2020-07-20 12:30:53 -04:00
return False, response.json().get('message', '')
2020-01-04 13:04:01 -05:00
def script_show(config, name):
"""
Get information about script name
API endpoint: GET /api/v1/provisioner/script/{name}
API arguments:
API schema: [{json_data_object},{json_data_object},etc.]
"""
response = call_api(config, 'get', '/provisioner/script/{}'.format(name))
if response.status_code == 200:
return True, response.json()[0]['script']
else:
2020-07-20 12:30:53 -04:00
return False, response.json().get('message', '')
2020-01-04 13:04:01 -05:00
def script_add(config, params):
"""
Add a new script with {params}
API endpoint: POST /api/v1/provisioner/script
API_arguments: args
API schema: {message}
"""
2020-01-06 23:28:06 -05:00
name = params.get('name')
script_data = params.get('data')
params = {
'name': name
}
data = {
'data': script_data
}
response = call_api(config, 'post', '/provisioner/script', params=params, data=data)
2020-01-04 13:04:01 -05:00
if response.status_code == 200:
retvalue = True
else:
retvalue = False
2020-07-20 12:30:53 -04:00
return retvalue, response.json().get('message', '')
2020-01-04 13:04:01 -05:00
2020-01-04 13:04:01 -05:00
def script_modify(config, name, params):
"""
Modify script {name} with {params}
2020-01-04 11:58:30 -05:00
2020-01-04 13:04:01 -05:00
API endpoint: PUT /api/v1/provisioner/script/{name}
API_arguments: args
API schema: {message}
"""
2020-01-06 23:28:06 -05:00
script_data = params.get('data')
params = {
'name': name
}
data = {
'data': script_data
}
response = call_api(config, 'put', '/provisioner/script/{name}'.format(name=name), params=params, data=data)
2020-01-04 13:04:01 -05:00
if response.status_code == 200:
retvalue = True
else:
retvalue = False
2020-07-20 12:30:53 -04:00
return retvalue, response.json().get('message', '')
2020-01-04 13:04:01 -05:00
2020-01-04 13:04:01 -05:00
def script_remove(config, name):
"""
Remove script {name}
API endpoint: DELETE /api/v1/provisioner/script/{name}
API_arguments:
API schema: {message}
"""
response = call_api(config, 'delete', '/provisioner/script/{name}'.format(name=name))
2020-01-04 13:04:01 -05:00
if response.status_code == 200:
retvalue = True
else:
retvalue = False
2020-07-20 12:30:53 -04:00
return retvalue, response.json().get('message', '')
2020-01-04 11:58:30 -05:00
def ova_info(config, name):
"""
Get information about OVA image {name}
API endpoint: GET /api/v1/provisioner/ova/{name}
API arguments:
API schema: {json_data_object}
"""
response = call_api(config, 'get', '/provisioner/ova/{name}'.format(name=name))
if response.status_code == 200:
if isinstance(response.json(), list) and len(response.json()) != 1:
# No exact match; return not found
return False, "OVA not found."
else:
# Return a single instance if the response is a list
if isinstance(response.json(), list):
return True, response.json()[0]
# This shouldn't happen, but is here just in case
else:
return True, response.json()
else:
2020-07-20 12:30:53 -04:00
return False, response.json().get('message', '')
def ova_list(config, limit):
"""
Get list information about OVA images (limited by {limit})
API endpoint: GET /api/v1/provisioner/ova
API arguments: limit={limit}
API schema: [{json_data_object},{json_data_object},etc.]
"""
params = dict()
if limit:
params['limit'] = limit
response = call_api(config, 'get', '/provisioner/ova', params=params)
if response.status_code == 200:
return True, response.json()
else:
2020-07-20 12:30:53 -04:00
return False, response.json().get('message', '')
def ova_upload(config, name, ova_file, params):
"""
Upload an OVA image to the cluster
API endpoint: POST /api/v1/provisioner/ova/{name}
API arguments: pool={pool}, ova_size={ova_size}
API schema: {"message":"{data}"}
"""
import click
bar = UploadProgressBar(ova_file, end_message="Parsing file on remote side...", end_nl=False)
upload_data = MultipartEncoder(
2020-11-07 12:38:31 -05:00
fields={'file': ('filename', open(ova_file, 'rb'), 'application/octet-stream')}
)
upload_monitor = MultipartEncoderMonitor(upload_data, bar.update)
headers = {
"Content-Type": upload_monitor.content_type
}
response = call_api(config, 'post', '/provisioner/ova/{}'.format(name), headers=headers, params=params, data=upload_monitor)
click.echo("done.")
click.echo()
if response.status_code == 200:
retstatus = True
else:
retstatus = False
2020-07-20 12:30:53 -04:00
return retstatus, response.json().get('message', '')
def ova_remove(config, name):
"""
Remove OVA image {name}
API endpoint: DELETE /api/v1/provisioner/ova/{name}
API_arguments:
API schema: {message}
"""
response = call_api(config, 'delete', '/provisioner/ova/{name}'.format(name=name))
if response.status_code == 200:
retvalue = True
else:
retvalue = False
2020-07-20 12:30:53 -04:00
return retvalue, response.json().get('message', '')
2020-01-04 14:06:36 -05:00
def profile_info(config, profile):
"""
Get information about profile
API endpoint: GET /api/v1/provisioner/profile/{profile}
API arguments:
API schema: {json_data_object}
"""
response = call_api(config, 'get', '/provisioner/profile/{profile}'.format(profile=profile))
2020-01-04 14:06:36 -05:00
if response.status_code == 200:
if isinstance(response.json(), list) and len(response.json()) != 1:
# No exact match; return not found
return False, "Profile not found."
else:
# Return a single instance if the response is a list
if isinstance(response.json(), list):
return True, response.json()[0]
# This shouldn't happen, but is here just in case
else:
return True, response.json()
2020-01-04 14:06:36 -05:00
else:
2020-07-20 12:30:53 -04:00
return False, response.json().get('message', '')
2020-01-04 14:06:36 -05:00
2020-01-04 14:06:36 -05:00
def profile_list(config, limit):
"""
Get list information about profiles (limited by {limit})
API endpoint: GET /api/v1/provisioner/profile/{profile_type}
API arguments: limit={limit}
API schema: [{json_data_object},{json_data_object},etc.]
"""
params = dict()
if limit:
params['limit'] = limit
response = call_api(config, 'get', '/provisioner/profile', params=params)
2020-01-04 14:06:36 -05:00
if response.status_code == 200:
return True, response.json()
else:
2020-07-20 12:30:53 -04:00
return False, response.json().get('message', '')
2020-01-04 14:06:36 -05:00
2020-01-04 14:06:36 -05:00
def profile_add(config, params):
"""
Add a new profile with {params}
API endpoint: POST /api/v1/provisioner/profile
API_arguments: args
API schema: {message}
"""
response = call_api(config, 'post', '/provisioner/profile', params=params)
2020-01-04 14:06:36 -05:00
if response.status_code == 200:
retvalue = True
else:
retvalue = False
2020-07-20 12:30:53 -04:00
return retvalue, response.json().get('message', '')
2020-01-04 14:06:36 -05:00
2020-01-04 14:06:36 -05:00
def profile_modify(config, name, params):
"""
Modify profile {name} with {params}
API endpoint: PUT /api/v1/provisioner/profile/{name}
API_arguments: args
API schema: {message}
"""
response = call_api(config, 'put', '/provisioner/profile/{name}'.format(name=name), params=params)
2020-01-04 14:06:36 -05:00
if response.status_code == 200:
retvalue = True
else:
retvalue = False
2020-07-20 12:30:53 -04:00
return retvalue, response.json().get('message', '')
2020-01-04 14:06:36 -05:00
2020-01-04 14:06:36 -05:00
def profile_remove(config, name):
"""
Remove profile {name}
API endpoint: DELETE /api/v1/provisioner/profile/{name}
API_arguments:
API schema: {message}
"""
response = call_api(config, 'delete', '/provisioner/profile/{name}'.format(name=name))
2020-01-04 14:06:36 -05:00
if response.status_code == 200:
retvalue = True
else:
retvalue = False
2020-07-20 12:30:53 -04:00
return retvalue, response.json().get('message', '')
2020-01-04 14:06:36 -05:00
def vm_create(config, name, profile, wait_flag, define_flag, start_flag, script_args):
2020-01-04 14:06:36 -05:00
"""
2020-01-04 14:31:22 -05:00
Create a new VM named {name} with profile {profile}
2020-01-04 14:06:36 -05:00
2020-01-04 14:31:22 -05:00
API endpoint: POST /api/v1/provisioner/create
API_arguments: name={name}, profile={profile}, arg={script_args}
2020-01-04 14:31:22 -05:00
API schema: {message}
"""
params = {
'name': name,
'profile': profile,
'start_vm': start_flag,
'define_vm': define_flag,
'arg': script_args
}
response = call_api(config, 'post', '/provisioner/create', params=params)
2020-01-04 14:31:22 -05:00
if response.status_code == 202:
retvalue = True
if not wait_flag:
retdata = 'Task ID: {}'.format(response.json()['task_id'])
else:
# Just return the task_id raw, instead of formatting it
retdata = response.json()['task_id']
2020-01-04 14:31:22 -05:00
else:
retvalue = False
2020-07-20 12:30:53 -04:00
retdata = response.json().get('message', '')
2020-01-04 14:31:22 -05:00
return retvalue, retdata
2020-01-12 14:01:47 -05:00
def task_status(config, task_id=None, is_watching=False):
2020-01-04 14:31:22 -05:00
"""
2020-01-12 14:01:47 -05:00
Get information about provisioner job {task_id} or all tasks if None
2020-01-04 14:31:22 -05:00
API endpoint: GET /api/v1/provisioner/status
2020-01-04 14:06:36 -05:00
API arguments:
API schema: {json_data_object}
"""
2020-01-12 14:01:47 -05:00
if task_id is not None:
response = call_api(config, 'get', '/provisioner/status/{task_id}'.format(task_id=task_id))
else:
response = call_api(config, 'get', '/provisioner/status')
if task_id is not None:
if response.status_code == 200:
retvalue = True
respjson = response.json()
if is_watching:
# Just return the raw JSON to the watching process instead of formatting it
return respjson
job_state = respjson['state']
if job_state == 'RUNNING':
retdata = 'Job state: RUNNING\nStage: {}/{}\nStatus: {}'.format(
respjson['current'],
respjson['total'],
respjson['status']
)
elif job_state == 'FAILED':
retdata = 'Job state: FAILED\nStatus: {}'.format(
respjson['status']
)
elif job_state == 'COMPLETED':
retdata = 'Job state: COMPLETED\nStatus: {}'.format(
respjson['status']
)
else:
retdata = 'Job state: {}\nStatus: {}'.format(
respjson['state'],
respjson['status']
)
2020-01-04 14:45:40 -05:00
else:
2020-01-12 14:01:47 -05:00
retvalue = False
2020-07-20 12:30:53 -04:00
retdata = response.json().get('message', '')
2020-01-04 14:06:36 -05:00
else:
2020-01-12 14:01:47 -05:00
retvalue = True
task_data_raw = response.json()
# Format the Celery data into a more useful data structure
task_data = list()
for task_type in ['active', 'reserved', 'scheduled']:
2021-08-21 03:25:16 -04:00
try:
type_data = task_data_raw[task_type]
except Exception:
type_data = None
if not type_data:
type_data = dict()
for task_host in type_data:
for task_job in task_data_raw[task_type][task_host]:
task = dict()
if task_type == 'reserved':
task['type'] = 'pending'
else:
task['type'] = task_type
task['worker'] = task_host
task['id'] = task_job.get('id')
task_args = literal_eval(task_job.get('args'))
task['vm_name'] = task_args[0]
task['vm_profile'] = task_args[1]
task_kwargs = literal_eval(task_job.get('kwargs'))
task['vm_define'] = str(bool(task_kwargs['define_vm']))
task['vm_start'] = str(bool(task_kwargs['start_vm']))
task_data.append(task)
retdata = task_data
2020-01-04 14:31:22 -05:00
return retvalue, retdata
2020-01-04 14:06:36 -05:00
2020-01-04 11:58:30 -05:00
#
# Format functions
#
2020-01-04 14:06:36 -05:00
def format_list_template(template_data, template_type=None):
2020-01-02 11:18:46 -05:00
"""
2020-01-04 13:04:01 -05:00
Format the returned template template
2020-01-02 11:18:46 -05:00
template_type can be used to only display part of the full list, allowing function
reuse with more limited output options.
"""
2020-11-07 13:02:54 -05:00
template_types = ['system', 'network', 'storage']
2020-01-04 14:06:36 -05:00
normalized_template_data = dict()
ainformation = list()
2020-01-02 11:18:46 -05:00
if template_type in template_types:
2020-11-07 13:02:54 -05:00
template_types = [template_type]
2020-01-04 14:06:36 -05:00
template_data_type = '{}_templates'.format(template_type)
normalized_template_data[template_data_type] = template_data
2020-01-04 11:58:30 -05:00
else:
2020-01-04 14:06:36 -05:00
normalized_template_data = template_data
2020-01-02 11:18:46 -05:00
if 'system' in template_types:
ainformation.append(format_list_template_system(normalized_template_data['system_templates']))
2020-01-04 11:58:30 -05:00
if len(template_types) > 1:
ainformation.append('')
2020-01-02 11:18:46 -05:00
if 'network' in template_types:
ainformation.append(format_list_template_network(normalized_template_data['network_templates']))
2020-01-04 11:58:30 -05:00
if len(template_types) > 1:
ainformation.append('')
2020-01-02 11:18:46 -05:00
2020-01-04 11:58:30 -05:00
if 'storage' in template_types:
ainformation.append(format_list_template_storage(normalized_template_data['storage_templates']))
return '\n'.join(ainformation)
2020-01-02 11:18:46 -05:00
2020-01-04 14:06:36 -05:00
def format_list_template_system(template_data):
if isinstance(template_data, dict):
2020-11-07 13:02:54 -05:00
template_data = [template_data]
2020-01-02 11:18:46 -05:00
template_list_output = []
# Determine optimal column widths
template_name_length = 15
template_id_length = 5
2020-01-02 11:18:46 -05:00
template_vcpu_length = 6
template_vram_length = 9
2020-01-02 11:18:46 -05:00
template_serial_length = 7
template_vnc_length = 4
template_vnc_bind_length = 9
template_node_limit_length = 6
template_node_selector_length = 9
template_node_autostart_length = 10
template_migration_method_length = 10
2020-01-02 11:18:46 -05:00
2020-01-04 14:06:36 -05:00
for template in template_data:
2020-01-02 11:18:46 -05:00
# template_name column
_template_name_length = len(str(template['name'])) + 1
if _template_name_length > template_name_length:
template_name_length = _template_name_length
# template_id column
_template_id_length = len(str(template['id'])) + 1
if _template_id_length > template_id_length:
template_id_length = _template_id_length
# template_vcpu column
_template_vcpu_length = len(str(template['vcpu_count'])) + 1
if _template_vcpu_length > template_vcpu_length:
template_vcpu_length = _template_vcpu_length
# template_vram column
_template_vram_length = len(str(template['vram_mb'])) + 1
if _template_vram_length > template_vram_length:
template_vram_length = _template_vram_length
# template_serial column
_template_serial_length = len(str(template['serial'])) + 1
if _template_serial_length > template_serial_length:
template_serial_length = _template_serial_length
# template_vnc column
_template_vnc_length = len(str(template['vnc'])) + 1
if _template_vnc_length > template_vnc_length:
template_vnc_length = _template_vnc_length
# template_vnc_bind column
_template_vnc_bind_length = len(str(template['vnc_bind'])) + 1
if _template_vnc_bind_length > template_vnc_bind_length:
template_vnc_bind_length = _template_vnc_bind_length
# template_node_limit column
_template_node_limit_length = len(str(template['node_limit'])) + 1
if _template_node_limit_length > template_node_limit_length:
template_node_limit_length = _template_node_limit_length
# template_node_selector column
_template_node_selector_length = len(str(template['node_selector'])) + 1
if _template_node_selector_length > template_node_selector_length:
template_node_selector_length = _template_node_selector_length
# template_node_autostart column
_template_node_autostart_length = len(str(template['node_autostart'])) + 1
if _template_node_autostart_length > template_node_autostart_length:
template_node_autostart_length = _template_node_autostart_length
# template_migration_method column
_template_migration_method_length = len(str(template['migration_method'])) + 1
if _template_migration_method_length > template_migration_method_length:
template_migration_method_length = _template_migration_method_length
2020-01-02 11:18:46 -05:00
# Format the string (header)
template_list_output.append('{bold}{template_header: <{template_header_length}} {resources_header: <{resources_header_length}} {consoles_header: <{consoles_header_length}} {metadata_header: <{metadata_header_length}}{end_bold}'.format(
bold=ansiprint.bold(),
end_bold=ansiprint.end(),
template_header_length=template_name_length + template_id_length + 1,
resources_header_length=template_vcpu_length + template_vram_length + 1,
consoles_header_length=template_serial_length + template_vnc_length + template_vnc_bind_length + 2,
metadata_header_length=template_node_limit_length + template_node_selector_length + template_node_autostart_length + template_migration_method_length + 3,
template_header='System Templates ' + ''.join(['-' for _ in range(17, template_name_length + template_id_length)]),
resources_header='Resources ' + ''.join(['-' for _ in range(10, template_vcpu_length + template_vram_length)]),
consoles_header='Consoles ' + ''.join(['-' for _ in range(9, template_serial_length + template_vnc_length + template_vnc_bind_length + 1)]),
metadata_header='Metadata ' + ''.join(['-' for _ in range(9, template_node_limit_length + template_node_selector_length + template_node_autostart_length + template_migration_method_length + 2)]))
)
template_list_output.append('{bold}{template_name: <{template_name_length}} {template_id: <{template_id_length}} \
2020-01-02 11:18:46 -05:00
{template_vcpu: <{template_vcpu_length}} \
{template_vram: <{template_vram_length}} \
{template_serial: <{template_serial_length}} \
2020-01-02 11:18:46 -05:00
{template_vnc: <{template_vnc_length}} \
{template_vnc_bind: <{template_vnc_bind_length}} \
{template_node_limit: <{template_node_limit_length}} \
2020-01-02 11:18:46 -05:00
{template_node_selector: <{template_node_selector_length}} \
{template_node_autostart: <{template_node_autostart_length}} \
{template_migration_method: <{template_migration_method_length}}{end_bold}'.format(
bold=ansiprint.bold(),
end_bold=ansiprint.end(),
template_state_colour='',
end_colour='',
template_name_length=template_name_length,
template_id_length=template_id_length,
template_vcpu_length=template_vcpu_length,
template_vram_length=template_vram_length,
template_serial_length=template_serial_length,
template_vnc_length=template_vnc_length,
template_vnc_bind_length=template_vnc_bind_length,
template_node_limit_length=template_node_limit_length,
template_node_selector_length=template_node_selector_length,
template_node_autostart_length=template_node_autostart_length,
template_migration_method_length=template_migration_method_length,
template_name='Name',
template_id='ID',
template_vcpu='vCPUs',
template_vram='vRAM [M]',
template_serial='Serial',
template_vnc='VNC',
template_vnc_bind='VNC bind',
template_node_limit='Limit',
template_node_selector='Selector',
template_node_autostart='Autostart',
template_migration_method='Migration')
)
2020-01-02 11:18:46 -05:00
# Format the string (elements)
2020-01-04 14:06:36 -05:00
for template in sorted(template_data, key=lambda i: i.get('name', None)):
2020-01-02 11:18:46 -05:00
template_list_output.append(
'{bold}{template_name: <{template_name_length}} {template_id: <{template_id_length}} \
{template_vcpu: <{template_vcpu_length}} \
{template_vram: <{template_vram_length}} \
{template_serial: <{template_serial_length}} \
2020-01-02 11:18:46 -05:00
{template_vnc: <{template_vnc_length}} \
{template_vnc_bind: <{template_vnc_bind_length}} \
{template_node_limit: <{template_node_limit_length}} \
2020-01-02 11:18:46 -05:00
{template_node_selector: <{template_node_selector_length}} \
{template_node_autostart: <{template_node_autostart_length}} \
{template_migration_method: <{template_migration_method_length}}{end_bold}'.format(
2020-01-02 11:18:46 -05:00
template_name_length=template_name_length,
template_id_length=template_id_length,
template_vcpu_length=template_vcpu_length,
template_vram_length=template_vram_length,
template_serial_length=template_serial_length,
template_vnc_length=template_vnc_length,
template_vnc_bind_length=template_vnc_bind_length,
template_node_limit_length=template_node_limit_length,
template_node_selector_length=template_node_selector_length,
template_node_autostart_length=template_node_autostart_length,
template_migration_method_length=template_migration_method_length,
2020-01-02 11:18:46 -05:00
bold='',
end_bold='',
template_name=str(template['name']),
template_id=str(template['id']),
template_vcpu=str(template['vcpu_count']),
template_vram=str(template['vram_mb']),
template_serial=str(template['serial']),
template_vnc=str(template['vnc']),
template_vnc_bind=str(template['vnc_bind']),
template_node_limit=str(template['node_limit']),
template_node_selector=str(template['node_selector']),
template_node_autostart=str(template['node_autostart']),
template_migration_method=str(template['migration_method'])
2020-01-02 11:18:46 -05:00
)
)
return '\n'.join(template_list_output)
2020-01-02 11:18:46 -05:00
2020-01-04 13:04:01 -05:00
def format_list_template_network(template_template):
if isinstance(template_template, dict):
2020-11-07 13:02:54 -05:00
template_template = [template_template]
2020-01-02 11:18:46 -05:00
template_list_output = []
# Determine optimal column widths
template_name_length = 18
template_id_length = 5
2020-01-02 11:18:46 -05:00
template_mac_template_length = 13
template_networks_length = 10
2020-01-04 13:04:01 -05:00
for template in template_template:
2020-01-02 11:18:46 -05:00
# Join the networks elements into a single list of VNIs
network_list = list()
for network in template['networks']:
network_list.append(str(network['vni']))
template['networks_csv'] = ','.join(network_list)
2020-01-04 13:04:01 -05:00
for template in template_template:
2020-01-02 11:18:46 -05:00
# template_name column
_template_name_length = len(str(template['name'])) + 1
if _template_name_length > template_name_length:
template_name_length = _template_name_length
# template_id column
_template_id_length = len(str(template['id'])) + 1
if _template_id_length > template_id_length:
template_id_length = _template_id_length
# template_mac_template column
_template_mac_template_length = len(str(template['mac_template'])) + 1
if _template_mac_template_length > template_mac_template_length:
template_mac_template_length = _template_mac_template_length
# template_networks column
_template_networks_length = len(str(template['networks_csv'])) + 1
if _template_networks_length > template_networks_length:
template_networks_length = _template_networks_length
# Format the string (header)
template_list_output.append('{bold}{template_header: <{template_header_length}} {details_header: <{details_header_length}}{end_bold}'.format(
bold=ansiprint.bold(),
end_bold=ansiprint.end(),
template_header_length=template_name_length + template_id_length + 1,
details_header_length=template_mac_template_length + template_networks_length + 1,
template_header='Network Templates ' + ''.join(['-' for _ in range(18, template_name_length + template_id_length)]),
details_header='Details ' + ''.join(['-' for _ in range(8, template_mac_template_length + template_networks_length)]))
)
template_list_output.append('{bold}{template_name: <{template_name_length}} {template_id: <{template_id_length}} \
2020-01-02 11:18:46 -05:00
{template_mac_template: <{template_mac_template_length}} \
{template_networks: <{template_networks_length}}{end_bold}'.format(
template_name_length=template_name_length,
template_id_length=template_id_length,
template_mac_template_length=template_mac_template_length,
template_networks_length=template_networks_length,
bold=ansiprint.bold(),
end_bold=ansiprint.end(),
template_name='Name',
template_id='ID',
template_mac_template='MAC template',
template_networks='Network VNIs')
)
2020-01-02 11:18:46 -05:00
# Format the string (elements)
2020-01-04 13:04:01 -05:00
for template in sorted(template_template, key=lambda i: i.get('name', None)):
2020-01-02 11:18:46 -05:00
template_list_output.append(
'{bold}{template_name: <{template_name_length}} {template_id: <{template_id_length}} \
{template_mac_template: <{template_mac_template_length}} \
{template_networks: <{template_networks_length}}{end_bold}'.format(
template_name_length=template_name_length,
template_id_length=template_id_length,
template_mac_template_length=template_mac_template_length,
template_networks_length=template_networks_length,
bold='',
end_bold='',
template_name=str(template['name']),
template_id=str(template['id']),
template_mac_template=str(template['mac_template']),
template_networks=str(template['networks_csv'])
)
)
return '\n'.join(template_list_output)
2020-01-02 11:18:46 -05:00
2020-01-04 13:04:01 -05:00
def format_list_template_storage(template_template):
if isinstance(template_template, dict):
2020-11-07 13:02:54 -05:00
template_template = [template_template]
2020-01-02 11:18:46 -05:00
2020-01-04 11:58:30 -05:00
template_list_output = []
2020-01-02 11:18:46 -05:00
2020-01-04 11:58:30 -05:00
# Determine optimal column widths
template_name_length = 18
template_id_length = 5
2020-01-04 11:58:30 -05:00
template_disk_id_length = 8
template_disk_pool_length = 5
2020-01-05 19:11:52 -05:00
template_disk_source_length = 14
template_disk_size_length = 9
2020-01-04 11:58:30 -05:00
template_disk_filesystem_length = 11
template_disk_fsargs_length = 10
template_disk_mountpoint_length = 10
2020-01-02 11:18:46 -05:00
2020-01-04 13:04:01 -05:00
for template in template_template:
2020-01-04 11:58:30 -05:00
# template_name column
_template_name_length = len(str(template['name'])) + 1
if _template_name_length > template_name_length:
template_name_length = _template_name_length
# template_id column
_template_id_length = len(str(template['id'])) + 1
if _template_id_length > template_id_length:
template_id_length = _template_id_length
2020-01-02 11:18:46 -05:00
2020-01-04 11:58:30 -05:00
for disk in template['disks']:
# template_disk_id column
_template_disk_id_length = len(str(disk['disk_id'])) + 1
if _template_disk_id_length > template_disk_id_length:
template_disk_id_length = _template_disk_id_length
# template_disk_pool column
_template_disk_pool_length = len(str(disk['pool'])) + 1
if _template_disk_pool_length > template_disk_pool_length:
template_disk_pool_length = _template_disk_pool_length
2020-01-05 19:11:52 -05:00
# template_disk_source column
_template_disk_source_length = len(str(disk['source_volume'])) + 1
if _template_disk_source_length > template_disk_source_length:
template_disk_source_length = _template_disk_source_length
2020-01-04 11:58:30 -05:00
# template_disk_size column
_template_disk_size_length = len(str(disk['disk_size_gb'])) + 1
if _template_disk_size_length > template_disk_size_length:
template_disk_size_length = _template_disk_size_length
# template_disk_filesystem column
_template_disk_filesystem_length = len(str(disk['filesystem'])) + 1
if _template_disk_filesystem_length > template_disk_filesystem_length:
template_disk_filesystem_length = _template_disk_filesystem_length
# template_disk_fsargs column
_template_disk_fsargs_length = len(str(disk['filesystem_args'])) + 1
if _template_disk_fsargs_length > template_disk_fsargs_length:
template_disk_fsargs_length = _template_disk_fsargs_length
# template_disk_mountpoint column
_template_disk_mountpoint_length = len(str(disk['mountpoint'])) + 1
if _template_disk_mountpoint_length > template_disk_mountpoint_length:
template_disk_mountpoint_length = _template_disk_mountpoint_length
2020-01-02 11:18:46 -05:00
# Format the string (header)
template_list_output.append('{bold}{template_header: <{template_header_length}} {details_header: <{details_header_length}}{end_bold}'.format(
bold=ansiprint.bold(),
end_bold=ansiprint.end(),
template_header_length=template_name_length + template_id_length + 1,
details_header_length=template_disk_id_length + template_disk_pool_length + template_disk_source_length + template_disk_size_length + template_disk_filesystem_length + template_disk_fsargs_length + template_disk_mountpoint_length + 7,
template_header='Storage Templates ' + ''.join(['-' for _ in range(18, template_name_length + template_id_length)]),
details_header='Details ' + ''.join(['-' for _ in range(8, template_disk_id_length + template_disk_pool_length + template_disk_source_length + template_disk_size_length + template_disk_filesystem_length + template_disk_fsargs_length + template_disk_mountpoint_length + 6)]))
)
template_list_output.append('{bold}{template_name: <{template_name_length}} {template_id: <{template_id_length}} \
2020-01-04 11:58:30 -05:00
{template_disk_id: <{template_disk_id_length}} \
{template_disk_pool: <{template_disk_pool_length}} \
2020-01-05 19:11:52 -05:00
{template_disk_source: <{template_disk_source_length}} \
2020-01-04 11:58:30 -05:00
{template_disk_size: <{template_disk_size_length}} \
{template_disk_filesystem: <{template_disk_filesystem_length}} \
{template_disk_fsargs: <{template_disk_fsargs_length}} \
{template_disk_mountpoint: <{template_disk_mountpoint_length}}{end_bold}'.format(
template_name_length=template_name_length,
template_id_length=template_id_length,
template_disk_id_length=template_disk_id_length,
template_disk_pool_length=template_disk_pool_length,
template_disk_source_length=template_disk_source_length,
template_disk_size_length=template_disk_size_length,
template_disk_filesystem_length=template_disk_filesystem_length,
template_disk_fsargs_length=template_disk_fsargs_length,
template_disk_mountpoint_length=template_disk_mountpoint_length,
bold=ansiprint.bold(),
end_bold=ansiprint.end(),
template_name='Name',
template_id='ID',
template_disk_id='Disk ID',
template_disk_pool='Pool',
template_disk_source='Source Volume',
template_disk_size='Size [G]',
template_disk_filesystem='Filesystem',
template_disk_fsargs='Arguments',
template_disk_mountpoint='Mountpoint')
)
2020-01-02 11:18:46 -05:00
# Format the string (elements)
2020-01-04 13:04:01 -05:00
for template in sorted(template_template, key=lambda i: i.get('name', None)):
2020-01-04 11:58:30 -05:00
template_list_output.append(
'{bold}{template_name: <{template_name_length}} {template_id: <{template_id_length}}{end_bold}'.format(
template_name_length=template_name_length,
template_id_length=template_id_length,
2020-01-02 11:18:46 -05:00
bold='',
end_bold='',
2020-01-04 11:58:30 -05:00
template_name=str(template['name']),
template_id=str(template['id'])
2020-01-02 11:18:46 -05:00
)
)
2020-01-04 11:58:30 -05:00
for disk in sorted(template['disks'], key=lambda i: i.get('disk_id', None)):
template_list_output.append(
'{bold}{template_name: <{template_name_length}} {template_id: <{template_id_length}} \
{template_disk_id: <{template_disk_id_length}} \
{template_disk_pool: <{template_disk_pool_length}} \
2020-01-05 19:11:52 -05:00
{template_disk_source: <{template_disk_source_length}} \
2020-01-04 11:58:30 -05:00
{template_disk_size: <{template_disk_size_length}} \
{template_disk_filesystem: <{template_disk_filesystem_length}} \
{template_disk_fsargs: <{template_disk_fsargs_length}} \
{template_disk_mountpoint: <{template_disk_mountpoint_length}}{end_bold}'.format(
template_name_length=template_name_length,
template_id_length=template_id_length,
template_disk_id_length=template_disk_id_length,
template_disk_pool_length=template_disk_pool_length,
2020-01-05 19:11:52 -05:00
template_disk_source_length=template_disk_source_length,
2020-01-04 11:58:30 -05:00
template_disk_size_length=template_disk_size_length,
template_disk_filesystem_length=template_disk_filesystem_length,
template_disk_fsargs_length=template_disk_fsargs_length,
template_disk_mountpoint_length=template_disk_mountpoint_length,
bold='',
end_bold='',
template_name='',
template_id='',
template_disk_id=str(disk['disk_id']),
template_disk_pool=str(disk['pool']),
2020-01-05 19:11:52 -05:00
template_disk_source=str(disk['source_volume']),
2020-01-04 11:58:30 -05:00
template_disk_size=str(disk['disk_size_gb']),
template_disk_filesystem=str(disk['filesystem']),
template_disk_fsargs=str(disk['filesystem_args']),
template_disk_mountpoint=str(disk['mountpoint'])
)
)
2020-01-02 11:18:46 -05:00
return '\n'.join(template_list_output)
2020-01-04 11:58:30 -05:00
2020-01-04 14:06:36 -05:00
def format_list_userdata(userdata_data, lines=None):
if isinstance(userdata_data, dict):
2020-11-07 13:02:54 -05:00
userdata_data = [userdata_data]
2020-01-04 13:04:01 -05:00
2020-01-04 14:06:36 -05:00
userdata_list_output = []
2020-01-04 13:04:01 -05:00
# Determine optimal column widths
userdata_name_length = 12
userdata_id_length = 5
userdata_document_length = 92 - userdata_name_length - userdata_id_length
2020-01-04 14:06:36 -05:00
for userdata in userdata_data:
# userdata_name column
_userdata_name_length = len(str(userdata['name'])) + 1
if _userdata_name_length > userdata_name_length:
userdata_name_length = _userdata_name_length
# userdata_id column
_userdata_id_length = len(str(userdata['id'])) + 1
if _userdata_id_length > userdata_id_length:
userdata_id_length = _userdata_id_length
2020-01-04 13:04:01 -05:00
# Format the string (header)
userdata_list_output.append('{bold}{userdata_header: <{userdata_header_length}}{end_bold}'.format(
bold=ansiprint.bold(),
end_bold=ansiprint.end(),
userdata_header_length=userdata_name_length + userdata_id_length + userdata_document_length + 2,
userdata_header='Userdata ' + ''.join(['-' for _ in range(9, userdata_name_length + userdata_id_length + userdata_document_length + 1)]))
)
userdata_list_output.append('{bold}{userdata_name: <{userdata_name_length}} {userdata_id: <{userdata_id_length}} \
2020-01-04 14:06:36 -05:00
{userdata_data}{end_bold}'.format(
userdata_name_length=userdata_name_length,
userdata_id_length=userdata_id_length,
bold=ansiprint.bold(),
end_bold=ansiprint.end(),
userdata_name='Name',
userdata_id='ID',
userdata_data='Document')
)
2020-01-04 13:04:01 -05:00
# Format the string (elements)
2020-01-04 14:06:36 -05:00
for data in sorted(userdata_data, key=lambda i: i.get('name', None)):
2020-01-04 13:04:01 -05:00
line_count = 0
for line in data['userdata'].split('\n'):
if line_count < 1:
2020-01-04 14:06:36 -05:00
userdata_name = data['name']
userdata_id = data['id']
2020-01-04 13:04:01 -05:00
else:
2020-01-04 14:06:36 -05:00
userdata_name = ''
userdata_id = ''
2020-01-04 13:04:01 -05:00
line_count += 1
if lines and line_count > lines:
2020-01-04 14:06:36 -05:00
userdata_list_output.append(
'{bold}{userdata_name: <{userdata_name_length}} {userdata_id: <{userdata_id_length}} \
{userdata_data}{end_bold}'.format(
userdata_name_length=userdata_name_length,
userdata_id_length=userdata_id_length,
2020-01-04 13:04:01 -05:00
bold='',
end_bold='',
2020-01-04 14:06:36 -05:00
userdata_name=userdata_name,
userdata_id=userdata_id,
userdata_data='[...]'
2020-01-04 13:04:01 -05:00
)
)
break
2020-01-04 14:06:36 -05:00
userdata_list_output.append(
'{bold}{userdata_name: <{userdata_name_length}} {userdata_id: <{userdata_id_length}} \
{userdata_data}{end_bold}'.format(
userdata_name_length=userdata_name_length,
userdata_id_length=userdata_id_length,
2020-01-04 13:04:01 -05:00
bold='',
end_bold='',
2020-01-04 14:06:36 -05:00
userdata_name=userdata_name,
userdata_id=userdata_id,
userdata_data=str(line)
2020-01-04 13:04:01 -05:00
)
)
return '\n'.join(userdata_list_output)
2020-01-04 13:04:01 -05:00
2020-01-04 14:06:36 -05:00
def format_list_script(script_data, lines=None):
if isinstance(script_data, dict):
2020-11-07 13:02:54 -05:00
script_data = [script_data]
2020-01-04 13:04:01 -05:00
2020-01-04 14:06:36 -05:00
script_list_output = []
2020-01-04 13:04:01 -05:00
# Determine optimal column widths
script_name_length = 12
script_id_length = 5
script_data_length = 92 - script_name_length - script_id_length
2020-01-04 14:06:36 -05:00
for script in script_data:
# script_name column
_script_name_length = len(str(script['name'])) + 1
if _script_name_length > script_name_length:
script_name_length = _script_name_length
# script_id column
_script_id_length = len(str(script['id'])) + 1
if _script_id_length > script_id_length:
script_id_length = _script_id_length
2020-01-04 13:04:01 -05:00
# Format the string (header)
script_list_output.append('{bold}{script_header: <{script_header_length}}{end_bold}'.format(
bold=ansiprint.bold(),
end_bold=ansiprint.end(),
script_header_length=script_name_length + script_id_length + script_data_length + 2,
script_header='Script ' + ''.join(['-' for _ in range(7, script_name_length + script_id_length + script_data_length + 1)]))
)
script_list_output.append('{bold}{script_name: <{script_name_length}} {script_id: <{script_id_length}} \
2020-01-04 14:06:36 -05:00
{script_data}{end_bold}'.format(
script_name_length=script_name_length,
script_id_length=script_id_length,
bold=ansiprint.bold(),
end_bold=ansiprint.end(),
script_name='Name',
script_id='ID',
script_data='Script')
)
2020-01-04 13:04:01 -05:00
# Format the string (elements)
2020-01-04 14:06:36 -05:00
for script in sorted(script_data, key=lambda i: i.get('name', None)):
2020-01-04 13:04:01 -05:00
line_count = 0
2020-01-04 14:06:36 -05:00
for line in script['script'].split('\n'):
2020-01-04 13:04:01 -05:00
if line_count < 1:
2020-01-04 14:06:36 -05:00
script_name = script['name']
script_id = script['id']
2020-01-04 13:04:01 -05:00
else:
2020-01-04 14:06:36 -05:00
script_name = ''
script_id = ''
2020-01-04 13:04:01 -05:00
line_count += 1
if lines and line_count > lines:
2020-01-04 14:06:36 -05:00
script_list_output.append(
'{bold}{script_name: <{script_name_length}} {script_id: <{script_id_length}} \
{script_data}{end_bold}'.format(
script_name_length=script_name_length,
script_id_length=script_id_length,
2020-01-04 13:04:01 -05:00
bold='',
end_bold='',
2020-01-04 14:06:36 -05:00
script_name=script_name,
script_id=script_id,
script_data='[...]'
2020-01-04 13:04:01 -05:00
)
)
break
2020-01-04 14:06:36 -05:00
script_list_output.append(
'{bold}{script_name: <{script_name_length}} {script_id: <{script_id_length}} \
{script_data}{end_bold}'.format(
script_name_length=script_name_length,
script_id_length=script_id_length,
2020-01-04 13:04:01 -05:00
bold='',
end_bold='',
2020-01-04 14:06:36 -05:00
script_name=script_name,
script_id=script_id,
script_data=str(line)
2020-01-04 13:04:01 -05:00
)
)
return '\n'.join(script_list_output)
2020-01-04 14:06:36 -05:00
def format_list_ova(ova_data):
if isinstance(ova_data, dict):
2020-11-07 13:02:54 -05:00
ova_data = [ova_data]
ova_list_output = []
# Determine optimal column widths
ova_name_length = 18
ova_id_length = 5
ova_disk_id_length = 8
ova_disk_size_length = 10
ova_disk_pool_length = 5
ova_disk_volume_format_length = 7
ova_disk_volume_name_length = 13
for ova in ova_data:
# ova_name column
_ova_name_length = len(str(ova['name'])) + 1
if _ova_name_length > ova_name_length:
ova_name_length = _ova_name_length
# ova_id column
_ova_id_length = len(str(ova['id'])) + 1
if _ova_id_length > ova_id_length:
ova_id_length = _ova_id_length
for disk in ova['volumes']:
# ova_disk_id column
_ova_disk_id_length = len(str(disk['disk_id'])) + 1
if _ova_disk_id_length > ova_disk_id_length:
ova_disk_id_length = _ova_disk_id_length
# ova_disk_size column
_ova_disk_size_length = len(str(disk['disk_size_gb'])) + 1
if _ova_disk_size_length > ova_disk_size_length:
ova_disk_size_length = _ova_disk_size_length
# ova_disk_pool column
_ova_disk_pool_length = len(str(disk['pool'])) + 1
if _ova_disk_pool_length > ova_disk_pool_length:
ova_disk_pool_length = _ova_disk_pool_length
# ova_disk_volume_format column
_ova_disk_volume_format_length = len(str(disk['volume_format'])) + 1
if _ova_disk_volume_format_length > ova_disk_volume_format_length:
ova_disk_volume_format_length = _ova_disk_volume_format_length
# ova_disk_volume_name column
_ova_disk_volume_name_length = len(str(disk['volume_name'])) + 1
if _ova_disk_volume_name_length > ova_disk_volume_name_length:
ova_disk_volume_name_length = _ova_disk_volume_name_length
# Format the string (header)
ova_list_output.append('{bold}{ova_header: <{ova_header_length}} {details_header: <{details_header_length}}{end_bold}'.format(
bold=ansiprint.bold(),
end_bold=ansiprint.end(),
ova_header_length=ova_name_length + ova_id_length + 1,
details_header_length=ova_disk_id_length + ova_disk_size_length + ova_disk_pool_length + ova_disk_volume_format_length + ova_disk_volume_name_length + 4,
ova_header='OVAs ' + ''.join(['-' for _ in range(5, ova_name_length + ova_id_length)]),
details_header='Details ' + ''.join(['-' for _ in range(8, ova_disk_id_length + ova_disk_size_length + ova_disk_pool_length + ova_disk_volume_format_length + ova_disk_volume_name_length + 3)]))
)
ova_list_output.append('{bold}{ova_name: <{ova_name_length}} {ova_id: <{ova_id_length}} \
{ova_disk_id: <{ova_disk_id_length}} \
{ova_disk_size: <{ova_disk_size_length}} \
{ova_disk_pool: <{ova_disk_pool_length}} \
{ova_disk_volume_format: <{ova_disk_volume_format_length}} \
{ova_disk_volume_name: <{ova_disk_volume_name_length}}{end_bold}'.format(
ova_name_length=ova_name_length,
ova_id_length=ova_id_length,
ova_disk_id_length=ova_disk_id_length,
ova_disk_pool_length=ova_disk_pool_length,
ova_disk_size_length=ova_disk_size_length,
ova_disk_volume_format_length=ova_disk_volume_format_length,
ova_disk_volume_name_length=ova_disk_volume_name_length,
bold=ansiprint.bold(),
end_bold=ansiprint.end(),
ova_name='Name',
ova_id='ID',
ova_disk_id='Disk ID',
ova_disk_size='Size [GB]',
ova_disk_pool='Pool',
ova_disk_volume_format='Format',
ova_disk_volume_name='Source Volume')
)
# Format the string (elements)
for ova in sorted(ova_data, key=lambda i: i.get('name', None)):
ova_list_output.append(
'{bold}{ova_name: <{ova_name_length}} {ova_id: <{ova_id_length}}{end_bold}'.format(
ova_name_length=ova_name_length,
ova_id_length=ova_id_length,
bold='',
end_bold='',
ova_name=str(ova['name']),
ova_id=str(ova['id'])
)
)
for disk in sorted(ova['volumes'], key=lambda i: i.get('disk_id', None)):
ova_list_output.append(
'{bold}{ova_name: <{ova_name_length}} {ova_id: <{ova_id_length}} \
{ova_disk_id: <{ova_disk_id_length}} \
{ova_disk_size: <{ova_disk_size_length}} \
{ova_disk_pool: <{ova_disk_pool_length}} \
{ova_disk_volume_format: <{ova_disk_volume_format_length}} \
{ova_disk_volume_name: <{ova_disk_volume_name_length}}{end_bold}'.format(
ova_name_length=ova_name_length,
ova_id_length=ova_id_length,
ova_disk_id_length=ova_disk_id_length,
ova_disk_size_length=ova_disk_size_length,
ova_disk_pool_length=ova_disk_pool_length,
ova_disk_volume_format_length=ova_disk_volume_format_length,
ova_disk_volume_name_length=ova_disk_volume_name_length,
bold='',
end_bold='',
ova_name='',
ova_id='',
ova_disk_id=str(disk['disk_id']),
ova_disk_size=str(disk['disk_size_gb']),
ova_disk_pool=str(disk['pool']),
ova_disk_volume_format=str(disk['volume_format']),
ova_disk_volume_name=str(disk['volume_name']),
)
)
return '\n'.join(ova_list_output)
2020-01-04 14:06:36 -05:00
def format_list_profile(profile_data):
if isinstance(profile_data, dict):
2020-11-07 13:02:54 -05:00
profile_data = [profile_data]
2020-01-04 14:06:36 -05:00
2020-02-17 11:53:34 -05:00
# Format the profile "source" from the type and, if applicable, OVA profile name
for profile in profile_data:
profile_type = profile['type']
if 'ova' in profile_type:
# Set the source to the name of the OVA:
profile['source'] = 'OVA {}'.format(profile['ova'])
2020-02-17 11:53:34 -05:00
else:
# Set the source to be the type
profile['source'] = profile_type
2020-01-04 14:06:36 -05:00
profile_list_output = []
# Determine optimal column widths
profile_name_length = 18
profile_id_length = 5
2020-02-17 11:53:34 -05:00
profile_source_length = 7
2020-01-04 14:06:36 -05:00
profile_system_template_length = 7
profile_network_template_length = 8
profile_storage_template_length = 8
profile_userdata_length = 9
profile_script_length = 7
profile_arguments_length = 18
2020-01-04 14:06:36 -05:00
for profile in profile_data:
# profile_name column
_profile_name_length = len(str(profile['name'])) + 1
if _profile_name_length > profile_name_length:
profile_name_length = _profile_name_length
# profile_id column
_profile_id_length = len(str(profile['id'])) + 1
if _profile_id_length > profile_id_length:
profile_id_length = _profile_id_length
2020-02-17 11:53:34 -05:00
# profile_source column
_profile_source_length = len(str(profile['source'])) + 1
if _profile_source_length > profile_source_length:
profile_source_length = _profile_source_length
2020-01-04 14:06:36 -05:00
# profile_system_template column
_profile_system_template_length = len(str(profile['system_template'])) + 1
if _profile_system_template_length > profile_system_template_length:
profile_system_template_length = _profile_system_template_length
# profile_network_template column
_profile_network_template_length = len(str(profile['network_template'])) + 1
if _profile_network_template_length > profile_network_template_length:
profile_network_template_length = _profile_network_template_length
# profile_storage_template column
_profile_storage_template_length = len(str(profile['storage_template'])) + 1
if _profile_storage_template_length > profile_storage_template_length:
profile_storage_template_length = _profile_storage_template_length
# profile_userdata column
_profile_userdata_length = len(str(profile['userdata'])) + 1
if _profile_userdata_length > profile_userdata_length:
profile_userdata_length = _profile_userdata_length
# profile_script column
_profile_script_length = len(str(profile['script'])) + 1
if _profile_script_length > profile_script_length:
profile_script_length = _profile_script_length
# Format the string (header)
profile_list_output.append('{bold}{profile_header: <{profile_header_length}} {templates_header: <{templates_header_length}} {data_header: <{data_header_length}}{end_bold}'.format(
bold=ansiprint.bold(),
end_bold=ansiprint.end(),
profile_header_length=profile_name_length + profile_id_length + profile_source_length + 2,
templates_header_length=profile_system_template_length + profile_network_template_length + profile_storage_template_length + 2,
data_header_length=profile_userdata_length + profile_script_length + profile_arguments_length + 2,
profile_header='Profiles ' + ''.join(['-' for _ in range(9, profile_name_length + profile_id_length + profile_source_length + 1)]),
templates_header='Templates ' + ''.join(['-' for _ in range(10, profile_system_template_length + profile_network_template_length + profile_storage_template_length + 1)]),
data_header='Data ' + ''.join(['-' for _ in range(5, profile_userdata_length + profile_script_length + profile_arguments_length + 1)]))
)
profile_list_output.append('{bold}{profile_name: <{profile_name_length}} {profile_id: <{profile_id_length}} {profile_source: <{profile_source_length}} \
{profile_system_template: <{profile_system_template_length}} \
2020-01-04 14:06:36 -05:00
{profile_network_template: <{profile_network_template_length}} \
{profile_storage_template: <{profile_storage_template_length}} \
{profile_userdata: <{profile_userdata_length}} \
2020-01-04 14:06:36 -05:00
{profile_script: <{profile_script_length}} \
{profile_arguments}{end_bold}'.format(
profile_name_length=profile_name_length,
profile_id_length=profile_id_length,
profile_source_length=profile_source_length,
profile_system_template_length=profile_system_template_length,
profile_network_template_length=profile_network_template_length,
profile_storage_template_length=profile_storage_template_length,
profile_userdata_length=profile_userdata_length,
profile_script_length=profile_script_length,
bold=ansiprint.bold(),
end_bold=ansiprint.end(),
profile_name='Name',
profile_id='ID',
profile_source='Source',
profile_system_template='System',
profile_network_template='Network',
profile_storage_template='Storage',
profile_userdata='Userdata',
profile_script='Script',
profile_arguments='Script Arguments')
)
2020-01-04 14:06:36 -05:00
# Format the string (elements)
for profile in sorted(profile_data, key=lambda i: i.get('name', None)):
arguments_list = ', '.join(profile['arguments'])
if not arguments_list:
arguments_list = 'N/A'
2020-01-04 14:06:36 -05:00
profile_list_output.append(
2020-02-17 11:53:34 -05:00
'{bold}{profile_name: <{profile_name_length}} {profile_id: <{profile_id_length}} {profile_source: <{profile_source_length}} \
{profile_system_template: <{profile_system_template_length}} \
2020-01-04 14:06:36 -05:00
{profile_network_template: <{profile_network_template_length}} \
{profile_storage_template: <{profile_storage_template_length}} \
{profile_userdata: <{profile_userdata_length}} \
2020-01-04 14:06:36 -05:00
{profile_script: <{profile_script_length}} \
{profile_arguments}{end_bold}'.format(
profile_name_length=profile_name_length,
profile_id_length=profile_id_length,
2020-02-17 11:53:34 -05:00
profile_source_length=profile_source_length,
2020-01-04 14:06:36 -05:00
profile_system_template_length=profile_system_template_length,
profile_network_template_length=profile_network_template_length,
profile_storage_template_length=profile_storage_template_length,
profile_userdata_length=profile_userdata_length,
profile_script_length=profile_script_length,
bold='',
end_bold='',
profile_name=profile['name'],
profile_id=profile['id'],
2020-02-17 11:53:34 -05:00
profile_source=profile['source'],
2020-01-04 14:06:36 -05:00
profile_system_template=profile['system_template'],
profile_network_template=profile['network_template'],
profile_storage_template=profile['storage_template'],
profile_userdata=profile['userdata'],
profile_script=profile['script'],
profile_arguments=arguments_list,
2020-01-04 14:06:36 -05:00
)
)
return '\n'.join(profile_list_output)
2020-01-12 14:01:47 -05:00
def format_list_task(task_data):
2020-01-12 14:01:47 -05:00
task_list_output = []
# Determine optimal column widths
2020-01-12 14:15:34 -05:00
task_id_length = 7
2020-01-12 14:01:47 -05:00
task_type_length = 7
task_worker_length = 7
2020-01-12 14:01:47 -05:00
task_vm_name_length = 5
task_vm_profile_length = 8
task_vm_define_length = 8
task_vm_start_length = 7
for task in task_data:
# task_id column
_task_id_length = len(str(task['id'])) + 1
if _task_id_length > task_id_length:
task_id_length = _task_id_length
# task_worker column
_task_worker_length = len(str(task['worker'])) + 1
if _task_worker_length > task_worker_length:
task_worker_length = _task_worker_length
2020-01-12 14:01:47 -05:00
# task_type column
_task_type_length = len(str(task['type'])) + 1
if _task_type_length > task_type_length:
task_type_length = _task_type_length
# task_vm_name column
_task_vm_name_length = len(str(task['vm_name'])) + 1
if _task_vm_name_length > task_vm_name_length:
task_vm_name_length = _task_vm_name_length
# task_vm_profile column
_task_vm_profile_length = len(str(task['vm_profile'])) + 1
if _task_vm_profile_length > task_vm_profile_length:
task_vm_profile_length = _task_vm_profile_length
# task_vm_define column
_task_vm_define_length = len(str(task['vm_define'])) + 1
if _task_vm_define_length > task_vm_define_length:
task_vm_define_length = _task_vm_define_length
# task_vm_start column
_task_vm_start_length = len(str(task['vm_start'])) + 1
if _task_vm_start_length > task_vm_start_length:
task_vm_start_length = _task_vm_start_length
# Format the string (header)
task_list_output.append('{bold}{task_header: <{task_header_length}} {vms_header: <{vms_header_length}}{end_bold}'.format(
bold=ansiprint.bold(),
end_bold=ansiprint.end(),
task_header_length=task_id_length + task_type_length + task_worker_length + 2,
vms_header_length=task_vm_name_length + task_vm_profile_length + task_vm_define_length + task_vm_start_length + 3,
task_header='Tasks ' + ''.join(['-' for _ in range(6, task_id_length + task_type_length + task_worker_length + 1)]),
vms_header='VM Details ' + ''.join(['-' for _ in range(11, task_vm_name_length + task_vm_profile_length + task_vm_define_length + task_vm_start_length + 2)]))
)
task_list_output.append('{bold}{task_id: <{task_id_length}} {task_type: <{task_type_length}} \
2020-01-12 14:01:47 -05:00
{task_worker: <{task_worker_length}} \
{task_vm_name: <{task_vm_name_length}} \
2020-01-12 14:01:47 -05:00
{task_vm_profile: <{task_vm_profile_length}} \
{task_vm_define: <{task_vm_define_length}} \
{task_vm_start: <{task_vm_start_length}}{end_bold}'.format(
task_id_length=task_id_length,
task_type_length=task_type_length,
task_worker_length=task_worker_length,
task_vm_name_length=task_vm_name_length,
task_vm_profile_length=task_vm_profile_length,
task_vm_define_length=task_vm_define_length,
task_vm_start_length=task_vm_start_length,
bold=ansiprint.bold(),
end_bold=ansiprint.end(),
task_id='Job ID',
task_type='Status',
task_worker='Worker',
task_vm_name='Name',
task_vm_profile='Profile',
task_vm_define='Define?',
task_vm_start='Start?')
)
2020-01-12 14:01:47 -05:00
# Format the string (elements)
for task in sorted(task_data, key=lambda i: i.get('type', None)):
task_list_output.append(
'{bold}{task_id: <{task_id_length}} {task_type: <{task_type_length}} \
{task_worker: <{task_worker_length}} \
{task_vm_name: <{task_vm_name_length}} \
2020-01-12 14:01:47 -05:00
{task_vm_profile: <{task_vm_profile_length}} \
{task_vm_define: <{task_vm_define_length}} \
{task_vm_start: <{task_vm_start_length}}{end_bold}'.format(
task_id_length=task_id_length,
task_type_length=task_type_length,
task_worker_length=task_worker_length,
task_vm_name_length=task_vm_name_length,
task_vm_profile_length=task_vm_profile_length,
task_vm_define_length=task_vm_define_length,
task_vm_start_length=task_vm_start_length,
bold='',
end_bold='',
task_id=task['id'],
task_type=task['type'],
task_worker=task['worker'],
task_vm_name=task['vm_name'],
task_vm_profile=task['vm_profile'],
task_vm_define=task['vm_define'],
task_vm_start=task['vm_start']
)
)
return '\n'.join(task_list_output)