86 lines
2.9 KiB
Python
Executable File
86 lines
2.9 KiB
Python
Executable File
#!/usr/bin/env python3
|
|
|
|
# Output DNS for a new host
|
|
|
|
# Copyright (C) 2013 OpenStack Foundation
|
|
# Copyright (C) 2023 Red Hat, Inc.
|
|
#
|
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
# you may not use this file except in compliance with the License.
|
|
# You may obtain a copy of the License at
|
|
#
|
|
# http://www.apache.org/licenses/LICENSE-2.0
|
|
#
|
|
# Unless required by applicable law or agreed to in writing, software
|
|
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
|
# implied.
|
|
#
|
|
# See the License for the specific language governing permissions and
|
|
# limitations under the License.
|
|
|
|
import argparse
|
|
import subprocess
|
|
|
|
def print_sshfp_records(host, ip):
|
|
'''Given a hostname and and IP address, scan the IP address (hostname
|
|
not in dns yet) and print the sshfp records in standard bind format'''
|
|
p = ['ssh-keyscan', '-D', ip]
|
|
s = subprocess.run(p,
|
|
stdout=subprocess.PIPE,
|
|
stderr=subprocess.PIPE).stdout.decode('utf-8')
|
|
fingerprints = []
|
|
for line in s.split('\n'):
|
|
if not line:
|
|
continue
|
|
_, _, _, algo, key_type, fingerprint = line.split(' ')
|
|
# ssh-keygen on the host seems to return DSS/DSA keys, which
|
|
# aren't valid to log in and not shown by ssh-keyscan -D
|
|
# ... prune it.
|
|
if algo == '2':
|
|
continue
|
|
fingerprints.append(
|
|
(algo, key_type, fingerprint))
|
|
|
|
# sort by algo and key_type to keep it consistent
|
|
fingerprints = sorted(fingerprints,
|
|
key=lambda x: (x[0], x[1]))
|
|
for f in fingerprints:
|
|
print(f"{host}\t\t\tIN\tSSHFP\t{f[0]} {f[1]} {f[2]}")
|
|
|
|
def print_dns(server):
|
|
ip4 = server.public_v4
|
|
ip6 = server.public_v6
|
|
# note handle things like mirror.iad.rax.opendev.org
|
|
domain = '.'.join(server.name.split('.')[-2:])
|
|
host = '.'.join(server.name.split('.')[0:-2])
|
|
|
|
# openstack.org is the only domain we deal with that is still in
|
|
# RAX DNS
|
|
if (domain == "openstack.org"):
|
|
print("Add the following manually to openstack.org domain in RAX\n")
|
|
else:
|
|
print(f"Put the following into zone-{domain}:zones/{domain}/zone.db\n")
|
|
print(f"{host} IN A {ip4}")
|
|
if ip6:
|
|
print(f"{host} IN AAAA {ip6}")
|
|
print_sshfp_records(host, ip4)
|
|
|
|
def main():
|
|
parser = argparse.ArgumentParser()
|
|
parser.add_argument("name", help="server name")
|
|
options = parser.parse_args()
|
|
|
|
import openstack
|
|
cloud = openstack.connect()
|
|
# Get the server using the shade layer so that we have server.public_v4
|
|
# and server.public_v6
|
|
try:
|
|
server = cloud.get_server(options.name)
|
|
except AttributeError:
|
|
print("Please update your version of shade/openstacksdk."
|
|
" openstacksdk >= 0.12 is required")
|
|
raise
|
|
|
|
print_dns(server)
|