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)
openstack_addresses = get_openstack_addresses(cloud, name) if isinstance(response, dict):
if current_records["Code"] == 404: if response["Code"] == 404:
for address in openstack_addresses: response = []
rtype = None
if address["version"] == 4:
rtype = "A"
elif address["version"] == 6:
rtype = "AAAA"
if rtype:
url = setup_url(
baseurl,
None, # arguments,
address["addr"], # data,
name,
rtype,
None, # ttl,
zone,
)
run_add(url, jsonout, headers)
else: else:
previpv4 = False output(error(f'{name}: could not list records', 'API Error'))
previpv6 = False sys.exit(1)
curripv4 = False
curripv6 = False # List of DNS records for name
for record in current_records: dns_records = []
if record.type == "A": for record in response:
previpv4 = record.data rtype = record['rtype']
elif record.type == "AAAA": rname = record['name'].rstrip('.')
previpv6 = record.data raddr = record['data']
for address in openstack_addresses: if rtype not in ('A', 'AAAA'):
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 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)
# Add missing DNS records
for address in openstack_addresses:
rtype = None
if address["version"] == 4 and ipv4:
rtype = "A"
elif address["version"] == 6 and ipv6:
rtype = "AAAA"
if not rtype:
continue
raddr = address['addr']
wanted_record = (f'{name}.{zone}', rtype, raddr)
if wanted_record in dns_records:
dns_records.remove(wanted_record)
else: else:
url = setup_url( url = setup_url(
baseurl, baseurl,
None, # arguments, None, # arguments,
address.addr, # data, raddr, # data,
name, name,
record.type, rtype, # rtype,
None, # ttl,
zone,
)
run_update(url, jsonout, headers)
if previpv4 and not curripv4:
url = setup_url(
baseurl,
None, # arguments,
previpv4, # data,
name,
"A",
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