uwsgi_it_client 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -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