Move backup and restore into common
This commit is contained in:
		| @@ -45,89 +45,33 @@ def initialize_cluster(zkhandler, overwrite=False): | ||||
|     """ | ||||
|     Initialize a new cluster | ||||
|     """ | ||||
|     # Abort if we've initialized the cluster before | ||||
|     if zkhandler.exists('/config/primary_node') and not overwrite: | ||||
|         return False | ||||
|     retflag, retmsg = pvc_cluster.cluster_initialize(zkhandler, overwrite) | ||||
|  | ||||
|     if overwrite: | ||||
|         # Delete the existing keys; ignore any errors | ||||
|         status = zkhandler.delete([ | ||||
|             '/config' | ||||
|             '/nodes', | ||||
|             '/domains', | ||||
|             '/networks', | ||||
|             '/ceph', | ||||
|             '/ceph/osds', | ||||
|             '/ceph/pools', | ||||
|             '/ceph/volumes', | ||||
|             '/ceph/snapshots', | ||||
|             '/cmd', | ||||
|             '/cmd/domains', | ||||
|             '/cmd/ceph', | ||||
|             '/locks', | ||||
|             '/locks/flush_lock', | ||||
|             '/locks/primary_node' | ||||
|         ], recursive=True) | ||||
|     retmsg = { | ||||
|         'message': retmsg | ||||
|     } | ||||
|     if retflag: | ||||
|         retcode = 200 | ||||
|     else: | ||||
|         retcode = 400 | ||||
|  | ||||
|         if not status: | ||||
|             return False | ||||
|  | ||||
|     # Create the root keys | ||||
|     status = zkhandler.write([ | ||||
|         ('/config', ''), | ||||
|         ('/config/primary_node', 'none'), | ||||
|         ('/config/upstream_ip', 'none'), | ||||
|         ('/config/maintenance', 'False'), | ||||
|         ('/config/migration_target_selector', 'none'), | ||||
|         ('/nodes', ''), | ||||
|         ('/domains', ''), | ||||
|         ('/networks', ''), | ||||
|         ('/ceph', ''), | ||||
|         ('/ceph/osds', ''), | ||||
|         ('/ceph/pools', ''), | ||||
|         ('/ceph/volumes', ''), | ||||
|         ('/ceph/snapshots', ''), | ||||
|         ('/cmd', ''), | ||||
|         ('/cmd/domains', ''), | ||||
|         ('/cmd/ceph', ''), | ||||
|         ('/locks', ''), | ||||
|         ('/locks/flush_lock', ''), | ||||
|         ('/locks/primary_node', ''), | ||||
|     ]) | ||||
|  | ||||
|     return status | ||||
|     return retmsg, retcode | ||||
|  | ||||
|  | ||||
| @ZKConnection(config) | ||||
| def backup_cluster(zkhandler): | ||||
|     # Dictionary of values to come | ||||
|     cluster_data = dict() | ||||
|     retflag, retdata = pvc_cluster.cluster_backup(zkhandler) | ||||
|  | ||||
|     def get_data(path): | ||||
|         data = zkhandler.read(path) | ||||
|         children = zkhandler.children(path) | ||||
|  | ||||
|         cluster_data[path] = data | ||||
|  | ||||
|         if children: | ||||
|             if path == '/': | ||||
|                 child_prefix = '/' | ||||
|     if retflag: | ||||
|         retcode = 200 | ||||
|         retdata = json.dumps(retdata) | ||||
|     else: | ||||
|                 child_prefix = path + '/' | ||||
|         retcode = 400 | ||||
|         retdata = { | ||||
|             'message': retdata | ||||
|         } | ||||
|  | ||||
|             for child in children: | ||||
|                 if child_prefix + child == '/zookeeper': | ||||
|                     # We must skip the built-in /zookeeper tree | ||||
|                     continue | ||||
|                 if child_prefix + child == '/patroni': | ||||
|                     # We must skip the /patroni tree | ||||
|                     continue | ||||
|  | ||||
|                 get_data(child_prefix + child) | ||||
|  | ||||
|     get_data('/') | ||||
|  | ||||
|     return json.dumps(cluster_data), 200 | ||||
|     return retdata, retcode | ||||
|  | ||||
|  | ||||
| @ZKConnection(config) | ||||
| @@ -135,21 +79,19 @@ def restore_cluster(zkhandler, cluster_data_raw): | ||||
|     try: | ||||
|         cluster_data = json.loads(cluster_data_raw) | ||||
|     except Exception as e: | ||||
|         return {"message": "Failed to parse JSON data: {}.".format(e)}, 400 | ||||
|         return {'message': 'ERROR: Failed to parse JSON data: {}'.format(e)}, 400 | ||||
|  | ||||
|     # Build a key+value list | ||||
|     kv = [] | ||||
|     for key in cluster_data: | ||||
|         data = cluster_data[key] | ||||
|         kv.append((key, data)) | ||||
|     retflag, retdata = pvc_cluster.cluster_restore(zkhandler, cluster_data) | ||||
|  | ||||
|     # Close the Zookeeper connection | ||||
|     result = zkhandler.write(kv) | ||||
|  | ||||
|     if result: | ||||
|         return {'message': 'Restore completed successfully.'}, 200 | ||||
|     retdata = { | ||||
|         'message': retdata | ||||
|     } | ||||
|     if retflag: | ||||
|         retcode = 200 | ||||
|     else: | ||||
|         return {'message': 'Restore failed.'}, 500 | ||||
|         retcode = 400 | ||||
|  | ||||
|     return retdata, retcode | ||||
|  | ||||
|  | ||||
| # | ||||
|   | ||||
| @@ -259,3 +259,77 @@ def get_info(zkhandler): | ||||
|         return True, cluster_information | ||||
|     else: | ||||
|         return False, 'ERROR: Failed to obtain cluster information!' | ||||
|  | ||||
|  | ||||
| def cluster_initialize(zkhandler, overwrite=False): | ||||
|     # Abort if we've initialized the cluster before | ||||
|     if zkhandler.exists('base.config.primary_node') and not overwrite: | ||||
|         return False, 'ERROR: Cluster contains data and overwrite not set.' | ||||
|  | ||||
|     if overwrite: | ||||
|         # Delete the existing keys; ignore any errors | ||||
|         status = zkhandler.delete(zkhandler.schema.keys('base'), recursive=True) | ||||
|  | ||||
|         if not status: | ||||
|             return False, 'ERROR: Failed to delete data in cluster; running nodes perhaps?' | ||||
|  | ||||
|     # Create the root keys | ||||
|     zkhandler.schema.apply(zkhandler) | ||||
|  | ||||
|     return True, 'Successfully initialized cluster' | ||||
|  | ||||
|  | ||||
| def cluster_backup(zkhandler): | ||||
|     # Dictionary of values to come | ||||
|     cluster_data = dict() | ||||
|  | ||||
|     def get_data(path): | ||||
|         data = zkhandler.read(path) | ||||
|         children = zkhandler.children(path) | ||||
|  | ||||
|         cluster_data[path] = data | ||||
|  | ||||
|         if children: | ||||
|             if path == '/': | ||||
|                 child_prefix = '/' | ||||
|             else: | ||||
|                 child_prefix = path + '/' | ||||
|  | ||||
|             for child in children: | ||||
|                 if child_prefix + child == '/zookeeper': | ||||
|                     # We must skip the built-in /zookeeper tree | ||||
|                     continue | ||||
|                 if child_prefix + child == '/patroni': | ||||
|                     # We must skip the /patroni tree | ||||
|                     continue | ||||
|  | ||||
|                 get_data(child_prefix + child) | ||||
|  | ||||
|     try: | ||||
|         get_data('/') | ||||
|     except Exception as e: | ||||
|         return False, 'ERROR: Failed to obtain backup: {}'.format(e) | ||||
|  | ||||
|     return True, cluster_data | ||||
|  | ||||
|  | ||||
| def cluster_restore(zkhandler, cluster_data): | ||||
|     # Build a key+value list | ||||
|     kv = [] | ||||
|     schema_version = None | ||||
|     for key in cluster_data: | ||||
|         if key == zkhandler.zkschema.path('base.schema.version'): | ||||
|             schema_version = cluster_data[key] | ||||
|         data = cluster_data[key] | ||||
|         kv.append((key, data)) | ||||
|  | ||||
|     if schema_version != zkhandler.schema.version: | ||||
|         return False, 'ERROR: Schema version of backup ({}) does not match cluster schema version ({}).'.format(schema_version, zkhandler.schema.version) | ||||
|  | ||||
|     # Close the Zookeeper connection | ||||
|     result = zkhandler.write(kv) | ||||
|  | ||||
|     if result: | ||||
|         return True, 'Restore completed successfully.' | ||||
|     else: | ||||
|         return False, 'Restore failed.' | ||||
|   | ||||
		Reference in New Issue
	
	Block a user