launch: Automatically do RAX rdns updates when launching nodes
On the old bridge node we had some unmanaged venv's with a very old, now unmaintained RAX DNS API interaction tool. Adding the RDNS entries is fairly straight forward, and this small tool is mostly a copy of some of the bits for our dns api backup tool. It really just comes down to getting a token and making a post request with the name/ip addresses. When the cloud the node is launched as is identified as RAX, this will automatically add the PTR records for the ip4 & 6 addresses. It also has an entrypoint to be called manually. This is added and hacked in, along with a config file for the appropriate account (I have added these details on bridge). I've left the update of openstack.org DNS entries as a manual procedure. Although they could be set automatically with small updates to the tool (just a different POST) -- details like CNAMES, etc. and the relatively few servers we start in the RAX mangaed DNS domains means I think it's easier to just do manually via the web ui. The output comment is updated. Change-Id: I8a42afdd00be2595ca73819610757ce5d4435d0a
This commit is contained in:
parent
f40c52b01a
commit
20d2643f74
@ -27,6 +27,7 @@ dependencies = [
|
||||
[project.scripts]
|
||||
launch-node = "opendev_launch:launch_node.main"
|
||||
show-dns = "opendev_launch:dns.main"
|
||||
rax-rdns = "opendev_launch:rax_rdns.main"
|
||||
|
||||
[tool.setuptools.package-data]
|
||||
opendev_launch = ["*.sh"]
|
||||
|
@ -19,8 +19,10 @@
|
||||
# limitations under the License.
|
||||
|
||||
import argparse
|
||||
from . import rax_rdns
|
||||
from .sshfp import sshfp_print_records
|
||||
|
||||
|
||||
def get_href(server):
|
||||
if not hasattr(server, 'links'):
|
||||
return None
|
||||
@ -33,18 +35,15 @@ def print_dns(cloud, server):
|
||||
ip4 = server.public_v4
|
||||
ip6 = server.public_v6
|
||||
|
||||
if 'rax' in cloud.config.name:
|
||||
print_reverse_dns(cloud, server, ip4, ip6)
|
||||
|
||||
if server.name.endswith('opendev.org'):
|
||||
print_dns_opendev(server.name.rsplit('.', 2)[0], ip4, ip6)
|
||||
else:
|
||||
print_dns_legacy(server, ip4, ip6)
|
||||
print("Login to manage.rackspace.com and setup DNS manually.")
|
||||
|
||||
print_inventory_yaml(server, ip4, ip6)
|
||||
|
||||
|
||||
def print_dns_opendev(name, ip4, ip6):
|
||||
|
||||
print("\n")
|
||||
print("Put the following into zone-opendev.org:zones/opendev.org/zone.db")
|
||||
print("{name} IN A {ip4}".format(name=name, ip4=ip4))
|
||||
@ -52,7 +51,8 @@ def print_dns_opendev(name, ip4, ip6):
|
||||
print("{name} IN AAAA {ip6}".format(name=name, ip6=ip6))
|
||||
sshfp_print_records(name, ip4)
|
||||
|
||||
def print_reverse_dns(cloud, server, ip4, ip6):
|
||||
|
||||
def set_rax_reverse_dns(cloud, server, ip4, ip6):
|
||||
# Get the server object from the sdk layer so that we can pull the
|
||||
# href data out of the links dict.
|
||||
try:
|
||||
@ -63,43 +63,12 @@ def print_reverse_dns(cloud, server, ip4, ip6):
|
||||
raise
|
||||
href = get_href(raw_server)
|
||||
|
||||
print("\n")
|
||||
print("Run the following commands to set up DNS:")
|
||||
print("\n")
|
||||
print(". ~root/ci-launch/openstackci-rs-nova.sh")
|
||||
print(". ~root/rackdns-venv/bin/activate")
|
||||
print("\n")
|
||||
print(
|
||||
"rackdns rdns-create --name %s \\\n"
|
||||
" --data %s \\\n"
|
||||
" --server-href %s \\\n"
|
||||
" --ttl 3600" % (
|
||||
server.name, ip6, href))
|
||||
print("\n")
|
||||
print(
|
||||
"rackdns rdns-create --name %s \\\n"
|
||||
" --data %s \\\n"
|
||||
" --server-href %s \\\n"
|
||||
" --ttl 3600" % (
|
||||
server.name, ip4, href))
|
||||
print("\n")
|
||||
# Reads default config file /etc/rax-rdns-auth.conf and calls to
|
||||
# API to set reverse dns for RAX servers.
|
||||
auth = rax_rdns.get_auth()
|
||||
rax_rdns.rax_rdns(server.name, href, ip4, ip6, 3600, auth)
|
||||
|
||||
|
||||
def print_dns_legacy(server, ip4, ip6):
|
||||
print(". ~root/ci-launch/openstack-rs-nova.sh")
|
||||
print("\n")
|
||||
print(
|
||||
"rackdns record-create --name %s \\\n"
|
||||
" --type AAAA --data %s \\\n"
|
||||
" --ttl 3600 openstack.org" % (
|
||||
server.name, ip6))
|
||||
print("\n")
|
||||
print(
|
||||
"rackdns record-create --name %s \\\n"
|
||||
" --type A --data %s \\\n"
|
||||
" --ttl 3600 openstack.org" % (
|
||||
server.name, ip4))
|
||||
|
||||
def print_inventory_yaml(server, ip4, ip6):
|
||||
print("\n")
|
||||
print("Put the following into system-config:inventory/base/hosts.yaml")
|
||||
@ -130,4 +99,8 @@ def main():
|
||||
print("Please update your version of shade/openstacksdk."
|
||||
" openstacksdk >= 0.12 is required")
|
||||
raise
|
||||
|
||||
if 'rax' in cloud.config.name:
|
||||
set_rax_reverse_dns(cloud, server, ip4, ip6)
|
||||
|
||||
print_dns(cloud, server)
|
||||
|
136
launch/src/opendev_launch/rax_rdns.py
Normal file
136
launch/src/opendev_launch/rax_rdns.py
Normal file
@ -0,0 +1,136 @@
|
||||
#!/usr/bin/env python3
|
||||
|
||||
# Copyright 2022 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.
|
||||
|
||||
# Set RDNS values for a server
|
||||
#
|
||||
# Set auth in an .ini file specified with --config:
|
||||
#
|
||||
# [DEFAULT]
|
||||
# RACKSPACE_USERNAME = <used to login to web>
|
||||
# RACKSPACE_PROJECT_ID = <listed on account info>
|
||||
# RACKSPACE_API_KEY = <listed in the account details page>
|
||||
#
|
||||
|
||||
import argparse
|
||||
import configparser
|
||||
import collections
|
||||
import logging
|
||||
import os
|
||||
import requests
|
||||
import sys
|
||||
|
||||
# Verbose call debugging:
|
||||
# import http.client as http_client
|
||||
# http_client.HTTPConnection.debuglevel = 1
|
||||
|
||||
RACKSPACE_IDENTITY_ENDPOINT='https://identity.api.rackspacecloud.com/v2.0/tokens'
|
||||
RACKSPACE_DNS_ENDPOINT="https://dns.api.rackspacecloud.com/v1.0"
|
||||
|
||||
def _get_auth_token(session, username, api_key):
|
||||
# Get auth token
|
||||
data = {'auth':
|
||||
{
|
||||
'RAX-KSKEY:apiKeyCredentials':
|
||||
{
|
||||
'username': username,
|
||||
'apiKey': api_key
|
||||
}
|
||||
}
|
||||
}
|
||||
token_response = session.post(url=RACKSPACE_IDENTITY_ENDPOINT, json=data)
|
||||
token = token_response.json()['access']['token']['id']
|
||||
|
||||
return token
|
||||
|
||||
|
||||
def get_auth(config_file='/etc/rax-rdns-auth.conf'):
|
||||
'''Return a tuple for passing to rax_rnds update function'''
|
||||
try:
|
||||
logging.info("Reading config file %s" % config_file)
|
||||
config = configparser.ConfigParser()
|
||||
config.read(config_file)
|
||||
return (config['DEFAULT']['RACKSPACE_PROJECT_ID'],
|
||||
config['DEFAULT']['RACKSPACE_USERNAME'],
|
||||
config['DEFAULT']['RACKSPACE_API_KEY'])
|
||||
except Exception as e:
|
||||
logging.error("Can not read config: %s" % e)
|
||||
sys.exit(1)
|
||||
|
||||
|
||||
def rax_rdns(name, server_href, ip4, ip6, ttl, auth):
|
||||
(rax_project_id, rax_username, rax_api_key) = auth
|
||||
|
||||
session = requests.Session()
|
||||
token = _get_auth_token(session, rax_username, rax_api_key)
|
||||
|
||||
rdns_url = '%s/%s/rdns' % (RACKSPACE_DNS_ENDPOINT,
|
||||
rax_project_id)
|
||||
|
||||
rdns_json = {
|
||||
'recordsList': {
|
||||
'records': [
|
||||
{
|
||||
'name': name,
|
||||
'type': 'PTR',
|
||||
'data': ip4,
|
||||
'ttl': ttl
|
||||
}, {
|
||||
'name': name,
|
||||
'type': 'PTR',
|
||||
'data': ip6,
|
||||
'ttl': ttl
|
||||
}
|
||||
]
|
||||
},
|
||||
'link': {
|
||||
'content': '',
|
||||
'href': server_href,
|
||||
'rel': 'cloudServersOpenStack'
|
||||
}
|
||||
}
|
||||
|
||||
headers = {
|
||||
'Accept': 'application/json',
|
||||
'X-Auth-Token': token,
|
||||
'X-Project-Id': rax_project_id,
|
||||
'Content-Type': 'application/json'
|
||||
}
|
||||
|
||||
r = session.post(url=rdns_url, headers=headers, json=rdns_json)
|
||||
logging.info("RDNS Done: %s %s" % (r.status_code, r.reason))
|
||||
|
||||
|
||||
def main():
|
||||
parser = argparse.ArgumentParser(description='Update RDNS')
|
||||
parser.add_argument('--debug', dest='debug', action='store_true')
|
||||
parser.add_argument('--config', dest='config',
|
||||
default='/etc/rax-rdns-auth.conf')
|
||||
parser.add_argument('--ttl', dest='ttl', type=int, default=3600)
|
||||
parser.add_argument('name')
|
||||
parser.add_argument('server_href')
|
||||
parser.add_argument('ip4')
|
||||
parser.add_argument('ip6')
|
||||
args = parser.parse_args()
|
||||
|
||||
logging.basicConfig(level=logging.INFO)
|
||||
if args.debug:
|
||||
logging.getLogger().setLevel(logging.DEBUG)
|
||||
requests_log = logging.getLogger("requests.packages.urllib3")
|
||||
requests_log.setLevel(logging.DEBUG)
|
||||
requests_log.propogate = True
|
||||
|
||||
auth = get_auth(args.config)
|
||||
rax_rdns(args.name, args.server_href, args.ip4, args.ip6, args.ttl, auth)
|
@ -4,6 +4,14 @@
|
||||
vars:
|
||||
create_venv_path: '/usr/launcher-venv'
|
||||
|
||||
- name: Add RAX rdns credentials
|
||||
template:
|
||||
src: rax-rdns-auth.conf.j2
|
||||
dest: /etc/rax-rdns-auth.conf
|
||||
owner: root
|
||||
group: root
|
||||
mode: '0600'
|
||||
|
||||
- name: Install node launcher
|
||||
pip:
|
||||
name: 'file:///home/zuul/src/opendev.org/opendev/system-config/launch'
|
||||
|
@ -0,0 +1,4 @@
|
||||
[DEFAULT]
|
||||
RACKSPACE_USERNAME={{ rackspace_rdns_username }}
|
||||
RACKSPACE_PROJECT_ID={{ rackspace_rdns_project_id }}
|
||||
RACKSPACE_API_KEY={{ rackspace_rdns_api_key }}
|
@ -7,3 +7,7 @@ extra_users: []
|
||||
rackspace_dns_username: user
|
||||
rackspace_dns_project_id: 1234
|
||||
rackspace_dns_api_key: apikey
|
||||
|
||||
rackspace_rdns_username: user
|
||||
rackspace_rdns_project_id: 1234
|
||||
rackspace_rdns_api_key: apikey
|
||||
|
Loading…
x
Reference in New Issue
Block a user