turbot 0.1.36 → 0.2.3

Sign up to get free protection for your applications and to get access to all the features.
Files changed (103) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +8 -0
  3. data/.rspec +3 -0
  4. data/.travis.yml +15 -0
  5. data/.yardopts +3 -0
  6. data/Gemfile +4 -0
  7. data/LICENSE +22 -0
  8. data/README.md +44 -25
  9. data/Rakefile +16 -0
  10. data/appveyor.yml +35 -0
  11. data/bin/turbot +2 -16
  12. data/data/schema.json +134 -0
  13. data/{templates → data/templates}/LICENSE.txt +0 -0
  14. data/{templates → data/templates}/manifest.json +0 -0
  15. data/{templates → data/templates}/python/scraper.py +0 -0
  16. data/{templates → data/templates}/ruby/scraper.rb +0 -0
  17. data/dist/deb.rake +32 -0
  18. data/dist/gem.rake +16 -0
  19. data/dist/manifest.rake +9 -0
  20. data/dist/pkg.rake +60 -0
  21. data/dist/resources/deb/control +10 -0
  22. data/dist/resources/deb/postinst +45 -0
  23. data/dist/resources/deb/turbot +25 -0
  24. data/dist/resources/deb/turbot-release-key.txt +30 -0
  25. data/dist/resources/pkg/Distribution.erb +15 -0
  26. data/dist/resources/pkg/PackageInfo.erb +6 -0
  27. data/dist/resources/pkg/postinstall +45 -0
  28. data/dist/resources/pkg/turbot +24 -0
  29. data/dist/resources/tgz/turbot +24 -0
  30. data/dist/rpm.rake +35 -0
  31. data/dist/tgz.rake +26 -0
  32. data/dist/zip.rake +40 -0
  33. data/lib/turbot.rb +18 -15
  34. data/lib/turbot/cli.rb +10 -27
  35. data/lib/turbot/command.rb +59 -212
  36. data/lib/turbot/command/auth.rb +72 -34
  37. data/lib/turbot/command/base.rb +22 -61
  38. data/lib/turbot/command/bots.rb +251 -300
  39. data/lib/turbot/command/help.rb +57 -110
  40. data/lib/turbot/command/version.rb +6 -10
  41. data/lib/turbot/handlers/base_handler.rb +21 -0
  42. data/lib/turbot/handlers/dump_handler.rb +10 -0
  43. data/lib/turbot/handlers/preview_handler.rb +30 -0
  44. data/lib/turbot/handlers/validation_handler.rb +17 -0
  45. data/lib/turbot/helpers.rb +14 -482
  46. data/lib/turbot/helpers/api_helper.rb +41 -0
  47. data/lib/turbot/helpers/netrc_helper.rb +66 -0
  48. data/lib/turbot/helpers/shell_helper.rb +36 -0
  49. data/lib/turbot/version.rb +1 -1
  50. data/spec/fixtures/bad_permissions +0 -0
  51. data/spec/fixtures/empty +0 -0
  52. data/spec/fixtures/netrc +6 -0
  53. data/spec/spec_helper.rb +17 -219
  54. data/spec/support/bot_helper.rb +102 -0
  55. data/spec/support/command_helper.rb +20 -0
  56. data/spec/support/custom_matchers.rb +5 -0
  57. data/spec/support/fixture_helper.rb +9 -0
  58. data/spec/support/netrc_helper.rb +21 -0
  59. data/spec/turbot/command/auth_spec.rb +202 -20
  60. data/spec/turbot/command/base_spec.rb +22 -58
  61. data/spec/turbot/command/bots_spec.rb +580 -89
  62. data/spec/turbot/command/help_spec.rb +32 -75
  63. data/spec/turbot/command/version_spec.rb +11 -10
  64. data/spec/turbot/command_spec.rb +55 -87
  65. data/spec/turbot/helpers_spec.rb +28 -44
  66. data/turbot.gemspec +31 -0
  67. metadata +88 -178
  68. data/data/cacert.pem +0 -3988
  69. data/lib/turbot/auth.rb +0 -315
  70. data/lib/turbot/client.rb +0 -757
  71. data/lib/turbot/client/cisaurus.rb +0 -25
  72. data/lib/turbot/client/pgbackups.rb +0 -113
  73. data/lib/turbot/client/rendezvous.rb +0 -111
  74. data/lib/turbot/client/ssl_endpoint.rb +0 -25
  75. data/lib/turbot/client/turbot_postgresql.rb +0 -148
  76. data/lib/turbot/command/ssl.rb +0 -43
  77. data/lib/turbot/deprecated.rb +0 -5
  78. data/lib/turbot/deprecated/help.rb +0 -38
  79. data/lib/turbot/distribution.rb +0 -9
  80. data/lib/turbot/errors.rb +0 -28
  81. data/lib/turbot/excon.rb +0 -11
  82. data/lib/turbot/helpers/log_displayer.rb +0 -70
  83. data/lib/turbot/helpers/pg_dump_restore.rb +0 -115
  84. data/lib/turbot/helpers/turbot_postgresql.rb +0 -213
  85. data/lib/turbot/plugin.rb +0 -165
  86. data/lib/turbot/updater.rb +0 -171
  87. data/lib/vendor/turbot/okjson.rb +0 -598
  88. data/spec/helper/legacy_help.rb +0 -16
  89. data/spec/helper/pg_dump_restore_spec.rb +0 -67
  90. data/spec/spec.opts +0 -1
  91. data/spec/support/display_message_matcher.rb +0 -49
  92. data/spec/support/dummy_api.rb +0 -120
  93. data/spec/support/openssl_mock_helper.rb +0 -8
  94. data/spec/support/organizations_mock_helper.rb +0 -11
  95. data/spec/turbot/auth_spec.rb +0 -214
  96. data/spec/turbot/client/pgbackups_spec.rb +0 -43
  97. data/spec/turbot/client/rendezvous_spec.rb +0 -62
  98. data/spec/turbot/client/ssl_endpoint_spec.rb +0 -48
  99. data/spec/turbot/client/turbot_postgresql_spec.rb +0 -71
  100. data/spec/turbot/client_spec.rb +0 -548
  101. data/spec/turbot/helpers/turbot_postgresql_spec.rb +0 -181
  102. data/spec/turbot/plugin_spec.rb +0 -172
  103. data/spec/turbot/updater_spec.rb +0 -44
@@ -1,16 +0,0 @@
1
- require "turbot/command/help"
2
-
3
- Turbot::Command::Help.group("Foo Group") do |foo|
4
- foo.command "foo:bar", "do a bar to foo"
5
- foo.space
6
- foo.command "foo:baz", "do a baz to foo"
7
- end
8
-
9
- class Turbot::Command::Foo < Turbot::Command::Base
10
- def bar
11
- end
12
-
13
- def baz
14
- end
15
- end
16
-
@@ -1,67 +0,0 @@
1
- require "turbot/helpers/pg_dump_restore"
2
-
3
- describe PgDumpRestore, 'pull' do
4
- before do
5
- @localdb = 'postgres:///localdbname'
6
- @remotedb = 'postgres://uname:pass@remotehost/remotedbname'
7
- end
8
-
9
- it 'requires uris for from and to arguments' do
10
- expect { PgDumpRestore.new(nil , @localdb, mock) }.to raise_error
11
- expect { PgDumpRestore.new(@remotedb, nil , mock) }.to raise_error
12
- expect { PgDumpRestore.new(@remotedb, @localdb, mock) }.to_not raise_error
13
- end
14
-
15
- it 'uses PGPORT from ENV to set local port' do
16
- ENV['PGPORT'] = '15432'
17
- expect(PgDumpRestore.new(@remotedb, @localdb, mock).instance_variable_get('@target').port).to eq 15432
18
- end
19
-
20
- it 'on pulls, prepare requires the local database to not exist' do
21
- mock_command = mock
22
- mock_command.should_receive(:error).once
23
- pgdr = PgDumpRestore.new(@remotedb, @localdb, mock_command)
24
- pgdr.should_receive(:`).once.and_return(`false`)
25
-
26
- pgdr.prepare
27
- end
28
-
29
- it 'on pushes, prepare requires the remote database to be empty' do
30
- mock_command = mock
31
- mock_command.should_receive(:error).once
32
- pgdr = PgDumpRestore.new(@localdb, @remotedb, mock_command)
33
- mock_command.should_receive(:exec_sql_on_uri).once.and_return("something that isn't a true")
34
- pgdr.prepare
35
- end
36
-
37
- it 'executes a proper dump/restore command' do
38
- pgdr = PgDumpRestore.new(@remotedb, @localdb, mock)
39
- expect(pgdr.dump_restore_cmd).to match(/
40
- pg_dump .*
41
- remotehost .*
42
- remotedbname .*
43
- \| .*
44
- pg_restore .*
45
- localhost .*
46
- localdbname
47
- /x)
48
- end
49
-
50
- describe 'verification' do
51
- it 'errors when the extensions do not match' do
52
- mock_command = mock
53
- mock_command.should_receive(:error).once
54
- pgdr = PgDumpRestore.new(@localdb, @remotedb, mock_command)
55
- mock_command.should_receive(:exec_sql_on_uri).twice.and_return("these", "don't match")
56
- pgdr.verify
57
- end
58
-
59
- it 'is fine when the extensions match' do
60
- mock_command = mock
61
- mock_command.should_not_receive(:error)
62
- pgdr = PgDumpRestore.new(@localdb, @remotedb, mock_command)
63
- mock_command.should_receive(:exec_sql_on_uri).twice.and_return("these match", "these match")
64
- pgdr.verify
65
- end
66
- end
67
- end
data/spec/spec.opts DELETED
@@ -1 +0,0 @@
1
- --color
@@ -1,49 +0,0 @@
1
- module DisplayMessageMatcher
2
-
3
- def display_message(command, message)
4
- DisplayMessageMatcher::DisplayMessage.new command, message
5
- end
6
-
7
- class DisplayMessage
8
- def initialize(command, message)
9
- @command = command
10
- @message = message
11
- end
12
-
13
- def matches?(given_proc)
14
- displayed_expected_message = false
15
- @given_messages = []
16
-
17
- @command.should_receive(:display).
18
- any_number_of_times do |message, newline|
19
- @given_messages << message
20
- displayed_expected_message = displayed_expected_message ||
21
- message == @message
22
- end
23
-
24
- given_proc.call
25
-
26
- displayed_expected_message
27
- end
28
-
29
- def failure_message
30
- "expected #{ @command } to display the message #{ @message.inspect } but #{ given_messages }"
31
- end
32
-
33
- def negative_failure_message
34
- "expected #{ @command } to not display the message #{ @message.inspect } but it was displayed"
35
- end
36
-
37
- private
38
-
39
- def given_messages
40
- if @given_messages.empty?
41
- 'no messages were displayed'
42
- else
43
- formatted_given_messages = @given_messages.map(&:inspect).join ', '
44
- "the follow messages were displayed: #{ formatted_given_messages }"
45
- end
46
- end
47
-
48
- end
49
- end
@@ -1,120 +0,0 @@
1
- require 'json'
2
-
3
- module Turbot
4
- class API
5
- def initialize(params)
6
- @headers = params[:headers]
7
- @host = params[:host]
8
- @port = params[:port]
9
- @username = params[:username]
10
- @password = params[:password]
11
- @scheme = params[:scheme]
12
- @ssl_verify_peer = params[:ssl_verify_peer]
13
- @api_key = params[:api_key] || get_api_key(@username, @password)
14
- authenticate
15
-
16
- end
17
-
18
- def authenticate
19
- # Try to authenticate at this stage - something like
20
- #user_pass = ":#{@api_key}"
21
- #options[:headers] = HEADERS.merge({
22
- # 'Authorization' => "Basic #{Base64.encode64(user_pass).gsub("\n", '')}",
23
- # }).merge(options[:headers])
24
-
25
- # @connection = Excon.new("http://missions.opencorporates.com/login", options)
26
-
27
- end
28
-
29
- def get_user
30
- # raise if not authenticated
31
- # @connection.code < 400
32
- end
33
-
34
- def get_api_key(user, password)
35
- # get the api key, raise exception if credentials broken
36
- # this is a hash of the username and password plus salt
37
- return "some-api-key"
38
- end
39
-
40
- def get_keys
41
- # return an array of ssh keys
42
- read_db("keys")
43
- end
44
-
45
- def post_key(key)
46
- # receive ssh key and associate with account
47
- append_db("keys", {"contents" => key})
48
- end
49
-
50
- def delete_key(key)
51
- keys = read_db("keys")
52
- keys.delete(key)
53
- write_db("keys", keys)
54
- end
55
-
56
- def delete_keys
57
- write_db("keys", [])
58
- end
59
-
60
- def post_bot(data)
61
- # XXX need to implement this to make the config command pass...
62
- # save an "bot" - we'll replace this with the bot stuff chris did
63
- db = read_db("bot")
64
- db[data["name"]] = data
65
- write_db("bot", db)
66
- end
67
-
68
- def delete_bot(bot)
69
- db = read_db("bot")
70
- db.delete(bot)
71
- write_db("bot", db)
72
- end
73
-
74
- def get_bots
75
- read_db("bot", [])
76
- end
77
-
78
- def get_bot(bot)
79
- db = read_db("bot_data", [])
80
- db[bot]
81
- end
82
-
83
- def put_config_vars(bot, vars)
84
- # Set vars for bot specified
85
- config = read_db("config")
86
- config[bot] = vars
87
- write_db("config", config)
88
- end
89
-
90
- def get_config_vars(bot)
91
- read_db("config", [])[bot]
92
- end
93
-
94
- def delete_config_var(bot, key)
95
- db = read_db("config", [])
96
- keys = db[bot]
97
- keys.delete(key)
98
- db[bot] = keys
99
- write_db("config", db)
100
- end
101
-
102
- private
103
-
104
- def write_db(name, data)
105
- open("/tmp/#{name}", "w") do |f|
106
- f.write(JSON.dump(data))
107
- end
108
- end
109
-
110
- def read_db(name, default={})
111
- JSON.parse(open("/tmp/#{name}", "r").read) rescue {}
112
- end
113
-
114
- def append_db(name, data)
115
- db = read_db(name, [])
116
- db << data
117
- write_db(name, db)
118
- end
119
- end
120
- end
@@ -1,8 +0,0 @@
1
- def mock_openssl
2
- @ctx_mock = mock "SSLContext", :key= => nil, :cert= => nil, :ssl_version= => nil
3
- @tcp_socket_mock = mock "TCPSocket", :close => true
4
- @ssl_socket_mock = mock "SSLSocket", :sync= => true, :connect => true, :close => true, :to_io => $stdin
5
-
6
- OpenSSL::SSL::SSLSocket.stub(:new).and_return(@ssl_socket_mock)
7
- OpenSSL::SSL::SSLContext.stub(:new).and_return(@ctx_mock)
8
- end
@@ -1,11 +0,0 @@
1
- class Turbot::Client::Organizations
2
-
3
- # stub GET /v1/user/info
4
- Excon.stub(:expects => 200, :method => :get, :path => %r{^/v1/user/info$} ) do |params|
5
- {
6
- :body => "",
7
- :status => 404
8
- }
9
- end
10
-
11
- end
@@ -1,214 +0,0 @@
1
- require "spec_helper"
2
- require "turbot/auth"
3
- require "turbot/helpers"
4
-
5
- module Turbot
6
- describe Auth do
7
- include Turbot::Helpers
8
-
9
- before do
10
- ENV['TURBOT_API_KEY'] = nil
11
-
12
- @cli = Turbot::Auth
13
- @cli.stub!(:check)
14
- @cli.stub!(:display)
15
- @cli.stub!(:running_on_a_mac?).and_return(false)
16
- @cli.credentials = nil
17
-
18
- FakeFS.activate!
19
-
20
- FakeFS::File.stub!(:stat).and_return(double('stat', :mode => "0600".to_i(8)))
21
- FakeFS::FileUtils.stub!(:chmod)
22
- FakeFS::File.stub!(:readlines) do |path|
23
- File.read(path).split("\n").map {|line| "#{line}\n"}
24
- end
25
-
26
- FileUtils.mkdir_p(@cli.netrc_path.split("/")[0..-2].join("/"))
27
-
28
- File.open(@cli.netrc_path, "w") do |file|
29
- file.puts("machine api.turbot.com\n login user\n password pass\n")
30
- file.puts("machine code.turbot.com\n login user\n password pass\n")
31
- end
32
- end
33
-
34
- after do
35
- FileUtils.rm_rf(@cli.netrc_path)
36
- FakeFS.deactivate!
37
- end
38
-
39
-
40
- context "API key is set via environment variable" do
41
- before do
42
- ENV['TURBOT_API_KEY'] = "secret"
43
- end
44
-
45
- it "gets credentials from environment variables in preference to credentials file" do
46
- @cli.read_credentials.should == ['', ENV['TURBOT_API_KEY']]
47
- end
48
-
49
- it "returns a blank username" do
50
- @cli.user.should be_empty
51
- end
52
-
53
- it "returns the api key as the password" do
54
- @cli.password.should == ENV['TURBOT_API_KEY']
55
- end
56
-
57
- it "does not overwrite credentials file with environment variable credentials" do
58
- @cli.should_not_receive(:write_credentials)
59
- @cli.read_credentials
60
- end
61
-
62
- context "reauthenticating" do
63
- before do
64
- @cli.stub!(:ask_for_credentials).and_return(['new_user', 'new_password'])
65
- @cli.stub!(:check)
66
- # @cli.should_receive(:check_for_associated_ssh_key)
67
- @cli.reauthorize
68
- end
69
- it "updates saved credentials" do
70
- Netrc.read(@cli.netrc_path)["api.#{@cli.host}"].should == ['new_user', 'new_password']
71
- end
72
- it "returns environment variable credentials" do
73
- @cli.read_credentials.should == ['', ENV['TURBOT_API_KEY']]
74
- end
75
- end
76
-
77
- end
78
-
79
- describe "#base_host" do
80
- it "returns the host without the first part" do
81
- @cli.base_host("http://foo.bar.com").should == "bar.com"
82
- end
83
-
84
- it "works with localhost" do
85
- @cli.base_host("http://localhost:3000").should == "localhost"
86
- end
87
- end
88
-
89
- it "asks for credentials when the file doesn't exist" do
90
- @cli.delete_credentials
91
- @cli.should_receive(:ask_for_credentials).and_return(["u", "p"])
92
- # @cli.should_receive(:check_for_associated_ssh_key)
93
- @cli.user.should == 'u'
94
- @cli.password.should == 'p'
95
- end
96
-
97
- it "writes credentials and uploads authkey when credentials are saved" do
98
- @cli.stub!(:credentials)
99
- @cli.stub!(:check)
100
- @cli.stub!(:ask_for_credentials).and_return("username", "apikey")
101
- @cli.should_receive(:write_credentials)
102
- # @cli.should_receive(:check_for_associated_ssh_key)
103
- @cli.ask_for_and_save_credentials
104
- end
105
-
106
- it "save_credentials deletes the credentials when the upload authkey is unauthorized" do
107
- @cli.stub!(:write_credentials)
108
- @cli.stub!(:retry_login?).and_return(false)
109
- @cli.stub!(:ask_for_credentials).and_return("username", "apikey")
110
- @cli.stub!(:check) { raise RestClient::Unauthorized }
111
- @cli.should_receive(:delete_credentials)
112
- lambda { @cli.ask_for_and_save_credentials }.should raise_error(SystemExit)
113
- end
114
-
115
- it "asks for login again when not authorized, for three times" do
116
- @cli.stub!(:read_credentials)
117
- @cli.stub!(:write_credentials)
118
- @cli.stub!(:delete_credentials)
119
- @cli.stub!(:ask_for_credentials).and_return("username", "apikey")
120
- @cli.stub!(:check) { raise RestClient::Unauthorized }
121
- @cli.should_receive(:ask_for_credentials).exactly(3).times
122
- lambda { @cli.ask_for_and_save_credentials }.should raise_error(SystemExit)
123
- end
124
-
125
- it "writes the login information to the credentials file for the 'turbot login' command" do
126
- @cli.stub!(:ask_for_credentials).and_return(['one', 'two'])
127
- @cli.stub!(:check)
128
- # @cli.should_receive(:check_for_associated_ssh_key)
129
- @cli.reauthorize
130
- Netrc.read(@cli.netrc_path)["api.#{@cli.host}"].should == (['one', 'two'])
131
- end
132
-
133
- it "migrates long api keys to short api keys" do
134
- @cli.delete_credentials
135
- api_key = "7e262de8cac430d8a250793ce8d5b334ae56b4ff15767385121145198a2b4d2e195905ef8bf7cfc5"
136
- @cli.netrc["api.#{@cli.host}"] = ["user", api_key]
137
-
138
- @cli.get_credentials.should == ["user", api_key[0,40]]
139
- %w{api code}.each do |section|
140
- Netrc.read(@cli.netrc_path)["#{section}.#{@cli.host}"].should == ["user", api_key[0,40]]
141
- end
142
- end
143
-
144
- # describe "automatic key uploading" do
145
- # before(:each) do
146
- # FileUtils.mkdir_p("#{@cli.home_directory}/.ssh")
147
- # @cli.stub!(:ask_for_credentials).and_return("username", "apikey")
148
- # end
149
-
150
- # describe "an account with existing keys" do
151
- # before :each do
152
- # @api = mock(Object)
153
- # @response = mock(Object)
154
- # @response.should_receive(:body).and_return(['existingkeys'])
155
- # @api.should_receive(:get_ssh_keys).and_return(@response)
156
- # @cli.should_receive(:api).and_return(@api)
157
- # end
158
-
159
- # it "should not do anything if the account already has keys" do
160
- # @cli.should_not_receive(:associate_key)
161
- # @cli.check_for_associated_ssh_key
162
- # end
163
- # end
164
-
165
- # describe "an account with no keys" do
166
- # before :each do
167
- # @api = mock(Object)
168
- # @response = mock(Object)
169
- # @response.should_receive(:body).and_return([])
170
- # @api.should_receive(:get_ssh_keys).and_return(@response)
171
- # @cli.should_receive(:api).and_return(@api)
172
- # end
173
-
174
- # describe "with zero public keys" do
175
- # it "should ask to generate a key" do
176
- # @cli.should_receive(:ask).and_return("y")
177
- # @cli.should_receive(:generate_ssh_key).with("id_rsa")
178
- # @cli.should_receive(:associate_key).with("#{@cli.home_directory}/.ssh/id_rsa.pub")
179
- # @cli.check_for_associated_ssh_key
180
- # end
181
- # end
182
-
183
- # describe "with one public key" do
184
- # before(:each) { FileUtils.touch("#{@cli.home_directory}/.ssh/id_rsa.pub") }
185
- # after(:each) { FileUtils.rm("#{@cli.home_directory}/.ssh/id_rsa.pub") }
186
-
187
- # it "should upload the key" do
188
- # @cli.should_receive(:associate_key).with("#{@cli.home_directory}/.ssh/id_rsa.pub")
189
- # @cli.check_for_associated_ssh_key
190
- # end
191
- # end
192
-
193
- # describe "with many public keys" do
194
- # before(:each) do
195
- # FileUtils.touch("#{@cli.home_directory}/.ssh/id_rsa.pub")
196
- # FileUtils.touch("#{@cli.home_directory}/.ssh/id_rsa2.pub")
197
- # end
198
-
199
- # after(:each) do
200
- # FileUtils.rm("#{@cli.home_directory}/.ssh/id_rsa.pub")
201
- # FileUtils.rm("#{@cli.home_directory}/.ssh/id_rsa2.pub")
202
- # end
203
-
204
- # it "should ask which key to upload" do
205
- # File.open("#{@cli.home_directory}/.ssh/id_rsa.pub", "w") { |f| f.puts }
206
- # @cli.should_receive(:associate_key).with("#{@cli.home_directory}/.ssh/id_rsa2.pub")
207
- # @cli.should_receive(:ask).and_return("2")
208
- # @cli.check_for_associated_ssh_key
209
- # end
210
- # end
211
- # end
212
- # end
213
- end
214
- end