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 <config.h>
18 #include <sysexits.h>
19 #include <ctype.h>
20 #include <stdlib.h>
21 #include <stdio.h>
22 #include <unistd.h>
23 #include <errno.h>
24 #include <string.h>
25 #include <curl/curl.h>
26 #include <expat.h>
27 #include "grecs.h"
28 #include "grecs/opt.h"
29 #include "wordsplit.h"
30 #include "libeclat.h"
31 #include "forlan.h"
32 
33 #define EX_CANCELLED 16
34 
35 #define	ECLAT_DEBCAT_MAIN    0
36 #define ECLAT_DEBCAT_CFGRAM  1
37 #define ECLAT_DEBCAT_CFLEX   2
38 #define ECLAT_DEBCAT_CONF    3
39 #define ECLAT_DEBCAT_CURL    4
40 #define ECLAT_DEBCAT_FORLAN  5
41 #define ECLAT_DEBCAT_DUMP    6
42 
43 enum authentication_provider {
44 	authp_undefined,
45 	authp_immediate,
46 	authp_file,
47 	authp_instance
48 };
49 
50 extern char *endpoint;
51 extern char *signature_version;
52 extern int use_ssl;
53 extern int use_post;
54 extern int ssl_verify_peer;
55 extern char *ssl_ca_file;
56 extern char *ssl_ca_path;
57 extern int dry_run_mode;
58 extern char *region_name;
59 extern enum authentication_provider authentication_provider;
60 extern char *access_file_name;
61 extern char *access_key;
62 extern char *secret_key;
63 extern char *security_token;
64 extern char *format_file;
65 extern int translation_enabled;
66 extern char *custom_map;
67 extern enum eclat_confirm_mode confirm_mode;
68 
69 extern char *instance_store_base_url;
70 extern unsigned short instance_store_port;
71 extern char *instance_store_document_path;
72 extern char *instance_store_credentials_path;
73 extern unsigned long max_retry_sleep;
74 extern unsigned long max_retry_time;
75 
76 typedef int (*config_finish_hook_t) (void*);
77 
78 void add_config_finish_hook(config_finish_hook_t fun, void *data);
79 
80 void config_help(void);
81 void config_init(void);
82 void config_finish(struct grecs_node *tree);
83 int run_config_finish_hooks(void);
84 
85 struct eclat_command_env {
86 	struct eclat_command const *cmd;
87 	struct ec2_request *request;
88 	struct grecs_node *xmltree;
89 };
90 
91 typedef struct eclat_command_env eclat_command_env_t;
92 
93 typedef int (*eclat_command_handler_t) (eclat_command_env_t *env, int argc, char **argv);
94 
95 struct eclat_command {
96 	const char *name;
97 	const char *ident;
98 	const char *tag;
99 	eclat_command_handler_t handler;
100 	int flags;
101 	enum eclat_confirm_mode confirm;
102 	char *fmt;
103 	struct grecs_locus locus;
104 };
105 
106 struct eclat_command *find_command_name(const char *name);
107 int eclat_do_command(eclat_command_env_t *env, struct eclat_command *command,
108 		     int argc, char **argv);
109 
110 struct eclat_io {
111 	XML_Parser parser;
112 	eclat_partial_tree_t part;
113 	CURL *curl;
114 };
115 
116 struct eclat_io *eclat_io_init(int errfatal);
117 void eclat_io_free(struct eclat_io *io);
118 void eclat_io_shutdown(struct eclat_io *io);
119 struct grecs_node *eclat_io_finish(struct eclat_io *io);
120 
121 int eclat_trace_fun(CURL *handle, curl_infotype type,
122 		    char *data, size_t size,
123 		    void *userp);
124 
125 
126 int eclat_start_instance(eclat_command_env_t *env, int argc, char **argv);
127 int eclat_stop_instance(eclat_command_env_t *env, int argc, char **argv);
128 int eclat_reboot_instance(eclat_command_env_t *env, int argc, char **argv);
129 int eclat_describe_tags(eclat_command_env_t *env, int argc, char **argv);
130 int eclat_describe_instance_status(eclat_command_env_t *env, int argc, char **argv);
131 int eclat_describe_instances(eclat_command_env_t *env, int argc, char **argv);
132 int eclat_allocate_address(eclat_command_env_t *env, int argc, char **argv);
133 int eclat_release_address(eclat_command_env_t *env, int argc, char **argv);
134 int eclat_associate_address(eclat_command_env_t *env, int argc, char **argv);
135 int eclat_disassociate_address(eclat_command_env_t *env, int argc, char **argv);
136 int eclat_describe_addresses(eclat_command_env_t *env, int argc, char **argv);
137 int eclat_describe_volumes(eclat_command_env_t *env, int argc, char **argv);
138 int eclat_get_console_output(eclat_command_env_t *env, int argc, char **argv);
139 int eclat_describe_instance_attribute(eclat_command_env_t *env, int argc, char **argv);
140 int eclat_create_tags(eclat_command_env_t *env, int argc, char **argv);
141 int eclat_delete_tags(eclat_command_env_t *env, int argc, char **argv);
142 int eclat_describe_security_groups(eclat_command_env_t *env, int argc, char **argv);
143 int eclat_create_snapshot(eclat_command_env_t *env, int argc, char **argv);
144 int eclat_describe_snapshots(eclat_command_env_t *env, int argc, char **argv);
145 int eclat_delete_snapshot(eclat_command_env_t *env, int argc, char **argv);
146 int eclat_describe_snapshot_attribute(eclat_command_env_t *env,
147 				      int argc, char **argv);
148 int eclat_modify_snapshot_attribute(eclat_command_env_t *env,
149 				    int argc, char **argv);
150 int eclat_reset_snapshot_attribute(eclat_command_env_t *env,
151 				   int argc, char **argv);
152 
153 int eclat_describe_avaialbility_zones(eclat_command_env_t *env, int argc, char **argv);
154 int eclat_describe_regions(eclat_command_env_t *env, int argc, char **argv);
155 int eclat_create_volume(eclat_command_env_t *env, int argc, char **argv);
156 int eclat_delete_volume(eclat_command_env_t *env, int argc, char **argv);
157 int eclat_attach_volume(eclat_command_env_t *env, int argc, char **argv);
158 int eclat_detach_volume(eclat_command_env_t *env, int argc, char **argv);
159 int eclat_modify_instance_attribute(eclat_command_env_t *env,
160 				    int argc, char **argv);
161 int eclat_run_instances(eclat_command_env_t *env, int argc, char **argv);
162 int eclat_describe_images(eclat_command_env_t *env, int argc, char **argv);
163 int eclat_create_image(eclat_command_env_t *env, int argc, char **argv);
164 int eclat_deregister_image(eclat_command_env_t *env, int argc, char **argv);
165 int eclat_copy_image(eclat_command_env_t *env, int argc, char **argv);
166 int eclat_copy_snapshot(eclat_command_env_t *env, int argc, char **argv);
167 int eclat_sg(eclat_command_env_t *env, int argc, char **argv);
168 
169 int eclat_describe_vpcs(eclat_command_env_t *env, int argc, char **argv);
170 int eclat_describe_vpc_attribute(eclat_command_env_t *env, int argc, char **argv);
171 int eclat_modify_vpc_attribute(eclat_command_env_t *env, int argc, char **argv);
172 int eclat_delete_vpc(eclat_command_env_t *env, int argc, char **argv);
173 
174 int eclat_create_internet_gateway(eclat_command_env_t *env,
175 				  int argc, char **argv);
176 int eclat_delete_internet_gateway(eclat_command_env_t *env,
177 				  int argc, char **argv);
178 int eclat_describe_internet_gateways(eclat_command_env_t *env,
179 				     int argc, char **argv);
180 int eclat_attach_internet_gateway(eclat_command_env_t *env,
181 				  int argc, char **argv);
182 int eclat_detach_internet_gateway(eclat_command_env_t *env,
183 				  int argc, char **argv);
184 
185 int eclat_create_subnet(eclat_command_env_t *env, int argc, char **argv);
186 int eclat_describe_subnets(eclat_command_env_t *env,
187 			   int argc, char **argv);
188 int eclat_modify_subnet_attribute(eclat_command_env_t *env,
189 				  int argc, char **argv);
190 int eclat_delete_subnet(eclat_command_env_t *env, int argc, char **argv);
191 
192 int eclat_create_route_table(eclat_command_env_t *env, int argc, char **argv);
193 int eclat_delete_route_table(eclat_command_env_t *env, int argc, char **argv);
194 int eclat_describe_route_tables(eclat_command_env_t *env,
195 				int argc, char **argv);
196 int eclat_associate_route_table(eclat_command_env_t *env,
197 				int argc, char **argv);
198 int eclat_disassociate_route_table(eclat_command_env_t *env,
199 				   int argc, char **argv);
200 int eclat_route(eclat_command_env_t *env, int argc, char **argv);
201 
202 int eclat_create_security_group(eclat_command_env_t *env,
203 				int argc, char **argv);
204 int eclat_delete_security_group(eclat_command_env_t *env,
205 				int argc, char **argv);
206 
207 int eclat_describe_image_attribute(eclat_command_env_t *env,
208 				   int argc, char **argv);
209 int eclat_modify_image_attribute(eclat_command_env_t *env,
210 				 int argc, char **argv);
211 
212 int eclat_lsattr(eclat_command_env_t *env, int argc, char **argv);
213 int eclat_create_vpc(eclat_command_env_t *env, int argc, char **argv);
214 
215 char *region_to_endpoint(const char *region);
216 
217 void define_format(const char *name, const char *format, grecs_locus_t *locus);
218 void set_command_format(const char *name, const char *format,
219 			grecs_locus_t *locus);
220 
221 void describe_request_create(eclat_command_env_t *env, int argc, char **argv,
222 			   const char *uparm);
223 void describe_request_update(eclat_command_env_t *env, int argc, char **argv,
224 			   const char *uparm, int n_in, int *n_out);
225 
226 int eclat_send_request(struct ec2_request *q, struct grecs_node **ret);
227 char *eclat_get_instance_zone(void);
228 void eclat_get_instance_creds(char *id,
229 			      char **access_key_ptr, char **secret_key_ptr,
230 			      char **token_ptr);
231 
232 int eclat_actcmp(const char *a, const char *b);
233 
234 #define XML_DUMP_FILE_NAME "eclat.dump.xml"
235 
236 #define FILTER_STRING 0
237 #define FILTER_DATE   1
238 #define FILTER_BOOL   2
239 #define FILTER_INT    3
240 #define FILTER_ENUM   4
241 
242 struct filter_descr {
243 	char *name;
244 	int type;
245 	char **avail;
246 };
247 
248 extern struct filter_descr *available_filters;
249 
250 void list_filters(FILE *fp);
251 
252 extern char **available_attrs;
253 void list_attrs(FILE *fp);
254 char *canonattrname(char **attrs, const char *arg, char *delim,
255 		    size_t *plen);
256 char *read_file(const char *file);
257 
258 int get_scr_cols(void);
259 
260 #define MAP_IMAGE       "ImageId"
261 #define MAP_INSTANCE    "InstanceId"
262 #define MAP_GROUPID     "GroupId"
263 #define MAP_GROUPNAME   "GroupName"
264 #define MAP_SNAPSHOT    "SnapshotId"
265 #define MAP_VOLUME      "VolumeId"
266 #define MAP_AZ          "AZ"
267 #define MAP_REG         "reg"
268 #define MAP_VPC         "VpcId"
269 #define MAP_IGW         "InternetGatewayId"
270 #define MAP_SUBNET      "SubnetId"
271 #define MAP_ROUTE_TABLE "RouteTableId"
272 
273 void translate_ids(int argc, char **argv, const char *map);
274 void translate_resource_ids(int argc, char **argv);
275 void eclat_encode_devmap(struct ec2_request *q, struct grecs_list *list);
276 
277 int get_access_creds(const char *id, char **access_key_ptr,
278 		     char **secret_key_ptr);
279 
280 void define_format(const char *name, const char *fmt, grecs_locus_t *loc);
281 forlan_eval_env_t find_format(const char *name);
282 
283 void generic_parse_options(struct eclat_command const *command,
284 			   const char *docstring,
285 			   int argc, char *argv[], int *index);
286 extern struct grecs_proginfo *generic_proginfo;
287 
288 void set_command_confirmation(const char *name, enum eclat_confirm_mode cfmode,
289 			      grecs_locus_t *locus);
290 
291 extern struct eclat_map_drv eclat_map_drv_ec2;
292 
293