You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@trafficcontrol.apache.org by ne...@apache.org on 2021/03/17 18:01:00 UTC

[trafficcontrol] branch master updated: Add ORT dns local bind inference (#5645)

This is an automated email from the ASF dual-hosted git repository.

neuman pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/trafficcontrol.git


The following commit(s) were added to refs/heads/master by this push:
     new eea83b9  Add ORT dns local bind inference (#5645)
eea83b9 is described below

commit eea83b96cb1d5e7bac3c7a7d3b32d5000c25776e
Author: Robert O Butts <ro...@users.noreply.github.com>
AuthorDate: Wed Mar 17 11:59:23 2021 -0600

    Add ORT dns local bind inference (#5645)
---
 CHANGELOG.md                                 |   1 +
 lib/go-atscfg/atscfg_test.go                 |  10 +-
 lib/go-atscfg/recordsdotconfig.go            |  32 +++++++
 lib/go-atscfg/recordsdotconfig_test.go       |  18 +++-
 traffic_ops_ort/atstccfg/cfgfile/wrappers.go |   3 +-
 traffic_ops_ort/atstccfg/config/config.go    | 135 ++++++++++++---------------
 traffic_ops_ort/traffic_ops_ort.pl           |  26 ++++--
 7 files changed, 132 insertions(+), 93 deletions(-)

diff --git a/CHANGELOG.md b/CHANGELOG.md
index 444a766..0adc00f 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -19,6 +19,7 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/).
 - Traffic Ops: Adds API endpoints to fetch (GET), create (POST) or delete (DELETE) a cdn notification. Create and delete are limited to users with operations or admin role.
 - Added ACME certificate renewals and ACME account registration using external account binding
 - Added functionality to automatically renew ACME certificates.
+- Added ORT flag to set local.dns bind address from server service addresses
 - Added an endpoint for statuses on asynchronous jobs and applied it to the ACME renewal endpoint.
 - Traffic Ops API version 4.0
 - `GET` request method for `/deliveryservices/{{ID}}/assign`
diff --git a/lib/go-atscfg/atscfg_test.go b/lib/go-atscfg/atscfg_test.go
index 806bd33..f5cbb6d 100644
--- a/lib/go-atscfg/atscfg_test.go
+++ b/lib/go-atscfg/atscfg_test.go
@@ -119,10 +119,12 @@ func setIP6(sv *Server, ip6Address string) {
 }
 
 func setIPInfo(sv *Server, interfaceName string, ipAddress string, ip6Address string) {
-	sv.Interfaces = []tc.ServerInterfaceInfo{
-		tc.ServerInterfaceInfo{
-			Name: interfaceName,
-		},
+	if len(sv.Interfaces) == 0 {
+		sv.Interfaces = []tc.ServerInterfaceInfo{
+			tc.ServerInterfaceInfo{
+				Name: interfaceName,
+			},
+		}
 	}
 	if ipAddress != "" {
 		sv.Interfaces[0].IPAddresses = append(sv.Interfaces[0].IPAddresses, tc.ServerIPAddress{
diff --git a/lib/go-atscfg/recordsdotconfig.go b/lib/go-atscfg/recordsdotconfig.go
index d662841..a09913d 100644
--- a/lib/go-atscfg/recordsdotconfig.go
+++ b/lib/go-atscfg/recordsdotconfig.go
@@ -37,6 +37,10 @@ type RecordsConfigOpts struct {
 	// defined build hash (or whatever the user wants) type value to give more
 	// specific info as well as obfuscating the real ATS version from prying eyes
 	ReleaseViaStr bool
+
+	// DNSLocalBindServiceAddr is whether to set the server's service addresses
+	// as the records.config proxy.config.dns.local_ipv* settings.
+	DNSLocalBindServiceAddr bool
 }
 
 func MakeRecordsDotConfig(
@@ -85,6 +89,12 @@ func addRecordsDotConfigOverrides(txt string, server *Server, opt RecordsConfigO
 		warnings = append(warnings, viaWarns...)
 	}
 
+	if opt.DNSLocalBindServiceAddr {
+		dnsWarns := []string{}
+		txt, dnsWarns = addRecordsDotConfigDNSLocal(txt, server)
+		warnings = append(warnings, dnsWarns...)
+	}
+
 	return txt, warnings
 }
 
@@ -155,6 +165,28 @@ func addRecordsDotConfigViaStr(txt string) (string, []string) {
 	return txt, warnings
 }
 
+func addRecordsDotConfigDNSLocal(txt string, server *Server) (string, []string) {
+	warnings := []string{}
+
+	const dnsLocalV4 = `proxy.config.dns.local_ipv4`
+	const dnsLocalV6 = `proxy.config.dns.local_ipv6`
+
+	v4, v6 := getServiceAddresses(server)
+	if v4 == nil {
+		warnings = append(warnings, "server had no IPv4 Service Address, not setting records.config dns v4 local bind addr!")
+	} else {
+		txt += `CONFIG ` + dnsLocalV4 + ` STRING ` + v4.String() + "\n"
+	}
+
+	if v6 == nil {
+		warnings = append(warnings, "server had no IPv6 Service Address, not setting records.config dns v6 local bind addr!")
+	} else {
+		txt += `CONFIG ` + dnsLocalV6 + ` STRING [` + v6.String() + `]` + "\n"
+	}
+
+	return txt, warnings
+}
+
 func replaceLineSuffixes(txt string, suffix string, newSuffix string) string {
 	lines := strings.Split(txt, "\n")
 	newLines := make([]string, 0, len(lines))
diff --git a/lib/go-atscfg/recordsdotconfig_test.go b/lib/go-atscfg/recordsdotconfig_test.go
index e4649a9..cd19c44 100644
--- a/lib/go-atscfg/recordsdotconfig_test.go
+++ b/lib/go-atscfg/recordsdotconfig_test.go
@@ -38,10 +38,16 @@ func TestMakeRecordsDotConfig(t *testing.T) {
 	})
 
 	server := makeTestRemapServer()
-	ipStr := "192.168.2.99"
-	setIP(server, ipStr)
+	server.Interfaces = nil
+	ipStr := "192.163.2.99"
+	ipCIDR := ipStr + "/30" // set the ip to a cidr, to make sure addr logic removes it
+	setIP(server, ipCIDR)
+	ip6Str := "2001:db8::9"
+	ip6CIDR := ip6Str + "/48" // set the ip to a cidr, to make sure addr logic removes it
+	setIP6(server, ip6CIDR)
 	server.Profile = util.StrPtr(profileName)
 	opt := RecordsConfigOpts{}
+	opt.DNSLocalBindServiceAddr = true
 	cfg, err := MakeRecordsDotConfig(server, paramData, hdr, opt)
 	if err != nil {
 		t.Fatal(err)
@@ -63,7 +69,13 @@ func TestMakeRecordsDotConfig(t *testing.T) {
 		t.Errorf("expected config to replace 'STRING __HOSTNAME__' with 'STRING __FULL_HOSTNAME__', actual: '%v'", txt)
 	}
 	if !strings.Contains(txt, "LOCAL proxy.local.outgoing_ip_to_bind STRING "+ipStr) {
-		t.Errorf("expected config to contain outgoing_ip_to_bind from server, actual: '%v'", txt)
+		t.Errorf("expected config to contain outgoing_ip_to_bind from server, actual: '%v' warnings '%+v'", txt, cfg.Warnings)
+	}
+	if !strings.Contains(txt, "CONFIG proxy.config.dns.local_ipv4 STRING "+ipStr) {
+		t.Errorf("expected config to contain dns.local_ipv4 from server, actual: '%v'", txt)
+	}
+	if !strings.Contains(txt, "CONFIG proxy.config.dns.local_ipv6 STRING ["+ip6Str+"]") {
+		t.Errorf("expected config to contain dns.local_ipv6 from server, actual: '%v'", txt)
 	}
 }
 
diff --git a/traffic_ops_ort/atstccfg/cfgfile/wrappers.go b/traffic_ops_ort/atstccfg/cfgfile/wrappers.go
index 2884dfb..4ea5314 100644
--- a/traffic_ops_ort/atstccfg/cfgfile/wrappers.go
+++ b/traffic_ops_ort/atstccfg/cfgfile/wrappers.go
@@ -147,7 +147,8 @@ func MakeRecordsDotConfig(toData *config.TOData, fileName string, hdrCommentTxt
 		toData.ServerParams,
 		hdrCommentTxt,
 		atscfg.RecordsConfigOpts{
-			ReleaseViaStr: cfg.ViaRelease,
+			ReleaseViaStr:           cfg.ViaRelease,
+			DNSLocalBindServiceAddr: cfg.SetDNSLocalBind,
 		},
 	)
 }
diff --git a/traffic_ops_ort/atstccfg/config/config.go b/traffic_ops_ort/atstccfg/config/config.go
index baa434c..5db78c3 100644
--- a/traffic_ops_ort/atstccfg/config/config.go
+++ b/traffic_ops_ort/atstccfg/config/config.go
@@ -66,6 +66,7 @@ type Cfg struct {
 	TOUser          string
 	Dir             string
 	ViaRelease      bool
+	SetDNSLocalBind bool
 	ParentComments  bool
 }
 
@@ -82,120 +83,102 @@ func (cfg Cfg) EventLog() log.LogLocation   { return log.LogLocation(log.LogLoca
 
 // GetCfg gets the application configuration, from arguments and environment variables.
 func GetCfg() (Cfg, error) {
-	toURLPtr := flag.StringP("traffic-ops-url", "u", "", "Traffic Ops URL. Must be the full URL, including the scheme. Required. May also be set with the environment variable TO_URL.")
-	toUserPtr := flag.StringP("traffic-ops-user", "U", "", "Traffic Ops username. Required. May also be set with the environment variable TO_USER.")
-	toPassPtr := flag.StringP("traffic-ops-password", "P", "", "Traffic Ops password. Required. May also be set with the environment variable TO_PASS.")
-	numRetriesPtr := flag.IntP("num-retries", "r", 5, "The number of times to retry getting a file if it fails.")
-	logLocationErrPtr := flag.StringP("log-location-error", "e", "stderr", "Where to log errors. May be a file path, stdout, stderr, or null.")
-	logLocationWarnPtr := flag.StringP("log-location-warning", "w", "stderr", "Where to log warnings. May be a file path, stdout, stderr, or null.")
-	logLocationInfoPtr := flag.StringP("log-location-info", "i", "stderr", "Where to log information messages. May be a file path, stdout, stderr, or null.")
-	toInsecurePtr := flag.BoolP("traffic-ops-insecure", "s", false, "Whether to ignore HTTPS certificate errors from Traffic Ops. It is HIGHLY RECOMMENDED to never use this in a production environment, but only for debugging.")
-	toTimeoutMSPtr := flag.IntP("traffic-ops-timeout-milliseconds", "t", 30000, "Timeout in milliseconds for Traffic Ops requests.")
-	versionPtr := flag.BoolP("version", "v", false, "Print version information and exit.")
-	listPluginsPtr := flag.BoolP("list-plugins", "l", false, "Print the list of plugins.")
-	helpPtr := flag.BoolP("help", "h", false, "Print usage information and exit")
-	cacheHostNamePtr := flag.StringP("cache-host-name", "n", "", "Host name of the cache to generate config for. Must be the server host name in Traffic Ops, not a URL, and not the FQDN")
-	getDataPtr := flag.StringP("get-data", "d", "", "non-config-file Traffic Ops Data to get. Valid values are update-status, packages, chkconfig, system-info, and statuses")
-	setQueueStatusPtr := flag.StringP("set-queue-status", "q", "", "POSTs to Traffic Ops setting the queue status of the server. Must be 'true' or 'false'. Requires --set-reval-status also be set")
-	setRevalStatusPtr := flag.StringP("set-reval-status", "a", "", "POSTs to Traffic Ops setting the revalidate status of the server. Must be 'true' or 'false'. Requires --set-queue-status also be set")
-	revalOnlyPtr := flag.BoolP("revalidate-only", "y", false, "Whether to exclude files not named 'regex_revalidate.config'")
-	disableProxyPtr := flag.BoolP("traffic-ops-disable-proxy", "p", false, "Whether to not use the Traffic Ops proxy specified in the GLOBAL Parameter tm.rev_proxy.url")
-	dirPtr := flag.StringP("dir", "D", "", "ATS config directory, used for config files without location parameters or with relative paths. May be blank. If blank and any required config file location parameter is missing or relative, will error.")
-	viaReleasePtr := flag.BoolP("via-string-release", "", false, "Whether to use the Release value from the RPM package as a replacement for the ATS version specified in the build that is returned in the Via and Server headers from ATS.")
+	toURL := flag.StringP("traffic-ops-url", "u", "", "Traffic Ops URL. Must be the full URL, including the scheme. Required. May also be set with the environment variable TO_URL.")
+	toUser := flag.StringP("traffic-ops-user", "U", "", "Traffic Ops username. Required. May also be set with the environment variable TO_USER.")
+	toPass := flag.StringP("traffic-ops-password", "P", "", "Traffic Ops password. Required. May also be set with the environment variable TO_PASS.")
+	numRetries := flag.IntP("num-retries", "r", 5, "The number of times to retry getting a file if it fails.")
+	logLocationErr := flag.StringP("log-location-error", "e", "stderr", "Where to log errors. May be a file path, stdout, stderr, or null.")
+	logLocationWarn := flag.StringP("log-location-warning", "w", "stderr", "Where to log warnings. May be a file path, stdout, stderr, or null.")
+	logLocationInfo := flag.StringP("log-location-info", "i", "stderr", "Where to log information messages. May be a file path, stdout, stderr, or null.")
+	toInsecure := flag.BoolP("traffic-ops-insecure", "s", false, "Whether to ignore HTTPS certificate errors from Traffic Ops. It is HIGHLY RECOMMENDED to never use this in a production environment, but only for debugging.")
+	toTimeoutMS := flag.IntP("traffic-ops-timeout-milliseconds", "t", 30000, "Timeout in milliseconds for Traffic Ops requests.")
+	version := flag.BoolP("version", "v", false, "Print version information and exit.")
+	listPlugins := flag.BoolP("list-plugins", "l", false, "Print the list of plugins.")
+	help := flag.BoolP("help", "h", false, "Print usage information and exit")
+	cacheHostName := flag.StringP("cache-host-name", "n", "", "Host name of the cache to generate config for. Must be the server host name in Traffic Ops, not a URL, and not the FQDN")
+	getData := flag.StringP("get-data", "d", "", "non-config-file Traffic Ops Data to get. Valid values are update-status, packages, chkconfig, system-info, and statuses")
+	setQueueStatus := flag.StringP("set-queue-status", "q", "", "POSTs to Traffic Ops setting the queue status of the server. Must be 'true' or 'false'. Requires --set-reval-status also be set")
+	setRevalStatus := flag.StringP("set-reval-status", "a", "", "POSTs to Traffic Ops setting the revalidate status of the server. Must be 'true' or 'false'. Requires --set-queue-status also be set")
+	revalOnly := flag.BoolP("revalidate-only", "y", false, "Whether to exclude files not named 'regex_revalidate.config'")
+	disableProxy := flag.BoolP("traffic-ops-disable-proxy", "p", false, "Whether to not use the Traffic Ops proxy specified in the GLOBAL Parameter tm.rev_proxy.url")
+	dir := flag.StringP("dir", "D", "", "ATS config directory, used for config files without location parameters or with relative paths. May be blank. If blank and any required config file location parameter is missing or relative, will error.")
+	viaRelease := flag.BoolP("via-string-release", "", false, "Whether to use the Release value from the RPM package as a replacement for the ATS version specified in the build that is returned in the Via and Server headers from ATS.")
+	dnsLocalBind := flag.BoolP("dns-local-bind", "", false, "Whether to use the server's Service Addresses to set the ATS DNS local bind address.")
 	disableParentConfigComments := flag.BoolP("disable-parent-config-comments", "", false, "Disable adding a comments to parent.config individual lines")
 
 	flag.Parse()
 
-	if *versionPtr {
+	if *version {
 		fmt.Println(AppName + " v" + Version)
 		os.Exit(0)
-	} else if *helpPtr {
+	} else if *help {
 		flag.PrintDefaults()
 		os.Exit(0)
-	} else if *listPluginsPtr {
+	} else if *listPlugins {
 		return Cfg{ListPlugins: true}, nil
 	}
 
-	toURL := *toURLPtr
-	toUser := *toUserPtr
-	toPass := *toPassPtr
-	numRetries := *numRetriesPtr
-	logLocationErr := *logLocationErrPtr
-	logLocationWarn := *logLocationWarnPtr
-	logLocationInfo := *logLocationInfoPtr
-	toInsecure := *toInsecurePtr
-	toTimeout := time.Millisecond * time.Duration(*toTimeoutMSPtr)
-	listPlugins := *listPluginsPtr
-	cacheHostName := *cacheHostNamePtr
-	getData := *getDataPtr
-	setQueueStatus := *setQueueStatusPtr
-	setRevalStatus := *setRevalStatusPtr
-	revalOnly := *revalOnlyPtr
-	disableProxy := *disableProxyPtr
-	dir := *dirPtr
-	viaRelease := *viaReleasePtr
-	parentComments := !(*disableParentConfigComments) //we use this as a boolean value so reverse it here to not have negative logic
-
 	urlSourceStr := "argument" // for error messages
-	if toURL == "" {
+	if *toURL == "" {
 		urlSourceStr = "environment variable"
-		toURL = os.Getenv("TO_URL")
+		*toURL = os.Getenv("TO_URL")
 	}
-	if toUser == "" {
-		toUser = os.Getenv("TO_USER")
+	if *toUser == "" {
+		*toUser = os.Getenv("TO_USER")
 	}
 
 	// TO_PASSWORD is preferred over TO_PASS, as it's the one commonly used by
 	// Traffic Control tools. Hopefully, we'll be able to get rid of TO_PASS
 	// entirely in the near future, to make this less confusing.
-	if toPass == "" {
-		toPass = os.Getenv("TO_PASS")
+	if *toPass == "" {
+		*toPass = os.Getenv("TO_PASS")
 	}
-	if toPass == "" {
-		toPass = os.Getenv("TO_PASSWORD")
+	if *toPass == "" {
+		*toPass = os.Getenv("TO_PASSWORD")
 	}
 
 	usageStr := "Usage: ./" + AppName + " --traffic-ops-url=myurl --traffic-ops-user=myuser --traffic-ops-password=mypass --cache-host-name=my-cache"
-	if strings.TrimSpace(toURL) == "" {
+	if strings.TrimSpace(*toURL) == "" {
 		return Cfg{}, errors.New("Missing required argument --traffic-ops-url or TO_URL environment variable. " + usageStr)
 	}
-	if strings.TrimSpace(toUser) == "" {
+	if strings.TrimSpace(*toUser) == "" {
 		return Cfg{}, errors.New("Missing required argument --traffic-ops-user or TO_USER environment variable. " + usageStr)
 	}
-	if strings.TrimSpace(toPass) == "" {
+	if strings.TrimSpace(*toPass) == "" {
 		return Cfg{}, errors.New("Missing required argument --traffic-ops-password or TO_PASS environment variable. " + usageStr)
 	}
-	if strings.TrimSpace(cacheHostName) == "" {
+	if strings.TrimSpace(*cacheHostName) == "" {
 		return Cfg{}, errors.New("Missing required argument --cache-host-name. " + usageStr)
 	}
 
-	toURLParsed, err := url.Parse(toURL)
+	toURLParsed, err := url.Parse(*toURL)
 	if err != nil {
-		return Cfg{}, errors.New("parsing Traffic Ops URL from " + urlSourceStr + " '" + toURL + "': " + err.Error())
+		return Cfg{}, errors.New("parsing Traffic Ops URL from " + urlSourceStr + " '" + *toURL + "': " + err.Error())
 	} else if err := ValidateURL(toURLParsed); err != nil {
-		return Cfg{}, errors.New("invalid Traffic Ops URL from " + urlSourceStr + " '" + toURL + "': " + err.Error())
+		return Cfg{}, errors.New("invalid Traffic Ops URL from " + urlSourceStr + " '" + *toURL + "': " + err.Error())
 	}
 
 	cfg := Cfg{
-		LogLocationErr:  logLocationErr,
-		LogLocationWarn: logLocationWarn,
-		LogLocationInfo: logLocationInfo,
-		NumRetries:      numRetries,
-		TOInsecure:      toInsecure,
-		TOPass:          toPass,
-		TOTimeout:       toTimeout,
+		LogLocationErr:  *logLocationErr,
+		LogLocationWarn: *logLocationWarn,
+		LogLocationInfo: *logLocationInfo,
+		NumRetries:      *numRetries,
+		TOInsecure:      *toInsecure,
+		TOPass:          *toPass,
+		TOTimeout:       time.Millisecond * time.Duration(*toTimeoutMS),
 		TOURL:           toURLParsed,
-		TOUser:          toUser,
-		ListPlugins:     listPlugins,
-		CacheHostName:   cacheHostName,
-		GetData:         getData,
-		SetRevalStatus:  setRevalStatus,
-		SetQueueStatus:  setQueueStatus,
-		RevalOnly:       revalOnly,
-		DisableProxy:    disableProxy,
-		Dir:             dir,
-		ViaRelease:      viaRelease,
-		ParentComments:  parentComments,
+		TOUser:          *toUser,
+		ListPlugins:     *listPlugins,
+		CacheHostName:   *cacheHostName,
+		GetData:         *getData,
+		SetRevalStatus:  *setRevalStatus,
+		SetQueueStatus:  *setQueueStatus,
+		RevalOnly:       *revalOnly,
+		DisableProxy:    *disableProxy,
+		Dir:             *dir,
+		ViaRelease:      *viaRelease,
+		SetDNSLocalBind: *dnsLocalBind,
+		ParentComments:  !(*disableParentConfigComments),
 	}
 	if err := log.InitCfg(cfg); err != nil {
 		return Cfg{}, errors.New("Initializing loggers: " + err.Error() + "\n")
diff --git a/traffic_ops_ort/traffic_ops_ort.pl b/traffic_ops_ort/traffic_ops_ort.pl
index 72dfeb5..d1ed816 100755
--- a/traffic_ops_ort/traffic_ops_ort.pl
+++ b/traffic_ops_ort/traffic_ops_ort.pl
@@ -45,6 +45,7 @@ my $to_timeout_ms = 30000;
 my $syncds_updates_ipallow = 0;
 my $traffic_ops_insecure = 0;
 my $via_string_release = 0;
+my $dns_local_bind = 0;
 my $disable_parent_config_comments = 0;
 
 GetOptions( "dispersion=i"       => \$dispersion, # dispersion (in seconds)
@@ -58,6 +59,7 @@ GetOptions( "dispersion=i"       => \$dispersion, # dispersion (in seconds)
             "syncds_updates_ipallow=i" => \$syncds_updates_ipallow,
             "traffic_ops_insecure=i" => \$traffic_ops_insecure,
             "via_string_release=i" => \$via_string_release,
+            "dns_local_bind=i" => \$dns_local_bind,
             "disable_parent_config_comments=i" => \$disable_parent_config_comments,
           );
 
@@ -182,6 +184,11 @@ if ($via_string_release == 1) {
 	$atstccfg_via_string_release = "--via-string-release";
 }
 
+my $atstccfg_dns_local_bind = "";
+if ($dns_local_bind == 1) {
+	$atstccfg_dns_local_bind = "--dns-local-bind";
+}
+
 my $atstccfg_parent_config_comments = "";
 if ($disable_parent_config_comments == 1) {
 	$atstccfg_parent_config_comments = "--disable-parent-config-comments";
@@ -368,6 +375,7 @@ sub usage {
 	print "\t   syncds_updates_ipallow=<0|1>   => Update ip_allow.config in syncds mode, which may trigger an ATS bug blocking random addresses on load! Default = 0, only update on badass and restart.\n";
 	print "\t   traffic_ops_insecure=<0|1>     => Turns off certificate checking when connecting to Traffic Ops.\n";
 	print "\t   via_string_release=<0|1>       => change the ATS via string to be the rpm release instead of the actual ATS version number\n";
+	print "\t   dns_local_bind=<0|1>           => set the server service addresses to the ATS config dns local bind address\n";
 	print "\t   disable_parent_config_comments=<0|1>     => do not write line comments to the parent.config file\n";
 	print "====-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-====\n";
 	exit 1;
@@ -808,7 +816,7 @@ sub send_update_to_trops {
 		$reval_str='true';
 	}
 
-	my $response = `$atstccfg_cmd $atstccfg_insecure_arg $atstccfg_via_string_release $atstccfg_parent_config_comments $atstccfg_timeout_arg $atstccfg_arg_disable_proxy --traffic-ops-user='$TO_USER' --traffic-ops-password='$TO_PASS' --traffic-ops-url='$TO_URL' --cache-host-name='$hostname_short' --log-location-error=stderr --log-location-warning=stderr --log-location-info=null --set-queue-status=$upd_str --set-reval-status=$reval_str 2>>$atstccfg_log_path`;
+	my $response = `$atstccfg_cmd $atstccfg_insecure_arg $atstccfg_via_string_release $atstccfg_dns_local_bind $atstccfg_parent_config_comments $atstccfg_timeout_arg $atstccfg_arg_disable_proxy --traffic-ops-user='$TO_USER' --traffic-ops-password='$TO_PASS' --traffic-ops-url='$TO_URL' --cache-host-name='$hostname_short' --log-location-error=stderr --log-location-warning=stderr --log-location-info=null --set-queue-status=$upd_str --set-reval-status=$reval_str 2>>$atstccfg_log_path`;
 	my $atstccfg_exit_code = $?;
 	if ($atstccfg_exit_code != 0) {
 		( $log_level >> $ERROR ) && printf("ERROR sending update status with atstccfg (via Traffic Ops). See $atstccfg_log_path.\n");
@@ -818,7 +826,7 @@ sub send_update_to_trops {
 }
 
 sub get_update_status {
-	my $upd_ref = `$atstccfg_cmd $atstccfg_insecure_arg $atstccfg_via_string_release $atstccfg_parent_config_comments $atstccfg_timeout_arg $atstccfg_arg_disable_proxy --traffic-ops-user='$TO_USER' --traffic-ops-password='$TO_PASS' --traffic-ops-url='$TO_URL' --cache-host-name='$hostname_short' --log-location-error=stderr --log-location-warning=stderr --log-location-info=null --get-data=update-status 2>>$atstccfg_log_path`;
+	my $upd_ref = `$atstccfg_cmd $atstccfg_insecure_arg $atstccfg_via_string_release $atstccfg_dns_local_bind $atstccfg_parent_config_comments $atstccfg_timeout_arg $atstccfg_arg_disable_proxy --traffic-ops-user='$TO_USER' --traffic-ops-password='$TO_PASS' --traffic-ops-url='$TO_URL' --cache-host-name='$hostname_short' --log-location-error=stderr --log-location-warning=stderr --log-location-info=null --get-data=update-status 2>>$atstccfg_log_path`;
 	my $atstccfg_exit_code = $?;
 	if ($atstccfg_exit_code != 0) {
 		( $log_level >> $ERROR ) && printf("ERROR getting update status from atstccfg (via Traffic Ops). See $atstccfg_log_path.\n");
@@ -829,7 +837,7 @@ sub get_update_status {
 
 	##Some versions of Traffic Ops had the 1.3 API but did not have the use_reval_pending field.  If this field is not present, exit.
 	if ( !defined( $upd_json->{'use_reval_pending'} ) ) {
-		my $info_ref = `$atstccfg_cmd $atstccfg_insecure_arg $atstccfg_via_string_release $atstccfg_parent_config_comments $atstccfg_timeout_arg $atstccfg_arg_disable_proxy --traffic-ops-user='$TO_USER' --traffic-ops-password='$TO_PASS' --traffic-ops-url='$TO_URL' --cache-host-name='$hostname_short' --log-location-error=stderr --log-location-warning=stderr --log-location-info=null --get-data=system-info 2>>$atstccfg_log_path`;
+		my $info_ref = `$atstccfg_cmd $atstccfg_insecure_arg $atstccfg_via_string_release $atstccfg_dns_local_bind $atstccfg_parent_config_comments $atstccfg_timeout_arg $atstccfg_arg_disable_proxy --traffic-ops-user='$TO_USER' --traffic-ops-password='$TO_PASS' --traffic-ops-url='$TO_URL' --cache-host-name='$hostname_short' --log-location-error=stderr --log-location-warning=stderr --log-location-info=null --get-data=system-info 2>>$atstccfg_log_path`;
 		my $atstccfg_exit_code = $?;
 		if ($atstccfg_exit_code != 0) {
 			( $log_level >> $ERROR ) && printf("ERROR Unable to get status of use_reval_pending parameter.  Stopping.\n");
@@ -884,7 +892,7 @@ sub check_revalidate_state {
 			( $log_level >> $ERROR ) && print "ERROR Traffic Ops is signaling that no revalidations are waiting to be applied.\n";
 		}
 
-		my $stj = `$atstccfg_cmd $atstccfg_insecure_arg $atstccfg_via_string_release $atstccfg_parent_config_comments $atstccfg_timeout_arg $atstccfg_arg_disable_proxy --traffic-ops-user='$TO_USER' --traffic-ops-password='$TO_PASS' --traffic-ops-url='$TO_URL' --cache-host-name='$hostname_short' --log-location-error=stderr --log-location-warning=stderr --log-location-info=null --get-data=statuses 2>>$atstccfg_log_path`;
+		my $stj = `$atstccfg_cmd $atstccfg_insecure_arg $atstccfg_via_string_release $atstccfg_dns_local_bind $atstccfg_parent_config_comments $atstccfg_timeout_arg $atstccfg_arg_disable_proxy --traffic-ops-user='$TO_USER' --traffic-ops-password='$TO_PASS' --traffic-ops-url='$TO_URL' --cache-host-name='$hostname_short' --log-location-error=stderr --log-location-warning=stderr --log-location-info=null --get-data=statuses 2>>$atstccfg_log_path`;
 		my $atstccfg_exit_code = $?;
 		if ( $atstccfg_exit_code != 0 ) {
 			( $log_level >> $ERROR ) && print "Statuses URL: returned $stj! Skipping creation of status file.\n";
@@ -1003,7 +1011,7 @@ sub check_syncds_state {
 			( $log_level >> $ERROR ) && print "ERROR Traffic Ops is signaling that no update is waiting to be applied.\n";
 		}
 
-		my $stj = `$atstccfg_cmd $atstccfg_insecure_arg $atstccfg_via_string_release $atstccfg_parent_config_comments $atstccfg_timeout_arg $atstccfg_arg_disable_proxy --traffic-ops-user='$TO_USER' --traffic-ops-password='$TO_PASS' --traffic-ops-url='$TO_URL' --cache-host-name='$hostname_short' --log-location-error=stderr --log-location-warning=stderr --log-location-info=null --get-data=statuses 2>>$atstccfg_log_path`;
+		my $stj = `$atstccfg_cmd $atstccfg_insecure_arg $atstccfg_via_string_release $atstccfg_dns_local_bind $atstccfg_parent_config_comments $atstccfg_timeout_arg $atstccfg_arg_disable_proxy --traffic-ops-user='$TO_USER' --traffic-ops-password='$TO_PASS' --traffic-ops-url='$TO_URL' --cache-host-name='$hostname_short' --log-location-error=stderr --log-location-warning=stderr --log-location-info=null --get-data=statuses 2>>$atstccfg_log_path`;
 		my $atstccfg_exit_code = $?;
 		if ( $atstccfg_exit_code != 0 ) {
 			( $log_level >> $ERROR ) && print "Statuses URL: returned $stj! Skipping creation of status file.\n";
@@ -1561,7 +1569,7 @@ sub get_cfg_file_list {
 		$atstccfg_reval_arg = '--revalidate-only';
 	}
 
-	my $result = `$atstccfg_cmd --dir='$ats_config_dir' $atstccfg_insecure_arg $atstccfg_via_string_release $atstccfg_parent_config_comments $atstccfg_timeout_arg $atstccfg_arg_disable_proxy --traffic-ops-user='$TO_USER' --traffic-ops-password='$TO_PASS' --traffic-ops-url='$TO_URL' --cache-host-name='$host_name' $atstccfg_reval_arg --log-location-error=stderr --log-location-warning=stderr --log-location-info=null 2>>$atstccfg_log_path`;
+	my $result = `$atstccfg_cmd --dir='$ats_config_dir' $atstccfg_insecure_arg $atstccfg_via_string_release $atstccfg_dns_local_bind $atstccfg_parent_config_comments $atstccfg_timeout_arg $atstccfg_arg_disable_proxy --traffic-ops-user='$TO_USER' --traffic-ops-password='$TO_PASS' --traffic-ops-url='$TO_URL' --cache-host-name='$host_name' $atstccfg_reval_arg --log-location-error=stderr --log-location-warning=stderr --log-location-info=null 2>>$atstccfg_log_path`;
 	my $atstccfg_exit_code = $?;
 	if ($atstccfg_exit_code != 0) {
 		( $log_level >> $ERROR ) && printf("ERROR getting config files from atstccfg via Traffic Ops. See $atstccfg_log_path for details\n");
@@ -1637,7 +1645,7 @@ sub parse_multipart_config_files {
 sub get_header_comment {
 	my $toolname;
 
-	my $result = `$atstccfg_cmd $atstccfg_insecure_arg $atstccfg_via_string_release $atstccfg_parent_config_comments $atstccfg_timeout_arg $atstccfg_arg_disable_proxy --traffic-ops-user='$TO_USER' --traffic-ops-password='$TO_PASS' --traffic-ops-url='$TO_URL' --cache-host-name='$hostname_short' --log-location-error=stderr --log-location-warning=stderr --log-location-info=null --get-data=system-info 2>>$atstccfg_log_path`;
+	my $result = `$atstccfg_cmd $atstccfg_insecure_arg $atstccfg_via_string_release $atstccfg_dns_local_bind $atstccfg_parent_config_comments $atstccfg_timeout_arg $atstccfg_arg_disable_proxy --traffic-ops-user='$TO_USER' --traffic-ops-password='$TO_PASS' --traffic-ops-url='$TO_URL' --cache-host-name='$hostname_short' --log-location-error=stderr --log-location-warning=stderr --log-location-info=null --get-data=system-info 2>>$atstccfg_log_path`;
 	my $atstccfg_exit_code = $?;
 	if ($atstccfg_exit_code != 0) {
 			( $log_level >> $ERROR ) && printf("ERROR Unable to get system info. Stopping.\n");
@@ -1812,7 +1820,7 @@ sub process_packages {
 
 	my $proceed = 0;
 
-	my $result = `$atstccfg_cmd $atstccfg_insecure_arg $atstccfg_via_string_release $atstccfg_parent_config_comments $atstccfg_timeout_arg $atstccfg_arg_disable_proxy --traffic-ops-user='$TO_USER' --traffic-ops-password='$TO_PASS' --traffic-ops-url='$TO_URL' --cache-host-name='$hostname_short' --log-location-error=stderr --log-location-warning=stderr --log-location-info=null --get-data=packages 2>>$atstccfg_log_path`;
+	my $result = `$atstccfg_cmd $atstccfg_insecure_arg $atstccfg_via_string_release $atstccfg_dns_local_bind $atstccfg_parent_config_comments $atstccfg_timeout_arg $atstccfg_arg_disable_proxy --traffic-ops-user='$TO_USER' --traffic-ops-password='$TO_PASS' --traffic-ops-url='$TO_URL' --cache-host-name='$hostname_short' --log-location-error=stderr --log-location-warning=stderr --log-location-info=null --get-data=packages 2>>$atstccfg_log_path`;
 	my $atstccfg_exit_code = $?;
 	if ($atstccfg_exit_code != 0) {
 		( $log_level >> $FATAL ) && print "FATAL Error getting package list from Traffic Ops!\n";
@@ -2058,7 +2066,7 @@ sub process_chkconfig {
 
 	my $proceed = 0;
 
-	my $result = `$atstccfg_cmd $atstccfg_insecure_arg $atstccfg_via_string_release $atstccfg_parent_config_comments $atstccfg_timeout_arg $atstccfg_arg_disable_proxy --traffic-ops-user='$TO_USER' --traffic-ops-password='$TO_PASS' --traffic-ops-url='$TO_URL' --cache-host-name='$hostname_short' --log-location-error=stderr --log-location-warning=stderr --log-location-info=null --get-data=chkconfig 2>>$atstccfg_log_path`;
+	my $result = `$atstccfg_cmd $atstccfg_insecure_arg $atstccfg_via_string_release $atstccfg_dns_local_bind $atstccfg_parent_config_comments $atstccfg_timeout_arg $atstccfg_arg_disable_proxy --traffic-ops-user='$TO_USER' --traffic-ops-password='$TO_PASS' --traffic-ops-url='$TO_URL' --cache-host-name='$hostname_short' --log-location-error=stderr --log-location-warning=stderr --log-location-info=null --get-data=chkconfig 2>>$atstccfg_log_path`;
 
 	my $atstccfg_exit_code = $?;
 	if ($atstccfg_exit_code != 0) {