Add profile handling

This commit is contained in:
Joshua Boniface 2020-01-04 14:06:36 -05:00
parent 0a04c5d748
commit b88bdc29af
2 changed files with 566 additions and 141 deletions

View File

@ -226,7 +226,7 @@ def userdata_list(config, limit):
""" """
Get list information about userdatas (limited by {limit}) Get list information about userdatas (limited by {limit})
API endpoint: GET /api/v1/provisioner/userdata/{userdata_type} API endpoint: GET /api/v1/provisioner/userdata
API arguments: limit={limit} API arguments: limit={limit}
API schema: [{json_data_object},{json_data_object},etc.] API schema: [{json_data_object},{json_data_object},etc.]
""" """
@ -354,7 +354,7 @@ def script_list(config, limit):
""" """
Get list information about scripts (limited by {limit}) Get list information about scripts (limited by {limit})
API endpoint: GET /api/v1/provisioner/script/{script_type} API endpoint: GET /api/v1/provisioner/script
API arguments: limit={limit} API arguments: limit={limit}
API schema: [{json_data_object},{json_data_object},etc.] API schema: [{json_data_object},{json_data_object},etc.]
""" """
@ -455,10 +455,161 @@ def script_remove(config, name):
return retvalue, response.json()['message'] return retvalue, response.json()['message']
def profile_info(config, profile):
"""
Get information about profile
API endpoint: GET /api/v1/provisioner/profile/{profile}
API arguments:
API schema: {json_data_object}
"""
request_uri = get_request_uri(config, '/provisioner/profile/{profile}'.format(profile=profile))
response = requests.get(
request_uri
)
if config['debug']:
print('API endpoint: GET {}'.format(request_uri))
print('Response code: {}'.format(response.status_code))
print('Response headers: {}'.format(response.headers))
if response.status_code == 200:
return True, response.json()[0]
else:
return False, response.json()['message']
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
request_uri = get_request_uri(config, '/provisioner/profile')
response = requests.get(
request_uri,
params=params
)
if config['debug']:
print('API endpoint: GET {}'.format(request_uri))
print('Response code: {}'.format(response.status_code))
print('Response headers: {}'.format(response.headers))
if response.status_code == 200:
return True, response.json()
else:
return False, response.json()['message']
def profile_add(config, params):
"""
Add a new profile with {params}
API endpoint: POST /api/v1/provisioner/profile
API_arguments: args
API schema: {message}
"""
request_uri = get_request_uri(config, '/provisioner/profile')
response = requests.post(
request_uri,
params=params
)
if config['debug']:
print('API endpoint: POST {}'.format(request_uri))
print('Response code: {}'.format(response.status_code))
print('Response headers: {}'.format(response.headers))
if response.status_code == 200:
retvalue = True
else:
retvalue = False
return retvalue, response.json()['message']
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}
"""
request_uri = get_request_uri(config, '/provisioner/profile/{name}'.format(name=name))
response = requests.put(
request_uri,
params=params
)
if config['debug']:
print('API endpoint: PUT {}'.format(request_uri))
print('Response code: {}'.format(response.status_code))
print('Response headers: {}'.format(response.headers))
if response.status_code == 200:
retvalue = True
else:
retvalue = False
return retvalue, response.json()['message']
def profile_remove(config, name):
"""
Remove profile {name}
API endpoint: DELETE /api/v1/provisioner/profile/{name}
API_arguments:
API schema: {message}
"""
request_uri = get_request_uri(config, '/provisioner/profile/{name}'.format(name=name))
response = requests.delete(
request_uri
)
if config['debug']:
print('API endpoint: DELETE {}'.format(request_uri))
print('Response code: {}'.format(response.status_code))
print('Response headers: {}'.format(response.headers))
if response.status_code == 200:
retvalue = True
else:
retvalue = False
return retvalue, response.json()['message']
def profile_info(config, profile):
"""
Get information about profile
API endpoint: GET /api/v1/provisioner/profile/{profile}
API arguments:
API schema: {json_data_object}
"""
request_uri = get_request_uri(config, '/provisioner/profile/{profile}'.format(profile=profile))
response = requests.get(
request_uri
)
if config['debug']:
print('API endpoint: GET {}'.format(request_uri))
print('Response code: {}'.format(response.status_code))
print('Response headers: {}'.format(response.headers))
if response.status_code == 200:
return True, response.json()[0]
else:
return False, response.json()['message']
# #
# Format functions # Format functions
# #
def format_list_template(template_template, template_type=None): def format_list_template(template_data, template_type=None):
""" """
Format the returned template template Format the returned template template
@ -466,43 +617,43 @@ def format_list_template(template_template, template_type=None):
reuse with more limited output options. reuse with more limited output options.
""" """
template_types = [ 'system', 'network', 'storage' ] template_types = [ 'system', 'network', 'storage' ]
normalized_template_template = dict() normalized_template_data = dict()
if template_type in template_types: if template_type in template_types:
template_types = [ template_type ] template_types = [ template_type ]
template_template_type = '{}_templates'.format(template_type) template_data_type = '{}_templates'.format(template_type)
normalized_template_template[template_template_type] = template_template normalized_template_data[template_data_type] = template_data
else: else:
normalized_template_template = template_template normalized_template_data = template_data
if 'system' in template_types: if 'system' in template_types:
click.echo('System templates:') click.echo('System templates:')
click.echo() click.echo()
format_list_template_system(normalized_template_template['system_templates']) format_list_template_system(normalized_template_data['system_templates'])
if len(template_types) > 1: if len(template_types) > 1:
click.echo() click.echo()
if 'network' in template_types: if 'network' in template_types:
click.echo('Network templates:') click.echo('Network templates:')
click.echo() click.echo()
format_list_template_network(normalized_template_template['network_templates']) format_list_template_network(normalized_template_data['network_templates'])
if len(template_types) > 1: if len(template_types) > 1:
click.echo() click.echo()
if 'storage' in template_types: if 'storage' in template_types:
click.echo('Storage templates:') click.echo('Storage templates:')
click.echo() click.echo()
format_list_template_storage(normalized_template_template['storage_templates']) format_list_template_storage(normalized_template_data['storage_templates'])
def format_list_template_system(template_template): def format_list_template_system(template_data):
if isinstance(template_template, dict): if isinstance(template_data, dict):
template_template = [ template_template ] template_data = [ template_data ]
template_list_output = [] template_list_output = []
# Determine optimal column widths # Determine optimal column widths
template_name_length = 5 template_name_length = 5
template_id_length = 4 template_id_length = 3
template_vcpu_length = 6 template_vcpu_length = 6
template_vram_length = 10 template_vram_length = 10
template_serial_length = 7 template_serial_length = 7
@ -512,7 +663,7 @@ def format_list_template_system(template_template):
template_node_selector_length = 11 template_node_selector_length = 11
template_node_autostart_length = 11 template_node_autostart_length = 11
for template in template_template: for template in template_data:
# template_name column # template_name column
_template_name_length = len(str(template['name'])) + 1 _template_name_length = len(str(template['name'])) + 1
if _template_name_length > template_name_length: if _template_name_length > template_name_length:
@ -594,7 +745,7 @@ Metatemplate: {template_node_limit: <{template_node_limit_length}} \
valid_net_list = [] valid_net_list = []
# Format the string (elements) # Format the string (elements)
for template in sorted(template_template, key=lambda i: i.get('name', None)): for template in sorted(template_data, key=lambda i: i.get('name', None)):
template_list_output.append( template_list_output.append(
'{bold}{template_name: <{template_name_length}} {template_id: <{template_id_length}} \ '{bold}{template_name: <{template_name_length}} {template_id: <{template_id_length}} \
{template_vcpu: <{template_vcpu_length}} \ {template_vcpu: <{template_vcpu_length}} \
@ -642,7 +793,7 @@ def format_list_template_network(template_template):
# Determine optimal column widths # Determine optimal column widths
template_name_length = 5 template_name_length = 5
template_id_length = 4 template_id_length = 3
template_mac_template_length = 13 template_mac_template_length = 13
template_networks_length = 10 template_networks_length = 10
@ -718,7 +869,7 @@ def format_list_template_storage(template_template):
# Determine optimal column widths # Determine optimal column widths
template_name_length = 5 template_name_length = 5
template_id_length = 4 template_id_length = 3
template_disk_id_length = 8 template_disk_id_length = 8
template_disk_pool_length = 8 template_disk_pool_length = 8
template_disk_size_length = 10 template_disk_size_length = 10
@ -842,157 +993,264 @@ def format_list_template_storage(template_template):
return True, '' return True, ''
def format_list_userdata(userdata, lines=None): def format_list_userdata(userdata_data, lines=None):
if isinstance(userdata, dict): if isinstance(userdata_data, dict):
userdata = [ userdata ] userdata_data = [ userdata_data ]
data_list_output = [] userdata_list_output = []
# Determine optimal column widths # Determine optimal column widths
data_name_length = 5 userdata_name_length = 5
data_id_length = 4 userdata_id_length = 3
data_userdata_length = 8 userdata_useruserdata_length = 8
for data in userdata: for userdata in userdata_data:
# data_name column # userdata_name column
_data_name_length = len(str(data['name'])) + 1 _userdata_name_length = len(str(userdata['name'])) + 1
if _data_name_length > data_name_length: if _userdata_name_length > userdata_name_length:
data_name_length = _data_name_length userdata_name_length = _userdata_name_length
# data_id column # userdata_id column
_data_id_length = len(str(data['id'])) + 1 _userdata_id_length = len(str(userdata['id'])) + 1
if _data_id_length > data_id_length: if _userdata_id_length > userdata_id_length:
data_id_length = _data_id_length userdata_id_length = _userdata_id_length
# Format the string (header) # Format the string (header)
data_list_output_header = '{bold}{data_name: <{data_name_length}} {data_id: <{data_id_length}} \ userdata_list_output_header = '{bold}{userdata_name: <{userdata_name_length}} {userdata_id: <{userdata_id_length}} \
{data_userdata}{end_bold}'.format( {userdata_data}{end_bold}'.format(
data_name_length=data_name_length, userdata_name_length=userdata_name_length,
data_id_length=data_id_length, userdata_id_length=userdata_id_length,
bold=ansiprint.bold(), bold=ansiprint.bold(),
end_bold=ansiprint.end(), end_bold=ansiprint.end(),
data_name='Name', userdata_name='Name',
data_id='ID', userdata_id='ID',
data_userdata='Document' userdata_data='Document'
) )
# Format the string (elements) # Format the string (elements)
for data in sorted(userdata, key=lambda i: i.get('name', None)): for data in sorted(userdata_data, key=lambda i: i.get('name', None)):
line_count = 0 line_count = 0
for line in data['userdata'].split('\n'): for line in data['userdata'].split('\n'):
if line_count < 1: if line_count < 1:
data_name = data['name'] userdata_name = data['name']
data_id = data['id'] userdata_id = data['id']
else: else:
data_name = '' userdata_name = ''
data_id = '' userdata_id = ''
line_count += 1 line_count += 1
if lines and line_count > lines: if lines and line_count > lines:
data_list_output.append( userdata_list_output.append(
'{bold}{data_name: <{data_name_length}} {data_id: <{data_id_length}} \ '{bold}{userdata_name: <{userdata_name_length}} {userdata_id: <{userdata_id_length}} \
{data_script}{end_bold}'.format( {userdata_data}{end_bold}'.format(
data_name_length=data_name_length, userdata_name_length=userdata_name_length,
data_id_length=data_id_length, userdata_id_length=userdata_id_length,
bold='', bold='',
end_bold='', end_bold='',
data_name=data_name, userdata_name=userdata_name,
data_id=data_id, userdata_id=userdata_id,
data_script='[...]' userdata_data='[...]'
) )
) )
break break
data_list_output.append( userdata_list_output.append(
'{bold}{data_name: <{data_name_length}} {data_id: <{data_id_length}} \ '{bold}{userdata_name: <{userdata_name_length}} {userdata_id: <{userdata_id_length}} \
{data_userdata}{end_bold}'.format( {userdata_data}{end_bold}'.format(
data_name_length=data_name_length, userdata_name_length=userdata_name_length,
data_id_length=data_id_length, userdata_id_length=userdata_id_length,
bold='', bold='',
end_bold='', end_bold='',
data_name=data_name, userdata_name=userdata_name,
data_id=data_id, userdata_id=userdata_id,
data_userdata=str(line) userdata_data=str(line)
) )
) )
click.echo('\n'.join([data_list_output_header] + data_list_output)) click.echo('\n'.join([userdata_list_output_header] + userdata_list_output))
return True, '' return True, ''
def format_list_script(script, lines=None): def format_list_script(script_data, lines=None):
if isinstance(script, dict): if isinstance(script_data, dict):
script = [ script ] script_data = [ script_data ]
data_list_output = [] script_list_output = []
# Determine optimal column widths # Determine optimal column widths
data_name_length = 5 script_name_length = 5
data_id_length = 4 script_id_length = 3
data_script_length = 8 script_script_length = 8
for data in script: for script in script_data:
# data_name column # script_name column
_data_name_length = len(str(data['name'])) + 1 _script_name_length = len(str(script['name'])) + 1
if _data_name_length > data_name_length: if _script_name_length > script_name_length:
data_name_length = _data_name_length script_name_length = _script_name_length
# data_id column # script_id column
_data_id_length = len(str(data['id'])) + 1 _script_id_length = len(str(script['id'])) + 1
if _data_id_length > data_id_length: if _script_id_length > script_id_length:
data_id_length = _data_id_length script_id_length = _script_id_length
# Format the string (header) # Format the string (header)
data_list_output_header = '{bold}{data_name: <{data_name_length}} {data_id: <{data_id_length}} \ script_list_output_header = '{bold}{script_name: <{script_name_length}} {script_id: <{script_id_length}} \
{data_script}{end_bold}'.format( {script_data}{end_bold}'.format(
data_name_length=data_name_length, script_name_length=script_name_length,
data_id_length=data_id_length, script_id_length=script_id_length,
bold=ansiprint.bold(), bold=ansiprint.bold(),
end_bold=ansiprint.end(), end_bold=ansiprint.end(),
data_name='Name', script_name='Name',
data_id='ID', script_id='ID',
data_script='Script' script_data='Script'
) )
# Format the string (elements) # Format the string (elements)
for data in sorted(script, key=lambda i: i.get('name', None)): for script in sorted(script_data, key=lambda i: i.get('name', None)):
line_count = 0 line_count = 0
for line in data['script'].split('\n'): for line in script['script'].split('\n'):
if line_count < 1: if line_count < 1:
data_name = data['name'] script_name = script['name']
data_id = data['id'] script_id = script['id']
else: else:
data_name = '' script_name = ''
data_id = '' script_id = ''
line_count += 1 line_count += 1
if lines and line_count > lines: if lines and line_count > lines:
data_list_output.append( script_list_output.append(
'{bold}{data_name: <{data_name_length}} {data_id: <{data_id_length}} \ '{bold}{script_name: <{script_name_length}} {script_id: <{script_id_length}} \
{data_script}{end_bold}'.format( {script_data}{end_bold}'.format(
data_name_length=data_name_length, script_name_length=script_name_length,
data_id_length=data_id_length, script_id_length=script_id_length,
bold='', bold='',
end_bold='', end_bold='',
data_name=data_name, script_name=script_name,
data_id=data_id, script_id=script_id,
data_script='[...]' script_data='[...]'
) )
) )
break break
data_list_output.append( script_list_output.append(
'{bold}{data_name: <{data_name_length}} {data_id: <{data_id_length}} \ '{bold}{script_name: <{script_name_length}} {script_id: <{script_id_length}} \
{data_script}{end_bold}'.format( {script_data}{end_bold}'.format(
data_name_length=data_name_length, script_name_length=script_name_length,
data_id_length=data_id_length, script_id_length=script_id_length,
bold='', bold='',
end_bold='', end_bold='',
data_name=data_name, script_name=script_name,
data_id=data_id, script_id=script_id,
data_script=str(line) script_data=str(line)
) )
) )
click.echo('\n'.join([data_list_output_header] + data_list_output)) click.echo('\n'.join([script_list_output_header] + script_list_output))
return True, ''
def format_list_profile(profile_data):
if isinstance(profile_data, dict):
profile_data = [ profile_data ]
profile_list_output = []
# Determine optimal column widths
profile_name_length = 5
profile_id_length = 3
profile_system_template_length = 7
profile_network_template_length = 8
profile_storage_template_length = 8
profile_userdata_length = 9
profile_script_length = 7
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
# 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_header = '{bold}{profile_name: <{profile_name_length}} {profile_id: <{profile_id_length}} \
Templates: {profile_system_template: <{profile_system_template_length}} \
{profile_network_template: <{profile_network_template_length}} \
{profile_storage_template: <{profile_storage_template_length}} \
Data: {profile_userdata: <{profile_userdata_length}} \
{profile_script: <{profile_script_length}} \
{profile_arguments}{end_bold}'.format(
profile_name_length=profile_name_length,
profile_id_length=profile_id_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_system_template='System',
profile_network_template='Network',
profile_storage_template='Storage',
profile_userdata='Userdata',
profile_script='Script',
profile_arguments='Script Arguments'
)
# Format the string (elements)
for profile in sorted(profile_data, key=lambda i: i.get('name', None)):
profile_list_output.append(
'{bold}{profile_name: <{profile_name_length}} {profile_id: <{profile_id_length}} \
{profile_system_template: <{profile_system_template_length}} \
{profile_network_template: <{profile_network_template_length}} \
{profile_storage_template: <{profile_storage_template_length}} \
{profile_userdata: <{profile_userdata_length}} \
{profile_script: <{profile_script_length}} \
{profile_arguments}{end_bold}'.format(
profile_name_length=profile_name_length,
profile_id_length=profile_id_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='',
end_bold='',
profile_name=profile['name'],
profile_id=profile['id'],
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=', '.join(profile['arguments'])
)
)
click.echo('\n'.join([profile_list_output_header] + profile_list_output))
return True, '' return True, ''

View File

@ -418,7 +418,7 @@ def node_info(node, long_output):
) )
def node_list(limit): def node_list(limit):
""" """
List all nodes in the cluster; optionally only match names matching regex LIMIT. List all nodes; optionally only match names matching regex LIMIT.
""" """
retcode, retdata = pvc_node.node_list(config, limit) retcode, retdata = pvc_node.node_list(config, limit)
@ -534,7 +534,7 @@ def vm_modify(domain, cfgfile, editor, restart):
retcode, vm_information = pvc_vm.vm_info(config, domain) retcode, vm_information = pvc_vm.vm_info(config, domain)
if not retcode and not vm_information.get('name', None): if not retcode and not vm_information.get('name', None):
cleanup(False, 'ERROR: Could not find VM "{}" in the cluster!'.format(domain)) cleanup(False, 'ERROR: Could not find VM "{}"!'.format(domain))
dom_uuid = vm_information.get('uuid') dom_uuid = vm_information.get('uuid')
dom_name = vm_information.get('name') dom_name = vm_information.get('name')
@ -612,7 +612,7 @@ def vm_modify(domain, cfgfile, editor, restart):
) )
def vm_undefine(domain): def vm_undefine(domain):
""" """
Stop virtual machine DOMAIN and remove it from the cluster database, preserving disks. DOMAIN may be a UUID or name. Stop virtual machine DOMAIN and remove it database, preserving disks. DOMAIN may be a UUID or name.
""" """
retcode, retmsg = pvc_vm.vm_remove(config, domain, delete_disks=False) retcode, retmsg = pvc_vm.vm_remove(config, domain, delete_disks=False)
@ -627,7 +627,7 @@ def vm_undefine(domain):
) )
def vm_remove(domain): def vm_remove(domain):
""" """
Stop virtual machine DOMAIN and remove it, along with all disks, from the cluster. DOMAIN may be a UUID or name. Stop virtual machine DOMAIN and remove it, along with all disks,. DOMAIN may be a UUID or name.
""" """
retcode, retmsg = pvc_vm.vm_remove(config, domain, delete_disks=True) retcode, retmsg = pvc_vm.vm_remove(config, domain, delete_disks=True)
@ -844,7 +844,7 @@ def vm_dump(domain):
retcode, vm_information = pvc_vm.vm_info(config, domain) retcode, vm_information = pvc_vm.vm_info(config, domain)
if not retcode and not vm_information.get('name', None): if not retcode and not vm_information.get('name', None):
cleanup(False, 'ERROR: Could not find VM "{}" in the cluster!'.format(domain)) cleanup(False, 'ERROR: Could not find VM "{}"!'.format(domain))
# Grab the current config # Grab the current config
current_vm_cfg_raw = vm_information.get('xml') current_vm_cfg_raw = vm_information.get('xml')
@ -873,7 +873,7 @@ def vm_dump(domain):
) )
def vm_list(target_node, target_state, limit, raw): def vm_list(target_node, target_state, limit, raw):
""" """
List all virtual machines in the cluster; optionally only match names matching regex LIMIT. List all virtual machines; optionally only match names matching regex LIMIT.
NOTE: Red-coloured network lists indicate one or more configured networks are missing/invalid. NOTE: Red-coloured network lists indicate one or more configured networks are missing/invalid.
""" """
@ -899,7 +899,7 @@ def cli_network():
############################################################################### ###############################################################################
# pvc network add # pvc network add
############################################################################### ###############################################################################
@click.command(name='add', short_help='Add a new virtual network to the cluster.') @click.command(name='add', short_help='Add a new virtual network.')
@click.option( @click.option(
'-d', '--description', 'description', '-d', '--description', 'description',
required=True, required=True,
@ -962,7 +962,7 @@ def cli_network():
) )
def net_add(vni, description, nettype, domain, ip_network, ip_gateway, ip6_network, ip6_gateway, dhcp_flag, dhcp_start, dhcp_end, name_servers): def net_add(vni, description, nettype, domain, ip_network, ip_gateway, ip6_network, ip6_gateway, dhcp_flag, dhcp_start, dhcp_end, name_servers):
""" """
Add a new virtual network with VXLAN identifier VNI to the cluster. Add a new virtual network with VXLAN identifier VNI.
Examples: Examples:
@ -1056,13 +1056,13 @@ def net_modify(vni, description, domain, name_servers, ip6_network, ip6_gateway,
############################################################################### ###############################################################################
# pvc network remove # pvc network remove
############################################################################### ###############################################################################
@click.command(name='remove', short_help='Remove a virtual network from the cluster.') @click.command(name='remove', short_help='Remove a virtual network.')
@click.argument( @click.argument(
'net' 'net'
) )
def net_remove(net): def net_remove(net):
""" """
Remove an existing virtual network NET from the cluster; NET must be a VNI. Remove an existing virtual network NET; NET must be a VNI.
WARNING: PVC does not verify whether clients are still present in this network. Before removing, ensure WARNING: PVC does not verify whether clients are still present in this network. Before removing, ensure
that all client VMs have been removed from the network or undefined behaviour may occur. that all client VMs have been removed from the network or undefined behaviour may occur.
@ -1102,7 +1102,7 @@ def net_info(vni, long_output):
) )
def net_list(limit): def net_list(limit):
""" """
List all virtual networks in the cluster; optionally only match VNIs or Descriptions matching regex LIMIT. List all virtual networks; optionally only match VNIs or Descriptions matching regex LIMIT.
""" """
retcode, retdata = pvc_network.net_list(config, limit) retcode, retdata = pvc_network.net_list(config, limit)
@ -1399,7 +1399,7 @@ def ceph_osd():
) )
def ceph_osd_add(node, device, weight, yes): def ceph_osd_add(node, device, weight, yes):
""" """
Add a new Ceph OSD on node NODE with block device DEVICE to the cluster. Add a new Ceph OSD on node NODE with block device DEVICE.
""" """
if not yes: if not yes:
@ -1425,7 +1425,7 @@ def ceph_osd_add(node, device, weight, yes):
) )
def ceph_osd_remove(osdid, yes): def ceph_osd_remove(osdid, yes):
""" """
Remove a Ceph OSD with ID OSDID from the cluster. Remove a Ceph OSD with ID OSDID.
""" """
if not yes: if not yes:
@ -1446,7 +1446,7 @@ def ceph_osd_remove(osdid, yes):
) )
def ceph_osd_in(osdid): def ceph_osd_in(osdid):
""" """
Set a Ceph OSD with ID OSDID online in the cluster. Set a Ceph OSD with ID OSDID online.
""" """
retcode, retmsg = pvc_ceph.ceph_osd_state(config, osdid, 'in') retcode, retmsg = pvc_ceph.ceph_osd_state(config, osdid, 'in')
@ -1461,7 +1461,7 @@ def ceph_osd_in(osdid):
) )
def ceph_osd_out(osdid): def ceph_osd_out(osdid):
""" """
Set a Ceph OSD with ID OSDID offline in the cluster. Set a Ceph OSD with ID OSDID offline.
""" """
retcode, retmsg = pvc_ceph.ceph_osd_state(config, osdid, 'out') retcode, retmsg = pvc_ceph.ceph_osd_state(config, osdid, 'out')
@ -1514,7 +1514,7 @@ def ceph_osd_unset(osd_property):
) )
def ceph_osd_list(limit): def ceph_osd_list(limit):
""" """
List all Ceph OSDs in the cluster; optionally only match elements matching ID regex LIMIT. List all Ceph OSDs; optionally only match elements matching ID regex LIMIT.
""" """
retcode, retdata = pvc_ceph.ceph_osd_list(config, limit) retcode, retdata = pvc_ceph.ceph_osd_list(config, limit)
@ -1599,7 +1599,7 @@ def ceph_pool_remove(name, yes):
) )
def ceph_pool_list(limit): def ceph_pool_list(limit):
""" """
List all Ceph RBD pools in the cluster; optionally only match elements matching name regex LIMIT. List all Ceph RBD pools; optionally only match elements matching name regex LIMIT.
""" """
retcode, retdata = pvc_ceph.ceph_pool_list(config, limit) retcode, retdata = pvc_ceph.ceph_pool_list(config, limit)
@ -1744,7 +1744,7 @@ def ceph_volume_clone(pool, name, new_name):
) )
def ceph_volume_list(limit, pool): def ceph_volume_list(limit, pool):
""" """
List all Ceph RBD volumes in the cluster; optionally only match elements matching name regex LIMIT. List all Ceph RBD volumes; optionally only match elements matching name regex LIMIT.
""" """
retcode, retdata = pvc_ceph.ceph_volume_list(config, limit, pool) retcode, retdata = pvc_ceph.ceph_volume_list(config, limit, pool)
@ -1898,7 +1898,7 @@ def provisioner_template():
############################################################################### ###############################################################################
# pvc provisioner template list # pvc provisioner template list
############################################################################### ###############################################################################
@click.command(name='list', short_help='List all templates in the cluster.') @click.command(name='list', short_help='List all templates.')
@click.argument( @click.argument(
'limit', default=None, required=False 'limit', default=None, required=False
) )
@ -1927,7 +1927,7 @@ def provisioner_template_system():
############################################################################### ###############################################################################
# pvc provisioner template system list # pvc provisioner template system list
############################################################################### ###############################################################################
@click.command(name='list', short_help='List all system templates in the cluster.') @click.command(name='list', short_help='List all system templates.')
@click.argument( @click.argument(
'limit', default=None, required=False 'limit', default=None, required=False
) )
@ -1944,7 +1944,7 @@ def provisioner_template_system_list(limit):
############################################################################### ###############################################################################
# pvc provisioner template system add # pvc provisioner template system add
############################################################################### ###############################################################################
@click.command(name='add', short_help='Add new system template to the cluster.') @click.command(name='add', short_help='Add new system template.')
@click.argument( @click.argument(
'name' 'name'
) )
@ -2014,7 +2014,7 @@ def provisioner_template_system_add(name, vcpus, vram, serial, vnc, vnc_bind, no
############################################################################### ###############################################################################
# pvc provisioner template system remove # pvc provisioner template system remove
############################################################################### ###############################################################################
@click.command(name='remove', short_help='Remove system template from the cluster.') @click.command(name='remove', short_help='Remove system template.')
@click.argument( @click.argument(
'name' 'name'
) )
@ -2041,7 +2041,7 @@ def provisioner_template_network():
############################################################################### ###############################################################################
# pvc provisioner template network list # pvc provisioner template network list
############################################################################### ###############################################################################
@click.command(name='list', short_help='List all network templates in the cluster.') @click.command(name='list', short_help='List all network templates.')
@click.argument( @click.argument(
'limit', default=None, required=False 'limit', default=None, required=False
) )
@ -2058,7 +2058,7 @@ def provisioner_template_network_list(limit):
############################################################################### ###############################################################################
# pvc provisioner template network add # pvc provisioner template network add
############################################################################### ###############################################################################
@click.command(name='add', short_help='Add new network template to the cluster.') @click.command(name='add', short_help='Add new network template.')
@click.argument( @click.argument(
'name' 'name'
) )
@ -2107,7 +2107,7 @@ def provisioner_template_network_add(name, mac_template):
############################################################################### ###############################################################################
# pvc provisioner template network remove # pvc provisioner template network remove
############################################################################### ###############################################################################
@click.command(name='remove', short_help='Remove network template from the cluster.') @click.command(name='remove', short_help='Remove network template.')
@click.argument( @click.argument(
'name' 'name'
) )
@ -2184,7 +2184,7 @@ def provisioner_template_storage():
############################################################################### ###############################################################################
# pvc provisioner template storage list # pvc provisioner template storage list
############################################################################### ###############################################################################
@click.command(name='list', short_help='List all storage templates in the cluster.') @click.command(name='list', short_help='List all storage templates.')
@click.argument( @click.argument(
'limit', default=None, required=False 'limit', default=None, required=False
) )
@ -2201,7 +2201,7 @@ def provisioner_template_storage_list(limit):
############################################################################### ###############################################################################
# pvc provisioner template storage add # pvc provisioner template storage add
############################################################################### ###############################################################################
@click.command(name='add', short_help='Add new storage template to the cluster.') @click.command(name='add', short_help='Add new storage template.')
@click.argument( @click.argument(
'name' 'name'
) )
@ -2218,7 +2218,7 @@ def provisioner_template_storage_add(name):
############################################################################### ###############################################################################
# pvc provisioner template storage remove # pvc provisioner template storage remove
############################################################################### ###############################################################################
@click.command(name='remove', short_help='Remove storage template from the cluster.') @click.command(name='remove', short_help='Remove storage template.')
@click.argument( @click.argument(
'name' 'name'
) )
@ -2339,7 +2339,7 @@ def provisioner_userdata():
############################################################################### ###############################################################################
# pvc provisioner userdata list # pvc provisioner userdata list
############################################################################### ###############################################################################
@click.command(name='list', short_help='List all userdata documents in the cluster.') @click.command(name='list', short_help='List all userdata documents.')
@click.argument( @click.argument(
'limit', default=None, required=False 'limit', default=None, required=False
) )
@ -2474,7 +2474,7 @@ def provisioner_userdata_modify(name, filename, editor):
############################################################################### ###############################################################################
# pvc provisioner userdata remove # pvc provisioner userdata remove
############################################################################### ###############################################################################
@click.command(name='remove', short_help='Remove userdata document from the cluster.') @click.command(name='remove', short_help='Remove userdata document.')
@click.argument( @click.argument(
'name' 'name'
) )
@ -2501,7 +2501,7 @@ def provisioner_script():
############################################################################### ###############################################################################
# pvc provisioner script list # pvc provisioner script list
############################################################################### ###############################################################################
@click.command(name='list', short_help='List all scripts in the cluster.') @click.command(name='list', short_help='List all scripts.')
@click.argument( @click.argument(
'limit', default=None, required=False 'limit', default=None, required=False
) )
@ -2636,7 +2636,7 @@ def provisioner_script_modify(name, filename, editor):
############################################################################### ###############################################################################
# pvc provisioner script remove # pvc provisioner script remove
############################################################################### ###############################################################################
@click.command(name='remove', short_help='Remove script from the cluster.') @click.command(name='remove', short_help='Remove script.')
@click.argument( @click.argument(
'name' 'name'
) )
@ -2648,6 +2648,167 @@ def provisioner_script_remove(name):
cleanup(retcode, retdata) cleanup(retcode, retdata)
###############################################################################
# pvc provisioner profile
###############################################################################
@click.group(name='profile', short_help='Manage PVC provisioner profiless.', context_settings=CONTEXT_SETTINGS)
def provisioner_profile():
"""
Manage profiles in the PVC provisioner.
"""
# Abort commands under this group if config is bad
if config.get('badcfg', None):
exit(1)
###############################################################################
# pvc provisioner profile list
###############################################################################
@click.command(name='list', short_help='List all profiles.')
@click.argument(
'limit', default=None, required=False
)
def provisioner_profile_list(limit):
"""
List all profiles in the PVC cluster provisioner.
"""
retcode, retdata = pvc_provisioner.profile_list(config, limit)
if retcode:
pvc_provisioner.format_list_profile(retdata)
retdata = ''
cleanup(retcode, retdata)
###############################################################################
# pvc provisioner profile add
###############################################################################
@click.command(name='add', short_help='Add provisioner profile.')
@click.argument(
'name'
)
@click.option(
'-s', '--system-template', 'system_template',
required=True,
help='The system template for the profile.'
)
@click.option(
'-n', '--network-template', 'network_template',
required=True,
help='The network template for the profile.'
)
@click.option(
'-t', '--storage-template', 'storage_template',
required=True,
help='The storage template for the profile.'
)
@click.option(
'-u', '--userdata', 'userdata',
required=True,
help='The userdata document for the profile.'
)
@click.option(
'-x', '--script', 'script',
required=True,
help='The script for the profile.'
)
@click.option(
'-a', '--script-arg', 'script_args',
default=[], multiple=True,
help='Additional argument to the script install() function in key=value format.'
)
def provisioner_profile_add(name, system_template, network_template, storage_template, userdata, script, script_args):
"""
Add a new provisioner profile NAME.
"""
params = dict()
params['name'] = name
params['system_template'] = system_template
params['network_template'] = network_template
params['storage_template'] = storage_template
params['userdata'] = userdata
params['script'] = script
params['arg'] = script_args
retcode, retdata = pvc_provisioner.profile_add(config, params)
cleanup(retcode, retdata)
###############################################################################
# pvc provisioner profile modify
###############################################################################
@click.command(name='modify', short_help='Modify provisioner profile.')
@click.argument(
'name'
)
@click.option(
'-s', '--system-template', 'system_template',
default=None,
help='The system template for the profile.'
)
@click.option(
'-n', '--network-template', 'network_template',
default=None,
help='The network template for the profile.'
)
@click.option(
'-t', '--storage-template', 'storage_template',
default=None,
help='The storage template for the profile.'
)
@click.option(
'-u', '--userdata', 'userdata',
default=None,
help='The userdata document for the profile.'
)
@click.option(
'-x', '--script', 'script',
default=None,
help='The script for the profile.'
)
@click.option(
'-d', '--delete-script-args', 'delete_script_args',
default=False, is_flag=True,
help="Delete any existing script arguments."
)
@click.option(
'-a', '--script-arg', 'script_args',
default=None, multiple=True,
help='Additional argument to the script install() function in key=value format.'
)
def provisioner_profile_modify(name, system_template, network_template, storage_template, userdata, script, delete_script_args, script_args):
"""
Modify existing provisioner profile NAME.
"""
params = dict()
if system_template is not None:
params['system_template'] = system_template
if network_template is not None:
params['network_template'] = network_template
if storage_template is not None:
params['storage_template'] = storage_template
if userdata is not None:
params['userdata'] = userdata
if script is not None:
params['script'] = script
if delete_script_args:
params['arg'] = []
if script_args is not None:
params['arg'] = script_args
retcode, retdata = pvc_provisioner.profile_modify(config, name, params)
cleanup(retcode, retdata)
###############################################################################
# pvc provisioner profile remove
###############################################################################
@click.command(name='remove', short_help='Remove profile.')
@click.argument(
'name'
)
def provisioner_profile_remove(name):
"""
Remove profile NAME from the PVC cluster provisioner.
"""
retcode, retdata = pvc_provisioner.profile_remove(config, name)
cleanup(retcode, retdata)
@ -2869,9 +3030,15 @@ provisioner_script.add_command(provisioner_script_add)
provisioner_script.add_command(provisioner_script_modify) provisioner_script.add_command(provisioner_script_modify)
provisioner_script.add_command(provisioner_script_remove) provisioner_script.add_command(provisioner_script_remove)
provisioner_profile.add_command(provisioner_profile_list)
provisioner_profile.add_command(provisioner_profile_add)
provisioner_profile.add_command(provisioner_profile_modify)
provisioner_profile.add_command(provisioner_profile_remove)
cli_provisioner.add_command(provisioner_template) cli_provisioner.add_command(provisioner_template)
cli_provisioner.add_command(provisioner_userdata) cli_provisioner.add_command(provisioner_userdata)
cli_provisioner.add_command(provisioner_script) cli_provisioner.add_command(provisioner_script)
cli_provisioner.add_command(provisioner_profile)
cli.add_command(cli_cluster) cli.add_command(cli_cluster)
cli.add_command(cli_node) cli.add_command(cli_node)