1 /* This file is part of Eclat.
2 Copyright (C) 2012-2018 Sergey Poznyakoff.
3
4 Eclat is free software; you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation; either version 3, or (at your option)
7 any later version.
8
9 Eclat is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
13
14 You should have received a copy of the GNU General Public License
15 along with Eclat. If not, see <http://www.gnu.org/licenses/>. */
16
17 #include "eclat.h"
18
19 static char *attrs[] = {
20 "InstanceType.Value",
21 "Kernel.Value",
22 "Ramdisk.Value",
23 "UserData.Value",
24 "DisableApiTermination.Value",
25 "InstanceInitiatedShutdownBehavior.Value",
26 "BlockDeviceMapping.ebs",
27 "SourceDestCheck.Value",
28 "GroupId.%d",
29 "EbsOptimized",
30 NULL
31 };
32
33 static void
list_mod_attrs(FILE * fp)34 list_mod_attrs(FILE *fp)
35 {
36 size_t ncols = get_scr_cols();
37 int i, col, len, alen;
38 char *delim = "";
39
40 fprintf(fp, "Available attributes are:\n");
41 col = 0;
42 for (i = 0; attrs[i]; i++) {
43 alen = strcspn(attrs[i], ".");
44 len = strlen(delim) + alen;
45 if (col + len > ncols) {
46 fprintf(fp, ",\n%*.*s", alen, alen, attrs[i]);
47 col = strlen(attrs[i]);
48 } else
49 col += fprintf(fp, "%s%*.*s", delim,
50 alen, alen, attrs[i]);
51 delim = ", ";
52 }
53 fputc('\n', fp);
54 fputc('\n', fp);
55 }
56
57 int from_file;
58 int is_base64;
59 #include "setiattr-cl.h"
60
61 int
eclat_modify_instance_attribute(eclat_command_env_t * env,int argc,char ** argv)62 eclat_modify_instance_attribute(eclat_command_env_t *env, int argc, char **argv)
63 {
64 int i;
65 struct ec2_request *q = env->request;
66 const char *canonattr;
67 size_t canonlen;
68 char *bufptr = NULL;
69 size_t bufsize = 0;
70
71 parse_options(env, argc, argv, &i);
72 argv += i;
73 argc -= i;
74
75 if (argc < 3)
76 die(EX_USAGE, "wrong number of arguments");
77
78 translate_ids(1, argv, MAP_INSTANCE);
79 eclat_request_add_param(q, "InstanceId", argv[0]);
80
81 canonattr = canonattrname(attrs, argv[1], ".", &canonlen);
82 if (!canonattr)
83 die(EX_USAGE, "unrecognized attribute: %s", argv[1]);
84
85 if (canonattr[canonlen] == '.' &&
86 strcmp(canonattr+canonlen+1, "%d") == 0) {
87 for (i = 2; i < argc; i++) {
88 grecs_asprintf(&bufptr, &bufsize, canonattr, i - 1);
89 eclat_request_add_param(q, bufptr, argv[i]);
90 }
91 } else if (canonattr[canonlen] == '.' &&
92 strcmp(canonattr+canonlen, ".ebs") == 0) {
93 for (i = 2; i < argc; i++) {
94 char *p = strchr(argv[i], '=');
95
96 if (!p)
97 die(EX_USAGE, "DeleteOnTermination must be supplied in %s", argv[i]);
98 *p++ = 0;
99 grecs_asprintf(&bufptr, &bufsize,
100 "%*.*s.%d.DeviceName",
101 canonlen, canonlen, canonattr, i - 1);
102 eclat_request_add_param(q, bufptr, argv[i]);
103
104 grecs_asprintf(&bufptr,
105 &bufsize,
106 "%*.*s.%d.Ebs.DeleteOnTermination",
107 canonlen, canonlen, canonattr,
108 i - 1);
109 if (strcmp(p, "false") && strcmp(p, "true"))
110 die(EX_USAGE, "not a valid boolean in %s",
111 argv[i]);
112 eclat_request_add_param(q, bufptr, p);
113 }
114 } else if (strcmp(canonattr, "UserData.Value") == 0) {
115 char *input = from_file ? read_file(argv[2]) : argv[2];
116 size_t enclen = 0;
117 char *data;
118
119 if (is_base64)
120 data = input;
121 else
122 eclat_base64_encode((unsigned char *)input,
123 strlen(input),
124 (unsigned char**) &data, &enclen);
125 eclat_request_add_param(q, canonattr, data);
126 if (enclen)
127 free(data);
128 } else
129 eclat_request_add_param(q, canonattr, argv[2]);
130 free(bufptr);
131 return 0;
132 }
133