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.
This commit is contained in:
Daniel Corbett 2019-11-17 09:48:56 -05:00 committed by Willy Tarreau
parent 64a18534e3
commit f8716914c7
4 changed files with 23 additions and 10 deletions

View File

@ -11931,6 +11931,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

View File

@ -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

View File

@ -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) {
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) {
/* 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);
}
}

View File

@ -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,
@ -2451,11 +2452,14 @@ int parse_server(const char *file, int linenum, char **args, struct proxy *curpr
if (!strcmp(p, "allow-dup-ip")) {
newsrv->dns_opts.accept_duplicate_ip = 1;
}
else if (!strcmp(p, "ignore-weight")) {
newsrv->dns_opts.ignore_weight = 1;
}
else if (!strcmp(p, "prevent-dup-ip")) {
newsrv->dns_opts.accept_duplicate_ip = 0;
}
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;