Unverified Commit 639b73cd authored by Wen Hui's avatar Wen Hui Committed by GitHub
Browse files

redis-cli cluster import support source and target that need auth (#7994)

Make it possible for redis-cli cluster import to work with source and
target that require AUTH.

Adding two different flags --cluster-from-user, --cluster-from-pass
and --cluster-askpass for source node authentication.
Also for target authentication, using existing --user and --pass flag.

Example:

./redis-cli --cluster import 127.0.0.1:7000 --cluster-from 127.0.0.1:6379 --pass 1234 --user default --cluster-from-user default --cluster-from-pass 123456

./redis-cli --cluster import 127.0.0.1:7000 --cluster-from 127.0.0.1:6379 --askpass --cluster-from-user default --cluster-from-askpass
parent a698a639
...@@ -189,6 +189,9 @@ typedef struct clusterManagerCommand { ...@@ -189,6 +189,9 @@ typedef struct clusterManagerCommand {
int pipeline; int pipeline;
float threshold; float threshold;
char *backup_dir; char *backup_dir;
char *from_user;
char *from_pass;
int from_askpass;
} clusterManagerCommand; } clusterManagerCommand;
static void createClusterManagerCommand(char *cmdname, int argc, char **argv); static void createClusterManagerCommand(char *cmdname, int argc, char **argv);
...@@ -753,14 +756,14 @@ static void freeHintsCallback(void *ptr) { ...@@ -753,14 +756,14 @@ static void freeHintsCallback(void *ptr) {
*--------------------------------------------------------------------------- */ *--------------------------------------------------------------------------- */
/* Send AUTH command to the server */ /* Send AUTH command to the server */
static int cliAuth(void) { static int cliAuth(redisContext *ctx, char *user, char *auth) {
redisReply *reply; redisReply *reply;
if (config.auth == NULL) return REDIS_OK; if (auth == NULL) return REDIS_OK;
if (config.user == NULL) if (user == NULL)
reply = redisCommand(context,"AUTH %s",config.auth); reply = redisCommand(ctx,"AUTH %s",auth);
else else
reply = redisCommand(context,"AUTH %s %s",config.user,config.auth); reply = redisCommand(ctx,"AUTH %s %s",user,auth);
if (reply != NULL) { if (reply != NULL) {
if (reply->type == REDIS_REPLY_ERROR) if (reply->type == REDIS_REPLY_ERROR)
fprintf(stderr,"Warning: AUTH failed\n"); fprintf(stderr,"Warning: AUTH failed\n");
...@@ -849,7 +852,7 @@ static int cliConnect(int flags) { ...@@ -849,7 +852,7 @@ static int cliConnect(int flags) {
anetKeepAlive(NULL, context->fd, REDIS_CLI_KEEPALIVE_INTERVAL); anetKeepAlive(NULL, context->fd, REDIS_CLI_KEEPALIVE_INTERVAL);
/* Do AUTH, select the right DB, switch to RESP3 if needed. */ /* Do AUTH, select the right DB, switch to RESP3 if needed. */
if (cliAuth() != REDIS_OK) if (cliAuth(context, config.user, config.auth) != REDIS_OK)
return REDIS_ERR; return REDIS_ERR;
if (cliSelect() != REDIS_OK) if (cliSelect() != REDIS_OK)
return REDIS_ERR; return REDIS_ERR;
...@@ -1574,6 +1577,12 @@ static int parseOptions(int argc, char **argv) { ...@@ -1574,6 +1577,12 @@ static int parseOptions(int argc, char **argv) {
config.cluster_manager_command.from = argv[++i]; config.cluster_manager_command.from = argv[++i];
} else if (!strcmp(argv[i],"--cluster-to") && !lastarg) { } else if (!strcmp(argv[i],"--cluster-to") && !lastarg) {
config.cluster_manager_command.to = argv[++i]; config.cluster_manager_command.to = argv[++i];
} else if (!strcmp(argv[i],"--cluster-from-user") && !lastarg) {
config.cluster_manager_command.from_user = argv[++i];
} else if (!strcmp(argv[i],"--cluster-from-pass") && !lastarg) {
config.cluster_manager_command.from_pass = argv[++i];
} else if (!strcmp(argv[i], "--cluster-from-askpass")) {
config.cluster_manager_command.from_askpass = 1;
} else if (!strcmp(argv[i],"--cluster-weight") && !lastarg) { } else if (!strcmp(argv[i],"--cluster-weight") && !lastarg) {
if (config.cluster_manager_command.weight != NULL) { if (config.cluster_manager_command.weight != NULL) {
fprintf(stderr, "WARNING: you cannot use --cluster-weight " fprintf(stderr, "WARNING: you cannot use --cluster-weight "
...@@ -2360,7 +2369,7 @@ clusterManagerCommandDef clusterManagerCommands[] = { ...@@ -2360,7 +2369,7 @@ clusterManagerCommandDef clusterManagerCommands[] = {
{"set-timeout", clusterManagerCommandSetTimeout, 2, {"set-timeout", clusterManagerCommandSetTimeout, 2,
"host:port milliseconds", NULL}, "host:port milliseconds", NULL},
{"import", clusterManagerCommandImport, 1, "host:port", {"import", clusterManagerCommandImport, 1, "host:port",
"from <arg>,copy,replace"}, "from <arg>,from-user <arg>,from-pass <arg>,from-askpass,copy,replace"},
{"backup", clusterManagerCommandBackup, 2, "host:port backup_directory", {"backup", clusterManagerCommandBackup, 2, "host:port backup_directory",
NULL}, NULL},
{"help", clusterManagerCommandHelp, 0, NULL, NULL} {"help", clusterManagerCommandHelp, 0, NULL, NULL}
...@@ -6303,6 +6312,7 @@ static int clusterManagerCommandImport(int argc, char **argv) { ...@@ -6303,6 +6312,7 @@ static int clusterManagerCommandImport(int argc, char **argv) {
int port = 0, src_port = 0; int port = 0, src_port = 0;
char *ip = NULL, *src_ip = NULL; char *ip = NULL, *src_ip = NULL;
char *invalid_args_msg = NULL; char *invalid_args_msg = NULL;
sds cmdfmt = NULL;
if (!getClusterHostFromCmdArgs(argc, argv, &ip, &port)) { if (!getClusterHostFromCmdArgs(argc, argv, &ip, &port)) {
invalid_args_msg = CLUSTER_MANAGER_INVALID_HOST_ARG; invalid_args_msg = CLUSTER_MANAGER_INVALID_HOST_ARG;
goto invalid_args; goto invalid_args;
...@@ -6334,6 +6344,14 @@ static int clusterManagerCommandImport(int argc, char **argv) { ...@@ -6334,6 +6344,14 @@ static int clusterManagerCommandImport(int argc, char **argv) {
src_port, src_ctx->errstr); src_port, src_ctx->errstr);
goto cleanup; goto cleanup;
} }
// Auth for the source node.
char *from_user = config.cluster_manager_command.from_user;
char *from_pass = config.cluster_manager_command.from_pass;
if (cliAuth(src_ctx, from_user, from_pass) == REDIS_ERR) {
success = 0;
goto cleanup;
}
src_reply = reconnectingRedisCommand(src_ctx, "INFO"); src_reply = reconnectingRedisCommand(src_ctx, "INFO");
if (!src_reply || src_reply->type == REDIS_REPLY_ERROR) { if (!src_reply || src_reply->type == REDIS_REPLY_ERROR) {
if (src_reply && src_reply->str) reply_err = src_reply->str; if (src_reply && src_reply->str) reply_err = src_reply->str;
...@@ -6373,8 +6391,15 @@ static int clusterManagerCommandImport(int argc, char **argv) { ...@@ -6373,8 +6391,15 @@ static int clusterManagerCommandImport(int argc, char **argv) {
} }
} }
} }
cmdfmt = sdsnew("MIGRATE %s %d %s %d %d");
if (config.auth) {
if (config.user) {
cmdfmt = sdscatfmt(cmdfmt," AUTH2 %s %s", config.user, config.auth);
} else {
cmdfmt = sdscatfmt(cmdfmt," AUTH %s", config.auth);
}
}
char cmdfmt[50] = "MIGRATE %s %d %s %d %d";
if (config.cluster_manager_command.flags & CLUSTER_MANAGER_CMD_FLAG_COPY) if (config.cluster_manager_command.flags & CLUSTER_MANAGER_CMD_FLAG_COPY)
strcat(cmdfmt, " %s"); strcat(cmdfmt, " %s");
if (config.cluster_manager_command.flags & CLUSTER_MANAGER_CMD_FLAG_REPLACE) if (config.cluster_manager_command.flags & CLUSTER_MANAGER_CMD_FLAG_REPLACE)
...@@ -6431,6 +6456,7 @@ cleanup: ...@@ -6431,6 +6456,7 @@ cleanup:
src_ip, src_port, reply_err); src_ip, src_port, reply_err);
if (src_ctx) redisFree(src_ctx); if (src_ctx) redisFree(src_ctx);
if (src_reply) freeReplyObject(src_reply); if (src_reply) freeReplyObject(src_reply);
if (cmdfmt) sdsfree(cmdfmt);
return success; return success;
invalid_args: invalid_args:
fprintf(stderr, "%s", invalid_args_msg); fprintf(stderr, "%s", invalid_args_msg);
...@@ -8000,9 +8026,9 @@ static void intrinsicLatencyMode(void) { ...@@ -8000,9 +8026,9 @@ static void intrinsicLatencyMode(void) {
} }
} }
static sds askPassword() { static sds askPassword(const char *msg) {
linenoiseMaskModeEnable(); linenoiseMaskModeEnable();
sds auth = linenoise("Please input password: "); sds auth = linenoise(msg);
linenoiseMaskModeDisable(); linenoiseMaskModeDisable();
return auth; return auth;
} }
...@@ -8060,6 +8086,9 @@ int main(int argc, char **argv) { ...@@ -8060,6 +8086,9 @@ int main(int argc, char **argv) {
config.cluster_manager_command.replicas = 0; config.cluster_manager_command.replicas = 0;
config.cluster_manager_command.from = NULL; config.cluster_manager_command.from = NULL;
config.cluster_manager_command.to = NULL; config.cluster_manager_command.to = NULL;
config.cluster_manager_command.from_user = NULL;
config.cluster_manager_command.from_pass = NULL;
config.cluster_manager_command.from_askpass = 0;
config.cluster_manager_command.weight = NULL; config.cluster_manager_command.weight = NULL;
config.cluster_manager_command.weight_argc = 0; config.cluster_manager_command.weight_argc = 0;
config.cluster_manager_command.slots = 0; config.cluster_manager_command.slots = 0;
...@@ -8090,7 +8119,12 @@ int main(int argc, char **argv) { ...@@ -8090,7 +8119,12 @@ int main(int argc, char **argv) {
parseEnv(); parseEnv();
if (config.askpass) { if (config.askpass) {
config.auth = askPassword(); config.auth = askPassword("Please input password: ");
}
if (config.cluster_manager_command.from_askpass) {
config.cluster_manager_command.from_pass = askPassword(
"Please input import source node password: ");
} }
#ifdef USE_OPENSSL #ifdef USE_OPENSSL
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment