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 |     Initialize a new cluster | ||||||
|     """ |     """ | ||||||
|     # Abort if we've initialized the cluster before |     retflag, retmsg = pvc_cluster.cluster_initialize(zkhandler, overwrite) | ||||||
|     if zkhandler.exists('/config/primary_node') and not overwrite: |  | ||||||
|         return False |  | ||||||
|  |  | ||||||
|     if overwrite: |     retmsg = { | ||||||
|         # Delete the existing keys; ignore any errors |         'message': retmsg | ||||||
|         status = zkhandler.delete([ |     } | ||||||
|             '/config' |     if retflag: | ||||||
|             '/nodes', |         retcode = 200 | ||||||
|             '/domains', |     else: | ||||||
|             '/networks', |         retcode = 400 | ||||||
|             '/ceph', |  | ||||||
|             '/ceph/osds', |  | ||||||
|             '/ceph/pools', |  | ||||||
|             '/ceph/volumes', |  | ||||||
|             '/ceph/snapshots', |  | ||||||
|             '/cmd', |  | ||||||
|             '/cmd/domains', |  | ||||||
|             '/cmd/ceph', |  | ||||||
|             '/locks', |  | ||||||
|             '/locks/flush_lock', |  | ||||||
|             '/locks/primary_node' |  | ||||||
|         ], recursive=True) |  | ||||||
|  |  | ||||||
|         if not status: |     return retmsg, retcode | ||||||
|             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 |  | ||||||
|  |  | ||||||
|  |  | ||||||
| @ZKConnection(config) | @ZKConnection(config) | ||||||
| def backup_cluster(zkhandler): | def backup_cluster(zkhandler): | ||||||
|     # Dictionary of values to come |     retflag, retdata = pvc_cluster.cluster_backup(zkhandler) | ||||||
|     cluster_data = dict() |  | ||||||
|  |  | ||||||
|     def get_data(path): |     if retflag: | ||||||
|         data = zkhandler.read(path) |         retcode = 200 | ||||||
|         children = zkhandler.children(path) |         retdata = json.dumps(retdata) | ||||||
|  |  | ||||||
|         cluster_data[path] = data |  | ||||||
|  |  | ||||||
|         if children: |  | ||||||
|             if path == '/': |  | ||||||
|                 child_prefix = '/' |  | ||||||
|     else: |     else: | ||||||
|                 child_prefix = path + '/' |         retcode = 400 | ||||||
|  |         retdata = { | ||||||
|  |             'message': retdata | ||||||
|  |         } | ||||||
|  |  | ||||||
|             for child in children: |     return retdata, retcode | ||||||
|                 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 |  | ||||||
|  |  | ||||||
|  |  | ||||||
| @ZKConnection(config) | @ZKConnection(config) | ||||||
| @@ -135,21 +79,19 @@ def restore_cluster(zkhandler, cluster_data_raw): | |||||||
|     try: |     try: | ||||||
|         cluster_data = json.loads(cluster_data_raw) |         cluster_data = json.loads(cluster_data_raw) | ||||||
|     except Exception as e: |     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 |     retflag, retdata = pvc_cluster.cluster_restore(zkhandler, cluster_data) | ||||||
|     kv = [] |  | ||||||
|     for key in cluster_data: |  | ||||||
|         data = cluster_data[key] |  | ||||||
|         kv.append((key, data)) |  | ||||||
|  |  | ||||||
|     # Close the Zookeeper connection |     retdata = { | ||||||
|     result = zkhandler.write(kv) |         'message': retdata | ||||||
|  |     } | ||||||
|     if result: |     if retflag: | ||||||
|         return {'message': 'Restore completed successfully.'}, 200 |         retcode = 200 | ||||||
|     else: |     else: | ||||||
|         return {'message': 'Restore failed.'}, 500 |         retcode = 400 | ||||||
|  |  | ||||||
|  |     return retdata, retcode | ||||||
|  |  | ||||||
|  |  | ||||||
| # | # | ||||||
|   | |||||||
| @@ -259,3 +259,77 @@ def get_info(zkhandler): | |||||||
|         return True, cluster_information |         return True, cluster_information | ||||||
|     else: |     else: | ||||||
|         return False, 'ERROR: Failed to obtain cluster information!' |         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