diff options
author | Sergey Poznyakoff <gray@gnu.org.ua> | 2012-09-26 15:56:48 +0300 |
---|---|---|
committer | Sergey Poznyakoff <gray@gnu.org.ua> | 2012-09-26 15:56:48 +0300 |
commit | 22084e1264031d59b8954b684c1d9f40733c8786 (patch) | |
tree | 00d6c93c3c016562b371b496e3f4f9dc3709be09 /src | |
parent | 5cb3ba92b9c891a481998a45052649a724931687 (diff) | |
download | eclat-22084e1264031d59b8954b684c1d9f40733c8786.tar.gz eclat-22084e1264031d59b8954b684c1d9f40733c8786.tar.bz2 |
Implement DescribeInstanceStatus action.
* lib/forlan.c (generic_print): Skip NULL entries.
* src/Makefile.am (eclat_SOURCES): Add new files.
(OPTFILES): New variable.
(BUILT_SOURCES,EXTRA_DIST): Add OPTFILES and their derivatives.
* src/dscrinststat-cl.opt: New file.
* src/dscrinststat.c: New file.
* src/util.c: New file.
* src/dscrtags.c: Use functions from util.c
* src/eclat.c: New command describe-instance-status.
(main): Don't coredump on NULL formats.
* src/eclat.conf (DescribeInstanceStatus): New format.
* src/eclat.h (eclat_describe_instance_status)
(describe_query_create)
(eclat_send_query): New protos.
Diffstat (limited to 'src')
-rw-r--r-- | src/Makefile.am | 17 | ||||
-rw-r--r-- | src/dscrinststat-cl.opt | 36 | ||||
-rw-r--r-- | src/dscrinststat.c | 36 | ||||
-rw-r--r-- | src/dscrtags.c | 62 | ||||
-rw-r--r-- | src/eclat.c | 6 | ||||
-rw-r--r-- | src/eclat.conf | 25 | ||||
-rw-r--r-- | src/eclat.h | 5 | ||||
-rw-r--r-- | src/util.c | 91 |
8 files changed, 217 insertions, 61 deletions
diff --git a/src/Makefile.am b/src/Makefile.am index bdc1f9e..042b833 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -22,10 +22,13 @@ eclat_SOURCES=\ config.c\ dscrtags.c\ dscrtags-cl.h\ + dscrinststat.c\ + dscrinststat-cl.h\ eclat.c\ eclat.h\ startinst.c\ - startinst-cl.h + startinst-cl.h\ + util.c AM_LDFLAGS = $(CURL_LIBS) LDADD=../lib/libeclat.a @LIBOBJS@ ../grecs/src/libgrecs.a @@ -36,12 +39,22 @@ AM_CPPFLAGS= \ -DDEFAULT_INCLUDE_DIR=\"$(pkgdatadir)/include\"\ -DDEFAULT_PREPROCESSOR="$(DEFAULT_PREPROCESSOR)" +OPTFILES=\ + dscrinststat-cl.opt\ + dscrtags-cl.opt\ + startinst-cl.opt + BUILT_SOURCES=\ cmdline.h\ + $(OPTFILES:.opt=.h)\ + dscrinststat-cl.h\ dscrtags-cl.h\ startinst-cl.h -EXTRA_DIST=cmdline.opt eclat.conf +EXTRA_DIST=\ + cmdline.opt\ + $(OPTFILES)\ + eclat.conf SUFFIXES=.opt .c .h diff --git a/src/dscrinststat-cl.opt b/src/dscrinststat-cl.opt new file mode 100644 index 0000000..13f5046 --- /dev/null +++ b/src/dscrinststat-cl.opt @@ -0,0 +1,36 @@ +/* This file is part of Eclat. + Copyright (C) 2012 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/>. */ + +OPTIONS_BEGIN("eclat describe-instance-status", + [<describe the status of Amazon EC2 instances including any scheduled events>], + [<[FILTER...]>], + [<gnu>], + [<nousage>], + [<noversion>]) + +OPTION(all,a,, + [<return the health status for all instances>]) +BEGIN + all_option = 1; +END + +OPTIONS_END + +static void +parse_options(int argc, char *argv[], int *index) +{ + GETOPT(argc, argv, *index, exit(EX_USAGE)) +} diff --git a/src/dscrinststat.c b/src/dscrinststat.c new file mode 100644 index 0000000..b89890e --- /dev/null +++ b/src/dscrinststat.c @@ -0,0 +1,36 @@ +/* This file is part of Eclat. + Copyright (C) 2012 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" +static int all_option; +#include "dscrinststat-cl.h" + +int +eclat_describe_instance_status(CURL *curl, int argc, char **argv) +{ + int i; + struct ec2_query *q; + + parse_options(argc, argv, &i); + argv += i; + argc -= i; + + q = describe_query_create(curl, "DescribeInstanceStatus", argc, argv); + + if (all_option) + eclat_query_add_param(q, "IncludeAllInstances", "1"); + return eclat_send_query(curl, q); +} diff --git a/src/dscrtags.c b/src/dscrtags.c index fca46d3..8707eb3 100644 --- a/src/dscrtags.c +++ b/src/dscrtags.c @@ -20,67 +20,15 @@ int eclat_describe_tags(CURL *curl, int argc, char **argv) { - int i, j, k; + int i; struct ec2_query *q; - char *url; - char *bufptr = NULL; - size_t bufsize = 0; - size_t bs; CURLcode res; - struct wordsplit ws; - int wsflags; - + char *url; + parse_options(argc, argv, &i); argv += i; argc -= i; - - q = eclat_query_create(use_ssl ? EC2_QF_HTTPS : 0, endpoint, "/"); - eclat_query_add_param(q, "Action", "DescribeTags"); - - ws.ws_delim = ","; - wsflags = WRDSF_DEFFLAGS | WRDSF_DELIM; - for (i = 0, j = 1; i < argc; i++) { - char *p = strchr(argv[i], '='); - if (!p) - die(EX_USAGE, "maformed filter: %s", argv[i]); - *p++ = 0; - grecs_asprintf(&bufptr, &bufsize, "Filter.%d.Name", j); - eclat_query_add_param(q, bufptr, argv[i]); - - if (wordsplit(p, &ws, wsflags)) - die(EX_SOFTWARE, "wordsplit failed at \"%s\": %s", - p, wordsplit_strerror(&ws)); - wsflags |= WRDSF_REUSE; - for (k = 0; k < ws.ws_wordc; k++) { - grecs_asprintf(&bufptr, &bufsize, "Filter.%d.Value.%d", - j, k+1); - eclat_query_add_param(q, bufptr, ws.ws_wordv[k]); - } - } - if (wsflags & WRDSF_REUSE) - wordsplit_free(&ws); - free(bufptr); - - eclat_query_add_param(q, "AWSAccessKeyId", access_key); - - eclat_query_signature(q, secret_key); - url = eclat_query_to_url(q, NULL); - - debug(ECLAT_DEBCAT_MAIN, 1, ("using URL: %s", url)); - curl_easy_setopt(curl, CURLOPT_URL, url); - - free(url); - eclat_query_free(q); - - if (dry_run_mode) - debug(ECLAT_DEBCAT_MAIN, 1, ("not sending request")); - else { - res = curl_easy_perform(curl); - - if (res != CURLE_OK) - err("CURL: %s", curl_easy_strerror(res)); - } - - return 0; + q = describe_query_create(curl, "DescribeTags", argc, argv); + return eclat_send_query(curl, q); } diff --git a/src/eclat.c b/src/eclat.c index 7d1c642..8fafc72 100644 --- a/src/eclat.c +++ b/src/eclat.c @@ -220,7 +220,9 @@ struct command { struct command cmdtab[] = { { "start-instances", 1, "StartInstances", eclat_start_instance }, { "stop-instances", 1, "StopInstances", eclat_stop_instance }, - { "describe-tags", 1, "DescribeTags", eclat_describe_tags } + { "describe-tags", 1, "DescribeTags", eclat_describe_tags }, + { "describe-instance-status", 1, "DescribeInstanceStatus", + eclat_describe_instance_status } }; size_t cmdcnt = sizeof(cmdtab) / sizeof(cmdtab[0]); @@ -424,7 +426,7 @@ main(int argc, char **argv) if (format_file) env = compile_format_file(format_file); - else if (command) + else if (command && command->fmt) env = compile_default_format(command); if (lint_mode) diff --git a/src/eclat.conf b/src/eclat.conf index 13b004d..88cd959 100644 --- a/src/eclat.conf +++ b/src/eclat.conf @@ -42,6 +42,31 @@ else { } EOT; +format "DescribeInstanceStatus" <<\EOT +if (.DescribeInstanceStatusResponse.instanceStatusSet) { + for (var in .DescribeInstanceStatusResponse.instanceStatusSet.item) { + print(var.instanceId,"\t", + var.availabilityZone,"\t", + var.instanceState.name); + if (var.instanceState.name[running]) { + print("\t",var.systemStatus.status); + for (detail in var.systemStatus.details.item.*) { + print("\t",detail.name,"=",detail.status); + } + } + print("\n"); + for (event in var.eventsSet.item) { + error(var.instanceId,"\t","Event: ", event.description,"\n"); + } + } +} else if (.Response.Errors) + error("Error: ",.Response.Errors.Error.Message,"\n"); +else { + error("Unrecognized response:\n"); + dump(.); +} +EOT; + format "StartInstances" <<\EOT if (.StartInstancesResponse) { for (var in .StartInstancesResponse.instancesSet.item) { diff --git a/src/eclat.h b/src/eclat.h index d8043f7..641d0ad 100644 --- a/src/eclat.h +++ b/src/eclat.h @@ -58,9 +58,14 @@ typedef int (*eclat_command_handler_t) (CURL *curl, int argc, char **argv); int eclat_start_instance(CURL *curl, int argc, char **argv); int eclat_stop_instance(CURL *curl, int argc, char **argv); int eclat_describe_tags(CURL *curl, int argc, char **argv); +int eclat_describe_instance_status(CURL *curl, int argc, char **argv); char *region_to_endpoint(const char *region); void define_format(const char *name, const char *format, grecs_locus_t *locus); +struct ec2_query *describe_query_create(CURL *curl, const char *verb, + int argc, char **argv); +int eclat_send_query(CURL *curl, struct ec2_query *q); + #define XML_DUMP_FILE_NAME "eclat.dump.xml" diff --git a/src/util.c b/src/util.c new file mode 100644 index 0000000..146567c --- /dev/null +++ b/src/util.c @@ -0,0 +1,91 @@ +/* This file is part of Eclat. + Copyright (C) 2012 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" + +struct ec2_query * +describe_query_create(CURL *curl, const char *verb, int argc, char **argv) +{ + int i, j, k; + struct ec2_query *q; + char *url; + char *bufptr = NULL; + size_t bufsize = 0; + size_t bs; + struct wordsplit ws; + int wsflags; + + q = eclat_query_create(use_ssl ? EC2_QF_HTTPS : 0, endpoint, "/"); + eclat_query_add_param(q, "Action", verb); + + ws.ws_delim = ","; + wsflags = WRDSF_DEFFLAGS | WRDSF_DELIM; + for (i = 0, j = 1; i < argc; i++) { + char *p = strchr(argv[i], '='); + if (!p) + die(EX_USAGE, "maformed filter: %s", argv[i]); + *p++ = 0; + grecs_asprintf(&bufptr, &bufsize, "Filter.%d.Name", j); + eclat_query_add_param(q, bufptr, argv[i]); + + if (wordsplit(p, &ws, wsflags)) + die(EX_SOFTWARE, "wordsplit failed at \"%s\": %s", + p, wordsplit_strerror(&ws)); + wsflags |= WRDSF_REUSE; + + for (k = 0; k < ws.ws_wordc; k++) { + grecs_asprintf(&bufptr, &bufsize, "Filter.%d.Value.%d", + j, k+1); + eclat_query_add_param(q, bufptr, ws.ws_wordv[k]); + } + } + if (wsflags & WRDSF_REUSE) + wordsplit_free(&ws); + free(bufptr); + + eclat_query_add_param(q, "AWSAccessKeyId", access_key); + + return q; +} + +int +eclat_send_query(CURL *curl, struct ec2_query *q) +{ + char *url; + CURLcode res; + int rc = 0; + + eclat_query_signature(q, secret_key); + url = eclat_query_to_url(q, NULL); + + debug(ECLAT_DEBCAT_MAIN, 1, ("using URL: %s", url)); + curl_easy_setopt(curl, CURLOPT_URL, url); + + free(url); + eclat_query_free(q); + + if (dry_run_mode) + debug(ECLAT_DEBCAT_MAIN, 1, ("not sending request")); + else { + res = curl_easy_perform(curl); + + if (res != CURLE_OK) { + err("CURL: %s", curl_easy_strerror(res)); + rc = 1; + } + } + return rc; +} |