From 84d5b1e6edd1a2c2abc3f53bf6131fcb459c544c Mon Sep 17 00:00:00 2001 From: Davide Principi Date: Fri, 13 Dec 2024 16:00:00 +0100 Subject: [PATCH 1/4] chore: format Python code --- .../cluster/actions/retrieve-cluster-backup/20save | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/core/imageroot/var/lib/nethserver/cluster/actions/retrieve-cluster-backup/20save b/core/imageroot/var/lib/nethserver/cluster/actions/retrieve-cluster-backup/20save index 1784dc350..ce1d9d9e7 100755 --- a/core/imageroot/var/lib/nethserver/cluster/actions/retrieve-cluster-backup/20save +++ b/core/imageroot/var/lib/nethserver/cluster/actions/retrieve-cluster-backup/20save @@ -73,6 +73,13 @@ fgz = gzip.open(f'{output_dir}/dump.json.gz', mode='r') dump = json.loads(fgz.read()) fgz.close() -result = {'cluster': dump['cluster']['ui_name'] or '', "vpn": dump['vpn']['endpoint'], 'domains': len(dump['cluster']['user_domain']['ldap']), 'backup_repositories': len(dump['cluster']['backup_repository']), "routes": len(dump['traefik']['leader']['routes']), "certificates": len(dump['traefik']['leader']['uploaded_certificates'])} +result = { + 'cluster': dump['cluster']['ui_name'] or '', + 'vpn': dump['vpn']['endpoint'], + 'domains': len(dump['cluster']['user_domain']['ldap']), + 'backup_repositories': len(dump['cluster']['backup_repository']), + 'routes': len(dump['traefik']['leader']['routes']), + 'certificates': len(dump['traefik']['leader']['uploaded_certificates']), +} json.dump(result, fp=sys.stdout) From 7c0ea5ed7ac0bbf63a0d58ae75a87b40fad5fbb9 Mon Sep 17 00:00:00 2001 From: Davide Principi Date: Fri, 13 Dec 2024 16:06:33 +0100 Subject: [PATCH 2/4] Implement "single_node_cluster" attribute Return a boolean that states if the cluster backup refers to a single node cluster or not. The implementation counts the nodes with the number Traefik instances for backward compatibility. --- .../nethserver/cluster/actions/retrieve-cluster-backup/20save | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/core/imageroot/var/lib/nethserver/cluster/actions/retrieve-cluster-backup/20save b/core/imageroot/var/lib/nethserver/cluster/actions/retrieve-cluster-backup/20save index ce1d9d9e7..a08e7ca45 100755 --- a/core/imageroot/var/lib/nethserver/cluster/actions/retrieve-cluster-backup/20save +++ b/core/imageroot/var/lib/nethserver/cluster/actions/retrieve-cluster-backup/20save @@ -73,7 +73,11 @@ fgz = gzip.open(f'{output_dir}/dump.json.gz', mode='r') dump = json.loads(fgz.read()) fgz.close() +# HACK! Count the nodes with the Traefik instances +single_node_cluster = len(dump.get('traefik', {})) == 1 + result = { + 'single_node_cluster': single_node_cluster, 'cluster': dump['cluster']['ui_name'] or '', 'vpn': dump['vpn']['endpoint'], 'domains': len(dump['cluster']['user_domain']['ldap']), From d378d1c213a4c08ef67351043ed534df13c7f23d Mon Sep 17 00:00:00 2001 From: Davide Principi Date: Mon, 16 Dec 2024 09:57:38 +0100 Subject: [PATCH 3/4] Cluster-backup format version "3" Add "node_count", the number of cluster nodes, in the cluster backup. --- .../cluster/actions/retrieve-cluster-backup/20save | 9 +++++++-- .../var/lib/nethserver/cluster/bin/cluster-backup | 7 +++++-- 2 files changed, 12 insertions(+), 4 deletions(-) diff --git a/core/imageroot/var/lib/nethserver/cluster/actions/retrieve-cluster-backup/20save b/core/imageroot/var/lib/nethserver/cluster/actions/retrieve-cluster-backup/20save index a08e7ca45..222b6b1d3 100755 --- a/core/imageroot/var/lib/nethserver/cluster/actions/retrieve-cluster-backup/20save +++ b/core/imageroot/var/lib/nethserver/cluster/actions/retrieve-cluster-backup/20save @@ -73,8 +73,13 @@ fgz = gzip.open(f'{output_dir}/dump.json.gz', mode='r') dump = json.loads(fgz.read()) fgz.close() -# HACK! Count the nodes with the Traefik instances -single_node_cluster = len(dump.get('traefik', {})) == 1 +if 'node_count' in dump['cluster']: + # available since cluster backup version "3" + single_node_cluster = dump['cluster']['node_count'] == 1 +else: + # fall back to the number of Traefik instances for previous cluster + # backups: + single_node_cluster = len(dump.get('traefik', {})) == 1 result = { 'single_node_cluster': single_node_cluster, diff --git a/core/imageroot/var/lib/nethserver/cluster/bin/cluster-backup b/core/imageroot/var/lib/nethserver/cluster/bin/cluster-backup index b5e3cbda2..d1387e76a 100755 --- a/core/imageroot/var/lib/nethserver/cluster/bin/cluster-backup +++ b/core/imageroot/var/lib/nethserver/cluster/bin/cluster-backup @@ -39,9 +39,12 @@ output_dir = f'{os.environ["AGENT_STATE_DIR"]}/backup' rdb = agent.redis_connect(host='127.0.0.1') -VERSION = "2" +VERSION = "3" -dump = { 'version': VERSION, 'modules': {}, 'vpn': {}, 'cluster': { 'subscription': {}, 'apply_updates': {}, 'repository': {}, 'backup': {}, 'backup_repository': {}, 'user_domain': { 'ldap': {} },'override': {'modules': {} } }, 'traefik': {} } +dump = { 'version': VERSION, 'modules': {}, 'vpn': {}, 'cluster': { 'node_count': 0, 'subscription': {}, 'apply_updates': {}, 'repository': {}, 'backup': {}, 'backup_repository': {}, 'user_domain': { 'ldap': {} },'override': {'modules': {} } }, 'traefik': {} } + +# cluster: number of nodes +dump['cluster']['node_count'] = len(set(rdb.hvals('cluster/module_node')) # cluster: subscription dump['cluster']['subscription'] = rdb.hgetall('cluster/subscription') or {} From 1e41b61883aef7e88124820087e61fda9b0228fb Mon Sep 17 00:00:00 2001 From: Davide Principi Date: Mon, 16 Dec 2024 14:29:19 +0100 Subject: [PATCH 4/4] Update retrieve-cluster-backup JSON output schema Define the "single_node_cluster" attribute. --- .../actions/retrieve-cluster-backup/validate-output.json | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/core/imageroot/var/lib/nethserver/cluster/actions/retrieve-cluster-backup/validate-output.json b/core/imageroot/var/lib/nethserver/cluster/actions/retrieve-cluster-backup/validate-output.json index 1fe4838e3..72edbdeb6 100644 --- a/core/imageroot/var/lib/nethserver/cluster/actions/retrieve-cluster-backup/validate-output.json +++ b/core/imageroot/var/lib/nethserver/cluster/actions/retrieve-cluster-backup/validate-output.json @@ -5,6 +5,7 @@ "description": "Return info from cluster backup", "examples": [ { + "single_node_cluster": true, "cluster": "mycluster1", "vpn": "cs1.leader.cluster0.gs.nethserver.net:55820", "domains": 1, @@ -13,12 +14,17 @@ ], "type": "object", "required": [ + "single_node_cluster", "cluster", "vpn", "domains", "backup_repositories" ], "properties": { + "single_node_cluster": { + "type": "boolean", + "description": "If true, the backup refers to a cluster of a single node" + }, "cluster": { "title": "Cluster label", "description": "User defined cluster label, can be empty'", @@ -40,4 +46,4 @@ "type": "integer" } } -} +} \ No newline at end of file