uwsgi_it_client 0.0.1

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.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 6f1f988f6e2cdc06a1c985e70855421cf146fa8b
4
+ data.tar.gz: 9352cdaf896756e406c1ba16e14a968c0ee834b7
5
+ SHA512:
6
+ metadata.gz: 7ec106f00f31923ed525939a7ec4d0e4572929e955c81de5d7e8a88c4e65dbe5b54fe3d52fe739c4501c49b2c3ef1dc85b4a6073ae64fda4c571a67cab320b6f
7
+ data.tar.gz: f5dc10085a3d69ce1b18964a6dcd3ec371db6a95c1c5952d3799708caf6e0dc278d6ec0b5ebe57b52c6efc91f9a311c141c1dc6fd5253c17db68b75039ba434a
@@ -0,0 +1,17 @@
1
+ *.gem
2
+ *.rbc
3
+ .bundle
4
+ .config
5
+ .yardoc
6
+ Gemfile.lock
7
+ InstalledFiles
8
+ _yardoc
9
+ coverage
10
+ doc/
11
+ lib/bundler/man
12
+ pkg
13
+ rdoc
14
+ spec/reports
15
+ test/tmp
16
+ test/version_tmp
17
+ tmp
data/.rspec ADDED
@@ -0,0 +1,2 @@
1
+ --color
2
+ --format documentation
@@ -0,0 +1 @@
1
+ 2.0.0
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in uwsgi_it_client.gemspec
4
+ gemspec
@@ -0,0 +1,24 @@
1
+ # A sample Guardfile
2
+ # More info at https://github.com/guard/guard#readme
3
+
4
+ guard :rspec do
5
+ watch(%r{^spec/.+_spec\.rb$})
6
+ watch(%r{^lib/(.+)\.rb$}) { |m| "spec/lib/#{m[1]}_spec.rb" }
7
+ watch('spec/spec_helper.rb') { "spec" }
8
+
9
+ # Rails example
10
+ watch(%r{^app/(.+)\.rb$}) { |m| "spec/#{m[1]}_spec.rb" }
11
+ watch(%r{^app/(.*)(\.erb|\.haml|\.slim)$}) { |m| "spec/#{m[1]}#{m[2]}_spec.rb" }
12
+ watch(%r{^app/controllers/(.+)_(controller)\.rb$}) { |m| ["spec/routing/#{m[1]}_routing_spec.rb", "spec/#{m[2]}s/#{m[1]}_#{m[2]}_spec.rb", "spec/acceptance/#{m[1]}_spec.rb"] }
13
+ watch(%r{^spec/support/(.+)\.rb$}) { "spec" }
14
+ watch('config/routes.rb') { "spec/routing" }
15
+ watch('app/controllers/application_controller.rb') { "spec/controllers" }
16
+
17
+ # Capybara features specs
18
+ watch(%r{^app/views/(.+)/.*\.(erb|haml|slim)$}) { |m| "spec/features/#{m[1]}_spec.rb" }
19
+
20
+ # Turnip features and steps
21
+ watch(%r{^spec/acceptance/(.+)\.feature$})
22
+ watch(%r{^spec/acceptance/steps/(.+)_steps\.rb$}) { |m| Dir[File.join("**/#{m[1]}.feature")][0] || 'spec/acceptance' }
23
+ end
24
+
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2014 andrea longhi
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.
@@ -0,0 +1,253 @@
1
+ # UwsgiItClient
2
+
3
+ Ruby client for uwsgi.it API. Now with a command line tool out of the box.
4
+
5
+ ## Installation
6
+
7
+ Add this line to your application's Gemfile:
8
+
9
+ gem 'uwsgi_it_client'
10
+
11
+ And then execute:
12
+
13
+ $ bundle
14
+
15
+ Or install it yourself as:
16
+
17
+ $ gem install uwsgi_it_client
18
+
19
+ ## Usage
20
+
21
+ After install you can run it with the CLI executable `uwsgi_client` or using the ruby API.
22
+
23
+ ### CLI interface
24
+ CLI requires username, password and url to be provided inline with the command unless you provide
25
+ a configuration file. You can create this file in the current directory or in your home directory.
26
+ The file must be named `.uwsgi_it_client.yml` and should read like the following example:
27
+ ```yaml
28
+ username: kratos
29
+ password: deimos
30
+ url: https://foobar.com/api
31
+ ```
32
+ If both files exist (one in the home directory and one in the current directory) then the one in
33
+ your current directory will have precedence.
34
+
35
+
36
+ ### Ruby API
37
+
38
+ To use the API, create a `UwsgiItClient` instance with your account data:
39
+ ```ruby
40
+ client = UwsgiItClient.new(
41
+ username: 'kratos',
42
+ password: 'deimos',
43
+ url: 'https://foobar.com/api/'
44
+ )
45
+ ```
46
+
47
+ Here are the mappings for the existing API calls and CLI commands:
48
+
49
+ #### List your data
50
+
51
+ ```bash
52
+ # Plain Usage
53
+ curl https://kratos:deimos@foobar.com/api/me/
54
+ ```
55
+
56
+ ```ruby
57
+ # Ruby Client
58
+ client.me
59
+ ```
60
+
61
+ ```bash
62
+ # CLI
63
+ uwsgi_client me -u=kratos -p=deimos -a=https://foobar.com/api
64
+
65
+ # CLI with configuration file
66
+ uwsgi_client me
67
+ ```
68
+
69
+
70
+ #### Change company name
71
+
72
+ ```bash
73
+ # Plain Usage
74
+ curl -X POST -d '{"company": "God of War 4 S.p.a."}' https://kratos:deimos@foobar.com/api/me/
75
+ ```
76
+
77
+ ```ruby
78
+ # Ruby Client
79
+ client.post :me, {company: 'God of War 4 S.p.a.'}
80
+ ```
81
+
82
+
83
+ #### Change password
84
+
85
+ ```bash
86
+ # Plain Usage
87
+ curl -X POST -d '{"password": "deimos17"}' https://kratos:deimos@foobar.com/api/me/
88
+ ```
89
+
90
+ ```ruby
91
+ # Ruby Client
92
+ client.post :me, {password: 'deimos17'}
93
+ ```
94
+
95
+
96
+ #### List your containers
97
+
98
+ ```bash
99
+ # Plain Usage
100
+ curl https://kratos:deimos17@foobar.com/api/me/containers/
101
+ ```
102
+
103
+ ```ruby
104
+ # Ruby Client
105
+ client.containers
106
+ ```
107
+
108
+ ```bash
109
+ # CLI
110
+ uwsgi_client containers -u=kratos -p=deimos17 -a=https://foobar.com/api
111
+ ```
112
+
113
+
114
+ #### Show a single container
115
+
116
+ ```bash
117
+ # Plain Usage
118
+ curl https://kratos:deimos17@foobar.com/api/containers/30009
119
+ ```
120
+
121
+ ```ruby
122
+ # Ruby Client
123
+ client.container 30009
124
+ ```
125
+
126
+ ```bash
127
+ # CLI
128
+ uwsgi_client containers 30009 -u=kratos -p=deimos17 -a=https://foobar.com/api
129
+ ```
130
+
131
+
132
+ #### List distros
133
+
134
+ ```bash
135
+ # Plain Usage
136
+ curl https://kratos:deimos17@foobar.com/api/distros/
137
+ ```
138
+
139
+ ```ruby
140
+ # Ruby Client
141
+ client.distros
142
+ ```
143
+
144
+ ```bash
145
+ # CLI
146
+ uwsgi_client distros -u=kratos -p=deimos17 -a=https://foobar.com/api
147
+ ```
148
+
149
+
150
+ #### Set container distro
151
+
152
+ ```bash
153
+ # Plain Usage
154
+ curl -X POST -d '{"distro": 2}' https://kratos:deimos17@foobar.com/api/containers/30009
155
+ ```
156
+
157
+ ```ruby
158
+ # Ruby Client
159
+ client.post :container, {distro: 2}, id: 30009
160
+ ```
161
+
162
+
163
+ #### Upload ssh keys
164
+
165
+ ```bash
166
+ # Plain Usage
167
+ curl -X POST -d '{"ssh_keys": ["ssh-rsa ........."]}' https://kratos:deimos17@foobar.com/api/containers/30009
168
+ ```
169
+
170
+ ```ruby
171
+ # Ruby Client
172
+ client.post :container, {ssh_keys: ["ssh-rsa..."]}, id: 30009
173
+ ```
174
+
175
+
176
+ #### List domains
177
+
178
+ ```bash
179
+ # Plain Usage
180
+ curl https://kratos:deimos17@foobar.com/api/domains/
181
+ ```
182
+
183
+ ```ruby
184
+ # Ruby Client
185
+ client.domains
186
+ ```
187
+
188
+ ```bash
189
+ # CLI
190
+ uwsgi_client domains -u=kratos -p=deimos17 -a=https://foobar.com/api
191
+ ```
192
+
193
+
194
+ #### Add domain
195
+
196
+ ```bash
197
+ # Plain Usage
198
+ curl -X POST -d '{"name":"mynewdomain.org"}' https://kratos:deimos17@foobar.com/api/domains/
199
+ ```
200
+
201
+ ```ruby
202
+ # Ruby Client
203
+ client.post :domains, {name: 'mynewdomain.org'}
204
+ ```
205
+
206
+
207
+ #### Delete domain
208
+
209
+ ```bash
210
+ # Plain Usage
211
+ curl -X DELETE -d '{"name":"mynewdomain.org"}' https://kratos:deimos17@foobar.com/api/domains/
212
+ ```
213
+
214
+ ```ruby
215
+ # Ruby Client
216
+ client.delete :domains, {name: 'mynewdomain.org'}
217
+ ```
218
+
219
+
220
+ ## High level syntax
221
+
222
+ Post and delete calls are by default low level, if you want the nicer syntax you need to extend your client with `ClientHelpers` module:
223
+
224
+ ```ruby
225
+ client.extend UwsgiItClient::ClientHelpers
226
+
227
+ client.company = 'Umbrella Corp.'
228
+
229
+ client.password = 'secret'
230
+
231
+ client.set_distro 3, 30009
232
+
233
+ client.add_key 'ssh-rsa...', 30009
234
+
235
+ client.add_keys ['ssh-rsa...', '...'], 30009
236
+
237
+ client.add_domain 'mynewdomain.org'
238
+
239
+ client.delete_domain 'mynewdomain.org'
240
+ ```
241
+
242
+
243
+ ## Contributing
244
+
245
+ 1. Fork it
246
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
247
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
248
+ 4. Push to the branch (`git push origin my-new-feature`)
249
+ 5. Create new Pull Request
250
+
251
+
252
+
253
+
@@ -0,0 +1,6 @@
1
+ require "bundler/gem_tasks"
2
+ require 'rspec/core/rake_task'
3
+
4
+ RSpec::Core::RakeTask.new(:spec)
5
+
6
+ task :default => :spec
@@ -0,0 +1,5 @@
1
+ #! /usr/bin/env ruby
2
+
3
+ require 'uwsgi_it_client/cli'
4
+
5
+ UwsgiItClient::CLI.start
@@ -0,0 +1,55 @@
1
+ require 'uwsgi_it_client/version'
2
+ require 'httparty'
3
+ require 'active_support/core_ext/module/delegation'
4
+
5
+ class UwsgiItClient
6
+ API = {
7
+ me: 'me/',
8
+ containers: 'me/containers/',
9
+ container: 'containers',
10
+ distros: 'distros/',
11
+ domains: 'domains/',
12
+ }
13
+
14
+ attr_reader :username, :password, :url
15
+
16
+
17
+ def initialize(opts)
18
+ @url = opts.fetch :url
19
+ @username = opts.fetch :username
20
+ @password = opts.fetch :password
21
+ end
22
+
23
+
24
+ API.each do |api_name, path|
25
+ api_url ="#{api_name}_url"
26
+
27
+ define_method api_url do |id=nil|
28
+ id = id && id.to_s
29
+ File.join [url, path, id].compact
30
+ end
31
+
32
+ define_method api_name do |id=nil|
33
+ Getter.new send(api_url, id), auth_data
34
+ end
35
+ end
36
+
37
+
38
+ def post(api_name, payload, opts={})
39
+ Poster.new send("#{api_name}_url", opts[:id]), payload, auth_data
40
+ end
41
+
42
+ def delete(api_name, payload, opts={})
43
+ Deleter.new send("#{api_name}_url", opts[:id]), payload, auth_data
44
+ end
45
+
46
+ private
47
+
48
+ def auth_data
49
+ {username: username, password: password}
50
+ end
51
+ end
52
+
53
+ Dir.entries('lib/uwsgi_it_client').each do |file|
54
+ require_relative "uwsgi_it_client/#{file}" if file =~ /\.rb$/
55
+ end
@@ -0,0 +1,112 @@
1
+ require 'ap'
2
+ require 'thor'
3
+ require 'yaml'
4
+ require 'active_support/core_ext/hash/keys'
5
+ require 'active_support/core_ext/object/try'
6
+ require 'active_support/hash_with_indifferent_access'
7
+
8
+ require 'uwsgi_it_client'
9
+
10
+ class UwsgiItClient
11
+ class CLI < Thor
12
+ no_commands do
13
+ def login_params
14
+ {
15
+ username: options[:username] || settings[:username],
16
+ password: options[:password] || settings[:password],
17
+ url: options[:api] || settings[:api]
18
+ }
19
+ end
20
+
21
+ def settings
22
+ current_dir_settings or home_settings or ErrorHash.new
23
+ end
24
+
25
+ def home_settings
26
+ load_settings File.expand_path('~/.uwsgi_it_client.yml')
27
+ end
28
+
29
+ def current_dir_settings
30
+ load_settings File.join Dir.pwd, '.uwsgi_it_client.yml'
31
+ end
32
+
33
+ def load_settings(file)
34
+ if File.file? file
35
+ hash = YAML.load_file file
36
+ ActiveSupport::HashWithIndifferentAccess.new hash
37
+ end
38
+ end
39
+
40
+ def print object
41
+ if object.is_a? String
42
+ puts object
43
+ else
44
+ ap object, indent: -2
45
+ end
46
+ end
47
+
48
+ def manage_action_result result
49
+ if result.response.code.to_i != 200
50
+ print "Cannot execute the desired action. The server responded with:"
51
+ print status: result.response.code.to_i, description: result.response.message
52
+ else
53
+ response = result.parsed_response.try(:symbolize_keys) || result.parsed_response.map(&:symbolize_keys)
54
+ if block_given?
55
+ yield response
56
+ else
57
+ print response
58
+ end
59
+ end
60
+ end
61
+ end
62
+
63
+ desc :me, "Retrieves user profile info"
64
+ method_option :username, aliases: '-u', type: :string, required: false,
65
+ desc: 'uwsgi.it username', banner: 'kratos'
66
+ method_option :password, aliases: '-p', type: :string, required: false,
67
+ desc: 'uwsgi.it password', banner: 'deimos'
68
+ method_option :api, aliases: '-a', type: :string, required: false,
69
+ desc: 'uwsgi.it api base url', banner: 'https://foobar.com/api'
70
+ def me
71
+ client = UwsgiItClient.new login_params
72
+ manage_action_result client.me
73
+ end
74
+
75
+ desc 'containers [ID]', "Retrieves containers list (if no ID is provided) or show container info"
76
+ method_option :username, aliases: '-u', type: :string, required: false,
77
+ desc: 'uwsgi.it username', banner: 'kratos'
78
+ method_option :password, aliases: '-p', type: :string, required: false,
79
+ desc: 'uwsgi.it password', banner: 'deimos'
80
+ method_option :api, aliases: '-a', type: :string, required: false,
81
+ desc: 'uwsgi.it api base url', banner: 'https://foobar.com/api'
82
+ def containers id = nil
83
+ client = UwsgiItClient.new login_params
84
+ result = id && client.container(id) || client.containers
85
+ manage_action_result result
86
+ end
87
+
88
+ desc :distros, "Retrieves distributions list"
89
+ method_option :username, aliases: '-u', type: :string, required: false,
90
+ desc: 'uwsgi.it username', banner: 'kratos'
91
+ method_option :password, aliases: '-p', type: :string, required: false,
92
+ desc: 'uwsgi.it password', banner: 'deimos'
93
+ method_option :api, aliases: '-a', type: :string, required: false,
94
+ desc: 'uwsgi.it api base url', banner: 'https://foobar.com/api'
95
+ def distros
96
+ client = UwsgiItClient.new login_params
97
+ manage_action_result client.distros
98
+ end
99
+
100
+ desc :domains, "Retrieves paired domains list"
101
+ method_option :username, aliases: '-u', type: :string, required: false,
102
+ desc: 'uwsgi.it username', banner: 'kratos'
103
+ method_option :password, aliases: '-p', type: :string, required: false,
104
+ desc: 'uwsgi.it password', banner: 'deimos'
105
+ method_option :api, aliases: '-a', type: :string, required: false,
106
+ desc: 'uwsgi.it api base url', banner: 'https://foobar.com/api'
107
+ def domains
108
+ client = UwsgiItClient.new login_params
109
+ manage_action_result client.domains
110
+ end
111
+ end
112
+ end
@@ -0,0 +1,33 @@
1
+ require 'active_support/core_ext/array/wrap'
2
+
3
+ class UwsgiItClient
4
+ module ClientHelpers
5
+ def company=(value)
6
+ post :me, {company: value}
7
+ end
8
+
9
+ def password=(value)
10
+ post :me, {password: value}
11
+ end
12
+
13
+ def set_distro(d_id, c_id)
14
+ post :container, {distro: d_id}, id: c_id
15
+ end
16
+
17
+ def add_keys(keys, c_id)
18
+ post :container, {ssh_keys: keys}, id: c_id
19
+ end
20
+
21
+ def add_key(key, c_id)
22
+ add_keys Array.wrap(key), c_id
23
+ end
24
+
25
+ def add_domain(name)
26
+ post :domains, {name: name}
27
+ end
28
+
29
+ def delete_domain(name)
30
+ delete :domains, {name: name}
31
+ end
32
+ end
33
+ end
@@ -0,0 +1,17 @@
1
+ class UwsgiItClient
2
+ class Deleter
3
+ include HTTParty
4
+
5
+ attr_reader :result
6
+
7
+ def initialize(url, body, auth_data)
8
+ @result = delete url, body: body.to_json, basic_auth: auth_data
9
+ end
10
+
11
+ private
12
+
13
+ def delete(*args)
14
+ self.class.delete *args
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,9 @@
1
+ class UwsgiItClient
2
+ class ErrorHash < Hash
3
+ def initialize
4
+ super do |hash, option|
5
+ hash[option] = raise "No value provided for required options '--#{option}'"
6
+ end
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,19 @@
1
+ class UwsgiItClient
2
+ class Getter
3
+ include HTTParty
4
+
5
+ attr_reader :result
6
+
7
+ delegate :success?, :body, :headers, :response, :parsed_response, to: :result
8
+
9
+ def initialize(url, auth_data)
10
+ @result = get url, basic_auth: auth_data
11
+ end
12
+
13
+ private
14
+
15
+ def get(*args)
16
+ self.class.get *args
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,17 @@
1
+ class UwsgiItClient
2
+ class Poster
3
+ include HTTParty
4
+
5
+ attr_reader :result
6
+
7
+ def initialize(url, body, auth_data)
8
+ @result = post url, body: body.to_json, basic_auth: auth_data
9
+ end
10
+
11
+ private
12
+
13
+ def post(*args)
14
+ self.class.post *args
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,3 @@
1
+ class UwsgiItClient
2
+ VERSION = "0.0.1"
3
+ end
@@ -0,0 +1,154 @@
1
+ require 'spec_helper'
2
+
3
+ describe UwsgiItClient::CLI do
4
+ include CLIHelpers
5
+
6
+ subject { UwsgiItClient::CLI }
7
+
8
+ shared_examples 'requires authentication' do |action_name|
9
+ let(:params) { ['-u=asd', '--password=asd', '-a=http://test.dev/api'] }
10
+
11
+ context 'when username is missing' do
12
+ before { params.delete '-u=asd' }
13
+ it 'requires username' do
14
+ expect { exec action_name, params }.to raise_error /--username/
15
+ end
16
+ end
17
+
18
+ context 'when password is missing' do
19
+ before { params.delete '--password=asd' }
20
+ it 'requires password' do
21
+ expect { exec action_name, params }.to raise_error /--password/
22
+ end
23
+ end
24
+
25
+ context 'when api url is misssing' do
26
+ before { params.delete '-a=http://test.dev/api' }
27
+ it 'requires api url' do
28
+ expect { exec action_name, params }.to raise_error /--api/
29
+ end
30
+ end
31
+
32
+ it 'is executed if all required arguments are present' do
33
+ expect { exec action_name, params }.to_not raise_error
34
+ end
35
+ end
36
+
37
+ shared_examples 'invokes api action' do |action_name, api_action_name = action_name, default_value = nil|
38
+ subject { exec action_name, [default_value, '-u=asd', '--password=asd', '-a=http://test.dev/api'].compact }
39
+
40
+ context 'and the server responds with an error' do
41
+ before do
42
+ fault = double response: double(code: '404', message: 'Not found')
43
+ expect_any_instance_of(UwsgiItClient).to receive(api_action_name).and_return fault
44
+ end
45
+
46
+ it 'the error is printed' do
47
+ expect(subject).to match /Cannot execute.*404.*Not\sfound/m
48
+ end
49
+ end
50
+
51
+ context 'and the server responds correctly' do
52
+ before do
53
+ expected = double response: double(code: '200'), parsed_response: response
54
+ expect_any_instance_of(UwsgiItClient).to receive(api_action_name).and_return expected
55
+ end
56
+
57
+ it 'the result is printed' do
58
+ expect(subject).to match match_regexp
59
+ end
60
+ end
61
+ end
62
+
63
+ context 'me' do
64
+ it_behaves_like 'requires authentication', :me
65
+
66
+ it_behaves_like 'invokes api action', :me do
67
+ let(:response) do
68
+ { company: 'asd', uuid: 'a-b-c-d' }
69
+ end
70
+ let(:match_regexp) { /company.*uuid/m }
71
+ end
72
+ end
73
+
74
+ context 'containers' do
75
+ it_behaves_like 'requires authentication', :containers
76
+
77
+ context 'when no id is provided' do
78
+ it_behaves_like 'invokes api action', :containers do
79
+ let(:response) do
80
+ [{ uid: 1234, ip: '10.0.0.2' }]
81
+ end
82
+ let(:match_regexp) { /\[.*\{.*uid.*ip.*\}.*\]/m }
83
+ end
84
+ end
85
+
86
+ context 'when an id is provided' do
87
+ it_behaves_like 'invokes api action', :containers, :container, '1' do
88
+ let(:response) do
89
+ { uid: 1234, ip: '10.0.0.2' }
90
+ end
91
+ let(:match_regexp) { /.*\{.*uid.*ip.*\}/m }
92
+ end
93
+ end
94
+ end
95
+
96
+ context 'distros' do
97
+ it_behaves_like 'requires authentication', :distros
98
+
99
+ it_behaves_like 'invokes api action', :distros do
100
+ let(:response) do
101
+ [{ id: 1, name: 'Sample Linux Distro' }]
102
+ end
103
+ let(:match_regexp) { /\[.*\{.*id.*name.*\}.*\]/m }
104
+ end
105
+ end
106
+
107
+ context 'domains' do
108
+ it_behaves_like 'requires authentication', :domains
109
+
110
+ it_behaves_like 'invokes api action', :domains do
111
+ let(:response) do
112
+ [{ id: 1, name: 'foobar.com' }]
113
+ end
114
+ let(:match_regexp) { /\[.*\{.*id.*name.*\}.*\]/m }
115
+ end
116
+ end
117
+
118
+ describe '#settings' do
119
+ subject { UwsgiItClient::CLI.new }
120
+
121
+ let(:current_dir_settings) { double }
122
+ let(:home_settings) { double }
123
+
124
+ context 'when no settings file is present' do
125
+ it 'returns an error hash' do
126
+ expect(subject.settings).to eq UwsgiItClient::ErrorHash.new
127
+ end
128
+ end
129
+
130
+ context 'when home dir settings are present' do
131
+ before { subject.stub home_settings: home_settings }
132
+
133
+ it 'loads home settings' do
134
+ expect(subject.settings).to eq home_settings
135
+ end
136
+ end
137
+
138
+ context 'when current dir settings are present' do
139
+ before { subject.stub current_dir_settings: current_dir_settings }
140
+
141
+ it 'loads current dir settings' do
142
+ expect(subject.settings).to eq current_dir_settings
143
+ end
144
+
145
+ context 'when home dir settings are present too' do
146
+ before { subject.stub home_settings: home_settings }
147
+
148
+ it 'still loads current dir settings' do
149
+ expect(subject.settings).to eq current_dir_settings
150
+ end
151
+ end
152
+ end
153
+ end
154
+ end
@@ -0,0 +1,28 @@
1
+ require 'spec_helper'
2
+
3
+
4
+ class UwsgiItClient
5
+ describe ClientHelpers do
6
+ context 'when extending a UwsgiItClient instance' do
7
+ let(:username) { 'username' }
8
+ let(:password) { 'password' }
9
+ let(:url) { 'https://domain.com/path/to/api' }
10
+
11
+ subject do
12
+ client = UwsgiItClient.new(
13
+ username: username,
14
+ password: password,
15
+ url: url
16
+ )
17
+ client.extend(ClientHelpers)
18
+ client
19
+ end
20
+
21
+ %w[company= password= set_distro add_keys add_key add_domain delete_domain].each do |method_name|
22
+ it "responds to #{method_name}" do
23
+ expect(subject).to respond_to method_name
24
+ end
25
+ end
26
+ end
27
+ end
28
+ end
@@ -0,0 +1,9 @@
1
+ require 'spec_helper'
2
+
3
+ class UwsgiItClient
4
+ describe Deleter do
5
+ it 'requires url, body and auth data' do
6
+ expect { Deleter.new }.to raise_error ArgumentError
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,9 @@
1
+ require 'spec_helper'
2
+
3
+ class UwsgiItClient
4
+ describe ErrorHash do
5
+ it 'raises an error everytime for every key' do
6
+ expect( -> {subject[:key]}).to raise_error
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,23 @@
1
+ require 'spec_helper'
2
+
3
+ class UwsgiItClient
4
+ describe Getter do
5
+ let(:url) { 'http://somedomain.com/path' }
6
+ let(:auth_data) { {username: 'racco', password: 'party'} }
7
+
8
+ subject { Getter.new url, auth_data }
9
+
10
+ it 'requires url and auth data' do
11
+ expect { Getter.new }.to raise_error ArgumentError
12
+ end
13
+
14
+ %w[success? body headers response].each do |method_name|
15
+ it "delegates #{method_name} to result object" do
16
+ result = double
17
+ subject.stub(result: result)
18
+ result.should_receive method_name
19
+ subject.send method_name
20
+ end
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,9 @@
1
+ require 'spec_helper'
2
+
3
+ class UwsgiItClient
4
+ describe Poster do
5
+ it 'requires url, body and auth data' do
6
+ expect { Poster.new }.to raise_error ArgumentError
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,81 @@
1
+ require 'spec_helper'
2
+
3
+ describe UwsgiItClient do
4
+ let(:username) { 'username' }
5
+ let(:password) { 'password' }
6
+ let(:url) { 'https://domain.com/path/to/api' }
7
+
8
+ subject { UwsgiItClient.new username: username, password: password, url: url }
9
+
10
+ context 'when the option param is missing' do
11
+ it { expect { UwsgiItClient.new }.to raise_error ArgumentError }
12
+ end
13
+
14
+ context 'when a required option is missing' do
15
+ it 'raises an error' do
16
+ expect { UwsgiItClient.new username: username }.to raise_error
17
+ end
18
+ end
19
+
20
+ context 'when passing valid options' do
21
+ it 'sets username, password, domain attributes as expected' do
22
+ expect(subject.url).to eq url
23
+ expect(subject.password).to eq password
24
+ expect(subject.username).to eq username
25
+ end
26
+ end
27
+
28
+ { me: 'me', containers: 'me/containers', distros: 'distros', domains: 'domains' }.each do |api_name, url|
29
+ context "when accessing #{api_name} API" do
30
+ it 'sets correctly the url' do
31
+ expect(subject.send "#{api_name}_url").to eq "#{subject.url}/#{url}/"
32
+ end
33
+
34
+ it 'creates a new getter object' do
35
+ expect(UwsgiItClient::Getter).to receive :new
36
+ subject.send api_name
37
+ end
38
+
39
+ it 'returns the getter object' do
40
+ UwsgiItClient::Getter.stub get: {}
41
+ expect(subject.send api_name).to be_a UwsgiItClient::Getter
42
+ end
43
+ end
44
+ end
45
+
46
+ context 'when adding an id to the url' do
47
+ context 'when the id is present' do
48
+ it 'converts the id to string if necessary' do
49
+ subject.container_url(3001).should eq "#{subject.url}/containers/3001"
50
+ end
51
+ end
52
+
53
+ context 'when id is nil' do
54
+ it 'removes the id param entirely' do
55
+ subject.container_url(nil).should eq "#{subject.url}/containers"
56
+ end
57
+ end
58
+ end
59
+
60
+ context 'when POSTing to API' do
61
+ let(:payload) { {some: :payload} }
62
+ let(:api_name) { :domains }
63
+ let(:auth_data) { subject.send :auth_data }
64
+
65
+ it 'creates a Poster instance' do
66
+ UwsgiItClient::Poster.should_receive :new
67
+ subject.post api_name, payload, auth_data
68
+ end
69
+ end
70
+
71
+ context 'when DELETEing to API' do
72
+ it 'creates a Deleter instance' do
73
+ end
74
+ end
75
+
76
+ describe '#container_url' do
77
+ it 'returns the expected url' do
78
+ expect(subject.container_url('3001')).to eq "#{url}/containers/3001"
79
+ end
80
+ end
81
+ end
@@ -0,0 +1,4 @@
1
+ require_relative '../lib/uwsgi_it_client'
2
+ require_relative '../lib/uwsgi_it_client/cli'
3
+
4
+ Dir["#{File.dirname __FILE__}/support/**/*.rb"].each { |f| require f }
@@ -0,0 +1,26 @@
1
+ module CLIHelpers
2
+ def self.included base
3
+ base.before :each do
4
+ ENV['THOR_DEBUG'] = '1'
5
+ end
6
+ end
7
+
8
+ def capture(stream)
9
+ begin
10
+ stream = stream.to_s
11
+ eval "$#{stream} = StringIO.new"
12
+ yield
13
+ result = eval("$#{stream}").string
14
+ ensure
15
+ eval("$#{stream} = #{stream.upcase}")
16
+ end
17
+
18
+ result
19
+ end
20
+
21
+ def exec command, args = []
22
+ capture :stdout do
23
+ UwsgiItClient::CLI.start [command].concat args
24
+ end
25
+ end
26
+ end
@@ -0,0 +1,32 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'uwsgi_it_client/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = "uwsgi_it_client"
8
+ spec.version = UwsgiItClient::VERSION
9
+ spec.authors = ["andrea longhi", "nicola racco"]
10
+ spec.email = ["andrea@mikamai.com", "nicola@mikamai.com"]
11
+ spec.description = %q{ruby client for uwsgi.it api}
12
+ spec.summary = %q{ruby client for uwsgi.it api}
13
+ spec.homepage = ""
14
+ spec.license = "MIT"
15
+
16
+ spec.files = `git ls-files`.split($/)
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_development_dependency "bundler", "~> 1.3"
22
+ spec.add_development_dependency "rake"
23
+ spec.add_development_dependency "rspec"
24
+ spec.add_development_dependency "guard-rspec"
25
+ spec.add_development_dependency "pry"
26
+
27
+ spec.add_dependency "json"
28
+ spec.add_dependency "httparty"
29
+ spec.add_dependency "activesupport"
30
+ spec.add_dependency "thor"
31
+ spec.add_dependency "awesome_print"
32
+ end
metadata ADDED
@@ -0,0 +1,223 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: uwsgi_it_client
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ platform: ruby
6
+ authors:
7
+ - andrea longhi
8
+ - nicola racco
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2014-01-23 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: bundler
16
+ requirement: !ruby/object:Gem::Requirement
17
+ requirements:
18
+ - - ~>
19
+ - !ruby/object:Gem::Version
20
+ version: '1.3'
21
+ type: :development
22
+ prerelease: false
23
+ version_requirements: !ruby/object:Gem::Requirement
24
+ requirements:
25
+ - - ~>
26
+ - !ruby/object:Gem::Version
27
+ version: '1.3'
28
+ - !ruby/object:Gem::Dependency
29
+ name: rake
30
+ requirement: !ruby/object:Gem::Requirement
31
+ requirements:
32
+ - - '>='
33
+ - !ruby/object:Gem::Version
34
+ version: '0'
35
+ type: :development
36
+ prerelease: false
37
+ version_requirements: !ruby/object:Gem::Requirement
38
+ requirements:
39
+ - - '>='
40
+ - !ruby/object:Gem::Version
41
+ version: '0'
42
+ - !ruby/object:Gem::Dependency
43
+ name: rspec
44
+ requirement: !ruby/object:Gem::Requirement
45
+ requirements:
46
+ - - '>='
47
+ - !ruby/object:Gem::Version
48
+ version: '0'
49
+ type: :development
50
+ prerelease: false
51
+ version_requirements: !ruby/object:Gem::Requirement
52
+ requirements:
53
+ - - '>='
54
+ - !ruby/object:Gem::Version
55
+ version: '0'
56
+ - !ruby/object:Gem::Dependency
57
+ name: guard-rspec
58
+ requirement: !ruby/object:Gem::Requirement
59
+ requirements:
60
+ - - '>='
61
+ - !ruby/object:Gem::Version
62
+ version: '0'
63
+ type: :development
64
+ prerelease: false
65
+ version_requirements: !ruby/object:Gem::Requirement
66
+ requirements:
67
+ - - '>='
68
+ - !ruby/object:Gem::Version
69
+ version: '0'
70
+ - !ruby/object:Gem::Dependency
71
+ name: pry
72
+ requirement: !ruby/object:Gem::Requirement
73
+ requirements:
74
+ - - '>='
75
+ - !ruby/object:Gem::Version
76
+ version: '0'
77
+ type: :development
78
+ prerelease: false
79
+ version_requirements: !ruby/object:Gem::Requirement
80
+ requirements:
81
+ - - '>='
82
+ - !ruby/object:Gem::Version
83
+ version: '0'
84
+ - !ruby/object:Gem::Dependency
85
+ name: json
86
+ requirement: !ruby/object:Gem::Requirement
87
+ requirements:
88
+ - - '>='
89
+ - !ruby/object:Gem::Version
90
+ version: '0'
91
+ type: :runtime
92
+ prerelease: false
93
+ version_requirements: !ruby/object:Gem::Requirement
94
+ requirements:
95
+ - - '>='
96
+ - !ruby/object:Gem::Version
97
+ version: '0'
98
+ - !ruby/object:Gem::Dependency
99
+ name: httparty
100
+ requirement: !ruby/object:Gem::Requirement
101
+ requirements:
102
+ - - '>='
103
+ - !ruby/object:Gem::Version
104
+ version: '0'
105
+ type: :runtime
106
+ prerelease: false
107
+ version_requirements: !ruby/object:Gem::Requirement
108
+ requirements:
109
+ - - '>='
110
+ - !ruby/object:Gem::Version
111
+ version: '0'
112
+ - !ruby/object:Gem::Dependency
113
+ name: activesupport
114
+ requirement: !ruby/object:Gem::Requirement
115
+ requirements:
116
+ - - '>='
117
+ - !ruby/object:Gem::Version
118
+ version: '0'
119
+ type: :runtime
120
+ prerelease: false
121
+ version_requirements: !ruby/object:Gem::Requirement
122
+ requirements:
123
+ - - '>='
124
+ - !ruby/object:Gem::Version
125
+ version: '0'
126
+ - !ruby/object:Gem::Dependency
127
+ name: thor
128
+ requirement: !ruby/object:Gem::Requirement
129
+ requirements:
130
+ - - '>='
131
+ - !ruby/object:Gem::Version
132
+ version: '0'
133
+ type: :runtime
134
+ prerelease: false
135
+ version_requirements: !ruby/object:Gem::Requirement
136
+ requirements:
137
+ - - '>='
138
+ - !ruby/object:Gem::Version
139
+ version: '0'
140
+ - !ruby/object:Gem::Dependency
141
+ name: awesome_print
142
+ requirement: !ruby/object:Gem::Requirement
143
+ requirements:
144
+ - - '>='
145
+ - !ruby/object:Gem::Version
146
+ version: '0'
147
+ type: :runtime
148
+ prerelease: false
149
+ version_requirements: !ruby/object:Gem::Requirement
150
+ requirements:
151
+ - - '>='
152
+ - !ruby/object:Gem::Version
153
+ version: '0'
154
+ description: ruby client for uwsgi.it api
155
+ email:
156
+ - andrea@mikamai.com
157
+ - nicola@mikamai.com
158
+ executables:
159
+ - uwsgi_client
160
+ extensions: []
161
+ extra_rdoc_files: []
162
+ files:
163
+ - .gitignore
164
+ - .rspec
165
+ - .ruby-version
166
+ - Gemfile
167
+ - Guardfile
168
+ - LICENSE.txt
169
+ - README.md
170
+ - Rakefile
171
+ - bin/uwsgi_client
172
+ - lib/uwsgi_it_client.rb
173
+ - lib/uwsgi_it_client/cli.rb
174
+ - lib/uwsgi_it_client/client_helpers.rb
175
+ - lib/uwsgi_it_client/deleter.rb
176
+ - lib/uwsgi_it_client/error_hash.rb
177
+ - lib/uwsgi_it_client/getter.rb
178
+ - lib/uwsgi_it_client/poster.rb
179
+ - lib/uwsgi_it_client/version.rb
180
+ - spec/lib/uwsgi_it_client/cli_spec.rb
181
+ - spec/lib/uwsgi_it_client/client_helpers_spec.rb
182
+ - spec/lib/uwsgi_it_client/deleter_spec.rb
183
+ - spec/lib/uwsgi_it_client/error_hash_spec.rb
184
+ - spec/lib/uwsgi_it_client/getter_spec.rb
185
+ - spec/lib/uwsgi_it_client/poster_spec.rb
186
+ - spec/lib/uwsgi_it_client_spec.rb
187
+ - spec/spec_helper.rb
188
+ - spec/support/cli_helpers.rb
189
+ - uwsgi_it_client.gemspec
190
+ homepage: ''
191
+ licenses:
192
+ - MIT
193
+ metadata: {}
194
+ post_install_message:
195
+ rdoc_options: []
196
+ require_paths:
197
+ - lib
198
+ required_ruby_version: !ruby/object:Gem::Requirement
199
+ requirements:
200
+ - - '>='
201
+ - !ruby/object:Gem::Version
202
+ version: '0'
203
+ required_rubygems_version: !ruby/object:Gem::Requirement
204
+ requirements:
205
+ - - '>='
206
+ - !ruby/object:Gem::Version
207
+ version: '0'
208
+ requirements: []
209
+ rubyforge_project:
210
+ rubygems_version: 2.1.11
211
+ signing_key:
212
+ specification_version: 4
213
+ summary: ruby client for uwsgi.it api
214
+ test_files:
215
+ - spec/lib/uwsgi_it_client/cli_spec.rb
216
+ - spec/lib/uwsgi_it_client/client_helpers_spec.rb
217
+ - spec/lib/uwsgi_it_client/deleter_spec.rb
218
+ - spec/lib/uwsgi_it_client/error_hash_spec.rb
219
+ - spec/lib/uwsgi_it_client/getter_spec.rb
220
+ - spec/lib/uwsgi_it_client/poster_spec.rb
221
+ - spec/lib/uwsgi_it_client_spec.rb
222
+ - spec/spec_helper.rb
223
+ - spec/support/cli_helpers.rb