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