Skip to content

Commit

Permalink
Merge pull request #70 from promptworks/ensure-configurable-path
Browse files Browse the repository at this point in the history
Ensure path is passed through to API middleware
  • Loading branch information
nicholaides committed Nov 25, 2014
2 parents 93d74f6 + a9a49b2 commit 88948c6
Show file tree
Hide file tree
Showing 33 changed files with 266 additions and 792 deletions.
51 changes: 43 additions & 8 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ And execute:

```ruby
cloud_stack = StackerBee::Client.new(
url: 'http://localhost:8080/client/api',
url: 'http://localhost:8080',
api_key: 'MY_API_KEY',
secret_key: 'MY_SECRET_KEY'
)
Expand Down Expand Up @@ -85,7 +85,7 @@ Usage:

Example:

$ stacker_bee -u http://localhost:8080/client/api -a MY_API_KEY -s MY_SECRET_KEY
$ stacker_bee -u http://localhost:8080 -a MY_API_KEY -s MY_SECRET_KEY
StackerBee CloudStack REPL
>> list_virtual_machines state: 'Running'
=> [{"id"=>"48b91ab4-dc23-4e24-bc6f-695d58c91087",
Expand All @@ -100,7 +100,7 @@ Configuring a client:

```ruby
cloud_stack = StackerBee::Client.new(
url: 'http://localhost:8080/client/api',
url: 'http://localhost:8080',
api_key: 'API_KEY',
secret_key: 'SECRET_KEY'
)
Expand All @@ -109,7 +109,7 @@ cloud_stack = StackerBee::Client.new(
All configuration parameters set on the `StackerBee::Client` class are used as defaults for `StackerBee::Client` instances.

```ruby
StackerBee::Client.url = 'http://localhost:8080/client/api'
StackerBee::Client.url = 'http://localhost:8080'

user_client = StackerBee::Client.new(
api_key: 'USER_API_KEY',
Expand All @@ -127,17 +127,52 @@ root_client = StackerBee::Client.new(
The URL of your CloudStack instance's URL.

```ruby
StackerBee::Client.url = 'http://localhost:8080/client/api'
StackerBee::Client.url = 'http://localhost:8080'
```

Or:

```ruby
my_client = StackerBee::Client.new(
url: 'http://localhost:8080/client/api'
url: 'http://localhost:8080'
)
```

### API path

The path of your CloudStack instance's API URL.
Defaults to `'/client/api/'`.

```ruby
StackerBee::Client.api_path = '/other-path/client/api'
```

Or:

```ruby
my_client = StackerBee::Client.new(
api_path: '/other-path/client/api'
)
```

### Console path

The path of your CloudStack instance's URL for console access.
Defaults to `'/client/console/'`.

```ruby
StackerBee::Client.console_path = '/other-path/client/console'
```

Or:

```ruby
my_client = StackerBee::Client.new(
console_path: '/other-path/client/console'
)
```


### Keys

Your CloudStack credentials, i.e. API key and secret key.
Expand Down Expand Up @@ -219,7 +254,7 @@ StackerBee supports using SSL. To do so, use an HTTPS URL. In some deployments,

```ruby
StackerBee::Client.configuration = {
url: 'https://my-cloudstack-server/client/api',
url: 'https://my-cloudstack-server',
ssl_verify: false # ignore certificate validation errors
}
```
Expand All @@ -230,7 +265,7 @@ The `StackerBee::Client` class can be configured with multiple options at once.

```ruby
StackerBee::Client.configuration = {
url: 'http://localhost:8080/client/api',
url: 'http://localhost:8080',
api_key: 'API_KEY',
secret_key: 'MY_SECRET_KEY'
}
Expand Down
2 changes: 1 addition & 1 deletion config.default.yml
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
url: 'http://127.0.0.1:1234/client/api/'
url: 'http://127.0.0.1:1234'
api_key: 'MY-KEY-MY-KEY-MY-KEY-MY-KEY-MY-KEY-MY-KEY-MY-KEY-MY-KEY-MY-KEY-MY-KEY-MY-KEY-MY-KEY-MY'
secret_key: 'TOP-SECRET-TOP-SECRET-TOP-SECRET-TOP-SECRET-TOP-SECRET-TOP-SECRET-TOP-SECRET-TOP-SECRE'
7 changes: 5 additions & 2 deletions lib/stacker_bee/client.rb
Original file line number Diff line number Diff line change
Expand Up @@ -34,11 +34,14 @@ class Client
# rubocop:disable Metrics/AbcSize
def middlewares
# request
builder.use Middleware::ConsoleAccess
builder.use Middleware::ConsoleAccess,
console_path: configuration.console_path

builder.use Middleware::EndpointNormalizer, api: self.class.api
builder.use Middleware::RemoveEmptyStrings
builder.use Middleware::CloudStackAPI, api_key: configuration.api_key
builder.use Middleware::CloudStackAPI,
api_path: configuration.api_path,
api_key: configuration.api_key

configuration.middlewares.call builder

Expand Down
24 changes: 22 additions & 2 deletions lib/stacker_bee/configuration.rb
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ class NoAttributeError < StandardError
ATTRIBUTES = [
:ssl_verify,
:url,
:api_path,
:console_path,
:secret_key,
:api_key,
:middlewares,
Expand Down Expand Up @@ -37,6 +39,14 @@ def url
attribute :url
end

def api_path
attribute :api_path, '/client/api'
end

def console_path
attribute :console_path, '/client/console'
end

def secret_key
attribute :secret_key
end
Expand Down Expand Up @@ -67,8 +77,18 @@ def merge(other)

private

def attribute(key, value = nil)
@attributes.fetch(key, value)
def attribute(key, default_value = nil)
value = @attributes.fetch(key, default_value)

if blank?(value)
default_value
else
value
end
end

def blank?(value)
value.nil? || value == ''
end
end
end
6 changes: 5 additions & 1 deletion lib/stacker_bee/middleware/adapter.rb
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,11 @@ def pluck_body(env)

def perform_request(env)
params = env.request.params.to_a.sort
env.raw_response = connection.get(env.request.path, params)
env.raw_response = connection.get(path(env), params)
end

def path(env)
env.request.path.to_s.gsub(/\/$/, '')
end

def endpoint_name_for(*)
Expand Down
3 changes: 1 addition & 2 deletions lib/stacker_bee/middleware/cloud_stack_api.rb
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,14 @@ module StackerBee
module Middleware
class CloudStackAPI < Base
RESPONSE_TYPE = 'json'
DEFAULT_PATH = '/client/api/'

def before(env)
env.request.params.merge!(
api_key: api_key,
command: env.request.endpoint_name,
response: RESPONSE_TYPE
)
env.request.path ||= DEFAULT_PATH
env.request.path ||= api_path
end
end
end
Expand Down
3 changes: 1 addition & 2 deletions lib/stacker_bee/middleware/console_access.rb
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,12 @@ class ConsoleAccess < Base
include Utilities

ENDPOINT = 'consoleAccess'
PATH = '/client/console'
PARAMS = { cmd: 'access' }

def before(env)
return unless matches_endpoint?(env.request.endpoint_name)
super
env.request.path = PATH
env.request.path = console_path
env.request.endpoint_name = ENDPOINT
end

Expand Down
2 changes: 1 addition & 1 deletion lib/stacker_bee/request_error.rb
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ class RequestError < StandardError
def initialize(env)
self.env = env
self.status = env.response.status
super env.response.error
super env.response.error || env.request.path
end

def self.for(env)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
http_interactions:
- request:
method: get
uri: <CLOUD_STACK_HOST>/client/console?apiKey=<CLOUD_STACK_API_KEY>&cmd=access&command=consoleAccess&response=json&signature=DsI/kxaNO7AgzDCgE1j/3rtq3xU&vm=36f9c08b-f17a-4d0e-ac9b-d45ce2d34fcd
uri: <CLOUD_STACK_HOST>/client/console?apiKey=<CLOUD_STACK_API_KEY>&cmd=access&command=consoleAccess&response=json&signature=0xjsh2gd3qbGVi9egkb6VHocx%2BI=&vm=36f9c08b-f17a-4d0e-ac9b-d45ce2d34fcd
body:
encoding: US-ASCII
string: ''
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,37 +2,7 @@
http_interactions:
- request:
method: get
uri: <CLOUD_STACK_URL>?apiKey=<CLOUD_STACK_API_KEY>&command=listAccounts&response=json&signature=oftBcJm8kFc%2Buxul8pAL2%2Bh0bdU=
body:
encoding: US-ASCII
string: ''
headers:
User-Agent:
- Faraday v0.8.8
Accept-Encoding:
- gzip;q=1.0,deflate;q=0.6,identity;q=0.3
Accept:
- '*/*'
response:
status:
code: 200
message: OK
headers:
Content-Type:
- text/javascript; charset=UTF-8
Content-Length:
- '1727'
Server:
- Jetty(6.1.26)
body:
encoding: UTF-8
string: '{ "listaccountsresponse" : { "count":1 ,"account" : [ {"id":"fdc009b8-2034-11e3-a44b-d6558ad1fb9f","name":"admin","accounttype":1,"domainid":"fdbfec94-2034-11e3-a44b-d6558ad1fb9f","domain":"ROOT","vmlimit":"Unlimited","vmtotal":0,"vmavailable":"Unlimited","iplimit":"Unlimited","iptotal":0,"ipavailable":"Unlimited","volumelimit":"Unlimited","volumetotal":0,"volumeavailable":"Unlimited","snapshotlimit":"Unlimited","snapshottotal":0,"snapshotavailable":"Unlimited","templatelimit":"Unlimited","templatetotal":0,"templateavailable":"Unlimited","projectlimit":"Unlimited","projecttotal":0,"projectavailable":"Unlimited","networklimit":"Unlimited","networktotal":0,"networkavailable":"Unlimited","vpclimit":"Unlimited","vpctotal":0,"vpcavailable":"Unlimited","cpulimit":"Unlimited","cputotal":0,"cpuavailable":"Unlimited","memorylimit":"Unlimited","memorytotal":0,"memoryavailable":"Unlimited","primarystoragelimit":"Unlimited","primarystoragetotal":0,"primarystorageavailable":"Unlimited","secondarystoragelimit":"Unlimited","secondarystoragetotal":0,"secondarystorageavailable":"Unlimited","state":"enabled","user":[{"id":"fdc03456-2034-11e3-a44b-d6558ad1fb9f","username":"admin","firstname":"Admin","lastname":"User","email":"admin@mailprovider.com","created":"2013-09-17T23:36:11-0400","state":"enabled","account":"admin","accounttype":1,"domainid":"fdbfec94-2034-11e3-a44b-d6558ad1fb9f","domain":"ROOT","apikey":"<CLOUD_STACK_API_KEY>","secretkey":"<CLOUD_STACK_SECRET_KEY>","accountid":"fdc009b8-2034-11e3-a44b-d6558ad1fb9f","iscallerchilddomain":false,"isdefault":true}],"isdefault":true}
] } }'
http_version:
recorded_at: Thu, 24 Oct 2013 18:42:15 GMT
- request:
method: get
uri: <CLOUD_STACK_URL>/?apiKey=<CLOUD_STACK_API_KEY>&command=listAccounts&response=json&signature=oftBcJm8kFc%2Buxul8pAL2%2Bh0bdU=
uri: <CLOUD_STACK_HOST>/client/api?apiKey=<CLOUD_STACK_API_KEY>&command=listAccounts&response=json&signature=oftBcJm8kFc%2Buxul8pAL2%2Bh0bdU=
body:
encoding: US-ASCII
string: ''
Expand All @@ -51,13 +21,13 @@ http_interactions:
Content-Type:
- text/javascript; charset=UTF-8
Content-Length:
- '1728'
- '1727'
Server:
- Jetty(6.1.26)
body:
encoding: UTF-8
string: '{ "listaccountsresponse" : { "count":1 ,"account" : [ {"id":"b32dc958-b904-11e3-b3f0-080027079e3d","name":"admin","accounttype":1,"domainid":"b32db4c2-b904-11e3-b3f0-080027079e3d","domain":"ROOT","vmlimit":"Unlimited","vmtotal":0,"vmavailable":"Unlimited","iplimit":"Unlimited","iptotal":0,"ipavailable":"Unlimited","volumelimit":"Unlimited","volumetotal":0,"volumeavailable":"Unlimited","snapshotlimit":"Unlimited","snapshottotal":0,"snapshotavailable":"Unlimited","templatelimit":"Unlimited","templatetotal":0,"templateavailable":"Unlimited","projectlimit":"Unlimited","projecttotal":0,"projectavailable":"Unlimited","networklimit":"Unlimited","networktotal":11,"networkavailable":"Unlimited","vpclimit":"Unlimited","vpctotal":0,"vpcavailable":"Unlimited","cpulimit":"Unlimited","cputotal":0,"cpuavailable":"Unlimited","memorylimit":"Unlimited","memorytotal":0,"memoryavailable":"Unlimited","primarystoragelimit":"Unlimited","primarystoragetotal":0,"primarystorageavailable":"Unlimited","secondarystoragelimit":"Unlimited","secondarystoragetotal":0,"secondarystorageavailable":"Unlimited","state":"enabled","user":[{"id":"b32e02b0-b904-11e3-b3f0-080027079e3d","username":"admin","firstname":"Admin","lastname":"User","email":"admin@mailprovider.com","created":"2014-03-31T18:45:58+0000","state":"enabled","account":"admin","accounttype":1,"domainid":"b32db4c2-b904-11e3-b3f0-080027079e3d","domain":"ROOT","apikey":"<CLOUD_STACK_API_KEY>","secretkey":"<CLOUD_STACK_SECRET_KEY>","accountid":"b32dc958-b904-11e3-b3f0-080027079e3d","iscallerchilddomain":false,"isdefault":true}],"isdefault":true}
string: '{ "listaccountsresponse" : { "count":1 ,"account" : [ {"id":"b32dc958-b904-11e3-b3f0-080027079e3d","name":"admin","accounttype":1,"domainid":"b32db4c2-b904-11e3-b3f0-080027079e3d","domain":"ROOT","vmlimit":"Unlimited","vmtotal":0,"vmavailable":"Unlimited","iplimit":"Unlimited","iptotal":0,"ipavailable":"Unlimited","volumelimit":"Unlimited","volumetotal":0,"volumeavailable":"Unlimited","snapshotlimit":"Unlimited","snapshottotal":0,"snapshotavailable":"Unlimited","templatelimit":"Unlimited","templatetotal":0,"templateavailable":"Unlimited","projectlimit":"Unlimited","projecttotal":0,"projectavailable":"Unlimited","networklimit":"Unlimited","networktotal":2,"networkavailable":"Unlimited","vpclimit":"Unlimited","vpctotal":0,"vpcavailable":"Unlimited","cpulimit":"Unlimited","cputotal":0,"cpuavailable":"Unlimited","memorylimit":"Unlimited","memorytotal":0,"memoryavailable":"Unlimited","primarystoragelimit":"Unlimited","primarystoragetotal":0,"primarystorageavailable":"Unlimited","secondarystoragelimit":"Unlimited","secondarystoragetotal":0,"secondarystorageavailable":"Unlimited","state":"enabled","user":[{"id":"b32e02b0-b904-11e3-b3f0-080027079e3d","username":"admin","firstname":"Admin","lastname":"User","email":"admin@mailprovider.com","created":"2014-03-31T18:45:58+0000","state":"enabled","account":"admin","accounttype":1,"domainid":"b32db4c2-b904-11e3-b3f0-080027079e3d","domain":"ROOT","apikey":"<CLOUD_STACK_API_KEY>","secretkey":"<CLOUD_STACK_SECRET_KEY>","accountid":"b32dc958-b904-11e3-b3f0-080027079e3d","iscallerchilddomain":false,"isdefault":true}],"isdefault":true}
] } }'
http_version:
recorded_at: Thu, 09 Oct 2014 18:16:02 GMT
recorded_at: Mon, 24 Nov 2014 18:07:24 GMT
recorded_with: VCR 2.9.3

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

0 comments on commit 88948c6

Please sign in to comment.