From 0ceda0a025d694f69c95f02363311a30dc10c1da Mon Sep 17 00:00:00 2001 From: Nipa Kumar Date: Tue, 16 Aug 2016 17:16:38 -0700 Subject: [PATCH] Support dynamic configuration update of named 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 --- src/dns/SConscript | 2 + src/dns/applynamedconfig.py | 144 +++++++++++++++++++++++++++++++++++ src/dns/bind/named_config.cc | 40 ++++++---- 3 files changed, 173 insertions(+), 13 deletions(-) create mode 100755 src/dns/applynamedconfig.py diff --git a/src/dns/SConscript b/src/dns/SConscript index ecb1966780c..0505fdaaa95 100644 --- a/src/dns/SConscript +++ b/src/dns/SConscript @@ -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')) diff --git a/src/dns/applynamedconfig.py b/src/dns/applynamedconfig.py new file mode 100755 index 00000000000..f2d92c05e8b --- /dev/null +++ b/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() diff --git a/src/dns/bind/named_config.cc b/src/dns/bind/named_config.cc index f241b0b449d..8c0300500c5 100644 --- a/src/dns/bind/named_config.cc +++ b/src/dns/bind/named_config.cc @@ -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();