Fix openstack sync

Add options to skip sync of IPv4 and/or IPv6 addresses.
This commit is contained in:
Ralf Nyren 2025-01-30 12:10:21 +01:00
parent 3c52eb2a81
commit 3c9293417e

View file

@ -232,7 +232,8 @@ def run_list(url: str,
def run_openstack_sync(cloud: str, name: str, zone: str, headers: dict, def run_openstack_sync(cloud: str, name: str, zone: str, headers: dict,
baseurl: str, jsonout: bool): baseurl: str, jsonout: bool, ipv4: bool, ipv6: bool):
# List DNS records for name
url = setup_url( url = setup_url(
baseurl, baseurl,
None, # arguments, None, # arguments,
@ -242,103 +243,72 @@ def run_openstack_sync(cloud: str, name: str, zone: str, headers: dict,
None, # ttl, None, # ttl,
zone, zone,
) )
current_records = run_list(url, jsonout=True, headers=headers, ret=True) response = run_list(url, jsonout=True, headers=headers, ret=True)
if isinstance(response, dict):
if response["Code"] == 404:
response = []
else:
output(error(f'{name}: could not list records', 'API Error'))
sys.exit(1)
# List of DNS records for name
dns_records = []
for record in response:
rtype = record['rtype']
rname = record['name'].rstrip('.')
raddr = record['data']
if rtype not in ('A', 'AAAA'):
continue
if f'{name}.{zone}' != rname:
output(error(f'{rname}: not the DNS name asked for', 'API Error'))
sys.exit(1)
dns_records.append((rname, rtype, raddr))
# List instance addresses in openstack
openstack_addresses = get_openstack_addresses(cloud, name) openstack_addresses = get_openstack_addresses(cloud, name)
if current_records["Code"] == 404:
for address in openstack_addresses: # Add missing DNS records
rtype = None for address in openstack_addresses:
if address["version"] == 4: rtype = None
rtype = "A" if address["version"] == 4 and ipv4:
elif address["version"] == 6: rtype = "A"
rtype = "AAAA" elif address["version"] == 6 and ipv6:
if rtype: rtype = "AAAA"
url = setup_url( if not rtype:
baseurl, continue
None, # arguments,
address["addr"], # data, raddr = address['addr']
name,
rtype, wanted_record = (f'{name}.{zone}', rtype, raddr)
None, # ttl,
zone, if wanted_record in dns_records:
) dns_records.remove(wanted_record)
run_add(url, jsonout, headers) else:
else:
previpv4 = False
previpv6 = False
curripv4 = False
curripv6 = False
for record in current_records:
if record.type == "A":
previpv4 = record.data
elif record.type == "AAAA":
previpv6 = record.data
for address in openstack_addresses:
rtype = None
if address.version == 4:
rtype = "A"
curripv4 = True
elif address.version == 6:
rtype = "AAAA"
curripv6 = True
if rtype and recor.type == rtype:
if record.data == address.addr:
continue
else:
url = setup_url(
baseurl,
None, # arguments,
address.addr, # data,
name,
record.type,
None, # ttl,
zone,
)
run_update(url, jsonout, headers)
if previpv4 and not curripv4:
url = setup_url( url = setup_url(
baseurl, baseurl,
None, # arguments, None, # arguments,
previpv4, # data, raddr, # data,
name, name,
"A", rtype, # rtype,
None, # ttl,
zone,
)
run_delete(url, jsonout, headers)
if previpv6 and not curripv6:
url = setup_url(
baseurl,
None, # arguments,
previpv6, # data,
name,
"AAAA",
None, # ttl,
zone,
)
run_delete(url, jsonout, headers)
if curripv4 and not previpv4:
url = setup_url(
baseurl,
None, # arguments,
curripv4, # data,
name,
"A",
None, # ttl,
zone,
)
run_add(url, jsonout, headers)
if curripv6 and not previpv6:
url = setup_url(
baseurl,
None, # arguments,
curripv6, # data,
name,
"AAAA",
None, # ttl, None, # ttl,
zone, zone,
) )
run_add(url, jsonout, headers) run_add(url, jsonout, headers)
# Remove obsolete DNS records
for record in dns_records:
rname, rtype, raddr = record
url = setup_url(
baseurl,
None, # arguments,
raddr, # data,
name,
rtype, # rtype,
None, # ttl,
zone,
)
run_delete(url, jsonout, headers)
def run_update(url: str, jsonout: bool, headers: dict): def run_update(url: str, jsonout: bool, headers: dict):
response = requests.patch(url, headers=headers) response = requests.patch(url, headers=headers)
@ -557,6 +527,8 @@ def get_parser() -> dict:
openstackcmd.add_argument("-n", "--name", required=True) openstackcmd.add_argument("-n", "--name", required=True)
openstackcmd.add_argument("-c", "--cloud", required=True) openstackcmd.add_argument("-c", "--cloud", required=True)
openstackcmd.add_argument("-z", "--zone", required=True) openstackcmd.add_argument("-z", "--zone", required=True)
openstackcmd.add_argument("--no-ipv4", action='store_true')
openstackcmd.add_argument("--no-ipv6", action='store_true')
user_description = "View user information." user_description = "View user information."
usercmd = subparsers.add_parser("user", description=user_description) usercmd = subparsers.add_parser("user", description=user_description)
@ -645,7 +617,8 @@ def run(url, args, headers, baseurl, parser, username):
run_zone(url, args.json, headers) run_zone(url, args.json, headers)
elif args.command == "openstack-sync": elif args.command == "openstack-sync":
run_openstack_sync(args.cloud, args.name, args.zone, headers, run_openstack_sync(args.cloud, args.name, args.zone, headers,
baseurl, args.json) baseurl, args.json,
args.no_ipv4 is False, args.no_ipv6 is False)
else: else:
parser.print_help(sys.stderr) parser.print_help(sys.stderr)
return 2 return 2