elastomer-cli 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: eca5b5a54ecb727c3c790ff26332120568610f89
4
+ data.tar.gz: 69141e48ad5496d14d41f8259516834c751e28f1
5
+ SHA512:
6
+ metadata.gz: 56022b1a27992c308a84102f064343001bef7253aa0be850fede460a77a949a84ec26db618a72e0001c4bc6ae7c85404442f5d70c2ccafca4d0c891a1ed6116f
7
+ data.tar.gz: 9fb869355b3338152b626b0b58db7694d44ed8812af56a8cf95fbff036869737f34c7497fe818cc1c85604813771f7787e8ad3f37ab8976090396634d6c030a1
data/.gitignore ADDED
@@ -0,0 +1,22 @@
1
+ *.rbc
2
+ .bundle
3
+ .config
4
+ .yardoc
5
+ Gemfile.lock
6
+ InstalledFiles
7
+ _yardoc
8
+ coverage
9
+ doc/
10
+ lib/bundler/man
11
+ pkg
12
+ rdoc
13
+ spec/reports
14
+ test/tmp
15
+ test/version_tmp
16
+ tmp
17
+ *.bundle
18
+ *.so
19
+ *.o
20
+ *.a
21
+ mkmf.log
22
+ vendor/gems
data/.ruby-version ADDED
@@ -0,0 +1 @@
1
+ 2.1.0-github
data/CHANGELOG.md ADDED
@@ -0,0 +1,8 @@
1
+ ## 0.1.0 (2014-06-24)
2
+ - First rubygems release
3
+ - New commands
4
+ - `cluster health`
5
+ - `cluster settings`
6
+ - `cluster allocation <command>`
7
+ - `node hot_threads`
8
+ - `node list`
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in elastomer-cli.gemspec
4
+ gemspec
data/LICENSE.txt ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2014 GitHub Inc.
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,29 @@
1
+ # Elastomer::Cli
2
+
3
+ A command-line interface to your ES cluster.
4
+
5
+ ## Installation
6
+
7
+ Add this line to your application's Gemfile:
8
+
9
+ gem 'elastomer-cli'
10
+
11
+ And then execute:
12
+
13
+ $ bundle
14
+
15
+ Or install it yourself as:
16
+
17
+ $ gem install elastomer-cli
18
+
19
+ ## Usage
20
+
21
+ `bin/elastomer help`
22
+
23
+ ## Contributing
24
+
25
+ 1. Fork it ( https://github.com/[my-github-username]/elastomer-cli/fork )
26
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
27
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
28
+ 4. Push to the branch (`git push origin my-new-feature`)
29
+ 5. Create a new Pull Request
data/Rakefile ADDED
@@ -0,0 +1,9 @@
1
+ require "bundler/gem_tasks"
2
+
3
+ require 'rake/testtask'
4
+
5
+ Rake::TestTask.new do |t|
6
+ t.pattern = "test/**/*_test.rb"
7
+ end
8
+
9
+ task :default => :test
data/bin/elastomer ADDED
@@ -0,0 +1,5 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'elastomer/cli'
4
+
5
+ Elastomer::CLI.start
@@ -0,0 +1,30 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'elastomer/cli/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = "elastomer-cli"
8
+ spec.version = Elastomer::Cli::VERSION
9
+ spec.authors = ["Grant Rodgers"]
10
+ spec.email = ["grant.rodgers@github.com"]
11
+ spec.summary = %q{Command line interface for elastomer}
12
+ spec.description = %q{}
13
+ spec.homepage = "https://github.com/github/elastomer-cli"
14
+ spec.license = "MIT"
15
+
16
+ spec.files = `git ls-files -z`.split("\x0")
17
+ spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
18
+ spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
19
+ spec.require_paths = ["lib"]
20
+
21
+ spec.add_runtime_dependency "thor"
22
+ spec.add_runtime_dependency "terminal-table"
23
+ spec.add_runtime_dependency "elastomer-client", "~> 0.3.1"
24
+
25
+ spec.add_development_dependency "bundler", "~> 1.5"
26
+ spec.add_development_dependency "rake"
27
+ spec.add_development_dependency "minitest"
28
+ spec.add_development_dependency "vcr"
29
+ spec.add_development_dependency "webmock"
30
+ end
@@ -0,0 +1,11 @@
1
+ module Elastomer
2
+ module CLI
3
+ class Application < Base
4
+
5
+ desc "cluster SUBCOMMAND ...ARGS", "execute cluster commands"
6
+ subcommand "cluster", Cluster
7
+ desc "node SUBCOMMAND ...ARGS", "execute node commands"
8
+ subcommand "node", Node
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,20 @@
1
+ module Elastomer
2
+ module CLI
3
+ class Base < Thor
4
+ class_option :url
5
+ class_option :read_timeout
6
+ class_option :open_timeout
7
+
8
+ protected
9
+ def client
10
+ # Elastomer::Client requires symbol keys, but options returns
11
+ # string keys
12
+ @client ||= Elastomer::Client.new(
13
+ :url => options[:url] || 'http://localhost:9200',
14
+ :read_timeout => options[:read_timeout],
15
+ :open_timeout => options[:open_timeout]
16
+ )
17
+ end
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,96 @@
1
+ module Elastomer
2
+ module CLI
3
+ class Cluster < Base
4
+ desc "health", "get cluster health"
5
+ def health
6
+ response = cluster.health
7
+ puts Terminal::Table.new(
8
+ :headings => ['CLUSTER HEALTH', ""],
9
+ :rows => [
10
+ ['Name', response["cluster_name"]],
11
+ ['Status', response["status"]],
12
+ ['Timed Out', response["timed_out"]],
13
+ ['Number of Nodes', response["number_of_nodes"]],
14
+ ['Number of Data Nodes', response["number_of_data_nodes"]],
15
+ ['Active Primary Shards', response["active_primary_shards"]],
16
+ ['Active Shards', response["active_shards"]],
17
+ ['Relocating Shards', response["relocating_shards"]],
18
+ ['Initializing Shards', response["initializing_shards"]],
19
+ ['Unassigned Shards', response["unassigned_shards"]]
20
+ ])
21
+ end
22
+
23
+ desc "settings", "show persistent and transient cluster settings"
24
+ def settings
25
+ response = cluster.get_settings(:flat_settings => true)
26
+
27
+ persistent_settings = response["persistent"].collect do |key, value|
28
+ [key, value]
29
+ end
30
+ transient_settings = response["transient"].collect do |key, value|
31
+ [key, value]
32
+ end
33
+
34
+ puts Terminal::Table.new(
35
+ :headings => ['SETTING NAME', "VALUE"],
36
+ :rows => [
37
+ ['PERSISTENT', '']
38
+ ] + persistent_settings + [
39
+ ['TRANSIENT', '']
40
+ ] + transient_settings
41
+ )
42
+
43
+ end
44
+
45
+ desc "allocation", "control shard allocation"
46
+ long_desc <<-LONGDESC
47
+ Manage cluster allocation settings.
48
+
49
+ For Elasticsearch clusters running 0.90.x, valid options are:
50
+ - enable
51
+ - disable
52
+
53
+ For Elasticsearch clusters running 1.x, valid options are:
54
+ - all (alias: enable)
55
+ - primaries
56
+ - new_primaries
57
+ - none (alias: disable)
58
+ LONGDESC
59
+ def allocation(command)
60
+ if client.version =~ /^0.90/
61
+ setting = "cluster.routing.allocation.disable_allocation"
62
+ value = case command
63
+ when 'enable'
64
+ false
65
+ when 'disable'
66
+ true
67
+ else
68
+ raise Thor::Error, "ERROR: Unknown allocation command: #{command}"
69
+ end
70
+ elsif client.version =~ /^1./
71
+ setting = "cluster.routing.allocation.enable"
72
+ value = case command
73
+ when 'enable'
74
+ 'all'
75
+ when 'disable'
76
+ 'none'
77
+ when 'all', 'primaries', 'new_primaries', 'none'
78
+ command
79
+ else
80
+ raise Thor::Error, "ERROR: Unknown allocation command: #{command}"
81
+ end
82
+ else
83
+ raise Thor::Error, "ERROR: Unknown Elasticsearch version: #{client.version}"
84
+ return
85
+ end
86
+ cluster.update_settings("persistent" => {setting => value})
87
+ puts "Successfully set #{setting}=#{value}"
88
+ end
89
+
90
+ private
91
+ def cluster
92
+ client.cluster
93
+ end
94
+ end
95
+ end
96
+ end
@@ -0,0 +1,33 @@
1
+ module Elastomer
2
+ module CLI
3
+ class Node < Base
4
+ desc "hot_threads", "get hot_threads"
5
+ def hot_threads
6
+ response = nodes.hot_threads
7
+ puts response
8
+ end
9
+
10
+ desc "list", "list all nodes in the cluster"
11
+ def list
12
+ response = nodes.info
13
+ puts Terminal::Table.new(
14
+ :headings => ['NAME', 'HOSTNAME', 'VERSION', 'HTTP ADDRESS', 'ATTRIBUTES'],
15
+ :rows => response["nodes"].collect do |node_id, node|
16
+ [
17
+ node["name"],
18
+ node["host"],
19
+ node["version"],
20
+ node["http_address"],
21
+ node["attributes"]
22
+ ]
23
+ end
24
+ )
25
+ end
26
+
27
+ private
28
+ def nodes
29
+ client.nodes('_local')
30
+ end
31
+ end
32
+ end
33
+ end
@@ -0,0 +1,5 @@
1
+ module Elastomer
2
+ module Cli
3
+ VERSION = "0.1.0"
4
+ end
5
+ end
@@ -0,0 +1,19 @@
1
+ require "elastomer/cli/version"
2
+
3
+ require 'thor'
4
+ require 'terminal-table'
5
+ require 'elastomer/client'
6
+
7
+ require 'elastomer/cli/base'
8
+ require 'elastomer/cli/cluster'
9
+ require 'elastomer/cli/node'
10
+
11
+ require 'elastomer/cli/application'
12
+
13
+ module Elastomer
14
+ module CLI
15
+ def self.start(*args)
16
+ Elastomer::CLI::Application.start(*args)
17
+ end
18
+ end
19
+ end
data/script/bootstrap ADDED
@@ -0,0 +1,5 @@
1
+ #!/bin/sh
2
+ set -e
3
+
4
+ cd "$(dirname "$0")/.."
5
+ bundle install --path vendor/gems --quiet "$@"
data/script/cibuild ADDED
@@ -0,0 +1,11 @@
1
+ #!/bin/sh
2
+ # Usage: script/cibuild
3
+ # CI build script.
4
+ set -e
5
+
6
+ cd $(dirname "$0")/..
7
+ PATH="$(pwd)/bin:$(pwd)/script:/usr/share/rbenv/shims:$PATH"
8
+ export RBENV_VERSION="$(cat .ruby-version)"
9
+
10
+ script/bootstrap
11
+ script/test
data/script/console ADDED
@@ -0,0 +1,8 @@
1
+ #!/usr/bin/env ruby
2
+ require 'irb'
3
+ require 'rubygems'
4
+ require 'bundler/setup'
5
+
6
+ require 'elastomer/cli'
7
+
8
+ IRB.start
data/script/test ADDED
@@ -0,0 +1,4 @@
1
+ #!/bin/sh
2
+
3
+ # run entire test suite
4
+ bundle exec rake test
@@ -0,0 +1,17 @@
1
+ require File.expand_path('../test_helper', __FILE__)
2
+
3
+ describe Elastomer::CLI::Application do
4
+ describe 'global options' do
5
+ it 'should accept --url' do
6
+ VCR.use_cassette("default_9201") do
7
+ elastomer "cluster health --url http://localhost:9201"
8
+ @out.must_match /Name.*elasticsearch/
9
+ end
10
+ end
11
+
12
+ it 'should accept timeouts' do
13
+ Elastomer::CLI::Application.class_options.keys.must_include :read_timeout
14
+ Elastomer::CLI::Application.class_options.keys.must_include :open_timeout
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,89 @@
1
+ require File.expand_path('../test_helper', __FILE__)
2
+
3
+ describe Elastomer::CLI::Cluster do
4
+ describe 'health' do
5
+ it 'should get cluster health' do
6
+ VCR.use_cassette('default') do
7
+ elastomer 'cluster health'
8
+ @out.must_match /Name.*elasticsearch/
9
+ @out.must_match /Status.*green/
10
+ @out.must_match /Timed Out.*false/
11
+ @out.must_match /Number of Nodes.*1/
12
+ @out.must_match /Number of Data Nodes.*1/
13
+ @out.must_match /Active Primary Shards.*0/
14
+ @out.must_match /Active Shards.*0/
15
+ @out.must_match /Relocating Shards.*0/
16
+ @out.must_match /Initializing Shards.*0/
17
+ @out.must_match /Unassigned Shards.*0/
18
+ end
19
+ end
20
+ end
21
+
22
+ describe 'settings' do
23
+ it 'should get persistent and transient cluster settings' do
24
+ VCR.use_cassette('default') do
25
+ elastomer 'cluster settings'
26
+ @out.must_match /PERSISTENT.*indices.ttl.interval\s+|\s*50/m
27
+ @out.must_match /TRANSIENT.*indices.ttl.interval\s+|\s*60/m
28
+ end
29
+ end
30
+ end
31
+
32
+ describe 'allocation' do
33
+
34
+ it 'should deny unknown commands' do
35
+ VCR.use_cassette('default') do
36
+ elastomer 'cluster allocation foobar'
37
+ @err.must_match "ERROR: Unknown allocation command: foobar"
38
+ end
39
+ end
40
+
41
+ it 'should deny unknown versions' do
42
+ VCR.use_cassette('0.20') do
43
+ elastomer 'cluster allocation disable'
44
+ @err.must_match "ERROR: Unknown Elasticsearch version: 0.20.6"
45
+ end
46
+ end
47
+
48
+ describe '0.90' do
49
+ it 'should disable allocation' do
50
+ VCR.use_cassette('0.90') do
51
+ elastomer 'cluster allocation disable'
52
+ @out.must_match /cluster.routing.allocation.disable_allocation=true/
53
+ end
54
+ end
55
+
56
+ it 'should enable allocation' do
57
+ VCR.use_cassette('0.90') do
58
+ elastomer 'cluster allocation enable'
59
+ @out.must_match /cluster.routing.allocation.disable_allocation=false/
60
+ end
61
+ end
62
+ end
63
+
64
+ describe '1.x' do
65
+ it 'should disable allocation' do
66
+ VCR.use_cassette('1.x') do
67
+ elastomer 'cluster allocation disable'
68
+ @out.must_match /PERSISTENT.*cluster.routing.allocation.enable\s+|\s*none/m
69
+ end
70
+ end
71
+
72
+ it 'should enable allocation' do
73
+ VCR.use_cassette('1.x') do
74
+ elastomer 'cluster allocation enable'
75
+ @out.must_match /PERSISTENT.*cluster.routing.allocation.enable\s+|\s*all/m
76
+ end
77
+ end
78
+
79
+ it 'should allow new allocation states' do
80
+ VCR.use_cassette('1.x') do
81
+ %w{ all primaries new_primaries none }.each do |state|
82
+ elastomer "cluster allocation #{state}"
83
+ @out.must_match /PERSISTENT.*cluster.routing.allocation.enable\s+|\s*#{state}/m
84
+ end
85
+ end
86
+ end
87
+ end
88
+ end
89
+ end
@@ -0,0 +1,114 @@
1
+ ---
2
+ http_interactions:
3
+ - request:
4
+ method: get
5
+ uri: http://localhost:9200/
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
+ - '167'
25
+ body:
26
+ encoding: UTF-8
27
+ string: |-
28
+ {
29
+ "ok" : true,
30
+ "status" : 200,
31
+ "name" : "Amun",
32
+ "version" : {
33
+ "number" : "0.20.6",
34
+ "snapshot_build" : false
35
+ },
36
+ "tagline" : "You Know, for Search"
37
+ }
38
+ http_version:
39
+ recorded_at: Wed, 18 Jun 2014 02:23:38 GMT
40
+ - request:
41
+ method: get
42
+ uri: http://localhost:9200/
43
+ body:
44
+ encoding: US-ASCII
45
+ string: ''
46
+ headers:
47
+ User-Agent:
48
+ - Faraday v0.9.0
49
+ Accept-Encoding:
50
+ - gzip;q=1.0,deflate;q=0.6,identity;q=0.3
51
+ Accept:
52
+ - '*/*'
53
+ response:
54
+ status:
55
+ code: 200
56
+ message: OK
57
+ headers:
58
+ Content-Type:
59
+ - application/json; charset=UTF-8
60
+ Content-Length:
61
+ - '167'
62
+ body:
63
+ encoding: UTF-8
64
+ string: |-
65
+ {
66
+ "ok" : true,
67
+ "status" : 200,
68
+ "name" : "Amun",
69
+ "version" : {
70
+ "number" : "0.20.6",
71
+ "snapshot_build" : false
72
+ },
73
+ "tagline" : "You Know, for Search"
74
+ }
75
+ http_version:
76
+ recorded_at: Wed, 18 Jun 2014 02:23:38 GMT
77
+ - request:
78
+ method: get
79
+ uri: http://localhost:9200/
80
+ body:
81
+ encoding: US-ASCII
82
+ string: ''
83
+ headers:
84
+ User-Agent:
85
+ - Faraday v0.9.0
86
+ Accept-Encoding:
87
+ - gzip;q=1.0,deflate;q=0.6,identity;q=0.3
88
+ Accept:
89
+ - '*/*'
90
+ response:
91
+ status:
92
+ code: 200
93
+ message: OK
94
+ headers:
95
+ Content-Type:
96
+ - application/json; charset=UTF-8
97
+ Content-Length:
98
+ - '167'
99
+ body:
100
+ encoding: UTF-8
101
+ string: |-
102
+ {
103
+ "ok" : true,
104
+ "status" : 200,
105
+ "name" : "Amun",
106
+ "version" : {
107
+ "number" : "0.20.6",
108
+ "snapshot_build" : false
109
+ },
110
+ "tagline" : "You Know, for Search"
111
+ }
112
+ http_version:
113
+ recorded_at: Wed, 18 Jun 2014 02:23:38 GMT
114
+ recorded_with: VCR 2.9.2