From 6eb4bf28e5ac5f001f0c2ba5fc92a8d81171133e Mon Sep 17 00:00:00 2001 From: Jarrod Johnson Date: Wed, 5 Oct 2022 12:23:47 -0400 Subject: [PATCH] Another iteration to try to have IP adaptive syncfiles It is likely that a client connects from fe80::, which is explicitly omitted from ssh principals. This time, have the client provide all currently set IP addresses and the server will make a determination. There remains the possibility it misconfigures a nic and tries to use that, inducing failure. One strategy would be to filter the addresses and only provide from the 'current' interface. Another is to just take the hit as the node is likely going to suffer a lot from such a misconfiguration anyway. --- .../profiles/default/scripts/syncfileclient | 18 ++++++++++++++++-- .../profiles/default/scripts/syncfileclient | 18 ++++++++++++++++-- .../profiles/default/scripts/syncfileclient | 18 ++++++++++++++++-- .../profiles/default/scripts/syncfileclient | 18 ++++++++++++++++-- .../suse15/profiles/hpc/scripts/syncfileclient | 18 ++++++++++++++++-- .../profiles/server/scripts/syncfileclient | 18 ++++++++++++++++-- .../profiles/default/scripts/syncfileclient | 18 ++++++++++++++++-- .../profiles/default/scripts/syncfileclient | 18 ++++++++++++++++-- confluent_server/confluent/selfservice.py | 4 +--- confluent_server/confluent/syncfiles.py | 10 +++++++++- 10 files changed, 138 insertions(+), 20 deletions(-) diff --git a/confluent_osdeploy/el8-diskless/profiles/default/scripts/syncfileclient b/confluent_osdeploy/el8-diskless/profiles/default/scripts/syncfileclient index 3fdd1f08..f7d4c0b4 100644 --- a/confluent_osdeploy/el8-diskless/profiles/default/scripts/syncfileclient +++ b/confluent_osdeploy/el8-diskless/profiles/default/scripts/syncfileclient @@ -1,4 +1,5 @@ -#!/usr/bin/python +#!/usr/bin/python3 +import subprocess import importlib import tempfile import json @@ -211,7 +212,20 @@ def synchronize(): appendoncedir = tempfile.mkdtemp() try: ac = apiclient.HTTPSClient() - data = json.dumps({'merge': tmpdir, 'appendonce': appendoncedir}) + myips = [] + ipaddrs = subprocess.check_output(['ip', '-br', 'a']).split(b'\n') + for line in ipaddrs: + isa = line.split() + if len(isa) < 3 or isa[1] != b'UP': + continue + for addr in isa[2:]: + if addr.startswith(b'fe80::') or addr.startswith(b'169.254'): + continue + addr = addr.split(b'/')[0] + if not isinstance(addr, str): + addr = addr.decode('utf8') + myips.append(addr) + data = json.dumps({'merge': tmpdir, 'appendonce': appendoncedir, 'myips': myips}) status, rsp = ac.grab_url_with_status('/confluent-api/self/remotesyncfiles', data) if status == 202: lastrsp = '' diff --git a/confluent_osdeploy/el8/profiles/default/scripts/syncfileclient b/confluent_osdeploy/el8/profiles/default/scripts/syncfileclient index 3fdd1f08..f7d4c0b4 100644 --- a/confluent_osdeploy/el8/profiles/default/scripts/syncfileclient +++ b/confluent_osdeploy/el8/profiles/default/scripts/syncfileclient @@ -1,4 +1,5 @@ -#!/usr/bin/python +#!/usr/bin/python3 +import subprocess import importlib import tempfile import json @@ -211,7 +212,20 @@ def synchronize(): appendoncedir = tempfile.mkdtemp() try: ac = apiclient.HTTPSClient() - data = json.dumps({'merge': tmpdir, 'appendonce': appendoncedir}) + myips = [] + ipaddrs = subprocess.check_output(['ip', '-br', 'a']).split(b'\n') + for line in ipaddrs: + isa = line.split() + if len(isa) < 3 or isa[1] != b'UP': + continue + for addr in isa[2:]: + if addr.startswith(b'fe80::') or addr.startswith(b'169.254'): + continue + addr = addr.split(b'/')[0] + if not isinstance(addr, str): + addr = addr.decode('utf8') + myips.append(addr) + data = json.dumps({'merge': tmpdir, 'appendonce': appendoncedir, 'myips': myips}) status, rsp = ac.grab_url_with_status('/confluent-api/self/remotesyncfiles', data) if status == 202: lastrsp = '' diff --git a/confluent_osdeploy/el9-diskless/profiles/default/scripts/syncfileclient b/confluent_osdeploy/el9-diskless/profiles/default/scripts/syncfileclient index 3fdd1f08..f7d4c0b4 100644 --- a/confluent_osdeploy/el9-diskless/profiles/default/scripts/syncfileclient +++ b/confluent_osdeploy/el9-diskless/profiles/default/scripts/syncfileclient @@ -1,4 +1,5 @@ -#!/usr/bin/python +#!/usr/bin/python3 +import subprocess import importlib import tempfile import json @@ -211,7 +212,20 @@ def synchronize(): appendoncedir = tempfile.mkdtemp() try: ac = apiclient.HTTPSClient() - data = json.dumps({'merge': tmpdir, 'appendonce': appendoncedir}) + myips = [] + ipaddrs = subprocess.check_output(['ip', '-br', 'a']).split(b'\n') + for line in ipaddrs: + isa = line.split() + if len(isa) < 3 or isa[1] != b'UP': + continue + for addr in isa[2:]: + if addr.startswith(b'fe80::') or addr.startswith(b'169.254'): + continue + addr = addr.split(b'/')[0] + if not isinstance(addr, str): + addr = addr.decode('utf8') + myips.append(addr) + data = json.dumps({'merge': tmpdir, 'appendonce': appendoncedir, 'myips': myips}) status, rsp = ac.grab_url_with_status('/confluent-api/self/remotesyncfiles', data) if status == 202: lastrsp = '' diff --git a/confluent_osdeploy/genesis/profiles/default/scripts/syncfileclient b/confluent_osdeploy/genesis/profiles/default/scripts/syncfileclient index 3fdd1f08..f7d4c0b4 100644 --- a/confluent_osdeploy/genesis/profiles/default/scripts/syncfileclient +++ b/confluent_osdeploy/genesis/profiles/default/scripts/syncfileclient @@ -1,4 +1,5 @@ -#!/usr/bin/python +#!/usr/bin/python3 +import subprocess import importlib import tempfile import json @@ -211,7 +212,20 @@ def synchronize(): appendoncedir = tempfile.mkdtemp() try: ac = apiclient.HTTPSClient() - data = json.dumps({'merge': tmpdir, 'appendonce': appendoncedir}) + myips = [] + ipaddrs = subprocess.check_output(['ip', '-br', 'a']).split(b'\n') + for line in ipaddrs: + isa = line.split() + if len(isa) < 3 or isa[1] != b'UP': + continue + for addr in isa[2:]: + if addr.startswith(b'fe80::') or addr.startswith(b'169.254'): + continue + addr = addr.split(b'/')[0] + if not isinstance(addr, str): + addr = addr.decode('utf8') + myips.append(addr) + data = json.dumps({'merge': tmpdir, 'appendonce': appendoncedir, 'myips': myips}) status, rsp = ac.grab_url_with_status('/confluent-api/self/remotesyncfiles', data) if status == 202: lastrsp = '' diff --git a/confluent_osdeploy/suse15/profiles/hpc/scripts/syncfileclient b/confluent_osdeploy/suse15/profiles/hpc/scripts/syncfileclient index 3fdd1f08..f7d4c0b4 100644 --- a/confluent_osdeploy/suse15/profiles/hpc/scripts/syncfileclient +++ b/confluent_osdeploy/suse15/profiles/hpc/scripts/syncfileclient @@ -1,4 +1,5 @@ -#!/usr/bin/python +#!/usr/bin/python3 +import subprocess import importlib import tempfile import json @@ -211,7 +212,20 @@ def synchronize(): appendoncedir = tempfile.mkdtemp() try: ac = apiclient.HTTPSClient() - data = json.dumps({'merge': tmpdir, 'appendonce': appendoncedir}) + myips = [] + ipaddrs = subprocess.check_output(['ip', '-br', 'a']).split(b'\n') + for line in ipaddrs: + isa = line.split() + if len(isa) < 3 or isa[1] != b'UP': + continue + for addr in isa[2:]: + if addr.startswith(b'fe80::') or addr.startswith(b'169.254'): + continue + addr = addr.split(b'/')[0] + if not isinstance(addr, str): + addr = addr.decode('utf8') + myips.append(addr) + data = json.dumps({'merge': tmpdir, 'appendonce': appendoncedir, 'myips': myips}) status, rsp = ac.grab_url_with_status('/confluent-api/self/remotesyncfiles', data) if status == 202: lastrsp = '' diff --git a/confluent_osdeploy/suse15/profiles/server/scripts/syncfileclient b/confluent_osdeploy/suse15/profiles/server/scripts/syncfileclient index 3fdd1f08..f7d4c0b4 100644 --- a/confluent_osdeploy/suse15/profiles/server/scripts/syncfileclient +++ b/confluent_osdeploy/suse15/profiles/server/scripts/syncfileclient @@ -1,4 +1,5 @@ -#!/usr/bin/python +#!/usr/bin/python3 +import subprocess import importlib import tempfile import json @@ -211,7 +212,20 @@ def synchronize(): appendoncedir = tempfile.mkdtemp() try: ac = apiclient.HTTPSClient() - data = json.dumps({'merge': tmpdir, 'appendonce': appendoncedir}) + myips = [] + ipaddrs = subprocess.check_output(['ip', '-br', 'a']).split(b'\n') + for line in ipaddrs: + isa = line.split() + if len(isa) < 3 or isa[1] != b'UP': + continue + for addr in isa[2:]: + if addr.startswith(b'fe80::') or addr.startswith(b'169.254'): + continue + addr = addr.split(b'/')[0] + if not isinstance(addr, str): + addr = addr.decode('utf8') + myips.append(addr) + data = json.dumps({'merge': tmpdir, 'appendonce': appendoncedir, 'myips': myips}) status, rsp = ac.grab_url_with_status('/confluent-api/self/remotesyncfiles', data) if status == 202: lastrsp = '' diff --git a/confluent_osdeploy/ubuntu20.04/profiles/default/scripts/syncfileclient b/confluent_osdeploy/ubuntu20.04/profiles/default/scripts/syncfileclient index 3fdd1f08..f7d4c0b4 100644 --- a/confluent_osdeploy/ubuntu20.04/profiles/default/scripts/syncfileclient +++ b/confluent_osdeploy/ubuntu20.04/profiles/default/scripts/syncfileclient @@ -1,4 +1,5 @@ -#!/usr/bin/python +#!/usr/bin/python3 +import subprocess import importlib import tempfile import json @@ -211,7 +212,20 @@ def synchronize(): appendoncedir = tempfile.mkdtemp() try: ac = apiclient.HTTPSClient() - data = json.dumps({'merge': tmpdir, 'appendonce': appendoncedir}) + myips = [] + ipaddrs = subprocess.check_output(['ip', '-br', 'a']).split(b'\n') + for line in ipaddrs: + isa = line.split() + if len(isa) < 3 or isa[1] != b'UP': + continue + for addr in isa[2:]: + if addr.startswith(b'fe80::') or addr.startswith(b'169.254'): + continue + addr = addr.split(b'/')[0] + if not isinstance(addr, str): + addr = addr.decode('utf8') + myips.append(addr) + data = json.dumps({'merge': tmpdir, 'appendonce': appendoncedir, 'myips': myips}) status, rsp = ac.grab_url_with_status('/confluent-api/self/remotesyncfiles', data) if status == 202: lastrsp = '' diff --git a/confluent_osdeploy/ubuntu22.04/profiles/default/scripts/syncfileclient b/confluent_osdeploy/ubuntu22.04/profiles/default/scripts/syncfileclient index 3fdd1f08..f7d4c0b4 100644 --- a/confluent_osdeploy/ubuntu22.04/profiles/default/scripts/syncfileclient +++ b/confluent_osdeploy/ubuntu22.04/profiles/default/scripts/syncfileclient @@ -1,4 +1,5 @@ -#!/usr/bin/python +#!/usr/bin/python3 +import subprocess import importlib import tempfile import json @@ -211,7 +212,20 @@ def synchronize(): appendoncedir = tempfile.mkdtemp() try: ac = apiclient.HTTPSClient() - data = json.dumps({'merge': tmpdir, 'appendonce': appendoncedir}) + myips = [] + ipaddrs = subprocess.check_output(['ip', '-br', 'a']).split(b'\n') + for line in ipaddrs: + isa = line.split() + if len(isa) < 3 or isa[1] != b'UP': + continue + for addr in isa[2:]: + if addr.startswith(b'fe80::') or addr.startswith(b'169.254'): + continue + addr = addr.split(b'/')[0] + if not isinstance(addr, str): + addr = addr.decode('utf8') + myips.append(addr) + data = json.dumps({'merge': tmpdir, 'appendonce': appendoncedir, 'myips': myips}) status, rsp = ac.grab_url_with_status('/confluent-api/self/remotesyncfiles', data) if status == 202: lastrsp = '' diff --git a/confluent_server/confluent/selfservice.py b/confluent_server/confluent/selfservice.py index 2f17d456..1e9cc144 100644 --- a/confluent_server/confluent/selfservice.py +++ b/confluent_server/confluent/selfservice.py @@ -461,10 +461,8 @@ def handle_request(env, start_response): elif env['PATH_INFO'].startswith('/self/remotesyncfiles'): if 'POST' == operation: pals = get_extra_names(nodename, cfg, myip) - if clientip not in pals: - clientip = None result = syncfiles.start_syncfiles( - nodename, cfg, json.loads(reqbody), clientip) + nodename, cfg, json.loads(reqbody), pals) start_response(result, ()) yield '' return diff --git a/confluent_server/confluent/syncfiles.py b/confluent_server/confluent/syncfiles.py index a64b3c98..b04f5273 100644 --- a/confluent_server/confluent/syncfiles.py +++ b/confluent_server/confluent/syncfiles.py @@ -278,7 +278,15 @@ def mkpathorlink(source, destination, appendexist=False): syncrunners = {} -def start_syncfiles(nodename, cfg, suffixes, peerip=None): +def start_syncfiles(nodename, cfg, suffixes, principals=[]): + peerip = None + if 'myips' in suffixes: + targips = suffixes['myips'] + del suffixes['myips'] + for targip in targips: + if targip in principals: + peerip = targip + break deployinfo = cfg.get_node_attributes( nodename, ('deployment.*',)) deployinfo = deployinfo.get(nodename, {})