diff options
-rw-r--r-- | doc/eclat-delete-tags.1 | 12 | ||||
-rw-r--r-- | doc/eclat-describe-tags.1 | 36 | ||||
m--------- | grecs | 0 | ||||
-rw-r--r-- | src/Makefile.am | 1 | ||||
-rw-r--r-- | src/cretags.c | 10 | ||||
-rw-r--r-- | src/dscrsnapattr.c | 6 | ||||
-rw-r--r-- | src/dscrtags-cl.opt | 121 | ||||
-rw-r--r-- | src/dscrtags.c | 59 | ||||
-rw-r--r-- | src/eclat.h | 3 | ||||
-rw-r--r-- | src/util.c | 15 |
10 files changed, 203 insertions, 60 deletions
diff --git a/doc/eclat-delete-tags.1 b/doc/eclat-delete-tags.1 index 4184f0a..057d784 100644 --- a/doc/eclat-delete-tags.1 +++ b/doc/eclat-delete-tags.1 @@ -13,7 +13,7 @@ .\" .\" You should have received a copy of the GNU General Public License .\" along with Eclat. If not, see <http://www.gnu.org/licenses/>. -.TH DELETE\-TAGS 1 "January 19, 2013" "ECLAT" "Eclat User Reference" +.TH DELETE\-TAGS 1 "January 24, 2013" "ECLAT" "Eclat User Reference" .SH NAME eclat delete\-tags \- delete or replace tags for a resource .SH SYNOPSIS @@ -22,16 +22,18 @@ eclat delete\-tags [\fB\-a\fR \fIID\fR] [\fB\-i\fR \fIID\fR]\ [\fB\-T\fR \fIFILE\fR] [\fB\-\-ami\fR \fIID\fR] [\fB\-\-instance\fR \fIID\fR] [\fB\-\-resource\-id\fR [\fIMAP\fR:]\fIID\fR] [\fB\-\-volume\fR \fIID\fR] [\fB\-\-snapshot\fR \fIID\fR] - [\fB\-\-from\-file\fR \fIFILE\fR] \fITAG\fR[=\fIVAL\fR]... + [\fB\-\-from\-file\fR \fIFILE\fR] [\fITAG\fR[=\fIVAL\fR]...] eclat delete\-tags \fB\-\-help\fR .SH DESCRIPTION -This command deletes more tags for a given resource. Tags are -specified by their names. If a tag name is followed by an equals -sign and a value, it will be deleted only if both its name and value +This command deletes tags from a given resource. The names of tags to +delete are supplied in the command line. If a tag name is followed by +an equals sign and a value, it will be deleted only if both its name and value are the same as the supplied ones. Otherwise, the tag will be deleted regardless of its value. .PP +If no tag names are given, all tags are deleted. +.PP The resource to delete tags from is supplied with one of the options. The resource designation must be present. .PP diff --git a/doc/eclat-describe-tags.1 b/doc/eclat-describe-tags.1 index 85288e5..8d43461 100644 --- a/doc/eclat-describe-tags.1 +++ b/doc/eclat-describe-tags.1 @@ -13,16 +13,44 @@ .\" .\" You should have received a copy of the GNU General Public License .\" along with Eclat. If not, see <http://www.gnu.org/licenses/>. -.TH DESCRIBE\-TAGS 1 "January 19, 2013" "ECLAT" "Eclat User Reference" +.TH DESCRIBE\-TAGS 1 "February 9, 2013" "ECLAT" "Eclat User Reference" .SH NAME eclat describe\-tags \- list the EC2 tags .SH SYNOPSIS -eclat describe\-tags [\fBFILTER\fR...] +eclat describe\-tags [\fB\-a\fR \fIID\fR] [\fB\-i\fR \fIID\fR]\ + [\fB\-r\fR [\fIMAP\fR:]\fIID\fR] [\fB\-s \fIID\fR] [\fB\-v\fR \fIID\fR] + [\fB\-T\fR \fIFILE\fR] + [\fB\-\-ami\fR \fIID\fR] [\fB\-\-instance\fR \fIID\fR] [\fB\-\-resource\-id\fR [\fIMAP\fR:]\fIID\fR] + [\fB\-\-volume\fR \fIID\fR] [\fB\-\-snapshot\fR \fIID\fR] +[\fBFILTER\fR...] eclat describe\-tags \fB\-\-help\fR .SH DESCRIPTION This command lists the EC2 tags. If no filter has been supplied, all tags are listed. +.SH OPTIONS +.TP +\fB\-a\fR, \fB\-\-ami\fR \fIID\fR +Describes tags of the given image. In resource translation mode, uses +the map \fBImageId\fR. +.TP +\fB\-i\fR, \fB\-\-instance\fR \fIID\fR +Describes tags of the given instance. In resource translation mode, uses +the map \fBInstanceId\fR. +.TP +\fB\-r\fR, \fB\-\-resource\-id\fR [\fIMAP\fR:]\fIID\fR +Describes tags of the EC2 resource identified by \fIID\fR. If optional +\fIMAP\fR prefix is supplied and resource translation mode is enabled, +this option will use the \fIMAP\fR to translate \fIID\fR into AWS +resource identifier. +.TP +\fB\-s\fR, \fB\-\-snapshot\fR \fIID\fR +Describes tags of the given snapshot. In resource translation mode, uses +the map \fBSnapshotId\fR. +.TP +\fB\-v\fR, \fB\-\-volume\fR \fIID\fR +Describes tags of the given volume. In resource translation mode, uses +the map \fBVolumeId\fR. .SH FILTERS Available filters are: .TP @@ -46,7 +74,7 @@ eclat \-x describe\-tags resource\-id=InstanceId:webserver .fi .sp .TP -\fBresource\-type\fR=\fItype\fR. +\fBresource\-type\fR=\fItype\fR List only tags pertaining to resources of the given \fItype\fR. Valid \fItype\fRs are: \fBcustomer-gateway\fR, \fBdhcp-options\fR, \fBimage\fR, \fBinstance\fR, \fBinternet-gateway\fR, \fBnetwork-acl\fR, @@ -54,7 +82,7 @@ List only tags pertaining to resources of the given \fItype\fR. Valid \fBsnapshot\fR, \fBspot-instances-request\fR, \fBsubnet\fR, \fBvolume\fR, \fBvpc\fR, \fBvpn-connection\fR, and \fBvpn-gateway\fR. .TP -\fBvalue\fR +\fBvalue\fR=\fIstring\fR Lists tags with the given value. .SH OUTPUT The default output format lists on each line the resource ID, its diff --git a/grecs b/grecs -Subproject 5596f7cdcdc1983021185c5e0900d5fcba7f328 +Subproject 9cf45f0c658b583ee1ebdcb3d6345ad290993d6 diff --git a/src/Makefile.am b/src/Makefile.am index 996f2d8..10c5cf0 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -69,6 +69,7 @@ OPTFILES=\ dscrinststat-cl.opt\ dscrsecgrps-cl.opt\ dscrsnap-cl.opt\ + dscrtags-cl.opt\ generic-cl.opt\ reladdr-cl.opt diff --git a/src/cretags.c b/src/cretags.c index 872c319..08aa201 100644 --- a/src/cretags.c +++ b/src/cretags.c @@ -18,7 +18,7 @@ #include "cretags-cl.h" static int -process_tags(eclat_command_env_t *env, int argc, char **argv) +process_tags(eclat_command_env_t *env, int argc, char **argv, int require_tags) { int i, j; struct ec2_query *q = env->query; @@ -26,13 +26,15 @@ process_tags(eclat_command_env_t *env, int argc, char **argv) size_t bufsize = 0; struct grecs_list_entry *ep; + if (!require_tags) + proginfo.args_doc = "[TAG[=VALUE...]]"; parse_options(argc, argv, &i); argv += i; argc -= i; if (!reslist->head) die(EX_USAGE, "no resource IDs supplied"); - if (argc == 0 && !from_file) + if (require_tags && argc == 0 && !from_file) die(EX_USAGE, "no tags supplied"); for (ep = reslist->head, i = 1; ep; ep = ep->next, i++) { @@ -113,7 +115,7 @@ eclat_create_tags(eclat_command_env_t *env, int argc, char **argv) { proginfo.progname = "eclat create-tags"; proginfo.docstring = "create tags for the specified resources"; - return process_tags(env, argc, argv); + return process_tags(env, argc, argv, 1); } int @@ -121,5 +123,5 @@ eclat_delete_tags(eclat_command_env_t *env, int argc, char **argv) { proginfo.progname = "eclat delete-tags"; proginfo.docstring = "delete tags from the specified resources"; - return process_tags(env, argc, argv); + return process_tags(env, argc, argv, 0); } diff --git a/src/dscrsnapattr.c b/src/dscrsnapattr.c index 83b3117..92778db 100644 --- a/src/dscrsnapattr.c +++ b/src/dscrsnapattr.c @@ -92,7 +92,6 @@ eclat_modify_snapshot_attribute(eclat_command_env_t *env, { int i; struct ec2_query *q = env->query; - const char *attrname; char *bufptr = NULL; size_t bufsize = 0; @@ -106,7 +105,7 @@ eclat_modify_snapshot_attribute(eclat_command_env_t *env, if (argc < 2) die(EX_USAGE, "wrong number of arguments"); for (i = 0; i < argc - 1; i++) { - const char *action, *what, *arg; + const char *action, *what; switch (argv[i][0]) { case 'u': @@ -152,9 +151,6 @@ eclat_reset_snapshot_attribute(eclat_command_env_t *env, { int i; struct ec2_query *q = env->query; - const char *attrname; - char *bufptr = NULL; - size_t bufsize = 0; generic_proginfo->args_doc = "SNAP-ID"; generic_parse_options("eclat reset-snapshot-attribute", diff --git a/src/dscrtags-cl.opt b/src/dscrtags-cl.opt new file mode 100644 index 0000000..4adfea0 --- /dev/null +++ b/src/dscrtags-cl.opt @@ -0,0 +1,121 @@ +/* This file is part of Eclat. + Copyright (C) 2012, 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/>. */ + +static struct grecs_list *reslist; + +struct resource { + char *map; + char *resid; +}; + +OPTIONS_BEGIN("eclat describe-tags", + [<List tags and their values>], + [<[FILTER...]>], + [<gnu>], + [<nousage>], + [<noversion>]) + +OPTION(resource-id,r,[<[MAP:]ID>], + [<resource for which to list the tags>]) +BEGIN + struct resource *res = grecs_malloc(sizeof(*res)); + char *p = strchr(optarg, ':'); + if (p) { + res->map = optarg; + *p++ = 0; + res->resid = p; + } else { + res->map = NULL; + res->resid = optarg; + } + grecs_list_append(reslist, res); +END + +OPTION(instance,i,[<ID>], + [<instance ID>]) +BEGIN + struct resource *res = grecs_malloc(sizeof(*res)); + res->map = "InstanceId"; + res->resid = optarg; + grecs_list_append(reslist, res); +END + +OPTION(volume,v,[<ID>], + [<volume ID>]) +BEGIN + struct resource *res = grecs_malloc(sizeof(*res)); + res->map = "VolumeId"; + res->resid = optarg; + grecs_list_append(reslist, res); +END + +OPTION(ami,a,[<ID>], + [<AMI ID>]) +BEGIN + struct resource *res = grecs_malloc(sizeof(*res)); + res->map = "ImageId"; + res->resid = optarg; + grecs_list_append(reslist, res); +END + +OPTION(snapshot,s,[<ID>], + [<snapshot ID>]) +BEGIN + struct resource *res = grecs_malloc(sizeof(*res)); + res->map = "SnapshotId"; + res->resid = optarg; + grecs_list_append(reslist, res); +END + +OPTIONS_END + +static void +parse_options(int argc, char *argv[], int *index) +{ + static char *resource_types[] = { + "customer-gateway", + "dhcp-options", + "image", + "instance", + "internet-gateway", + "network-acl", + "reserved-instances", + "route-table", + "security-group", + "snapshot", + "spot-instances-request", + "subnet", + "volume", + "vpc", + "vpn-connection", + "vpn-gateway", + NULL + }; + + static struct filter_descr filters[] = { + { "key", FILTER_STRING }, + { "resource-id", FILTER_STRING }, + { "resource-type", FILTER_ENUM, resource_types }, + { "value", FILTER_STRING }, + { NULL } + }; + + available_filters = filters; + proginfo.print_help_hook = list_filters; + + reslist = grecs_list_create(); + GETOPT(argc, argv, *index, exit(EX_USAGE)) +} diff --git a/src/dscrtags.c b/src/dscrtags.c index 5081e28..3530e62 100644 --- a/src/dscrtags.c +++ b/src/dscrtags.c @@ -15,55 +15,36 @@ along with Eclat. If not, see <http://www.gnu.org/licenses/>. */ #include "eclat.h" - -static void -parse_options(int argc, char *argv[], int *index) -{ - static char *resource_types[] = { - "customer-gateway", - "dhcp-options", - "image", - "instance", - "internet-gateway", - "network-acl", - "reserved-instances", - "route-table", - "security-group", - "snapshot", - "spot-instances-request", - "subnet", - "volume", - "vpc", - "vpn-connection", - "vpn-gateway", - NULL - }; - - static struct filter_descr filters[] = { - { "key", FILTER_STRING }, - { "resource-id", FILTER_STRING }, - { "resource-type", FILTER_ENUM, resource_types }, - { "value", FILTER_STRING }, - { NULL } - }; - - available_filters = filters; - generic_proginfo->print_help_hook = list_filters; - return generic_parse_options("eclat describe-tags", - "List tags and their values", - argc, argv, index); -} +#include "dscrtags-cl.h" int eclat_describe_tags(eclat_command_env_t *env, int argc, char **argv) { int i; + char *bufptr = NULL; + size_t bufsize = 0; + struct grecs_list_entry *ep; + int n = 1; parse_options(argc, argv, &i); argv += i; argc -= i; translate_resource_ids(argc, argv); - describe_query_create(env, argc, argv, NULL); + if (reslist->head) { + eclat_query_add_param(env->query, + "Filter.1.Name", "resource-id"); + for (ep = reslist->head, i = 1; ep; ep = ep->next, i++) { + struct resource *res = ep->data; + if (res->map) + translate_ids(1, &res->resid, res->map); + grecs_asprintf(&bufptr, &bufsize, + "Filter.1.Value.%d", i); + eclat_query_add_param(env->query, bufptr, res->resid); + } + n++; + } + describe_query_update(env, argc, argv, NULL, n, NULL); + return 0; } diff --git a/src/eclat.h b/src/eclat.h index 2fab8cf..ba5d57b 100644 --- a/src/eclat.h +++ b/src/eclat.h @@ -116,6 +116,9 @@ void set_command_format(const char *name, const char *format, void describe_query_create(eclat_command_env_t *env, int argc, char **argv, const char *uparm); +void describe_query_update(eclat_command_env_t *env, int argc, char **argv, + const char *uparm, int n_in, int *n_out); + int eclat_send_query(CURL *curl, struct ec2_query *q); int eclat_actcmp(const char *a, const char *b); @@ -149,8 +149,8 @@ get_scr_cols() void -describe_query_create(eclat_command_env_t *env, int argc, char **argv, - const char *uparm) +describe_query_update(eclat_command_env_t *env, int argc, char **argv, + const char *uparm, int n_in, int *n_out) { int i, j, k; struct ec2_query *q = env->query; @@ -162,7 +162,7 @@ describe_query_create(eclat_command_env_t *env, int argc, char **argv, ws.ws_delim = ","; wsflags = WRDSF_DEFFLAGS | WRDSF_DELIM; - for (i = 0, j = 1; i < argc; i++) { + for (i = 0, j = n_in; i < argc; i++) { char *p = strchr(argv[i], '='); if (!p) { if (uparm) { @@ -192,8 +192,17 @@ describe_query_create(eclat_command_env_t *env, int argc, char **argv, if (wsflags & WRDSF_REUSE) wordsplit_free(&ws); free(bufptr); + if (n_out) + *n_out = j; } +void +describe_query_create(eclat_command_env_t *env, int argc, char **argv, + const char *uparm) +{ + describe_query_update(env, argc, argv, uparm, 1, NULL); +} + int eclat_send_query(CURL *curl, struct ec2_query *q) { |