Skip to content

Commit

Permalink
Support dynamic configuration update of named
Browse files Browse the repository at this point in the history
An additional file contrail-named-base.conf will contain the base named configurtion
such as options stanza, key stanza, controls stanza and logging stanza.

All configs generated due to vdns configuration resulting in view stanza will be written
to contrail-named.conf

Before sending "reconfig" command to named, both the files will be merged
into contrail-named.conf

The above gives flexibility to user to update and apply changes without restarting
the dns daemon which generated the contrail-named.conf

An additional helper script(applynamedconfig.py) will merge the files and apply the
config(contrail-named-base.conf) to named daemon.

Change-Id: If6089189a1104f648d8d7d3f638c58f9883deb50
Closes-Bug:1605341
  • Loading branch information
nipak committed Sep 8, 2016
1 parent 9c975a0 commit 0ceda0a
Show file tree
Hide file tree
Showing 3 changed files with 173 additions and 13 deletions.
2 changes: 2 additions & 0 deletions src/dns/SConscript
Expand Up @@ -65,6 +65,8 @@ doc_files += env.SandeshGenDoc('bind/bind.sandesh')
env.Alias('install', env.Install(env['INSTALL_BIN'], contrail_dns))
env.Alias('install', env.Install(env['INSTALL_CONF'] + '/dns', 'contrail-dns.conf'))
env.Alias('install', env.Install(env['INSTALL_CONF'] +
'/dns', 'applynamedconfig.py'))
env.Alias('install', env.Install(env['INSTALL_CONF'] +
'/supervisord_control_files/', 'contrail-dns.ini'))
env.Alias('install', env.Install(env['INSTALL_CONF'] +
'/supervisord_control_files/', 'contrail-named.ini'))
Expand Down
144 changes: 144 additions & 0 deletions src/dns/applynamedconfig.py
@@ -0,0 +1,144 @@
#
# Copyright (c) 2016 Juniper Networks, Inc. All rights reserved.
#

"""
This helper script is used to dynamically update configs to named.
o For backward compatibility we read the named configurable
params from contrail-dns.conf and build contrail-named-base.conf
o Alternatively user can create/update contrail-name-base.conf
for configuring named params
o contrail-named.conf will be generated by dnsd which will
contain views/zones stanzas
o contrail-named-base.conf will be merged with contrail-named.conf
by the script and config applied to named
"""

import sys
import os
import subprocess
import ConfigParser

def parse_contrail_dns_conf():

named_defaults = {
'named_config_file': 'DEFAULT....contrail-named.conf',
'named_config_directory': '/etc/contrail/dns',
'named_log_file': 'DEFAULT.../var/log/contrail/contrail-named.log',
'rndc_config_file': 'contrail-rndc.conf',
'rndc_secret': 'xvysmOR8lnUQRBcunkC6vg==',
'named_max_cache_size': '32M',
'named_max_retransmissions': '12',
'named_retransmission_interval': '1000',
}

# remove preceeding spaces from contrail-dns.conf
# and save it in contrail-dns-temp.conf
subprocess.call(["sed -e 's/^[ \t]*//g' < /etc/contrail/contrail-dns.conf \
> /etc/contrail/dns/contrail-dns-temp.conf"], shell=True)
# remove comments preceeding with #
subprocess.call(["sed -i 's/[;#].*$//g' /etc/contrail/dns/contrail-dns-temp.conf"], shell=True)

# parse contrail-dns.conf
dns_config = ConfigParser.SafeConfigParser()
dns_config.read('/etc/contrail/dns/contrail-dns-temp.conf')

# remove the temp file
os.remove("/etc/contrail/dns/contrail-dns-temp.conf")

# update defaults
named_defaults.update(dict(dns_config.items("DEFAULT")))

# create contrail-named-base.conf
file_named_base_conf=open('/etc/contrail/dns/contrail-named-base.conf', 'w+')

# build contrail-named-base.conf

# build options {} stanza
file_named_base_conf.write('options {\n')
file_named_base_conf.write(' directory "'+ named_defaults['named_config_directory'] + '";\n')
file_named_base_conf.write(' managed-keys-directory "'+ named_defaults['named_config_directory'] + '";\n')
file_named_base_conf.write(' empty-zones-enable no;\n')
file_named_base_conf.write(' pid-file "/etc/contrail/dns/contrail-named.pid";\n')
file_named_base_conf.write(' session-keyfile "/etc/contrail/dns/session.key";\n')
file_named_base_conf.write(' listen-on port 53 { any; };\n')
file_named_base_conf.write(' allow-query { any; };\n')
file_named_base_conf.write(' allow-recursion { any; };\n')
file_named_base_conf.write(' allow-query-cache { any; };\n')
file_named_base_conf.write(' max-cache-size '+ named_defaults['named_max_cache_size'] + ';\n')
file_named_base_conf.write('};\n\n')

# build rndc-key {} stanza
file_named_base_conf.write('key "rndc-key" {\n')
file_named_base_conf.write(' algorithm hmac-md5;\n')
file_named_base_conf.write(' secret "' + named_defaults['rndc_secret'] + '";\n')
file_named_base_conf.write('};\n\n')

#build controls {} stanza
file_named_base_conf.write('controls {\n')
file_named_base_conf.write(' inet 127.0.0.1 port 8094 \n')
file_named_base_conf.write(' allow { 127.0.0.1; } keys { "rndc-key"; };\n')
file_named_base_conf.write('};\n\n')

#build logging {} stanza
file_named_base_conf.write('logging {\n')
file_named_base_conf.write(' channel debug_log {\n')
file_named_base_conf.write(' file "'+ named_defaults['named_log_file'] + '" versions 5 size 5m;\n')
file_named_base_conf.write(' severity debug;\n')
file_named_base_conf.write(' print-time yes;\n')
file_named_base_conf.write(' print-severity yes;\n')
file_named_base_conf.write(' print-category yes;\n')
file_named_base_conf.write(' };\n')
file_named_base_conf.write(' category default {\n')
file_named_base_conf.write(' debug_log;\n')
file_named_base_conf.write(' };\n')
file_named_base_conf.write(' category queries {\n')
file_named_base_conf.write(' debug_log;\n')
file_named_base_conf.write(' };\n')
file_named_base_conf.write('};\n\n')

file_named_base_conf.close()

# end parse_contrail_dns_conf


def main():
if not os.path.exists('/etc/contrail/dns/contrail-named-base.conf'):
# parse contrail-dns.conf and build contrail-named-base.conf
parse_contrail_dns_conf()

# open contrail-named-base.conf and read the base configs
file1 = open('/etc/contrail/dns/contrail-named-base.conf', 'r')
file1_lines = file1.readlines()
file1.close()

# open contrail-named.conf and remove configurable stanzas
# options{} key{} controls{} logging {}
count = 0
file2 = open('/etc/contrail/dns/contrail-named.conf', 'r')
lines = file2.readlines()
for i, line in enumerate(lines[:]):
if line.startswith('view'):
break
else:
count = count + 1
file2.close()

# delete all lines before the view stanza {}
del lines[1:count]

# open contrail-named.conf
file3 = open('/etc/contrail/dns/contrail-named.conf', 'w')
file3.truncate()
file3.write("/* Build from contrail-named-base.conf */\n")
file3.writelines(file1_lines)
file3.write("/* Build from contrail-named.conf */\n")
file3.writelines(lines)
file3.close()

# apply config
os.system('/usr/bin/contrail-rndc -c /etc/contrail/dns/contrail-rndc.conf reconfig')
#end main

if __name__ == "__main__":
main()
40 changes: 27 additions & 13 deletions src/dns/bind/named_config.cc
Expand Up @@ -130,25 +130,39 @@ void NamedConfig::DelZone(const Subnet &subnet, const VirtualDnsConfig *vdns) {
void NamedConfig::UpdateNamedConf(const VirtualDnsConfig *updated_vdns) {
CreateNamedConf(updated_vdns);
sync();
// rndc_reconfig();
// TODO: convert this to a call to rndc library
std::stringstream str;
str << "/usr/bin/contrail-rndc -c " << rndc_config_file_ << " -p ";
str << ContrailPorts::DnsRndc();
str << " reconfig";
int res = system(str.str().c_str());
if (res) {
LOG(WARN, "/usr/bin/contrail-rndc command failed");

ifstream pyscript("/etc/contrail/dns/applynamedconfig.py");
if (!pyscript.good()) {
std::stringstream str;
str << "/usr/bin/contrail-rndc -c " << rndc_config_file_ << " -p ";
str << ContrailPorts::DnsRndc();
str << " reconfig";
int res = system(str.str().c_str());
if (res) {
LOG(WARN, "/usr/bin/contrail-rndc command failed");
}
} else {
std::stringstream str;
// execute the helper script to apply named config
str << "python /etc/contrail/dns/applynamedconfig.py";
int res = system(str.str().c_str());
if (res) {
LOG(ERROR, "Applying named configuration failed");
}
}
}

void NamedConfig::CreateNamedConf(const VirtualDnsConfig *updated_vdns) {
GetDefaultForwarders();
file_.open(named_config_file_.c_str());

WriteOptionsConfig();
WriteRndcConfig();
WriteLoggingConfig();

ifstream pyscript("/etc/contrail/dns/applynamedconfig.py");
if (!pyscript.good()) {
WriteOptionsConfig();
WriteRndcConfig();
WriteLoggingConfig();
}

WriteViewConfig(updated_vdns);

file_.flush();
Expand Down

0 comments on commit 0ceda0a

Please sign in to comment.