Hello,

I realize that new features are not preferred at the moment but I think this might be a usability issue and hopefully it can be considered for 2.1-dev, however, it's perfectly fine if it's decided to wait till next.

It was noted in GitHub issue #48 that there are times when a configuration may use the server-template directive with SRV records and simultaneously want to control weights separately using an agent-check or through the runtime api.  This patch adds a new option "ignore-weight" to the "resolve-opts" directive.

When specified, any weight indicated within an SRV record will be ignored.  This is for both initial resolution and ongoing resolution.

I wanted to include  VTC test with this, however, I could not think of an appropriate way to do it as I suspect we may need a "fake dns server" similar to what was made for syslog.


Thanks,

-- Daniel


>From 59381396c68d776d220e76ccc6b80e4a2f7ff068 Mon Sep 17 00:00:00 2001
From: Daniel Corbett <dcorb...@haproxy.com>
Date: Sun, 17 Nov 2019 09:48:56 -0500
Subject: [PATCH] [MEDIUM] dns: Add resolve-opts "ignore-weight"

It was noted in #48 that there are times when a configuration
may use the server-template directive with SRV records and
simultaneously want to control weights using an agent-check or
through the runtime api.  This patch adds a new option
"ignore-weight" to the "resolve-opts" directive.

When specified, any weight indicated within an SRV record will
be ignored.  This is for both initial resolution and ongoing
resolution.
---
 doc/configuration.txt |  5 +++++
 include/types/dns.h   |  1 +
 src/dns.c             | 21 ++++++++++++---------
 src/server.c          |  6 +++++-
 4 files changed, 23 insertions(+), 10 deletions(-)

diff --git a/doc/configuration.txt b/doc/configuration.txt
index b17ab9064..6ce23ece4 100644
--- a/doc/configuration.txt
+++ b/doc/configuration.txt
@@ -11932,6 +11932,11 @@ resolve-opts <option>,<option>,...
     For such case, simply enable this option.
     This is the opposite of prevent-dup-ip.
 
+  * ignore-weight
+    Ignore any weight that is set within an SRV record.  This is useful when
+    you would like to control the weights using an alternate method, such as
+    using an "agent-check" or through the runtime api.
+
   * prevent-dup-ip
     Ensure HAProxy's default behavior is enforced on a server: prevent re-using
     an IP address already set to a server in the same backend and sharing the
diff --git a/include/types/dns.h b/include/types/dns.h
index 5a60c0708..8347e93ab 100644
--- a/include/types/dns.h
+++ b/include/types/dns.h
@@ -249,6 +249,7 @@ struct dns_options {
 	int pref_net_nb; /* The number of registered preferred networks. */
 	int accept_duplicate_ip; /* flag to indicate whether the associated object can use an IP address
 				    already set to an other object of the same group */
+	int ignore_weight; /* flag to indicate whether to ignore the weight within the record */
 };
 
 /* Resolution structure associated to single server and used to manage name
diff --git a/src/dns.c b/src/dns.c
index 5f9e7eae5..9f422eef6 100644
--- a/src/dns.c
+++ b/src/dns.c
@@ -537,7 +537,8 @@ static void dns_check_dns_response(struct dns_resolution *res)
 				HA_SPIN_LOCK(SERVER_LOCK, &srv->lock);
 				if (srv->srvrq == srvrq && srv->svc_port == item->port &&
 				    item->data_len == srv->hostname_dn_len &&
-				    !memcmp(srv->hostname_dn, item->target, item->data_len)) {
+				    !memcmp(srv->hostname_dn, item->target, item->data_len) &&
+				    srv->dns_opts.ignore_weight != 1) {
 					int ha_weight;
 
 					/* DNS weight range if from 0 to 65535
@@ -589,15 +590,17 @@ static void dns_check_dns_response(struct dns_resolution *res)
 				    !(srv->flags & SRV_F_CHECKPORT))
 					srv->check.port = item->port;
 
-				/* DNS weight range if from 0 to 65535
-				 * HAProxy weight is from 0 to 256
-				 * The rule below ensures that weight 0 is well respected
-				 * while allowing a "mapping" from DNS weight into HAProxy's one.
-				 */
-				ha_weight = (item->weight + 255) / 256;
+				if (srv->dns_opts.ignore_weight != 1) {
+					/* DNS weight range if from 0 to 65535
+				 	 * HAProxy weight is from 0 to 256
+				 	 * The rule below ensures that weight 0 is well respected
+				 	 * while allowing a "mapping" from DNS weight into HAProxy's one.
+				 	 */
+					ha_weight = (item->weight + 255) / 256;
 
-				snprintf(weight, sizeof(weight), "%d", ha_weight);
-				server_parse_weight_change_request(srv, weight);
+					snprintf(weight, sizeof(weight), "%d", ha_weight);
+					server_parse_weight_change_request(srv, weight);
+				}
 				HA_SPIN_UNLOCK(SERVER_LOCK, &srv->lock);
 			}
 		}
diff --git a/src/server.c b/src/server.c
index 6b740240e..60c5ee38d 100644
--- a/src/server.c
+++ b/src/server.c
@@ -1796,6 +1796,7 @@ static void srv_settings_cpy(struct server *srv, struct server *src, int srv_tmp
 		srv->resolvers_id = strdup(src->resolvers_id);
 	srv->dns_opts.family_prio = src->dns_opts.family_prio;
 	srv->dns_opts.accept_duplicate_ip = src->dns_opts.accept_duplicate_ip;
+	srv->dns_opts.ignore_weight = src->dns_opts.ignore_weight;
 	if (srv->dns_opts.family_prio == AF_UNSPEC)
 		srv->dns_opts.family_prio = AF_INET6;
 	memcpy(srv->dns_opts.pref_net,
@@ -2454,8 +2455,11 @@ int parse_server(const char *file, int linenum, char **args, struct proxy *curpr
 					else if (!strcmp(p, "prevent-dup-ip")) {
 						newsrv->dns_opts.accept_duplicate_ip = 0;
 					}
+					else if (!strcmp(p, "ignore-weight")) {
+						newsrv->dns_opts.ignore_weight = 1;
+					}
 					else {
-						ha_alert("parsing [%s:%d]: '%s' : unknown resolve-opts option '%s', supported methods are 'allow-dup-ip' and 'prevent-dup-ip'.\n",
+						ha_alert("parsing [%s:%d]: '%s' : unknown resolve-opts option '%s', supported methods are 'allow-dup-ip', 'ignore-weight', and 'prevent-dup-ip'.\n",
 								file, linenum, args[cur_arg], p);
 						err_code |= ERR_ALERT | ERR_FATAL;
 						goto out;
-- 
2.17.1

Reply via email to