|  |  |  | @@ -29,9 +29,6 @@ import gevent.pywsgi | 
		
	
		
			
				|  |  |  |  |  | 
		
	
		
			
				|  |  |  |  | import api_lib.pvcapi as pvcapi | 
		
	
		
			
				|  |  |  |  |  | 
		
	
		
			
				|  |  |  |  | api = flask.Flask(__name__) | 
		
	
		
			
				|  |  |  |  | api.config['DEBUG'] = True | 
		
	
		
			
				|  |  |  |  |  | 
		
	
		
			
				|  |  |  |  | # Parse the configuration file | 
		
	
		
			
				|  |  |  |  | try: | 
		
	
		
			
				|  |  |  |  |     pvc_config_file = os.environ['PVC_CONFIG_FILE'] | 
		
	
	
		
			
				
					
					|  |  |  | @@ -52,6 +49,7 @@ except Exception as e: | 
		
	
		
			
				|  |  |  |  | try: | 
		
	
		
			
				|  |  |  |  |     # Create the config object | 
		
	
		
			
				|  |  |  |  |     config = { | 
		
	
		
			
				|  |  |  |  |         'debug': o_config['pvc']['debug'], | 
		
	
		
			
				|  |  |  |  |         'coordinators': o_config['pvc']['coordinators'], | 
		
	
		
			
				|  |  |  |  |         'listen_address': o_config['pvc']['api']['listen_address'], | 
		
	
		
			
				|  |  |  |  |         'listen_port': int(o_config['pvc']['api']['listen_port']), | 
		
	
	
		
			
				
					
					|  |  |  | @@ -69,6 +67,11 @@ except Exception as e: | 
		
	
		
			
				|  |  |  |  |     print('ERROR: {}.'.format(e)) | 
		
	
		
			
				|  |  |  |  |     exit(1) | 
		
	
		
			
				|  |  |  |  |  | 
		
	
		
			
				|  |  |  |  | api = flask.Flask(__name__) | 
		
	
		
			
				|  |  |  |  |  | 
		
	
		
			
				|  |  |  |  | if config['debug']: | 
		
	
		
			
				|  |  |  |  |     api.config['DEBUG'] = True | 
		
	
		
			
				|  |  |  |  |  | 
		
	
		
			
				|  |  |  |  | if config['auth_enabled']: | 
		
	
		
			
				|  |  |  |  |     api.config["SECRET_KEY"] = config['auth_secret_key'] | 
		
	
		
			
				|  |  |  |  |  | 
		
	
	
		
			
				
					
					|  |  |  | @@ -148,55 +151,61 @@ def api_node(): | 
		
	
		
			
				|  |  |  |  |  | 
		
	
		
			
				|  |  |  |  | @api.route('/api/v1/node/<node>', methods=['GET']) | 
		
	
		
			
				|  |  |  |  | @authenticator | 
		
	
		
			
				|  |  |  |  | def api_node_info(node): | 
		
	
		
			
				|  |  |  |  | def api_node_root(node): | 
		
	
		
			
				|  |  |  |  |     """ | 
		
	
		
			
				|  |  |  |  |     Return information about node NODE. | 
		
	
		
			
				|  |  |  |  |     """ | 
		
	
		
			
				|  |  |  |  |     # Same as specifying /node?limit=NODE | 
		
	
		
			
				|  |  |  |  |     return pvcapi.node_list(node) | 
		
	
		
			
				|  |  |  |  |  | 
		
	
		
			
				|  |  |  |  | @api.route('/api/v1/node/<node>/secondary', methods=['POST']) | 
		
	
		
			
				|  |  |  |  | @authenticator | 
		
	
		
			
				|  |  |  |  | def api_node_secondary(node): | 
		
	
		
			
				|  |  |  |  |     """ | 
		
	
		
			
				|  |  |  |  |     Take NODE out of primary router mode. | 
		
	
		
			
				|  |  |  |  |     """ | 
		
	
		
			
				|  |  |  |  |     return pvcapi.node_secondary(node) | 
		
	
		
			
				|  |  |  |  |  | 
		
	
		
			
				|  |  |  |  | @api.route('/api/v1/node/<node>/primary', methods=['POST']) | 
		
	
		
			
				|  |  |  |  | @api.route('/api/v1/node/<node>/coordinator-state', methods=['GET', 'POST']) | 
		
	
		
			
				|  |  |  |  | @authenticator | 
		
	
		
			
				|  |  |  |  | def api_node_primary(node): | 
		
	
		
			
				|  |  |  |  | def api_node_coordinator_state(node): | 
		
	
		
			
				|  |  |  |  |     """ | 
		
	
		
			
				|  |  |  |  |     Set NODE to primary router mode. | 
		
	
		
			
				|  |  |  |  |     Manage NODE coordinator state. | 
		
	
		
			
				|  |  |  |  |     """ | 
		
	
		
			
				|  |  |  |  |  | 
		
	
		
			
				|  |  |  |  |     if flask.request.method == 'GET': | 
		
	
		
			
				|  |  |  |  |         return "Test", 200 | 
		
	
		
			
				|  |  |  |  |  | 
		
	
		
			
				|  |  |  |  |     if flask.request.method == 'POST': | 
		
	
		
			
				|  |  |  |  |         if not coordinator-state in flask.request.values: | 
		
	
		
			
				|  |  |  |  |             flask.abort(400) | 
		
	
		
			
				|  |  |  |  |         new_state = flask.request.values['coordinator-state'] | 
		
	
		
			
				|  |  |  |  |         if new_state == 'primary': | 
		
	
		
			
				|  |  |  |  |             return pvcapi.node_primary(node) | 
		
	
		
			
				|  |  |  |  |         if new_state == 'secondary': | 
		
	
		
			
				|  |  |  |  |             return pvcapi.node_secondary(node) | 
		
	
		
			
				|  |  |  |  |         flask.abort(400) | 
		
	
		
			
				|  |  |  |  |  | 
		
	
		
			
				|  |  |  |  | @api.route('/api/v1/node/<node>/flush', methods=['POST']) | 
		
	
		
			
				|  |  |  |  | @api.route('/api/v1/node/<node>/domain-state', methods=['GET', 'POST']) | 
		
	
		
			
				|  |  |  |  | @authenticator | 
		
	
		
			
				|  |  |  |  | def api_node_flush(node): | 
		
	
		
			
				|  |  |  |  | def api_node_domain_state(node): | 
		
	
		
			
				|  |  |  |  |     """ | 
		
	
		
			
				|  |  |  |  |     Flush NODE of running VMs. | 
		
	
		
			
				|  |  |  |  |     Manage NODE domain state. | 
		
	
		
			
				|  |  |  |  |     """ | 
		
	
		
			
				|  |  |  |  |     return pvcapi.node_flush(node) | 
		
	
		
			
				|  |  |  |  |  | 
		
	
		
			
				|  |  |  |  | @api.route('/api/v1/node/<node>/unflush', methods=['POST']) | 
		
	
		
			
				|  |  |  |  | @api.route('/api/v1/node/<node>/ready', methods=['POST']) | 
		
	
		
			
				|  |  |  |  | @authenticator | 
		
	
		
			
				|  |  |  |  | def api_node_ready(node): | 
		
	
		
			
				|  |  |  |  |     """ | 
		
	
		
			
				|  |  |  |  |     Restore NODE to active service. | 
		
	
		
			
				|  |  |  |  |     """ | 
		
	
		
			
				|  |  |  |  |     if flask.request.method == 'GET': | 
		
	
		
			
				|  |  |  |  |         return "Test", 200 | 
		
	
		
			
				|  |  |  |  |  | 
		
	
		
			
				|  |  |  |  |     if flask.request.method == 'POST': | 
		
	
		
			
				|  |  |  |  |         if not domain-state in flask.request.values: | 
		
	
		
			
				|  |  |  |  |             flask.abort(400) | 
		
	
		
			
				|  |  |  |  |         new_state = flask.request.values['domain-state'] | 
		
	
		
			
				|  |  |  |  |         if new_state == 'ready': | 
		
	
		
			
				|  |  |  |  |             return pvcapi.node_ready(node) | 
		
	
		
			
				|  |  |  |  |         if new_state == 'flush': | 
		
	
		
			
				|  |  |  |  |             return pvcapi.node_flush(node) | 
		
	
		
			
				|  |  |  |  |         flask.abort(400) | 
		
	
		
			
				|  |  |  |  |  | 
		
	
		
			
				|  |  |  |  | # | 
		
	
		
			
				|  |  |  |  | # VM endpoints | 
		
	
		
			
				|  |  |  |  | # | 
		
	
		
			
				|  |  |  |  | @api.route('/api/v1/vm', methods=['GET']) | 
		
	
		
			
				|  |  |  |  | @api.route('/api/v1/vm', methods=['GET', 'POST']) | 
		
	
		
			
				|  |  |  |  | @authenticator | 
		
	
		
			
				|  |  |  |  | def api_vm(): | 
		
	
		
			
				|  |  |  |  |     """ | 
		
	
		
			
				|  |  |  |  |     Return a list of VMs with limit LIMIT. | 
		
	
		
			
				|  |  |  |  |     """ | 
		
	
		
			
				|  |  |  |  |     if flask.request.method == 'GET': | 
		
	
		
			
				|  |  |  |  |         # Get node limit | 
		
	
		
			
				|  |  |  |  |         if 'node' in flask.request.values: | 
		
	
		
			
				|  |  |  |  |             node = flask.request.values['node'] | 
		
	
	
		
			
				
					
					|  |  |  | @@ -217,35 +226,12 @@ def api_vm(): | 
		
	
		
			
				|  |  |  |  |      | 
		
	
		
			
				|  |  |  |  |         return pvcapi.vm_list(node, state, limit) | 
		
	
		
			
				|  |  |  |  |  | 
		
	
		
			
				|  |  |  |  | @api.route('/api/v1/vm/<vm>', methods=['GET']) | 
		
	
		
			
				|  |  |  |  | @authenticator | 
		
	
		
			
				|  |  |  |  | def api_vm_info(vm): | 
		
	
		
			
				|  |  |  |  |     """ | 
		
	
		
			
				|  |  |  |  |     Get information about a virtual machine named VM. | 
		
	
		
			
				|  |  |  |  |     """ | 
		
	
		
			
				|  |  |  |  |     # Same as specifying /vm?limit=VM | 
		
	
		
			
				|  |  |  |  |     return pvcapi.vm_list(None, None, vm, is_fuzzy=False) | 
		
	
		
			
				|  |  |  |  |  | 
		
	
		
			
				|  |  |  |  | # TODO: #22 | 
		
	
		
			
				|  |  |  |  | #@api.route('/api/v1/vm/<vm>/add', methods=['POST']) | 
		
	
		
			
				|  |  |  |  | #@authenticator | 
		
	
		
			
				|  |  |  |  | #def api_vm_add(vm): | 
		
	
		
			
				|  |  |  |  | #    """ | 
		
	
		
			
				|  |  |  |  | #    Add a virtual machine named VM. | 
		
	
		
			
				|  |  |  |  | #    """ | 
		
	
		
			
				|  |  |  |  | #    return pvcapi.vm_add() | 
		
	
		
			
				|  |  |  |  |  | 
		
	
		
			
				|  |  |  |  | @api.route('/api/v1/vm/<vm>/define', methods=['POST']) | 
		
	
		
			
				|  |  |  |  | @authenticator | 
		
	
		
			
				|  |  |  |  | def api_vm_define(vm): | 
		
	
		
			
				|  |  |  |  |     """ | 
		
	
		
			
				|  |  |  |  |     Define a virtual machine named VM from Libvirt XML. | 
		
	
		
			
				|  |  |  |  |     """ | 
		
	
		
			
				|  |  |  |  |     if flask.request.method == 'POST': | 
		
	
		
			
				|  |  |  |  |         # Get XML data | 
		
	
		
			
				|  |  |  |  |         if 'xml' in flask.request.values: | 
		
	
		
			
				|  |  |  |  |             libvirt_xml = flask.request.values['xml'] | 
		
	
		
			
				|  |  |  |  |         else: | 
		
	
		
			
				|  |  |  |  |         return flask.jsonify({"message":"ERROR: A Libvirt XML document must be specified."}), 520 | 
		
	
		
			
				|  |  |  |  |             return flask.jsonify({"message":"ERROR: A Libvirt XML document must be specified."}), 400 | 
		
	
		
			
				|  |  |  |  |      | 
		
	
		
			
				|  |  |  |  |         # Get node name | 
		
	
		
			
				|  |  |  |  |         if 'node' in flask.request.values: | 
		
	
	
		
			
				
					
					|  |  |  | @@ -261,132 +247,106 @@ def api_vm_define(vm): | 
		
	
		
			
				|  |  |  |  |      | 
		
	
		
			
				|  |  |  |  |         return pvcapi.vm_define(vm, libvirt_xml, node, selector) | 
		
	
		
			
				|  |  |  |  |  | 
		
	
		
			
				|  |  |  |  | @api.route('/api/v1/vm/<vm>/modify', methods=['POST']) | 
		
	
		
			
				|  |  |  |  | @api.route('/api/v1/vm/<vm>', methods=['GET', 'POST', 'PUT', 'DELETE']) | 
		
	
		
			
				|  |  |  |  | @authenticator | 
		
	
		
			
				|  |  |  |  | def api_vm_modify(vm): | 
		
	
		
			
				|  |  |  |  |     """ | 
		
	
		
			
				|  |  |  |  |     Modify an existing virtual machine named VM from Libvirt XML. | 
		
	
		
			
				|  |  |  |  |     """ | 
		
	
		
			
				|  |  |  |  |     # Get XML from the POST body | 
		
	
		
			
				|  |  |  |  | def api_vm_root(vm): | 
		
	
		
			
				|  |  |  |  |     if flask.request.method == 'GET': | 
		
	
		
			
				|  |  |  |  |         # Same as specifying /vm?limit=VM | 
		
	
		
			
				|  |  |  |  |         return pvcapi.vm_list(None, None, vm, is_fuzzy=False) | 
		
	
		
			
				|  |  |  |  |  | 
		
	
		
			
				|  |  |  |  |     if flask.request.method == 'POST': | 
		
	
		
			
				|  |  |  |  |         # TODO: #22 | 
		
	
		
			
				|  |  |  |  |         flask.abort(501) | 
		
	
		
			
				|  |  |  |  |  | 
		
	
		
			
				|  |  |  |  |     if flask.request.method == 'PUT': | 
		
	
		
			
				|  |  |  |  |         libvirt_xml = flask.request.data | 
		
	
		
			
				|  |  |  |  |      | 
		
	
		
			
				|  |  |  |  |     # Get node name | 
		
	
		
			
				|  |  |  |  |     if 'flag_restart' in flask.request.values: | 
		
	
		
			
				|  |  |  |  |         flag_restart = flask.request.values['flag_restart'] | 
		
	
		
			
				|  |  |  |  |         if 'restart' in flask.request.values and flask.request.values['restart']: | 
		
	
		
			
				|  |  |  |  |             flag_restart = True | 
		
	
		
			
				|  |  |  |  |         else: | 
		
	
		
			
				|  |  |  |  |         flag_restart = None | 
		
	
		
			
				|  |  |  |  |             flag_restart = False | 
		
	
		
			
				|  |  |  |  |      | 
		
	
		
			
				|  |  |  |  |         return pvcapi.vm_modify(vm, flag_restart, libvirt_xml) | 
		
	
		
			
				|  |  |  |  |  | 
		
	
		
			
				|  |  |  |  | @api.route('/api/v1/vm/<vm>/undefine', methods=['POST']) | 
		
	
		
			
				|  |  |  |  | @authenticator | 
		
	
		
			
				|  |  |  |  | def api_vm_undefine(vm): | 
		
	
		
			
				|  |  |  |  |     """ | 
		
	
		
			
				|  |  |  |  |     Undefine a virtual machine named VM. | 
		
	
		
			
				|  |  |  |  |     """ | 
		
	
		
			
				|  |  |  |  |     if flask.request.method == 'DELETE': | 
		
	
		
			
				|  |  |  |  |         if 'delete_disks' in flask.request.values and flask.request.values['delete_disks']: | 
		
	
		
			
				|  |  |  |  |             return pvcapi.vm_remove(vm) | 
		
	
		
			
				|  |  |  |  |         else: | 
		
	
		
			
				|  |  |  |  |             return pvcapi.vm_undefine(vm) | 
		
	
		
			
				|  |  |  |  |  | 
		
	
		
			
				|  |  |  |  | @api.route('/api/v1/vm/<vm>/remove', methods=['POST']) | 
		
	
		
			
				|  |  |  |  | @authenticator | 
		
	
		
			
				|  |  |  |  | def api_vm_remove(vm): | 
		
	
		
			
				|  |  |  |  |     """ | 
		
	
		
			
				|  |  |  |  |     Remove a virtual machine named VM including all disks. | 
		
	
		
			
				|  |  |  |  |     """ | 
		
	
		
			
				|  |  |  |  |     return pvcapi.vm_remove(vm) | 
		
	
		
			
				|  |  |  |  | #@api.route('/api/v1/vm/<vm>/dump', methods=['GET']) | 
		
	
		
			
				|  |  |  |  | #@authenticator | 
		
	
		
			
				|  |  |  |  | #def api_vm_dump(vm): | 
		
	
		
			
				|  |  |  |  | #    """ | 
		
	
		
			
				|  |  |  |  | #    Dump the Libvirt XML configuration of a virtual machine named VM. | 
		
	
		
			
				|  |  |  |  | #    """ | 
		
	
		
			
				|  |  |  |  | #    return pvcapi.vm_dump(vm) | 
		
	
		
			
				|  |  |  |  |  | 
		
	
		
			
				|  |  |  |  | @api.route('/api/v1/vm/<vm>/dump', methods=['GET']) | 
		
	
		
			
				|  |  |  |  | @api.route('/api/v1/vm/<vm>/state', methods=['GET', 'POST']) | 
		
	
		
			
				|  |  |  |  | @authenticator | 
		
	
		
			
				|  |  |  |  | def api_vm_dump(vm): | 
		
	
		
			
				|  |  |  |  |     """ | 
		
	
		
			
				|  |  |  |  |     Dump the Libvirt XML configuration of a virtual machine named VM. | 
		
	
		
			
				|  |  |  |  |     """ | 
		
	
		
			
				|  |  |  |  |     return pvcapi.vm_dump(vm) | 
		
	
		
			
				|  |  |  |  | def api_vm_state(vm): | 
		
	
		
			
				|  |  |  |  |     if flask.request.method == 'GET': | 
		
	
		
			
				|  |  |  |  |         return "Test", 200 | 
		
	
		
			
				|  |  |  |  |  | 
		
	
		
			
				|  |  |  |  | @api.route('/api/v1/vm/<vm>/start', methods=['POST']) | 
		
	
		
			
				|  |  |  |  | @authenticator | 
		
	
		
			
				|  |  |  |  | def api_vm_start(vm): | 
		
	
		
			
				|  |  |  |  |     """ | 
		
	
		
			
				|  |  |  |  |     Start a virtual machine named VM. | 
		
	
		
			
				|  |  |  |  |     """ | 
		
	
		
			
				|  |  |  |  |     if flask.request.method == 'POST': | 
		
	
		
			
				|  |  |  |  |         if not state in flask.request.values: | 
		
	
		
			
				|  |  |  |  |             flask.abort(400) | 
		
	
		
			
				|  |  |  |  |         new_state = flask.request.values['state'] | 
		
	
		
			
				|  |  |  |  |         if new_state == 'start': | 
		
	
		
			
				|  |  |  |  |             return pvcapi.vm_start(vm) | 
		
	
		
			
				|  |  |  |  |  | 
		
	
		
			
				|  |  |  |  | @api.route('/api/v1/vm/<vm>/restart', methods=['POST']) | 
		
	
		
			
				|  |  |  |  | @authenticator | 
		
	
		
			
				|  |  |  |  | def api_vm_restart(vm): | 
		
	
		
			
				|  |  |  |  |     """ | 
		
	
		
			
				|  |  |  |  |     Restart a virtual machine named VM. | 
		
	
		
			
				|  |  |  |  |     """ | 
		
	
		
			
				|  |  |  |  |     return pvcapi.vm_restart(vm) | 
		
	
		
			
				|  |  |  |  |  | 
		
	
		
			
				|  |  |  |  | @api.route('/api/v1/vm/<vm>/shutdown', methods=['POST']) | 
		
	
		
			
				|  |  |  |  | @authenticator | 
		
	
		
			
				|  |  |  |  | def api_vm_shutdown(vm): | 
		
	
		
			
				|  |  |  |  |     """ | 
		
	
		
			
				|  |  |  |  |     Shutdown a virtual machine named VM. | 
		
	
		
			
				|  |  |  |  |     """ | 
		
	
		
			
				|  |  |  |  |         if new_state == 'shutdown': | 
		
	
		
			
				|  |  |  |  |             return pvcapi.vm_shutdown(vm) | 
		
	
		
			
				|  |  |  |  |  | 
		
	
		
			
				|  |  |  |  | @api.route('/api/v1/vm/<vm>/stop', methods=['POST']) | 
		
	
		
			
				|  |  |  |  | @authenticator | 
		
	
		
			
				|  |  |  |  | def api_vm_stop(vm): | 
		
	
		
			
				|  |  |  |  |     """ | 
		
	
		
			
				|  |  |  |  |     Forcibly stop a virtual machine named VM. | 
		
	
		
			
				|  |  |  |  |     """ | 
		
	
		
			
				|  |  |  |  |         if new_state == 'stop': | 
		
	
		
			
				|  |  |  |  |             return pvcapi.vm_stop(vm) | 
		
	
		
			
				|  |  |  |  |         if new_state == 'restart': | 
		
	
		
			
				|  |  |  |  |             return pvcapi.vm_restart(vm) | 
		
	
		
			
				|  |  |  |  |         flask.abort(400) | 
		
	
		
			
				|  |  |  |  |  | 
		
	
		
			
				|  |  |  |  | @api.route('/api/v1/vm/<vm>/move', methods=['POST']) | 
		
	
		
			
				|  |  |  |  | @api.route('/api/v1/vm/<vm>/node', methods=['GET', 'POST']) | 
		
	
		
			
				|  |  |  |  | @authenticator | 
		
	
		
			
				|  |  |  |  | def api_vm_move(vm): | 
		
	
		
			
				|  |  |  |  |     """ | 
		
	
		
			
				|  |  |  |  |     Move a virtual machine named VM to another node. | 
		
	
		
			
				|  |  |  |  |     """ | 
		
	
		
			
				|  |  |  |  | def api_vm_node(vm): | 
		
	
		
			
				|  |  |  |  |     if flask.request.method == 'GET': | 
		
	
		
			
				|  |  |  |  |         return "Test", 200 | 
		
	
		
			
				|  |  |  |  |      | 
		
	
		
			
				|  |  |  |  |     if flask.request.method == 'POST': | 
		
	
		
			
				|  |  |  |  |         if 'action' in flask.request.values: | 
		
	
		
			
				|  |  |  |  |             action = flask.request.values['action'] | 
		
	
		
			
				|  |  |  |  |         else: | 
		
	
		
			
				|  |  |  |  |             flask.abort(400) | 
		
	
		
			
				|  |  |  |  |              | 
		
	
		
			
				|  |  |  |  |         # Get node name | 
		
	
		
			
				|  |  |  |  |         if 'node' in flask.request.values: | 
		
	
		
			
				|  |  |  |  |             node = flask.request.values['node'] | 
		
	
		
			
				|  |  |  |  |         else: | 
		
	
		
			
				|  |  |  |  |             node = None | 
		
	
		
			
				|  |  |  |  |  | 
		
	
		
			
				|  |  |  |  |         # Get target selector | 
		
	
		
			
				|  |  |  |  |         if 'selector' in flask.request.values: | 
		
	
		
			
				|  |  |  |  |             selector = flask.request.values['selector'] | 
		
	
		
			
				|  |  |  |  |         else: | 
		
	
		
			
				|  |  |  |  |             selector = None | 
		
	
		
			
				|  |  |  |  |  | 
		
	
		
			
				|  |  |  |  |     return pvcapi.vm_move(vm, node, selector) | 
		
	
		
			
				|  |  |  |  |  | 
		
	
		
			
				|  |  |  |  | @api.route('/api/v1/vm/<vm>/migrate', methods=['POST']) | 
		
	
		
			
				|  |  |  |  | @authenticator | 
		
	
		
			
				|  |  |  |  | def api_vm_migrate(vm): | 
		
	
		
			
				|  |  |  |  |     """ | 
		
	
		
			
				|  |  |  |  |     Temporarily migrate a virtual machine named VM to another node. | 
		
	
		
			
				|  |  |  |  |     """ | 
		
	
		
			
				|  |  |  |  |     # Get node name | 
		
	
		
			
				|  |  |  |  |     if 'node' in flask.request.values: | 
		
	
		
			
				|  |  |  |  |         node = flask.request.values['node'] | 
		
	
		
			
				|  |  |  |  |         # Get permanent flag | 
		
	
		
			
				|  |  |  |  |         if 'permanent' in flask.request.values and flask.request.values['permanent']: | 
		
	
		
			
				|  |  |  |  |             flag_permanent = True | 
		
	
		
			
				|  |  |  |  |         else: | 
		
	
		
			
				|  |  |  |  |         node = None | 
		
	
		
			
				|  |  |  |  |  | 
		
	
		
			
				|  |  |  |  |     # Get target selector | 
		
	
		
			
				|  |  |  |  |     if 'selector' in flask.request.values: | 
		
	
		
			
				|  |  |  |  |         selector = flask.request.values['selector'] | 
		
	
		
			
				|  |  |  |  |     else: | 
		
	
		
			
				|  |  |  |  |         selector = None | 
		
	
		
			
				|  |  |  |  |  | 
		
	
		
			
				|  |  |  |  |     # Get target selector | 
		
	
		
			
				|  |  |  |  |     if 'flag_force' in flask.request.values: | 
		
	
		
			
				|  |  |  |  |             flag_permanent = False | 
		
	
		
			
				|  |  |  |  |         # Get force flag | 
		
	
		
			
				|  |  |  |  |         if 'force' in flask.request.values and flask.request.values['force']: | 
		
	
		
			
				|  |  |  |  |             flag_force = True | 
		
	
		
			
				|  |  |  |  |         else: | 
		
	
		
			
				|  |  |  |  |             flag_force = False | 
		
	
		
			
				|  |  |  |  |  | 
		
	
		
			
				|  |  |  |  |     return pvcapi.vm_migrate(vm, node, selector, flag_force) | 
		
	
		
			
				|  |  |  |  |         # Check if VM is presently migrated | 
		
	
		
			
				|  |  |  |  |         is_migrated = pvcapi.vm_is_migrated(vm) | 
		
	
		
			
				|  |  |  |  |  | 
		
	
		
			
				|  |  |  |  |         if action == 'migrate' and not flag_permanent: | 
		
	
		
			
				|  |  |  |  |             return pvcapi.vm_migrate(vm, node, selector, flag_force) | 
		
	
		
			
				|  |  |  |  |         if action == 'migrate' and flag_permanent: | 
		
	
		
			
				|  |  |  |  |             return pvcapi.vm_move(vm, node, selector) | 
		
	
		
			
				|  |  |  |  |         if action == 'unmigrate' and is_migrated: | 
		
	
		
			
				|  |  |  |  |             return pvcapi.vm_unmigrate(vm) | 
		
	
		
			
				|  |  |  |  |  | 
		
	
		
			
				|  |  |  |  |         flask.abort(400) | 
		
	
		
			
				|  |  |  |  |  | 
		
	
		
			
				|  |  |  |  | @api.route('/api/v1/vm/<vm>/unmigrate', methods=['POST']) | 
		
	
		
			
				|  |  |  |  | @authenticator | 
		
	
		
			
				|  |  |  |  | def api_vm_unmigrate(vm): | 
		
	
		
			
				|  |  |  |  |     """ | 
		
	
		
			
				|  |  |  |  |     Unmigrate a migrated virtual machine named VM. | 
		
	
		
			
				|  |  |  |  |     """ | 
		
	
		
			
				|  |  |  |  |     return pvcapi.vm_move(vm) | 
		
	
		
			
				|  |  |  |  |  | 
		
	
		
			
				|  |  |  |  | # | 
		
	
		
			
				|  |  |  |  | # Network endpoints | 
		
	
	
		
			
				
					
					|  |  |  | @@ -982,13 +942,15 @@ def api_ceph_volume_snapshot_remove(pool, volume, snapshot): | 
		
	
		
			
				|  |  |  |  | # | 
		
	
		
			
				|  |  |  |  | # Entrypoint | 
		
	
		
			
				|  |  |  |  | # | 
		
	
		
			
				|  |  |  |  | if config['ssl_enabled']: | 
		
	
		
			
				|  |  |  |  |     # Run the WSGI server with SSL | 
		
	
		
			
				|  |  |  |  |     http_server = gevent.pywsgi.WSGIServer((config['listen_address'], config['listen_port']), api, | 
		
	
		
			
				|  |  |  |  |                                        keyfile=config['ssl_key_file'], certfile=config['ssl_cert_file']) | 
		
	
		
			
				|  |  |  |  | if config['debug']: | 
		
	
		
			
				|  |  |  |  |     api.run(config['listen_address'], config['listen_port']) | 
		
	
		
			
				|  |  |  |  | else: | 
		
	
		
			
				|  |  |  |  |     if config['ssl_enabled']: | 
		
	
		
			
				|  |  |  |  |         # Run the WSGI server with SSL | 
		
	
		
			
				|  |  |  |  |         http_server = gevent.pywsgi.WSGIServer((config['listen_address'], config['listen_port']), api,                                           keyfile=config['ssl_key_file'], certfile=config['ssl_cert_file']) | 
		
	
		
			
				|  |  |  |  |     else: | 
		
	
		
			
				|  |  |  |  |         # Run the ?WSGI server without SSL | 
		
	
		
			
				|  |  |  |  |         http_server = gevent.pywsgi.WSGIServer((config['listen_address'], config['listen_port']), api) | 
		
	
		
			
				|  |  |  |  |  | 
		
	
		
			
				|  |  |  |  | print('Starting PyWSGI server at {}:{} with SSL={}, Authentication={}'.format(config['listen_address'], config['listen_port'], config['ssl_enabled'], config['auth_enabled'])) | 
		
	
		
			
				|  |  |  |  | http_server.serve_forever() | 
		
	
		
			
				|  |  |  |  |     print('Starting PyWSGI server at {}:{} with SSL={}, Authentication={}'.format(config['listen_address'], config['listen_port'], config['ssl_enabled'], config['auth_enabled'])) | 
		
	
		
			
				|  |  |  |  |     http_server.serve_forever() | 
		
	
	
		
			
				
					
					| 
							
							
							
						 |  |  |   |