diff options
author | Sergey Poznyakoff <gray@gnu.org.ua> | 2013-11-28 16:06:56 +0200 |
---|---|---|
committer | Sergey Poznyakoff <gray@gnu.org.ua> | 2013-11-28 16:33:57 +0200 |
commit | 155a76453f41b7ad80af4f8b4bf0539f2df32498 (patch) | |
tree | b5322a09cf94efda672f7b195d6e8e5ff41d35aa /src | |
parent | d9fbe79146e386cc29a6000cb55d6fb5337e5214 (diff) | |
download | eclat-155a76453f41b7ad80af4f8b4bf0539f2df32498.tar.gz eclat-155a76453f41b7ad80af4f8b4bf0539f2df32498.tar.bz2 |
Implement sg command
* etc/sg.fln: New file.
* etc/Makefile.am (FLNFILES): Add sg.fln
* src/sg.c: New file.
* src/sg-cl.opt: New file.
* src/Makefile.am (eclat_SOURCES): Add sg.c
(OPTFILES): Add sg-cl.opt
* src/eclat.c (cmdtab): Add entry for "sg".
(eclat_do_command): Ignore tag if it is NULL.
* src/eclat.h (eclat_sg): New proto.
Diffstat (limited to 'src')
-rw-r--r-- | src/Makefile.am | 4 | ||||
-rw-r--r-- | src/eclat.c | 7 | ||||
-rw-r--r-- | src/eclat.h | 1 | ||||
-rw-r--r-- | src/sg-cl.opt | 124 | ||||
-rw-r--r-- | src/sg.c | 109 |
5 files changed, 242 insertions, 3 deletions
diff --git a/src/Makefile.am b/src/Makefile.am index 820af4f..6654f5c 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -57,6 +57,7 @@ eclat_SOURCES=\ rmsnap.c\ rmvol.c\ setiattr.c\ + sg.c\ startstop.c\ util.c @@ -87,7 +88,8 @@ OPTFILES=\ mkinst-cl.opt\ mktags-cl.opt\ mkvol-cl.opt\ - rmaddr-cl.opt + rmaddr-cl.opt\ + sg-cl.opt eclat_SOURCES += $(OPTFILES:.opt=.h) diff --git a/src/eclat.c b/src/eclat.c index 063accb..0558fcd 100644 --- a/src/eclat.c +++ b/src/eclat.c @@ -149,6 +149,7 @@ struct eclat_command cmdtab[] = { eclat_copy_snapshot }, { "lsattr", NULL, NULL, eclat_lsattr, CMD_NOQRY }, + { "sg", NULL, NULL, eclat_sg }, }; size_t cmdcnt = sizeof(cmdtab) / sizeof(cmdtab[0]); @@ -636,9 +637,11 @@ eclat_do_command(eclat_command_env_t *env, struct eclat_command *command, if (!(command->flags & CMD_NOQRY)) { env->query = eclat_query_create(use_ssl ? EC2_QF_HTTPS : 0, endpoint, "/"); - eclat_query_add_param(env->query, "Action", command->tag); } - + + if (command->tag) + eclat_query_add_param(env->query, "Action", command->tag); + rc = command->handler(env, argc, argv); if (rc == 0 && !(command->flags & CMD_NOQRY)) { diff --git a/src/eclat.h b/src/eclat.h index acf4c2d..03a0bdf 100644 --- a/src/eclat.h +++ b/src/eclat.h @@ -142,6 +142,7 @@ int eclat_create_image(eclat_command_env_t *env, int argc, char **argv); int eclat_deregister_image(eclat_command_env_t *env, int argc, char **argv); int eclat_copy_image(eclat_command_env_t *env, int argc, char **argv); int eclat_copy_snapshot(eclat_command_env_t *env, int argc, char **argv); +int eclat_sg(eclat_command_env_t *env, int argc, char **argv); int eclat_lsattr(eclat_command_env_t *env, int argc, char **argv); diff --git a/src/sg-cl.opt b/src/sg-cl.opt new file mode 100644 index 0000000..3a44c29 --- /dev/null +++ b/src/sg-cl.opt @@ -0,0 +1,124 @@ +/* This file is part of Eclat. + Copyright (C) 2013 Sergey Poznyakoff. + + Eclat is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3, or (at your option) + any later version. + + Eclat is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Eclat. If not, see <http://www.gnu.org/licenses/>. */ + +ECLAT_CL_BEGIN([<modify ingress rules of a security group>], + [<GROUPARG>]) + +OPTION(add,A,, + [<add rules>]) +BEGIN + command = "AuthorizeSecurityGroupIngress"; +END + +OPTION(delete,D,, + [<delete rules>]) +BEGIN + command = "RevokeSecurityGroupIngress"; +END + +OPTION(name,N,, + [<ID argument is a group name>]) +BEGIN + dest_n = GROUP_NAME; +END + +OPTION(protocol,p,[<PROTO>], + [<IP protocol name or number>]) +BEGIN + proto = optarg; +END + +OPTION(group-id,g,[<ID>], + [<use before --from to indicate that its argument is a group ID>]) +BEGIN + struct group_arg *g = grecs_malloc(sizeof(*g)); + translate_ids(1, &optarg, rt[GROUP_ID].map); + g->type = GROUP_ID; + g->str = optarg; + g->usr = user; + if (!group_list) + group_list = _grecs_simple_list_create(1); + grecs_list_append(group_list, g); +END + +OPTION(group-name,G,[<NAME>], + [<use before --from to indicate that its argument is a group name>]) +BEGIN + struct group_arg *g = grecs_malloc(sizeof(*g)); + translate_ids(1, &optarg, rt[GROUP_NAME].map); + g->type = GROUP_NAME; + g->str = optarg; + g->usr = user; + if (!group_list) + group_list = _grecs_simple_list_create(1); + grecs_list_append(group_list, g); +END + +OPTION(user,u,[<USER>], + [<user name for the subsequent --from option>]) +BEGIN + user = optarg; +END + +OPTION(source,s,[<CIDR>], + [<source CIDR>]) +BEGIN + if (!source_list) + source_list = grecs_list_create(); + grecs_list_append(source_list, optarg); +END + +OPTION(port,P,[<PORT[-PORT]>], + [<destination port number or range>]) +BEGIN + char *p = strchr(optarg, '-'); + if (p) { + *p++ = 0; + to_port = p; + } else + to_port = optarg; + from_port = optarg; +END + +OPTION(next,n,, + [<delimits rules>]) +ALIAS(new) +BEGIN + flush_rule(); +END + +ECLAT_CL_END + +ECLAT_CL_PARSER(parse_options, [<int argc, char *argv[]>],[< +{ + int idx; + + GETOPT(argc, argv, idx, exit(EX_USAGE)) + if (!command) + die(EX_USAGE, "either --add or --delete must be given"); + eclat_query_add_param(env->query, "Action", command); + argc -= idx; + argv += idx; + if (argc != 1) + die(EX_USAGE, "bad number of arguments"); + if (group_list || source_list || from_port || to_port) + flush_rule(); + if (rule_n == 1) + die(EX_USAGE, "no rules"); + translate_ids(1, argv, rt[dest_n].map); + + eclat_query_add_param(query, rt[dest_n].resid, argv[0]); +}>]) diff --git a/src/sg.c b/src/sg.c new file mode 100644 index 0000000..8b11ed4 --- /dev/null +++ b/src/sg.c @@ -0,0 +1,109 @@ +/* This file is part of Eclat. + Copyright (C) 2013 Sergey Poznyakoff. + + Eclat is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3, or (at your option) + any later version. + + Eclat is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Eclat. If not, see <http://www.gnu.org/licenses/>. */ + +#include "eclat.h" + +#define GROUP_ID 0 +#define GROUP_NAME 1 + +static struct { + char *resid; + char *map; +} rt[] = { + { "GroupId", MAP_GROUPID }, + { "GroupName", MAP_GROUPNAME } +}; + +static struct ec2_query *query; +static char *command; +static int dest_n = GROUP_ID; +static char *proto = "tcp"; +static int rule_n = 1; +static char *user; + +struct group_arg { + int type; + char *str; + char *usr; +}; + +static struct grecs_list *group_list; +static struct grecs_list *source_list; +static char *from_port, *to_port; + +static char *bufptr = NULL; +static size_t bufsize = 0; + +static void +flush_rule() +{ + int i; + struct grecs_list_entry *ep; + + grecs_asprintf(&bufptr, &bufsize, "IpPermissions.%d.IpProtocol", + rule_n); + eclat_query_add_param(query, bufptr, proto); + + if (group_list) { + for (i = 1, ep = group_list->head; ep; ep = ep->next, i++) { + struct group_arg *a = ep->data; + + grecs_asprintf(&bufptr, &bufsize, + "IpPermissions.%d.Groups.%d.%s", + rule_n, i, + rt[a->type].resid); + eclat_query_add_param(query, bufptr, a->str); + if (a->usr) { + grecs_asprintf(&bufptr, &bufsize, + "IpPermissions.%d.Groups.%d.UserId", + rule_n, i); + eclat_query_add_param(query, bufptr, a->usr); + } + } + grecs_list_clear(group_list); + } + if (source_list) { + for (i = 1, ep = source_list->head; ep; ep = ep->next, i++) { + grecs_asprintf(&bufptr, &bufsize, + "IpPermissions.%d.IpRanges.%d.CidrIp", + rule_n, i); + eclat_query_add_param(query, bufptr, (char*) ep->data); + } + grecs_list_clear(source_list); + } + + + if (!from_port) + die(EX_USAGE, "rule %d: no ports", rule_n); + + grecs_asprintf(&bufptr, &bufsize, "IpPermissions.%d.FromPort", rule_n); + eclat_query_add_param(query, bufptr, from_port); + grecs_asprintf(&bufptr, &bufsize, "IpPermissions.%d.ToPort", rule_n); + eclat_query_add_param(query, bufptr, to_port); + + from_port = to_port = NULL; + ++rule_n; +} + +#include "sg-cl.h" + +int +eclat_sg(eclat_command_env_t *env, int argc, char **argv) +{ + query = env->query; + parse_options(env, argc, argv); + return 0; +} |