elastomer-cli 0.2.3 → 0.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: b09a4148ac027157b8a858b8ca3efcd450195728
4
- data.tar.gz: 9f8b7f6b2c1a4d5a4e758a204acf35c446763ceb
3
+ metadata.gz: f328a782ba08c595c135c9cd83fcb4e731e9e07e
4
+ data.tar.gz: fc1e5586bfe819fd7f77fe0a1e5dd076196782d0
5
5
  SHA512:
6
- metadata.gz: 839e9ea2e84aad6f21ee6353ef82a5b1f1ea26cdf384eefb7ec77919ab9a2aec4b54f63abe373626bf465f163477a0cb903c6fa9200a857d0ba3545230df5490
7
- data.tar.gz: 322853197e039d9886ec4b4373f0ebc01f0a9f3bf67bb8c8a1b603c4728acb641d0517f45dae09ec4f1c08d7a3742eb892f92bf595dc774dc99723055afee859
6
+ metadata.gz: fd31f955bbb5c0fdd1b5440aa2c43501ffafa4fc678fce7674eed8616c906714f51f807285a862995e4f47cab9602e16b429123db234fa2c4d357ad9e0aff172
7
+ data.tar.gz: 1434e4bf4b9e04e2f8abc2e883a4dcf5b3b6b079ec9ab4771940358fd9bf97ca15f256a31d030820250360172e0e1c090d97a3872bf20e3e7e186f6c67357d51
data/CHANGELOG.md CHANGED
@@ -1,3 +1,18 @@
1
+ ## 0.3.0 (2014-12-12)
2
+ - New repository commands:
3
+ - `repository create`
4
+ - `repository get`
5
+ - `repository list`
6
+ - `repository delete`
7
+ - New snapshot commands:
8
+ - `snapshot create`
9
+ - `snapshot get`
10
+ - `snapshot list`
11
+ - `snapshot status`
12
+ - `snapshot restore`
13
+ - `snapshot delete`
14
+ - `cat help` now works correctly
15
+ - cat can now take query params in key=value syntax
1
16
  ## 0.2.3 (2014-10-21)
2
17
  - Nonzero exit status if command fails
3
18
  - New command:
@@ -4,30 +4,49 @@ module Elastomer
4
4
 
5
5
  desc "cluster SUBCOMMAND ...ARGS", "execute cluster commands"
6
6
  subcommand "cluster", Cluster
7
+
7
8
  desc "node SUBCOMMAND ...ARGS", "execute node commands"
8
9
  subcommand "node", Node
10
+
9
11
  desc "index SUBCOMMAND ...ARGS", "execute index commands"
10
12
  subcommand "index", Index
11
13
 
12
- desc "cat [COMMAND] [SCOPE]", "access the ES cat api"
14
+ desc "repository SUBCOMMAND ...ARGS", "execute repository commands"
15
+ subcommand "repository", Repository
16
+
17
+ desc "snapshot SUBCOMMAND ...ARGS", "execute snapshot commands"
18
+ subcommand "snapshot", Snapshot
19
+
20
+ desc "cat [COMMAND] [SCOPE] ...ARGS", "access the ES cat api"
13
21
  long_desc <<-LONGDESC
14
22
  Access the ES cat api. The cat api returns text formatted for humans.
15
23
 
16
- The command 'cat help' will list the available cat commands, as
24
+ The command `cat help` will list the available cat commands, as
17
25
  will 'cat' without a command.
18
26
 
19
- 'cat help <command>' will print a list of fields available from the
27
+ `cat help <command>` will print a list of fields available from the
20
28
  specified command.
21
29
 
30
+ You may pass an optional scope as the second argument to commands that
31
+ use it:
32
+ cat indices tw*
33
+
34
+ Other parameters may be given in key=value form. Specify fields with
35
+ the `h` parameter:
36
+ cat nodes h=name v=false
37
+ cat indices tw* h=index,health
38
+
22
39
  See http://www.elasticsearch.org/guide/en/elasticsearch/reference/current/cat.html
23
40
  LONGDESC
24
- def cat(command=nil, scope=nil)
25
- params = {:v => true}
41
+ def cat(command=nil, *args)
42
+ scope, params = extract_cat_scope(*args)
43
+ params = {'v' => true}.merge(params)
26
44
  if command == 'help'
27
45
  command = nil
28
- if !scope.empty?
46
+ if scope && !scope.empty?
29
47
  command = scope
30
- params[:help] = true
48
+ scope = nil
49
+ params['help'] = true
31
50
  end
32
51
  end
33
52
  template = Addressable::Template.new("/_cat{/command}{/scope}")
@@ -35,6 +54,20 @@ module Elastomer
35
54
  response = client.request(:get, path, params).body
36
55
  puts response
37
56
  end
57
+
58
+ private
59
+ def extract_cat_scope(*args)
60
+ scope = nil
61
+ params = {}
62
+ args.each do |arg|
63
+ if match = arg.match(/(.+)=(.+)/)
64
+ params[match.captures[0]] = match.captures[1]
65
+ else
66
+ scope = arg
67
+ end
68
+ end
69
+ [scope, params]
70
+ end
38
71
  end
39
72
  end
40
73
  end
@@ -7,10 +7,10 @@ module Elastomer
7
7
 
8
8
  protected
9
9
  def client
10
- # Elastomer::Client requires symbol keys, but options returns
11
- # string keys
10
+ # Elastomer::Client requires symbol keys, but options returns string
11
+ # keys
12
12
  @client ||= Elastomer::Client.new(
13
- :url => options[:url] || 'http://localhost:9200',
13
+ :url => options[:url] || ENV['BOXEN_ELASTICSEARCH_URL'] || 'http://localhost:9200',
14
14
  :read_timeout => options[:read_timeout],
15
15
  :open_timeout => options[:open_timeout]
16
16
  )
@@ -0,0 +1,32 @@
1
+ module Elastomer
2
+ module CLI
3
+ class Repository < Base
4
+ desc "create NAME", "create a snapshot repository called NAME"
5
+ option :type, :required => true
6
+ option :settings, :required => true, :desc => "repository settings as JSON"
7
+ def create(name)
8
+ options[:settings] = MultiJson.load(options[:settings])
9
+ response = client.repository(name).create(options, :pretty => true)
10
+ puts response
11
+ end
12
+
13
+ desc "get [NAME]", "get repository NAME"
14
+ def get(name=nil)
15
+ response = client.repository(name).get(:pretty => true)
16
+ puts response
17
+ end
18
+
19
+ desc "list", "list all repositories"
20
+ def list
21
+ response = client.repository.get
22
+ puts response
23
+ end
24
+
25
+ desc "delete NAME", "delete repository NAME"
26
+ def delete(name)
27
+ response = client.repository(name).delete
28
+ puts "Deleted repository #{name}."
29
+ end
30
+ end
31
+ end
32
+ end
@@ -0,0 +1,112 @@
1
+ module Elastomer
2
+ module CLI
3
+ class Snapshot < Base
4
+
5
+ desc "create REPOSITORY NAME", "create snapshot NAME in REPOSITORY"
6
+ option :indices
7
+ option :ignore_unavailable, :type => :boolean
8
+ option :partial, :type => :boolean
9
+ option :include_global_state, :type => :boolean
10
+ option :wait_for_completion, :type => :boolean, :aliases => "wait" #TODO why doesn't the alias work?
11
+ long_desc <<-LONGDESC
12
+ LONGDESC
13
+ def create(repository, name)
14
+ wait = !!options.delete(:wait_for_completion)
15
+ puts "Waiting for snapshot completion..." if wait
16
+ response = client.snapshot(repository, name).create(options, :wait_for_completion => wait, :pretty => true)
17
+ puts response
18
+ end
19
+
20
+ desc "get REPOSITORY [NAME]", "get info for snapshot NAME in REPOSITORY"
21
+ def get(repository, name=nil)
22
+ response = client.snapshot(repository, name).get(:pretty => true)
23
+ puts response
24
+ end
25
+
26
+ desc "list [REPOSITORY]", "list snapshots in REPOSITORY"
27
+ def list(repository)
28
+ response = client.snapshot(repository).get(:pretty => true)
29
+ puts Terminal::Table.new(
30
+ :headings => ['NAME', 'STATE', 'DURATION', 'START TIME', 'INDICES'],
31
+ :rows => response["snapshots"].collect do |snapshot|
32
+ [
33
+ snapshot["snapshot"],
34
+ snapshot["state"],
35
+ "%2.3fs" % (snapshot["duration_in_millis"] / 1000.0),
36
+ snapshot["start_time"],
37
+ snapshot["indices"].count,
38
+ ]
39
+ end
40
+ )
41
+ end
42
+
43
+ desc "status [REPOSITORY] [NAME]", "get status of snapshot NAME in REPOSITORY"
44
+ def status(repository=nil, name=nil)
45
+ response = client.snapshot(repository, name).status(:pretty => true)
46
+ response["snapshots"].each do |snapshot|
47
+ puts Terminal::Table.new(
48
+ :headings => ["SNAPSHOT STATUS", snapshot["snapshot"]],
49
+ :rows => [
50
+ ["Repository", snapshot["repository"]],
51
+ ["State", snapshot["state"]],
52
+ ["Start Time", Time.at(snapshot["stats"]["start_time_in_millis"].to_i / 1000)],
53
+ ["Duration", "%2.3fs" % (snapshot["stats"]["time_in_millis"] / 1000.0)],
54
+ ["Processed Files", processed_files(snapshot)],
55
+ ["Processed Bytes", processed_bytes(snapshot)],
56
+ ["Shard Status", shard_status(snapshot)],
57
+ ["Shards Failed", snapshot["shards_stats"]["failed"]],
58
+ ["Total Shards", snapshot["shards_stats"]["total"]],
59
+ ["Total Indices", snapshot["indices"].size],
60
+ ]
61
+ )
62
+ end
63
+ end
64
+
65
+ desc "restore REPOSITORY NAME", "restore snapshot NAME from REPOSITORY"
66
+ option :indices
67
+ option :ignore_unavailable, :type => :boolean
68
+ option :partial, :type => :boolean
69
+ option :include_global_state, :type => :boolean
70
+ option :wait_for_completion, :type => :boolean, :default => true, :aliases => "wait" #TODO why doesn't the alias work?
71
+ option :rename_pattern
72
+ option :rename_replacement
73
+ def restore(repository, name)
74
+ wait = options.delete(:wait_for_completion)
75
+ response = client.snapshot(repository, name).restore(options, :wait_for_completion => wait, :pretty => true)
76
+ puts response
77
+ end
78
+
79
+ desc "delete REPOSITORY NAME", "delete snapshot NAME in REPOSITORY"
80
+ def delete(repository, name)
81
+ response = client.snapshot(repository, name).delete
82
+ puts "Successfully deleted #{name} in #{repository}"
83
+ end
84
+
85
+ private
86
+ def processed_files(snapshot)
87
+ total = snapshot["stats"]["number_of_files"]
88
+ processed = snapshot["stats"]["processed_files"]
89
+
90
+ "%.1f%% (%d / %d)" % [processed / total.to_f * 100, processed, total]
91
+ end
92
+
93
+ def processed_bytes(snapshot)
94
+ total = snapshot["stats"]["total_size_in_bytes"]
95
+ processed = snapshot["stats"]["processed_size_in_bytes"]
96
+
97
+ "%.1f%% (%d / %d)" % [processed / total.to_f * 100, processed, total]
98
+ end
99
+
100
+ def shard_status(snapshot)
101
+ status = []
102
+ %w(initializing started finalizing done).each do |state|
103
+ count = snapshot["shards_stats"][state]
104
+ if count > 0
105
+ status << "#{count} #{state}"
106
+ end
107
+ end
108
+ status.join(", ")
109
+ end
110
+ end
111
+ end
112
+ end
@@ -1,5 +1,5 @@
1
1
  module Elastomer
2
2
  module Cli
3
- VERSION = "0.2.3"
3
+ VERSION = "0.3.0"
4
4
  end
5
5
  end
data/lib/elastomer/cli.rb CHANGED
@@ -8,6 +8,8 @@ require 'elastomer/cli/base'
8
8
  require 'elastomer/cli/cluster'
9
9
  require 'elastomer/cli/node'
10
10
  require 'elastomer/cli/index'
11
+ require 'elastomer/cli/repository'
12
+ require 'elastomer/cli/snapshot'
11
13
 
12
14
  require 'elastomer/cli/application'
13
15
 
data/script/console CHANGED
@@ -6,7 +6,7 @@ require 'bundler/setup'
6
6
  require 'elastomer/cli'
7
7
 
8
8
  def client
9
- @client ||= Elastomer::Client.new
9
+ @client ||= Elastomer::Client.new(:url => ENV['BOXEN_ELASTICSEARCH_URL'] || 'http://localhost:9200')
10
10
  end
11
11
 
12
12
  IRB.start
@@ -0,0 +1,595 @@
1
+ ---
2
+ http_interactions:
3
+ - request:
4
+ method: get
5
+ uri: http://127.0.0.1:19200/_snapshot/repo1/_all?pretty=true
6
+ body:
7
+ encoding: US-ASCII
8
+ string: ''
9
+ headers:
10
+ User-Agent:
11
+ - Faraday v0.9.0
12
+ Accept-Encoding:
13
+ - gzip;q=1.0,deflate;q=0.6,identity;q=0.3
14
+ Accept:
15
+ - "*/*"
16
+ response:
17
+ status:
18
+ code: 200
19
+ message: OK
20
+ headers:
21
+ Content-Type:
22
+ - application/json; charset=UTF-8
23
+ Content-Length:
24
+ - '839'
25
+ body:
26
+ encoding: UTF-8
27
+ string: |
28
+ {
29
+ "snapshots" : [ {
30
+ "snapshot" : "snapshot1",
31
+ "indices" : [ "index1" ],
32
+ "state" : "SUCCESS",
33
+ "start_time" : "2014-12-10T20:13:28.761Z",
34
+ "start_time_in_millis" : 1418242408761,
35
+ "end_time" : "2014-12-10T20:13:28.781Z",
36
+ "end_time_in_millis" : 1418242408781,
37
+ "duration_in_millis" : 20,
38
+ "failures" : [ ],
39
+ "shards" : {
40
+ "total" : 1,
41
+ "failed" : 0,
42
+ "successful" : 1
43
+ }
44
+ }, {
45
+ "snapshot" : "snapshot2",
46
+ "indices" : [ "index1" ],
47
+ "state" : "SUCCESS",
48
+ "start_time" : "2014-12-10T20:13:32.136Z",
49
+ "start_time_in_millis" : 1418242412136,
50
+ "end_time" : "2014-12-10T20:13:32.155Z",
51
+ "end_time_in_millis" : 1418242412155,
52
+ "duration_in_millis" : 19,
53
+ "failures" : [ ],
54
+ "shards" : {
55
+ "total" : 1,
56
+ "failed" : 0,
57
+ "successful" : 1
58
+ }
59
+ } ]
60
+ }
61
+ http_version:
62
+ recorded_at: Wed, 10 Dec 2014 20:39:45 GMT
63
+ - request:
64
+ method: get
65
+ uri: http://127.0.0.1:19200/_snapshot/repo1/snapshot1/_status?pretty=true
66
+ body:
67
+ encoding: US-ASCII
68
+ string: ''
69
+ headers:
70
+ User-Agent:
71
+ - Faraday v0.9.0
72
+ Accept-Encoding:
73
+ - gzip;q=1.0,deflate;q=0.6,identity;q=0.3
74
+ Accept:
75
+ - "*/*"
76
+ response:
77
+ status:
78
+ code: 200
79
+ message: OK
80
+ headers:
81
+ Content-Type:
82
+ - application/json; charset=UTF-8
83
+ Content-Length:
84
+ - '1374'
85
+ body:
86
+ encoding: UTF-8
87
+ string: |
88
+ {
89
+ "snapshots" : [ {
90
+ "snapshot" : "snapshot1",
91
+ "repository" : "repo1",
92
+ "state" : "SUCCESS",
93
+ "shards_stats" : {
94
+ "initializing" : 0,
95
+ "started" : 0,
96
+ "finalizing" : 0,
97
+ "done" : 1,
98
+ "failed" : 0,
99
+ "total" : 1
100
+ },
101
+ "stats" : {
102
+ "number_of_files" : 1,
103
+ "processed_files" : 1,
104
+ "total_size_in_bytes" : 79,
105
+ "processed_size_in_bytes" : 79,
106
+ "start_time_in_millis" : 1418242408779,
107
+ "time_in_millis" : 1
108
+ },
109
+ "indices" : {
110
+ "index1" : {
111
+ "shards_stats" : {
112
+ "initializing" : 0,
113
+ "started" : 0,
114
+ "finalizing" : 0,
115
+ "done" : 1,
116
+ "failed" : 0,
117
+ "total" : 1
118
+ },
119
+ "stats" : {
120
+ "number_of_files" : 1,
121
+ "processed_files" : 1,
122
+ "total_size_in_bytes" : 79,
123
+ "processed_size_in_bytes" : 79,
124
+ "start_time_in_millis" : 1418242408779,
125
+ "time_in_millis" : 1
126
+ },
127
+ "shards" : {
128
+ "0" : {
129
+ "stage" : "DONE",
130
+ "stats" : {
131
+ "number_of_files" : 1,
132
+ "processed_files" : 1,
133
+ "total_size_in_bytes" : 79,
134
+ "processed_size_in_bytes" : 79,
135
+ "start_time_in_millis" : 1418242408779,
136
+ "time_in_millis" : 1
137
+ }
138
+ }
139
+ }
140
+ }
141
+ }
142
+ } ]
143
+ }
144
+ http_version:
145
+ recorded_at: Wed, 10 Dec 2014 20:39:45 GMT
146
+ - request:
147
+ method: put
148
+ uri: http://127.0.0.1:19200/_snapshot/repo1/snapshot3?pretty=true&wait_for_completion=true
149
+ body:
150
+ encoding: UTF-8
151
+ string: "{\"indices\":\"index1\"}"
152
+ headers:
153
+ User-Agent:
154
+ - Faraday v0.9.0
155
+ Content-Type:
156
+ - application/json
157
+ Accept-Encoding:
158
+ - gzip;q=1.0,deflate;q=0.6,identity;q=0.3
159
+ Accept:
160
+ - "*/*"
161
+ response:
162
+ status:
163
+ code: 200
164
+ message: OK
165
+ headers:
166
+ Content-Type:
167
+ - application/json; charset=UTF-8
168
+ Content-Length:
169
+ - '426'
170
+ body:
171
+ encoding: UTF-8
172
+ string: |
173
+ {
174
+ "snapshot" : {
175
+ "snapshot" : "snapshot3",
176
+ "indices" : [ "index1" ],
177
+ "state" : "SUCCESS",
178
+ "start_time" : "2014-12-10T20:39:45.376Z",
179
+ "start_time_in_millis" : 1418243985376,
180
+ "end_time" : "2014-12-10T20:39:45.400Z",
181
+ "end_time_in_millis" : 1418243985400,
182
+ "duration_in_millis" : 24,
183
+ "failures" : [ ],
184
+ "shards" : {
185
+ "total" : 1,
186
+ "failed" : 0,
187
+ "successful" : 1
188
+ }
189
+ }
190
+ }
191
+ http_version:
192
+ recorded_at: Wed, 10 Dec 2014 20:39:45 GMT
193
+ - request:
194
+ method: get
195
+ uri: http://127.0.0.1:19200/_snapshot/repo1/snapshot1?pretty=true
196
+ body:
197
+ encoding: US-ASCII
198
+ string: ''
199
+ headers:
200
+ User-Agent:
201
+ - Faraday v0.9.0
202
+ Accept-Encoding:
203
+ - gzip;q=1.0,deflate;q=0.6,identity;q=0.3
204
+ Accept:
205
+ - "*/*"
206
+ response:
207
+ status:
208
+ code: 200
209
+ message: OK
210
+ headers:
211
+ Content-Type:
212
+ - application/json; charset=UTF-8
213
+ Content-Length:
214
+ - '431'
215
+ body:
216
+ encoding: UTF-8
217
+ string: |
218
+ {
219
+ "snapshots" : [ {
220
+ "snapshot" : "snapshot1",
221
+ "indices" : [ "index1" ],
222
+ "state" : "SUCCESS",
223
+ "start_time" : "2014-12-10T20:13:28.761Z",
224
+ "start_time_in_millis" : 1418242408761,
225
+ "end_time" : "2014-12-10T20:13:28.781Z",
226
+ "end_time_in_millis" : 1418242408781,
227
+ "duration_in_millis" : 20,
228
+ "failures" : [ ],
229
+ "shards" : {
230
+ "total" : 1,
231
+ "failed" : 0,
232
+ "successful" : 1
233
+ }
234
+ } ]
235
+ }
236
+ http_version:
237
+ recorded_at: Wed, 10 Dec 2014 20:39:45 GMT
238
+ - request:
239
+ method: delete
240
+ uri: http://127.0.0.1:19200/_snapshot/repo1/snapshot1
241
+ body:
242
+ encoding: US-ASCII
243
+ string: ''
244
+ headers:
245
+ User-Agent:
246
+ - Faraday v0.9.0
247
+ Accept-Encoding:
248
+ - gzip;q=1.0,deflate;q=0.6,identity;q=0.3
249
+ Accept:
250
+ - "*/*"
251
+ response:
252
+ status:
253
+ code: 200
254
+ message: OK
255
+ headers:
256
+ Content-Type:
257
+ - application/json; charset=UTF-8
258
+ Content-Length:
259
+ - '21'
260
+ body:
261
+ encoding: UTF-8
262
+ string: "{\"acknowledged\":true}"
263
+ http_version:
264
+ recorded_at: Wed, 10 Dec 2014 20:42:22 GMT
265
+ - request:
266
+ method: post
267
+ uri: http://127.0.0.1:19200/_snapshot/repo1/snapshot2/_restore?pretty=true&wait_for_completion=true
268
+ body:
269
+ encoding: UTF-8
270
+ string: "{\"indices\":\"index1\",\"rename_pattern\":\"(.+)\",\"rename_replacement\":\"restored_$1\"}"
271
+ headers:
272
+ User-Agent:
273
+ - Faraday v0.9.0
274
+ Content-Type:
275
+ - application/json
276
+ Accept-Encoding:
277
+ - gzip;q=1.0,deflate;q=0.6,identity;q=0.3
278
+ Accept:
279
+ - "*/*"
280
+ response:
281
+ status:
282
+ code: 200
283
+ message: OK
284
+ headers:
285
+ Content-Type:
286
+ - application/json; charset=UTF-8
287
+ Content-Length:
288
+ - '179'
289
+ body:
290
+ encoding: UTF-8
291
+ string: |
292
+ {
293
+ "snapshot" : {
294
+ "snapshot" : "snapshot2",
295
+ "indices" : [ "restored_index1" ],
296
+ "shards" : {
297
+ "total" : 1,
298
+ "failed" : 0,
299
+ "successful" : 1
300
+ }
301
+ }
302
+ }
303
+ http_version:
304
+ recorded_at: Wed, 10 Dec 2014 20:52:49 GMT
305
+ - request:
306
+ method: put
307
+ uri: http://127.0.0.1:19200/_snapshot/repo1/snapshot4?pretty=true&wait_for_completion=false
308
+ body:
309
+ encoding: UTF-8
310
+ string: "{\"indices\":\"index1\"}"
311
+ headers:
312
+ User-Agent:
313
+ - Faraday v0.9.0
314
+ Content-Type:
315
+ - application/json
316
+ Accept-Encoding:
317
+ - gzip;q=1.0,deflate;q=0.6,identity;q=0.3
318
+ Accept:
319
+ - "*/*"
320
+ response:
321
+ status:
322
+ code: 200
323
+ message: OK
324
+ headers:
325
+ Content-Type:
326
+ - application/json; charset=UTF-8
327
+ Content-Length:
328
+ - '24'
329
+ body:
330
+ encoding: UTF-8
331
+ string: |
332
+ {
333
+ "accepted" : true
334
+ }
335
+ http_version:
336
+ recorded_at: Wed, 10 Dec 2014 21:09:22 GMT
337
+ - request:
338
+ method: get
339
+ uri: http://127.0.0.1:19200/_snapshot/repo1/snapshot2/_status?pretty=true
340
+ body:
341
+ encoding: US-ASCII
342
+ string: ''
343
+ headers:
344
+ User-Agent:
345
+ - Faraday v0.9.0
346
+ Accept-Encoding:
347
+ - gzip;q=1.0,deflate;q=0.6,identity;q=0.3
348
+ Accept:
349
+ - "*/*"
350
+ response:
351
+ status:
352
+ code: 200
353
+ message: OK
354
+ headers:
355
+ Content-Type:
356
+ - application/json; charset=UTF-8
357
+ Content-Length:
358
+ - '1374'
359
+ body:
360
+ encoding: UTF-8
361
+ string: |
362
+ {
363
+ "snapshots" : [ {
364
+ "snapshot" : "snapshot2",
365
+ "repository" : "repo1",
366
+ "state" : "SUCCESS",
367
+ "shards_stats" : {
368
+ "initializing" : 0,
369
+ "started" : 0,
370
+ "finalizing" : 0,
371
+ "done" : 1,
372
+ "failed" : 0,
373
+ "total" : 1
374
+ },
375
+ "stats" : {
376
+ "number_of_files" : 1,
377
+ "processed_files" : 1,
378
+ "total_size_in_bytes" : 79,
379
+ "processed_size_in_bytes" : 79,
380
+ "start_time_in_millis" : 1418242412153,
381
+ "time_in_millis" : 1
382
+ },
383
+ "indices" : {
384
+ "index1" : {
385
+ "shards_stats" : {
386
+ "initializing" : 0,
387
+ "started" : 0,
388
+ "finalizing" : 0,
389
+ "done" : 1,
390
+ "failed" : 0,
391
+ "total" : 1
392
+ },
393
+ "stats" : {
394
+ "number_of_files" : 1,
395
+ "processed_files" : 1,
396
+ "total_size_in_bytes" : 79,
397
+ "processed_size_in_bytes" : 79,
398
+ "start_time_in_millis" : 1418242412153,
399
+ "time_in_millis" : 1
400
+ },
401
+ "shards" : {
402
+ "0" : {
403
+ "stage" : "DONE",
404
+ "stats" : {
405
+ "number_of_files" : 1,
406
+ "processed_files" : 1,
407
+ "total_size_in_bytes" : 79,
408
+ "processed_size_in_bytes" : 79,
409
+ "start_time_in_millis" : 1418242412153,
410
+ "time_in_millis" : 1
411
+ }
412
+ }
413
+ }
414
+ }
415
+ }
416
+ } ]
417
+ }
418
+ http_version:
419
+ recorded_at: Wed, 10 Dec 2014 21:10:44 GMT
420
+ - request:
421
+ method: get
422
+ uri: http://127.0.0.1:19200/_snapshot/repo1?pretty=true
423
+ body:
424
+ encoding: US-ASCII
425
+ string: ''
426
+ headers:
427
+ User-Agent:
428
+ - Faraday v0.9.0
429
+ Accept-Encoding:
430
+ - gzip;q=1.0,deflate;q=0.6,identity;q=0.3
431
+ Accept:
432
+ - "*/*"
433
+ response:
434
+ status:
435
+ code: 200
436
+ message: OK
437
+ headers:
438
+ Content-Type:
439
+ - application/json; charset=UTF-8
440
+ Content-Length:
441
+ - '98'
442
+ body:
443
+ encoding: UTF-8
444
+ string: |
445
+ {
446
+ "repo1" : {
447
+ "type" : "fs",
448
+ "settings" : {
449
+ "location" : "/tmp/repo1"
450
+ }
451
+ }
452
+ }
453
+ http_version:
454
+ recorded_at: Wed, 10 Dec 2014 21:27:44 GMT
455
+ - request:
456
+ method: get
457
+ uri: http://127.0.0.1:19200/_snapshot
458
+ body:
459
+ encoding: US-ASCII
460
+ string: ''
461
+ headers:
462
+ User-Agent:
463
+ - Faraday v0.9.0
464
+ Accept-Encoding:
465
+ - gzip;q=1.0,deflate;q=0.6,identity;q=0.3
466
+ Accept:
467
+ - "*/*"
468
+ response:
469
+ status:
470
+ code: 200
471
+ message: OK
472
+ headers:
473
+ Content-Type:
474
+ - application/json; charset=UTF-8
475
+ Content-Length:
476
+ - '119'
477
+ body:
478
+ encoding: UTF-8
479
+ string: "{\"repo1\":{\"type\":\"fs\",\"settings\":{\"location\":\"/tmp/repo1\"}},\"repo2\":{\"type\":\"fs\",\"settings\":{\"location\":\"/tmp/repo2\"}}}"
480
+ http_version:
481
+ recorded_at: Wed, 10 Dec 2014 21:31:24 GMT
482
+ - request:
483
+ method: delete
484
+ uri: http://127.0.0.1:19200/_snapshot/repo1
485
+ body:
486
+ encoding: US-ASCII
487
+ string: ''
488
+ headers:
489
+ User-Agent:
490
+ - Faraday v0.9.0
491
+ Accept-Encoding:
492
+ - gzip;q=1.0,deflate;q=0.6,identity;q=0.3
493
+ Accept:
494
+ - "*/*"
495
+ response:
496
+ status:
497
+ code: 200
498
+ message: OK
499
+ headers:
500
+ Content-Type:
501
+ - application/json; charset=UTF-8
502
+ Content-Length:
503
+ - '21'
504
+ body:
505
+ encoding: UTF-8
506
+ string: "{\"acknowledged\":true}"
507
+ http_version:
508
+ recorded_at: Wed, 10 Dec 2014 21:32:34 GMT
509
+ - request:
510
+ method: put
511
+ uri: http://127.0.0.1:19200/_snapshot/repo1?pretty=true
512
+ body:
513
+ encoding: UTF-8
514
+ string: "{\"type\":\"fs\",\"settings\":{\"location\":\"/tmp/repo1\"}}"
515
+ headers:
516
+ User-Agent:
517
+ - Faraday v0.9.0
518
+ Content-Type:
519
+ - application/json
520
+ Accept-Encoding:
521
+ - gzip;q=1.0,deflate;q=0.6,identity;q=0.3
522
+ Accept:
523
+ - "*/*"
524
+ response:
525
+ status:
526
+ code: 200
527
+ message: OK
528
+ headers:
529
+ Content-Type:
530
+ - application/json; charset=UTF-8
531
+ Content-Length:
532
+ - '28'
533
+ body:
534
+ encoding: UTF-8
535
+ string: |
536
+ {
537
+ "acknowledged" : true
538
+ }
539
+ http_version:
540
+ recorded_at: Wed, 10 Dec 2014 21:48:33 GMT
541
+ - request:
542
+ method: get
543
+ uri: http://127.0.0.1:19200/_snapshot/repo1/snapshot3/_status?pretty=true
544
+ body:
545
+ encoding: US-ASCII
546
+ string: ''
547
+ headers:
548
+ User-Agent:
549
+ - Faraday v0.9.0
550
+ Accept-Encoding:
551
+ - gzip;q=1.0,deflate;q=0.6,identity;q=0.3
552
+ Accept:
553
+ - "*/*"
554
+ response:
555
+ status:
556
+ code: 200
557
+ message: OK
558
+ headers:
559
+ Content-Type:
560
+ - application/json; charset=UTF-8
561
+ Content-Length:
562
+ - '1374'
563
+ body:
564
+ encoding: UTF-8
565
+ string: |
566
+ {
567
+ "snapshots" : [ {
568
+ "snapshot" : "snapshot3",
569
+ "repository" : "repo1",
570
+ "state" : "STARTED",
571
+ "shards_stats" : {
572
+ "initializing" : 17,
573
+ "started" : 1,
574
+ "finalizing" : 3,
575
+ "done" : 33,
576
+ "failed" : 0,
577
+ "total" : 54
578
+ },
579
+ "stats" : {
580
+ "number_of_files" : 223,
581
+ "processed_files" : 188,
582
+ "total_size_in_bytes" : 279913556,
583
+ "processed_size_in_bytes" : 28461769,
584
+ "start_time_in_millis" : 0,
585
+ "time_in_millis" : 0
586
+ },
587
+ "indices" : {
588
+ "index1": {
589
+ }
590
+ }
591
+ } ]
592
+ }
593
+ http_version:
594
+ recorded_at: Wed, 10 Dec 2014 20:39:45 GMT
595
+ recorded_with: VCR 2.9.2
@@ -0,0 +1,43 @@
1
+ require File.expand_path('../test_helper', __FILE__)
2
+
3
+ describe Elastomer::CLI::Repository do
4
+ describe 'create' do
5
+ it 'should create a repository' do
6
+ VCR.use_cassette('snapshots') do
7
+ elastomer %q(repository create repo1 --type fs --settings {"location":"/tmp/repo1"})
8
+ @out.must_match /acknowledged.+true/
9
+ end
10
+ end
11
+ end
12
+
13
+ describe 'get' do
14
+ it 'should get repository settings' do
15
+ VCR.use_cassette('snapshots') do
16
+ elastomer 'repository get repo1'
17
+ @out.must_match /repo1/
18
+ @out.must_match /type.+fs/
19
+ @out.must_match /location.+repo1/
20
+ @out.wont_match /repo2/
21
+ end
22
+ end
23
+ end
24
+
25
+ describe 'list' do
26
+ it 'should list repositories' do
27
+ VCR.use_cassette('snapshots') do
28
+ elastomer 'repository list'
29
+ @out.must_match /repo1/
30
+ @out.must_match /repo2/
31
+ end
32
+ end
33
+ end
34
+
35
+ describe 'delete' do
36
+ it 'should delete a repository' do
37
+ VCR.use_cassette('snapshots') do
38
+ elastomer 'repository delete repo1'
39
+ @out.must_match /Deleted repository repo1/
40
+ end
41
+ end
42
+ end
43
+ end
@@ -0,0 +1,101 @@
1
+ require File.expand_path('../test_helper', __FILE__)
2
+
3
+ describe Elastomer::CLI::Snapshot do
4
+ describe 'get' do
5
+ it 'should get snapshot info' do
6
+ VCR.use_cassette('snapshots') do
7
+ elastomer 'snapshot get repo1 snapshot1'
8
+ @out.must_match /snapshot1/
9
+ @out.must_match /SUCCESS/
10
+ @out.wont_match /snapshot2/
11
+ end
12
+ end
13
+ end
14
+
15
+ describe 'list' do
16
+ it 'should list snapshots in a repository' do
17
+ VCR.use_cassette('snapshots') do
18
+ elastomer 'snapshot list repo1'
19
+ @out.must_match /snapshot1.+SUCCESS/
20
+ @out.must_match /snapshot2.+SUCCESS/
21
+ end
22
+ end
23
+ end
24
+
25
+ describe 'status' do
26
+ it 'should get snapshot status' do
27
+ VCR.use_cassette('snapshots') do
28
+ elastomer 'snapshot status repo1 snapshot2'
29
+ @out.must_match /STATUS.+snapshot2/
30
+ @out.must_match /Repository.+repo1/
31
+ @out.must_match /State.+SUCCESS/
32
+ @out.must_match /Start Time.+2014-12-10/
33
+ @out.must_match /Duration.+0.001s/
34
+ @out.must_match /Processed Files.+100.0% \(1 \/ 1\)/
35
+ @out.must_match /Processed Bytes.+100.0% \(79 \/ 79\)/
36
+ @out.must_match /Shard Status.+1 done/
37
+ @out.must_match /Shards Failed.+0/
38
+ @out.must_match /Total Shards.+1/
39
+ @out.must_match /Total Indices.+1/
40
+ end
41
+ end
42
+
43
+ it 'should get snapshot status in progress' do
44
+ VCR.use_cassette('snapshots') do
45
+ elastomer 'snapshot status repo1 snapshot3'
46
+ @out.must_match /STATUS.+snapshot3/
47
+ @out.must_match /Repository.+repo1/
48
+ @out.must_match /State.+STARTED/
49
+ # Start time and total duration are broken in ES 1.2 for in-progress
50
+ # snapshots
51
+ # @out.must_match /Start Time.+2014-12-10/
52
+ # @out.must_match /Duration.+0.001s/
53
+ @out.must_match /Processed Files.+84.3% \(188 \/ 223\)/
54
+ @out.must_match /Processed Bytes.+10.2% \(28461769 \/ 279913556\)/
55
+ @out.must_match /Shard Status.+17 initializing, 1 started, 3 finalizing, 33 done/
56
+ @out.must_match /Shards Failed.+0/
57
+ @out.must_match /Total Shards.+54/
58
+ @out.must_match /Total Indices.+1/
59
+ end
60
+ end
61
+ end
62
+
63
+ describe 'create' do
64
+ it 'should create a snapshot' do
65
+ VCR.use_cassette('snapshots') do
66
+ elastomer 'snapshot create repo1 snapshot4 --indices index1'
67
+ @out.must_match /accepted/
68
+ end
69
+ end
70
+
71
+ it 'should wait for completion' do
72
+ VCR.use_cassette('snapshots') do
73
+ elastomer 'snapshot create repo1 snapshot3 --indices index1 --wait_for_completion'
74
+ @out.must_match /^Waiting/m
75
+ @out.must_match /snapshot3/
76
+ @out.must_match /index1/
77
+ @out.must_match /SUCCESS/
78
+ end
79
+ end
80
+ end
81
+
82
+ describe 'restore' do
83
+ it 'should restore a snapshot' do
84
+ VCR.use_cassette('snapshots') do
85
+ elastomer "snapshot restore repo1 snapshot2 --indices index1 --rename_pattern (.+) --rename_replacement restored_$1"
86
+ @status.must_equal nil
87
+ @out.must_match /snapshot2/
88
+ @out.must_match /restored_index1/
89
+ end
90
+ end
91
+ end
92
+
93
+ describe 'delete' do
94
+ it 'should delete a snapshot' do
95
+ VCR.use_cassette('snapshots') do
96
+ elastomer 'snapshot delete repo1 snapshot1'
97
+ @out.must_match /deleted snapshot1 in repo1/
98
+ end
99
+ end
100
+ end
101
+ end
data/test/test_helper.rb CHANGED
@@ -13,6 +13,9 @@ ENV['THOR_DEBUG'] = '0'
13
13
  VCR.configure do |c|
14
14
  c.cassette_library_dir = File.expand_path('../fixtures/vcr_cassettes', __FILE__)
15
15
  c.hook_into :webmock
16
+ c.default_cassette_options = {
17
+ :match_requests_on => [:method, :path],
18
+ }
16
19
  end
17
20
 
18
21
  module CLITestSupport
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: elastomer-cli
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.3
4
+ version: 0.3.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Grant Rodgers
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2014-10-22 00:00:00.000000000 Z
11
+ date: 2014-12-12 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: thor
@@ -145,6 +145,8 @@ files:
145
145
  - lib/elastomer/cli/cluster.rb
146
146
  - lib/elastomer/cli/index.rb
147
147
  - lib/elastomer/cli/node.rb
148
+ - lib/elastomer/cli/repository.rb
149
+ - lib/elastomer/cli/snapshot.rb
148
150
  - lib/elastomer/cli/version.rb
149
151
  - script/bootstrap
150
152
  - script/cibuild
@@ -158,9 +160,12 @@ files:
158
160
  - test/fixtures/vcr_cassettes/1_x.yml
159
161
  - test/fixtures/vcr_cassettes/default.yml
160
162
  - test/fixtures/vcr_cassettes/default_9201.yml
163
+ - test/fixtures/vcr_cassettes/snapshots.yml
161
164
  - test/fixtures/vcr_cassettes/two_node_cluster.yml
162
165
  - test/index_test.rb
163
166
  - test/node_test.rb
167
+ - test/repository_test.rb
168
+ - test/snapshot_test.rb
164
169
  - test/test_helper.rb
165
170
  homepage: https://github.com/github/elastomer-cli
166
171
  licenses:
@@ -195,7 +200,10 @@ test_files:
195
200
  - test/fixtures/vcr_cassettes/1_x.yml
196
201
  - test/fixtures/vcr_cassettes/default.yml
197
202
  - test/fixtures/vcr_cassettes/default_9201.yml
203
+ - test/fixtures/vcr_cassettes/snapshots.yml
198
204
  - test/fixtures/vcr_cassettes/two_node_cluster.yml
199
205
  - test/index_test.rb
200
206
  - test/node_test.rb
207
+ - test/repository_test.rb
208
+ - test/snapshot_test.rb
201
209
  - test/test_helper.rb