UNTESTED: Support for syncing with openstack

main
Micke Nordin 6 days ago
parent c90ee01b93
commit f711265629

@ -12,6 +12,8 @@ from typing import Union
from urllib.parse import urlparse from urllib.parse import urlparse
import argcomplete import argcomplete
import openstack
import openstack.config.loader
import requests import requests
import yaml import yaml
from requests.models import HTTPBasicAuth from requests.models import HTTPBasicAuth
@ -43,6 +45,21 @@ def get_config(config_filename: str):
return yaml.safe_load(fh.read()) return yaml.safe_load(fh.read())
def get_openstack_addresses(name: str, cloud: str):
conn = openstack.connect(cloud=cloud)
# List the servers
server = conn.compute.find_server(name)
if server is None:
print("Server not found")
exit(1)
openstack_addresses = []
for network in server.addresses:
for address in network:
openstack_addresses.append(address)
return openstack_addresses
def nested_out(input, tabs="") -> str: def nested_out(input, tabs="") -> str:
string = "" string = ""
if isinstance(input, str) or isinstance(input, int): if isinstance(input, str) or isinstance(input, int):
@ -208,6 +225,84 @@ def run_list(url: str,
output(string, jsonout) output(string, jsonout)
def run_openstack_sync(cloud: str, name: str, zone: str, headers: dict,
baseurl: str, jsonout: bool):
url = setup_url(
baseurl,
zone=zone,
name=name,
)
current_records = run_list(url, jsonout=True, headers=headers, ret=True)
openstack_addresses = get_openstack_addresses(cloud, name)
if current_records is None:
for address in openstack_addresses:
rtype = None
if address.version == 4:
rtype = "A"
elif address.version == 6:
rtype = "AAAA"
if rtype:
url = setup_url(baseurl,
zone=zone,
name=name,
rtype=rtype,
data=address.addr)
run_add(url, jsonout, headers)
else:
previpv4, previpv6, curripv4, 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 record["type"] == rtype:
if record["data"] == address.addr:
continue
else:
url = setup_url(baseurl,
zone=zone,
name=name,
rtype=record["type"],
data=address.addr)
run_update(url, jsonout, headers)
if previpv4 and not curripv4:
url = setup_url(baseurl,
zone=zone,
name=name,
rtype="A",
data=previpv4)
run_delete(url, jsonout, headers)
if previpv6 and not curripv6:
url = setup_url(baseurl,
zone=zone,
name=name,
rtype="AAAA",
data=previpv4)
run_delete(url, jsonout, headers)
if curripv4 and not previpv4:
url = setup_url(baseurl,
zone=zone,
name=name,
rtype="A",
data=curripv4)
run_add(url, jsonout, headers)
if curripv6 and not previpv6:
url = setup_url(baseurl,
zone=zone,
name=name,
rtype="AAAA",
data=curripv6)
run_add(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)
output(response.json(), jsonout) output(response.json(), jsonout)
@ -415,6 +510,13 @@ def get_parser() -> dict:
listcmd.add_argument("-r", "--rtype") listcmd.add_argument("-r", "--rtype")
listcmd.add_argument("-z", "--zone", required=False) listcmd.add_argument("-z", "--zone", required=False)
openstack_description = "Sync records with openstack."
openstackcmd = subparsers.add_parser("openstack-sync",
description=openstack_description)
openstackcmd.add_argument("-n", "--name", required=True)
openstackcmd.add_argument("-c", "--cloud", required=True)
openstackcmd.add_argument("-z", "--zone", required=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)
usercmd.add_argument("-u", "--username", default=None) usercmd.add_argument("-u", "--username", default=None)
@ -500,6 +602,9 @@ def run(url, args, headers, baseurl, parser, username):
elif args.command == "zone": elif args.command == "zone":
url = baseurl + "/zones" url = baseurl + "/zones"
run_zone(url, args.json, headers) run_zone(url, args.json, headers)
elif args.command == "openstack-sync":
run_openstack_sync(args.cloud, args.name, args.zone, headers,
baseurl, args.json)
else: else:
parser.print_help(sys.stderr) parser.print_help(sys.stderr)
return 2 return 2
@ -564,7 +669,9 @@ def main() -> int:
if args.command == "user": if args.command == "user":
if args.username: if args.username:
user = args.username user = args.username
if args.command in ["auditlog", "changelog", "user", "zone"]: if args.command in [
"auditlog", "changelog", "openstack-sync", "user", "zone"
]:
pass pass
else: else:
try: try:

@ -2,3 +2,4 @@ argcomplete==2.0.0
pyyaml==6.0.1 pyyaml==6.0.1
requests==2.27.1 requests==2.27.1
simplejson==3.17.6 simplejson==3.17.6
openstacksdk==4.2.0

Loading…
Cancel
Save