Add userdata and script options
This commit is contained in:
parent
1c12a4c2f9
commit
a4ad58e64c
|
@ -49,7 +49,7 @@ def template_info(config, template, template_type):
|
|||
|
||||
API endpoint: GET /api/v1/provisioner/template/{template_type}/{template}
|
||||
API arguments:
|
||||
API schema: {json_data_object}
|
||||
API schema: {json_template_object}
|
||||
"""
|
||||
request_uri = get_request_uri(config, '/provisioner/template/{template_type}/{template}'.format(template_type=template_type, template=template))
|
||||
response = requests.get(
|
||||
|
@ -72,7 +72,7 @@ def template_list(config, limit, template_type=None):
|
|||
|
||||
API endpoint: GET /api/v1/provisioner/template/{template_type}
|
||||
API arguments: limit={limit}
|
||||
API schema: [{json_data_object},{json_data_object},etc.]
|
||||
API schema: [{json_template_object},{json_template_object},etc.]
|
||||
"""
|
||||
params = dict()
|
||||
if limit:
|
||||
|
@ -125,7 +125,7 @@ def template_add(config, params, template_type=None):
|
|||
|
||||
def template_remove(config, name, template_type=None):
|
||||
"""
|
||||
Remove a template {name} of {template_type}
|
||||
Remove template {name} of {template_type}
|
||||
|
||||
API endpoint: DELETE /api/v1/provisioner/template/{template_type}/{name}
|
||||
API_arguments:
|
||||
|
@ -176,7 +176,7 @@ def template_element_add(config, name, element_id, params, element_type=None, te
|
|||
|
||||
def template_element_remove(config, name, element_id, element_type=None, template_type=None):
|
||||
"""
|
||||
Remove a template element {element_id} of {element_type} from template {name} of {template_type}
|
||||
Remove template element {element_id} of {element_type} from template {name} of {template_type}
|
||||
|
||||
API endpoint: DELETE /api/v1/provisioner/template/{template_type}/{name}/{element_type}/{element_id}
|
||||
API_arguments:
|
||||
|
@ -199,50 +199,304 @@ def template_element_remove(config, name, element_id, element_type=None, templat
|
|||
|
||||
return retvalue, response.json()['message']
|
||||
|
||||
def userdata_info(config, userdata):
|
||||
"""
|
||||
Get information about userdata
|
||||
|
||||
API endpoint: GET /api/v1/provisioner/userdata/{userdata}
|
||||
API arguments:
|
||||
API schema: {json_data_object}
|
||||
"""
|
||||
request_uri = get_request_uri(config, '/provisioner/userdata/{userdata}'.format(userdata=userdata))
|
||||
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 userdata_list(config, limit):
|
||||
"""
|
||||
Get list information about userdatas (limited by {limit})
|
||||
|
||||
API endpoint: GET /api/v1/provisioner/userdata/{userdata_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/userdata')
|
||||
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 userdata_add(config, params):
|
||||
"""
|
||||
Add a new userdata with {params}
|
||||
|
||||
API endpoint: POST /api/v1/provisioner/userdata
|
||||
API_arguments: args
|
||||
API schema: {message}
|
||||
"""
|
||||
request_uri = get_request_uri(config, '/provisioner/userdata')
|
||||
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 userdata_modify(config, name, params):
|
||||
"""
|
||||
Modify userdata {name} with {params}
|
||||
|
||||
API endpoint: PUT /api/v1/provisioner/userdata/{name}
|
||||
API_arguments: args
|
||||
API schema: {message}
|
||||
"""
|
||||
request_uri = get_request_uri(config, '/provisioner/userdata/{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 userdata_remove(config, name):
|
||||
"""
|
||||
Remove userdata {name}
|
||||
|
||||
API endpoint: DELETE /api/v1/provisioner/userdata/{name}
|
||||
API_arguments:
|
||||
API schema: {message}
|
||||
"""
|
||||
request_uri = get_request_uri(config, '/provisioner/userdata/{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 script_info(config, script):
|
||||
"""
|
||||
Get information about script
|
||||
|
||||
API endpoint: GET /api/v1/provisioner/script/{script}
|
||||
API arguments:
|
||||
API schema: {json_data_object}
|
||||
"""
|
||||
request_uri = get_request_uri(config, '/provisioner/script/{script}'.format(script=script))
|
||||
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 script_list(config, limit):
|
||||
"""
|
||||
Get list information about scripts (limited by {limit})
|
||||
|
||||
API endpoint: GET /api/v1/provisioner/script/{script_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/script')
|
||||
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 script_add(config, params):
|
||||
"""
|
||||
Add a new script with {params}
|
||||
|
||||
API endpoint: POST /api/v1/provisioner/script
|
||||
API_arguments: args
|
||||
API schema: {message}
|
||||
"""
|
||||
request_uri = get_request_uri(config, '/provisioner/script')
|
||||
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 script_modify(config, name, params):
|
||||
"""
|
||||
Modify script {name} with {params}
|
||||
|
||||
API endpoint: PUT /api/v1/provisioner/script/{name}
|
||||
API_arguments: args
|
||||
API schema: {message}
|
||||
"""
|
||||
request_uri = get_request_uri(config, '/provisioner/script/{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 script_remove(config, name):
|
||||
"""
|
||||
Remove script {name}
|
||||
|
||||
API endpoint: DELETE /api/v1/provisioner/script/{name}
|
||||
API_arguments:
|
||||
API schema: {message}
|
||||
"""
|
||||
request_uri = get_request_uri(config, '/provisioner/script/{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']
|
||||
|
||||
#
|
||||
# Format functions
|
||||
#
|
||||
def format_list_template(template_data, template_type=None):
|
||||
def format_list_template(template_template, template_type=None):
|
||||
"""
|
||||
Format the returned template data
|
||||
Format the returned template template
|
||||
|
||||
template_type can be used to only display part of the full list, allowing function
|
||||
reuse with more limited output options.
|
||||
"""
|
||||
template_types = [ 'system', 'network', 'storage' ]
|
||||
normalized_template_data = dict()
|
||||
normalized_template_template = dict()
|
||||
|
||||
if template_type in template_types:
|
||||
template_types = [ template_type ]
|
||||
template_data_type = '{}_templates'.format(template_type)
|
||||
normalized_template_data[template_data_type] = template_data
|
||||
template_template_type = '{}_templates'.format(template_type)
|
||||
normalized_template_template[template_template_type] = template_template
|
||||
else:
|
||||
normalized_template_data = template_data
|
||||
normalized_template_template = template_template
|
||||
|
||||
if 'system' in template_types:
|
||||
click.echo('System templates:')
|
||||
click.echo()
|
||||
format_list_template_system(normalized_template_data['system_templates'])
|
||||
format_list_template_system(normalized_template_template['system_templates'])
|
||||
if len(template_types) > 1:
|
||||
click.echo()
|
||||
|
||||
if 'network' in template_types:
|
||||
click.echo('Network templates:')
|
||||
click.echo()
|
||||
format_list_template_network(normalized_template_data['network_templates'])
|
||||
format_list_template_network(normalized_template_template['network_templates'])
|
||||
if len(template_types) > 1:
|
||||
click.echo()
|
||||
|
||||
if 'storage' in template_types:
|
||||
click.echo('Storage templates:')
|
||||
click.echo()
|
||||
format_list_template_storage(normalized_template_data['storage_templates'])
|
||||
format_list_template_storage(normalized_template_template['storage_templates'])
|
||||
|
||||
def format_list_template_system(template_data):
|
||||
if isinstance(template_data, dict):
|
||||
template_data = [ template_data ]
|
||||
def format_list_template_system(template_template):
|
||||
if isinstance(template_template, dict):
|
||||
template_template = [ template_template ]
|
||||
|
||||
template_list_output = []
|
||||
|
||||
|
@ -258,7 +512,7 @@ def format_list_template_system(template_data):
|
|||
template_node_selector_length = 11
|
||||
template_node_autostart_length = 11
|
||||
|
||||
for template in template_data:
|
||||
for template in template_template:
|
||||
# template_name column
|
||||
_template_name_length = len(str(template['name'])) + 1
|
||||
if _template_name_length > template_name_length:
|
||||
|
@ -307,7 +561,7 @@ def format_list_template_system(template_data):
|
|||
Consoles: {template_serial: <{template_serial_length}} \
|
||||
{template_vnc: <{template_vnc_length}} \
|
||||
{template_vnc_bind: <{template_vnc_bind_length}} \
|
||||
Metadata: {template_node_limit: <{template_node_limit_length}} \
|
||||
Metatemplate: {template_node_limit: <{template_node_limit_length}} \
|
||||
{template_node_selector: <{template_node_selector_length}} \
|
||||
{template_node_autostart: <{template_node_autostart_length}}{end_bold}'.format(
|
||||
template_name_length=template_name_length,
|
||||
|
@ -340,7 +594,7 @@ Metadata: {template_node_limit: <{template_node_limit_length}} \
|
|||
valid_net_list = []
|
||||
# Format the string (elements)
|
||||
|
||||
for template in sorted(template_data, key=lambda i: i.get('name', None)):
|
||||
for template in sorted(template_template, key=lambda i: i.get('name', None)):
|
||||
template_list_output.append(
|
||||
'{bold}{template_name: <{template_name_length}} {template_id: <{template_id_length}} \
|
||||
{template_vcpu: <{template_vcpu_length}} \
|
||||
|
@ -380,9 +634,9 @@ Metadata: {template_node_limit: <{template_node_limit_length}} \
|
|||
|
||||
return True, ''
|
||||
|
||||
def format_list_template_network(template_data):
|
||||
if isinstance(template_data, dict):
|
||||
template_data = [ template_data ]
|
||||
def format_list_template_network(template_template):
|
||||
if isinstance(template_template, dict):
|
||||
template_template = [ template_template ]
|
||||
|
||||
template_list_output = []
|
||||
|
||||
|
@ -392,14 +646,14 @@ def format_list_template_network(template_data):
|
|||
template_mac_template_length = 13
|
||||
template_networks_length = 10
|
||||
|
||||
for template in template_data:
|
||||
for template in template_template:
|
||||
# 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)
|
||||
|
||||
for template in template_data:
|
||||
for template in template_template:
|
||||
# template_name column
|
||||
_template_name_length = len(str(template['name'])) + 1
|
||||
if _template_name_length > template_name_length:
|
||||
|
@ -434,7 +688,7 @@ def format_list_template_network(template_data):
|
|||
)
|
||||
|
||||
# Format the string (elements)
|
||||
for template in sorted(template_data, key=lambda i: i.get('name', None)):
|
||||
for template in sorted(template_template, key=lambda i: i.get('name', None)):
|
||||
template_list_output.append(
|
||||
'{bold}{template_name: <{template_name_length}} {template_id: <{template_id_length}} \
|
||||
{template_mac_template: <{template_mac_template_length}} \
|
||||
|
@ -456,9 +710,9 @@ def format_list_template_network(template_data):
|
|||
|
||||
return True, ''
|
||||
|
||||
def format_list_template_storage(template_data):
|
||||
if isinstance(template_data, dict):
|
||||
template_data = [ template_data ]
|
||||
def format_list_template_storage(template_template):
|
||||
if isinstance(template_template, dict):
|
||||
template_template = [ template_template ]
|
||||
|
||||
template_list_output = []
|
||||
|
||||
|
@ -472,7 +726,7 @@ def format_list_template_storage(template_data):
|
|||
template_disk_fsargs_length = 10
|
||||
template_disk_mountpoint_length = 10
|
||||
|
||||
for template in template_data:
|
||||
for template in template_template:
|
||||
# template_name column
|
||||
_template_name_length = len(str(template['name'])) + 1
|
||||
if _template_name_length > template_name_length:
|
||||
|
@ -537,7 +791,7 @@ def format_list_template_storage(template_data):
|
|||
)
|
||||
|
||||
# Format the string (elements)
|
||||
for template in sorted(template_data, key=lambda i: i.get('name', None)):
|
||||
for template in sorted(template_template, key=lambda i: i.get('name', None)):
|
||||
template_list_output.append(
|
||||
'{bold}{template_name: <{template_name_length}} {template_id: <{template_id_length}}{end_bold}'.format(
|
||||
template_name_length=template_name_length,
|
||||
|
@ -588,3 +842,157 @@ def format_list_template_storage(template_data):
|
|||
|
||||
return True, ''
|
||||
|
||||
def format_list_userdata(userdata, lines=None):
|
||||
if isinstance(userdata, dict):
|
||||
userdata = [ userdata ]
|
||||
|
||||
data_list_output = []
|
||||
|
||||
# Determine optimal column widths
|
||||
data_name_length = 5
|
||||
data_id_length = 4
|
||||
data_userdata_length = 8
|
||||
|
||||
for data in userdata:
|
||||
# data_name column
|
||||
_data_name_length = len(str(data['name'])) + 1
|
||||
if _data_name_length > data_name_length:
|
||||
data_name_length = _data_name_length
|
||||
# data_id column
|
||||
_data_id_length = len(str(data['id'])) + 1
|
||||
if _data_id_length > data_id_length:
|
||||
data_id_length = _data_id_length
|
||||
|
||||
# Format the string (header)
|
||||
data_list_output_header = '{bold}{data_name: <{data_name_length}} {data_id: <{data_id_length}} \
|
||||
{data_userdata}{end_bold}'.format(
|
||||
data_name_length=data_name_length,
|
||||
data_id_length=data_id_length,
|
||||
bold=ansiprint.bold(),
|
||||
end_bold=ansiprint.end(),
|
||||
data_name='Name',
|
||||
data_id='ID',
|
||||
data_userdata='Document'
|
||||
)
|
||||
|
||||
# Format the string (elements)
|
||||
for data in sorted(userdata, key=lambda i: i.get('name', None)):
|
||||
line_count = 0
|
||||
for line in data['userdata'].split('\n'):
|
||||
if line_count < 1:
|
||||
data_name = data['name']
|
||||
data_id = data['id']
|
||||
else:
|
||||
data_name = ''
|
||||
data_id = ''
|
||||
line_count += 1
|
||||
|
||||
if lines and line_count > lines:
|
||||
data_list_output.append(
|
||||
'{bold}{data_name: <{data_name_length}} {data_id: <{data_id_length}} \
|
||||
{data_script}{end_bold}'.format(
|
||||
data_name_length=data_name_length,
|
||||
data_id_length=data_id_length,
|
||||
bold='',
|
||||
end_bold='',
|
||||
data_name=data_name,
|
||||
data_id=data_id,
|
||||
data_script='[...]'
|
||||
)
|
||||
)
|
||||
break
|
||||
|
||||
data_list_output.append(
|
||||
'{bold}{data_name: <{data_name_length}} {data_id: <{data_id_length}} \
|
||||
{data_userdata}{end_bold}'.format(
|
||||
data_name_length=data_name_length,
|
||||
data_id_length=data_id_length,
|
||||
bold='',
|
||||
end_bold='',
|
||||
data_name=data_name,
|
||||
data_id=data_id,
|
||||
data_userdata=str(line)
|
||||
)
|
||||
)
|
||||
|
||||
click.echo('\n'.join([data_list_output_header] + data_list_output))
|
||||
|
||||
return True, ''
|
||||
|
||||
def format_list_script(script, lines=None):
|
||||
if isinstance(script, dict):
|
||||
script = [ script ]
|
||||
|
||||
data_list_output = []
|
||||
|
||||
# Determine optimal column widths
|
||||
data_name_length = 5
|
||||
data_id_length = 4
|
||||
data_script_length = 8
|
||||
|
||||
for data in script:
|
||||
# data_name column
|
||||
_data_name_length = len(str(data['name'])) + 1
|
||||
if _data_name_length > data_name_length:
|
||||
data_name_length = _data_name_length
|
||||
# data_id column
|
||||
_data_id_length = len(str(data['id'])) + 1
|
||||
if _data_id_length > data_id_length:
|
||||
data_id_length = _data_id_length
|
||||
|
||||
# Format the string (header)
|
||||
data_list_output_header = '{bold}{data_name: <{data_name_length}} {data_id: <{data_id_length}} \
|
||||
{data_script}{end_bold}'.format(
|
||||
data_name_length=data_name_length,
|
||||
data_id_length=data_id_length,
|
||||
bold=ansiprint.bold(),
|
||||
end_bold=ansiprint.end(),
|
||||
data_name='Name',
|
||||
data_id='ID',
|
||||
data_script='Script'
|
||||
)
|
||||
|
||||
# Format the string (elements)
|
||||
for data in sorted(script, key=lambda i: i.get('name', None)):
|
||||
line_count = 0
|
||||
for line in data['script'].split('\n'):
|
||||
if line_count < 1:
|
||||
data_name = data['name']
|
||||
data_id = data['id']
|
||||
else:
|
||||
data_name = ''
|
||||
data_id = ''
|
||||
line_count += 1
|
||||
|
||||
if lines and line_count > lines:
|
||||
data_list_output.append(
|
||||
'{bold}{data_name: <{data_name_length}} {data_id: <{data_id_length}} \
|
||||
{data_script}{end_bold}'.format(
|
||||
data_name_length=data_name_length,
|
||||
data_id_length=data_id_length,
|
||||
bold='',
|
||||
end_bold='',
|
||||
data_name=data_name,
|
||||
data_id=data_id,
|
||||
data_script='[...]'
|
||||
)
|
||||
)
|
||||
break
|
||||
|
||||
data_list_output.append(
|
||||
'{bold}{data_name: <{data_name_length}} {data_id: <{data_id_length}} \
|
||||
{data_script}{end_bold}'.format(
|
||||
data_name_length=data_name_length,
|
||||
data_id_length=data_id_length,
|
||||
bold='',
|
||||
end_bold='',
|
||||
data_name=data_name,
|
||||
data_id=data_id,
|
||||
data_script=str(line)
|
||||
)
|
||||
)
|
||||
|
||||
click.echo('\n'.join([data_list_output_header] + data_list_output))
|
||||
|
||||
return True, ''
|
||||
|
||||
|
|
|
@ -582,7 +582,7 @@ def vm_modify(domain, cfgfile, editor, restart):
|
|||
click.echo(line)
|
||||
click.echo('')
|
||||
|
||||
click.confirm('Write modifications to Zookeeper?', abort=True)
|
||||
click.confirm('Write modifications to cluster?', abort=True)
|
||||
|
||||
if restart:
|
||||
click.echo('Writing modified configuration of VM "{}" and restarting.'.format(dom_name))
|
||||
|
@ -2020,7 +2020,7 @@ def provisioner_template_system_add(name, vcpus, vram, serial, vnc, vnc_bind, no
|
|||
)
|
||||
def provisioner_template_system_remove(name):
|
||||
"""
|
||||
Remove a system template from the PVC cluster provisioner.
|
||||
Remove system template NAME from the PVC cluster provisioner.
|
||||
"""
|
||||
retcode, retdata = pvc_provisioner.template_remove(config, name, template_type='system')
|
||||
cleanup(retcode, retdata)
|
||||
|
@ -2113,7 +2113,7 @@ def provisioner_template_network_add(name, mac_template):
|
|||
)
|
||||
def provisioner_template_network_remove(name):
|
||||
"""
|
||||
Remove a network template from the PVC cluster provisioner.
|
||||
Remove network template MAME from the PVC cluster provisioner.
|
||||
"""
|
||||
retcode, retdata = pvc_provisioner.template_remove(config, name, template_type='network')
|
||||
cleanup(retcode, retdata)
|
||||
|
@ -2161,7 +2161,7 @@ def provisioner_template_network_vni_add(name, vni):
|
|||
)
|
||||
def provisioner_template_network_vni_remove(name, vni):
|
||||
"""
|
||||
Remove a network VNI from network template NAME.
|
||||
Remove network VNI from network template NAME.
|
||||
"""
|
||||
params = dict()
|
||||
|
||||
|
@ -2224,7 +2224,7 @@ def provisioner_template_storage_add(name):
|
|||
)
|
||||
def provisioner_template_storage_remove(name):
|
||||
"""
|
||||
Remove a storage template from the PVC cluster provisioner.
|
||||
Remove storage template NAME from the PVC cluster provisioner.
|
||||
"""
|
||||
retcode, retdata = pvc_provisioner.template_remove(config, name, template_type='storage')
|
||||
cleanup(retcode, retdata)
|
||||
|
@ -2314,7 +2314,9 @@ def provisioner_template_storage_disk_add(name, disk, pool, size, filesystem, fs
|
|||
)
|
||||
def provisioner_template_storage_disk_remove(name, disk):
|
||||
"""
|
||||
Remove a DISK from storage template NAME.
|
||||
Remove DISK from storage template NAME.
|
||||
|
||||
DISK must be a Linux-style disk identifier such as "sda" or "vdb".
|
||||
"""
|
||||
params = dict()
|
||||
|
||||
|
@ -2322,6 +2324,328 @@ def provisioner_template_storage_disk_remove(name, disk):
|
|||
cleanup(retcode, retdata)
|
||||
|
||||
|
||||
###############################################################################
|
||||
# pvc provisioner userdata
|
||||
###############################################################################
|
||||
@click.group(name='userdata', short_help='Manage PVC provisioner userdata documents.', context_settings=CONTEXT_SETTINGS)
|
||||
def provisioner_userdata():
|
||||
"""
|
||||
Manage userdata documents in the PVC provisioner.
|
||||
"""
|
||||
# Abort commands under this group if config is bad
|
||||
if config.get('badcfg', None):
|
||||
exit(1)
|
||||
|
||||
###############################################################################
|
||||
# pvc provisioner userdata list
|
||||
###############################################################################
|
||||
@click.command(name='list', short_help='List all userdata documents in the cluster.')
|
||||
@click.argument(
|
||||
'limit', default=None, required=False
|
||||
)
|
||||
@click.option(
|
||||
'-f', '--full', 'full',
|
||||
is_flag=True, default=False,
|
||||
help='Show all lines of the document instead of first 4.'
|
||||
)
|
||||
def provisioner_userdata_list(limit, full):
|
||||
"""
|
||||
List all userdata documents in the PVC cluster provisioner.
|
||||
"""
|
||||
retcode, retdata = pvc_provisioner.userdata_list(config, limit)
|
||||
if retcode:
|
||||
if not full:
|
||||
lines = 4
|
||||
else:
|
||||
lines = None
|
||||
pvc_provisioner.format_list_userdata(retdata, lines)
|
||||
retdata = ''
|
||||
cleanup(retcode, retdata)
|
||||
|
||||
###############################################################################
|
||||
# pvc provisioner userdata add
|
||||
###############################################################################
|
||||
@click.command(name='add', short_help='Define userdata document from file.')
|
||||
@click.argument(
|
||||
'name'
|
||||
)
|
||||
@click.argument(
|
||||
'filename', type=click.File()
|
||||
)
|
||||
def provisioner_userdata_add(name, filename):
|
||||
"""
|
||||
Add a new userdata document NAME from file FILENAME.
|
||||
"""
|
||||
|
||||
# Open the XML file
|
||||
userdata = filename.read()
|
||||
filename.close()
|
||||
|
||||
params = dict()
|
||||
params['name'] = name
|
||||
params['data'] = userdata
|
||||
|
||||
retcode, retmsg = pvc_provisioner.userdata_add(config, params)
|
||||
cleanup(retcode, retmsg)
|
||||
|
||||
###############################################################################
|
||||
# pvc provisioner userdata modify
|
||||
###############################################################################
|
||||
@click.command(name='modify', short_help='Modify existing userdata document.')
|
||||
@click.option(
|
||||
'-e', '--editor', 'editor', is_flag=True,
|
||||
help='Use local editor to modify existing document.'
|
||||
)
|
||||
@click.argument(
|
||||
'name'
|
||||
)
|
||||
@click.argument(
|
||||
'filename', type=click.File(), default=None, required=False
|
||||
)
|
||||
def provisioner_userdata_modify(name, filename, editor):
|
||||
"""
|
||||
Modify existing userdata document NAME, either in-editor or with replacement FILE.
|
||||
"""
|
||||
|
||||
if editor == False and filename == None:
|
||||
cleanup(False, 'Either a file or the "--editor" option must be specified.')
|
||||
|
||||
if editor == True:
|
||||
# Grab the current config
|
||||
retcode, retdata = pvc_provisioner.userdata_info(config, name)
|
||||
if not retcode:
|
||||
click.echo(retdata)
|
||||
exit(1)
|
||||
current_userdata = retdata['userdata']
|
||||
|
||||
# Write it to a tempfile
|
||||
fd, path = tempfile.mkstemp()
|
||||
fw = os.fdopen(fd, 'w')
|
||||
fw.write(current_userdata.strip())
|
||||
fw.close()
|
||||
|
||||
# Edit it
|
||||
editor = os.getenv('EDITOR', 'vi')
|
||||
subprocess.call('%s %s' % (editor, path), shell=True)
|
||||
|
||||
# Open the tempfile to read
|
||||
with open(path, 'r') as fr:
|
||||
new_userdata = fr.read().strip()
|
||||
fr.close()
|
||||
|
||||
# Delete the tempfile
|
||||
os.unlink(path)
|
||||
|
||||
# Show a diff and confirm
|
||||
diff = list(difflib.unified_diff(current_userdata.split('\n'), new_userdata.split('\n'), fromfile='current', tofile='modified', fromfiledate='', tofiledate='', n=3, lineterm=''))
|
||||
if len(diff) < 1:
|
||||
click.echo('Aborting with no modifications.')
|
||||
exit(0)
|
||||
|
||||
click.echo('Pending modifications:')
|
||||
click.echo('')
|
||||
for line in diff:
|
||||
if re.match('^\+', line) != None:
|
||||
click.echo(colorama.Fore.GREEN + line + colorama.Fore.RESET)
|
||||
elif re.match('^\-', line) != None:
|
||||
click.echo(colorama.Fore.RED + line + colorama.Fore.RESET)
|
||||
elif re.match('^\^', line) != None:
|
||||
click.echo(colorama.Fore.BLUE + line + colorama.Fore.RESET)
|
||||
else:
|
||||
click.echo(line)
|
||||
click.echo('')
|
||||
|
||||
click.confirm('Write modifications to cluster?', abort=True)
|
||||
|
||||
userdata = new_userdata
|
||||
|
||||
# We're operating in replace mode
|
||||
else:
|
||||
# Open the new file
|
||||
userdata = filename.read().strip()
|
||||
filename.close()
|
||||
|
||||
params = dict()
|
||||
params['data'] = userdata
|
||||
|
||||
retcode, retmsg = pvc_provisioner.userdata_modify(config, name, params)
|
||||
cleanup(retcode, retmsg)
|
||||
|
||||
###############################################################################
|
||||
# pvc provisioner userdata remove
|
||||
###############################################################################
|
||||
@click.command(name='remove', short_help='Remove userdata document from the cluster.')
|
||||
@click.argument(
|
||||
'name'
|
||||
)
|
||||
def provisioner_userdata_remove(name):
|
||||
"""
|
||||
Remove userdata document NAME from the PVC cluster provisioner.
|
||||
"""
|
||||
retcode, retdata = pvc_provisioner.userdata_remove(config, name)
|
||||
cleanup(retcode, retdata)
|
||||
|
||||
|
||||
###############################################################################
|
||||
# pvc provisioner script
|
||||
###############################################################################
|
||||
@click.group(name='script', short_help='Manage PVC provisioner scripts.', context_settings=CONTEXT_SETTINGS)
|
||||
def provisioner_script():
|
||||
"""
|
||||
Manage scripts in the PVC provisioner.
|
||||
"""
|
||||
# Abort commands under this group if config is bad
|
||||
if config.get('badcfg', None):
|
||||
exit(1)
|
||||
|
||||
###############################################################################
|
||||
# pvc provisioner script list
|
||||
###############################################################################
|
||||
@click.command(name='list', short_help='List all scripts in the cluster.')
|
||||
@click.argument(
|
||||
'limit', default=None, required=False
|
||||
)
|
||||
@click.option(
|
||||
'-f', '--full', 'full',
|
||||
is_flag=True, default=False,
|
||||
help='Show all lines of the document instead of first 4.'
|
||||
)
|
||||
def provisioner_script_list(limit, full):
|
||||
"""
|
||||
List all scripts in the PVC cluster provisioner.
|
||||
"""
|
||||
retcode, retdata = pvc_provisioner.script_list(config, limit)
|
||||
if retcode:
|
||||
if not full:
|
||||
lines = 4
|
||||
else:
|
||||
lines = None
|
||||
pvc_provisioner.format_list_script(retdata, lines)
|
||||
retdata = ''
|
||||
cleanup(retcode, retdata)
|
||||
|
||||
###############################################################################
|
||||
# pvc provisioner script add
|
||||
###############################################################################
|
||||
@click.command(name='add', short_help='Define script from file.')
|
||||
@click.argument(
|
||||
'name'
|
||||
)
|
||||
@click.argument(
|
||||
'filename', type=click.File()
|
||||
)
|
||||
def provisioner_script_add(name, filename):
|
||||
"""
|
||||
Add a new script NAME from file FILENAME.
|
||||
"""
|
||||
|
||||
# Open the XML file
|
||||
script = filename.read()
|
||||
filename.close()
|
||||
|
||||
params = dict()
|
||||
params['name'] = name
|
||||
params['data'] = script
|
||||
|
||||
retcode, retmsg = pvc_provisioner.script_add(config, params)
|
||||
cleanup(retcode, retmsg)
|
||||
|
||||
###############################################################################
|
||||
# pvc provisioner script modify
|
||||
###############################################################################
|
||||
@click.command(name='modify', short_help='Modify existing script.')
|
||||
@click.option(
|
||||
'-e', '--editor', 'editor', is_flag=True,
|
||||
help='Use local editor to modify existing document.'
|
||||
)
|
||||
@click.argument(
|
||||
'name'
|
||||
)
|
||||
@click.argument(
|
||||
'filename', type=click.File(), default=None, required=False
|
||||
)
|
||||
def provisioner_script_modify(name, filename, editor):
|
||||
"""
|
||||
Modify existing script NAME, either in-editor or with replacement FILE.
|
||||
"""
|
||||
|
||||
if editor == False and filename == None:
|
||||
cleanup(False, 'Either a file or the "--editor" option must be specified.')
|
||||
|
||||
if editor == True:
|
||||
# Grab the current config
|
||||
retcode, retdata = pvc_provisioner.script_info(config, name)
|
||||
if not retcode:
|
||||
click.echo(retdata)
|
||||
exit(1)
|
||||
current_script = retdata['script']
|
||||
|
||||
# Write it to a tempfile
|
||||
fd, path = tempfile.mkstemp()
|
||||
fw = os.fdopen(fd, 'w')
|
||||
fw.write(current_script.strip())
|
||||
fw.close()
|
||||
|
||||
# Edit it
|
||||
editor = os.getenv('EDITOR', 'vi')
|
||||
subprocess.call('%s %s' % (editor, path), shell=True)
|
||||
|
||||
# Open the tempfile to read
|
||||
with open(path, 'r') as fr:
|
||||
new_script = fr.read().strip()
|
||||
fr.close()
|
||||
|
||||
# Delete the tempfile
|
||||
os.unlink(path)
|
||||
|
||||
# Show a diff and confirm
|
||||
diff = list(difflib.unified_diff(current_script.split('\n'), new_script.split('\n'), fromfile='current', tofile='modified', fromfiledate='', tofiledate='', n=3, lineterm=''))
|
||||
if len(diff) < 1:
|
||||
click.echo('Aborting with no modifications.')
|
||||
exit(0)
|
||||
|
||||
click.echo('Pending modifications:')
|
||||
click.echo('')
|
||||
for line in diff:
|
||||
if re.match('^\+', line) != None:
|
||||
click.echo(colorama.Fore.GREEN + line + colorama.Fore.RESET)
|
||||
elif re.match('^\-', line) != None:
|
||||
click.echo(colorama.Fore.RED + line + colorama.Fore.RESET)
|
||||
elif re.match('^\^', line) != None:
|
||||
click.echo(colorama.Fore.BLUE + line + colorama.Fore.RESET)
|
||||
else:
|
||||
click.echo(line)
|
||||
click.echo('')
|
||||
|
||||
click.confirm('Write modifications to cluster?', abort=True)
|
||||
|
||||
script = new_script
|
||||
|
||||
# We're operating in replace mode
|
||||
else:
|
||||
# Open the new file
|
||||
script = filename.read().strip()
|
||||
filename.close()
|
||||
|
||||
params = dict()
|
||||
params['data'] = script
|
||||
|
||||
retcode, retmsg = pvc_provisioner.script_modify(config, name, params)
|
||||
cleanup(retcode, retmsg)
|
||||
|
||||
###############################################################################
|
||||
# pvc provisioner script remove
|
||||
###############################################################################
|
||||
@click.command(name='remove', short_help='Remove script from the cluster.')
|
||||
@click.argument(
|
||||
'name'
|
||||
)
|
||||
def provisioner_script_remove(name):
|
||||
"""
|
||||
Remove script NAME from the PVC cluster provisioner.
|
||||
"""
|
||||
retcode, retdata = pvc_provisioner.script_remove(config, name)
|
||||
cleanup(retcode, retdata)
|
||||
|
||||
|
||||
|
||||
|
@ -2535,7 +2859,19 @@ provisioner_template.add_command(provisioner_template_network)
|
|||
provisioner_template.add_command(provisioner_template_storage)
|
||||
provisioner_template.add_command(provisioner_template_list)
|
||||
|
||||
provisioner_userdata.add_command(provisioner_userdata_list)
|
||||
provisioner_userdata.add_command(provisioner_userdata_add)
|
||||
provisioner_userdata.add_command(provisioner_userdata_modify)
|
||||
provisioner_userdata.add_command(provisioner_userdata_remove)
|
||||
|
||||
provisioner_script.add_command(provisioner_script_list)
|
||||
provisioner_script.add_command(provisioner_script_add)
|
||||
provisioner_script.add_command(provisioner_script_modify)
|
||||
provisioner_script.add_command(provisioner_script_remove)
|
||||
|
||||
cli_provisioner.add_command(provisioner_template)
|
||||
cli_provisioner.add_command(provisioner_userdata)
|
||||
cli_provisioner.add_command(provisioner_script)
|
||||
|
||||
cli.add_command(cli_cluster)
|
||||
cli.add_command(cli_node)
|
||||
|
|
Loading…
Reference in New Issue