turbot 0.1.36 → 0.2.3

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.
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