]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
MINOR: map: Add payload support to "add map"
authorAurélien Nephtali <aurelien.nephtali@corp.ovh.com>
Wed, 18 Apr 2018 12:04:47 +0000 (14:04 +0200)
committerWilly Tarreau <w@1wt.eu>
Thu, 26 Apr 2018 12:20:01 +0000 (14:20 +0200)
It is now possible to use a payload with the "add map" command.
These syntaxes will work the same way:

 # echo "add map #-1 key value" | socat /tmp/sock1 -

 # echo -e "add map #-1 <<\n$(cat data)\n" | socat /tmp/sock1 -

with

 # cat data
 key1 value1 with spaces
 key2 value2
 key3 value3 also with spaces

Signed-off-by: Aurélien Nephtali <aurelien.nephtali@corp.ovh.com>
doc/management.txt
src/map.c

index bca0fd469db7ef3c3d494af2c9d7182284176116..c0c3f48234f2144b55914daf5cf0ba72fdb6a2f4 100644 (file)
@@ -1331,11 +1331,28 @@ add acl <acl> <pattern>
   In this case, you must use the command "add map" in place of "add acl".
 
 add map <map> <key> <value>
+add map <map> <payload>
   Add an entry into the map <map> to associate the value <value> to the key
   <key>. This command does not verify if the entry already exists. It is
   mainly used to fill a map after a clear operation. Note that if the reference
   <map> is a file and is shared with a map, this map will contain also a new
-  pattern entry.
+  pattern entry. Using the payload syntax it is possible to add multiple
+  key/value pairs by entering them on separate lines. On each new line, the
+  first word is the key and the rest of the line is considered to be the value
+  which can even contains spaces.
+
+  Example:
+
+    # socat /tmp/sock1 -
+    prompt
+
+    > add map #-1 <<
+    + key1 value1
+    + key2 value2 with spaces
+    + key3 value3 also with spaces
+    + key4 value4
+
+    >
 
 clear counters
   Clear the max values of the statistics counters in each proxy (frontend &
index d02a0255c7d6dbaf9b57bc3ee2009ef2a43964e9..ad47c7f233fa570d9ca24fba8a2efb93b92ed720 100644 (file)
--- a/src/map.c
+++ b/src/map.c
@@ -772,6 +772,20 @@ static int cli_parse_set_map(char **args, char *payload, struct appctx *appctx,
        return 1;
 }
 
+static int map_add_key_value(struct appctx *appctx, const char *key, const char *value, char **err)
+{
+       int ret;
+
+       HA_SPIN_LOCK(PATREF_LOCK, &appctx->ctx.map.ref->lock);
+       if (appctx->ctx.map.display_flags == PAT_REF_MAP)
+               ret = pat_ref_add(appctx->ctx.map.ref, key, value, err);
+       else
+               ret = pat_ref_add(appctx->ctx.map.ref, key, NULL, err);
+       HA_SPIN_UNLOCK(PATREF_LOCK, &appctx->ctx.map.ref->lock);
+
+       return ret;
+}
+
 static int cli_parse_add_map(char **args, char *payload, struct appctx *appctx, void *private)
 {
        if (strcmp(args[1], "map") == 0 ||
@@ -785,13 +799,16 @@ static int cli_parse_add_map(char **args, char *payload, struct appctx *appctx,
                else
                        appctx->ctx.map.display_flags = PAT_REF_ACL;
 
-               /* If the keywork is "map", we expect three parameters, if it
-                * is "acl", we expect only two parameters
+               /* If the keyword is "map", we expect:
+                *   - three parameters if there is no payload
+                *   - one parameter if there is a payload
+                * If it is "acl", we expect only two parameters
                 */
                if (appctx->ctx.map.display_flags == PAT_REF_MAP) {
-                       if (!*args[2] || !*args[3] || !*args[4]) {
+                       if ((!payload && (!*args[2] || !*args[3] || !*args[4])) ||
+                           (payload && !*args[2])) {
                                appctx->ctx.cli.severity = LOG_ERR;
-                               appctx->ctx.cli.msg = "'add map' expects three parameters: map identifier, key and value.\n";
+                               appctx->ctx.cli.msg = "'add map' expects three parameters (map identifier, key and value) or one parameter (map identifier) and a payload\n";
                                appctx->st0 = CLI_ST_PRINT;
                                return 1;
                        }
@@ -832,26 +849,69 @@ static int cli_parse_add_map(char **args, char *payload, struct appctx *appctx,
                        return 1;
                }
 
-               /* Add value. */
+               /* Add value(s). */
                err = NULL;
-               HA_SPIN_LOCK(PATREF_LOCK, &appctx->ctx.map.ref->lock);
-               if (appctx->ctx.map.display_flags == PAT_REF_MAP)
-                       ret = pat_ref_add(appctx->ctx.map.ref, args[3], args[4], &err);
-               else
-                       ret = pat_ref_add(appctx->ctx.map.ref, args[3], NULL, &err);
-               HA_SPIN_UNLOCK(PATREF_LOCK, &appctx->ctx.map.ref->lock);
-               if (!ret) {
-                       if (err) {
-                               memprintf(&err, "%s.\n", err);
-                               appctx->ctx.cli.err = err;
-                               appctx->st0 = CLI_ST_PRINT_FREE;
+               if (!payload) {
+                       ret = map_add_key_value(appctx, args[3], args[4], &err);
+                       if (!ret) {
+                               if (err) {
+                                       memprintf(&err, "%s.\n", err);
+                                       appctx->ctx.cli.err = err;
+                                       appctx->st0 = CLI_ST_PRINT_FREE;
+                               }
+                               else {
+                                       appctx->ctx.cli.severity = LOG_ERR;
+                                       appctx->ctx.cli.msg = "Failed to add an entry.\n";
+                                       appctx->st0 = CLI_ST_PRINT;
+                               }
+                               return 1;
                        }
-                       else {
-                               appctx->ctx.cli.severity = LOG_ERR;
-                               appctx->ctx.cli.msg = "Failed to add an entry.\n";
-                               appctx->st0 = CLI_ST_PRINT;
+               }
+               else {
+                       const char *end = payload + strlen(payload);
+
+                       while (payload < end) {
+                               char *key, *value;
+                               size_t l;
+
+                               /* key */
+                               key = payload;
+                               l = strcspn(key, " \t");
+                               payload += l;
+
+                               if (!*payload && appctx->ctx.map.display_flags == PAT_REF_MAP) {
+                                       memprintf(&err, "Missing value for key '%s'.\n", key);
+                                       appctx->ctx.cli.err = err;
+                                       appctx->st0 = CLI_ST_PRINT_FREE;
+                                       return 1;
+                               }
+                               key[l] = 0;
+                               payload++;
+
+                               /* value */
+                               payload += strspn(payload, " \t");
+                               value = payload;
+                               l = strcspn(value, "\n");
+                               payload += l;
+                               if (*payload)
+                                       payload++;
+                               value[l] = 0;
+
+                               ret = map_add_key_value(appctx, key, value, &err);
+                               if (!ret) {
+                                       if (err) {
+                                               memprintf(&err, "%s.\n", err);
+                                               appctx->ctx.cli.err = err;
+                                               appctx->st0 = CLI_ST_PRINT_FREE;
+                                       }
+                                       else {
+                                               appctx->ctx.cli.severity = LOG_ERR;
+                                               appctx->ctx.cli.msg = "Failed to add a key.\n";
+                                               appctx->st0 = CLI_ST_PRINT;
+                                       }
+                                       return 1;
+                               }
                        }
-                       return 1;
                }
 
                /* The add is done, send message. */