engineyard-cloud-client 0.1.2
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.
- data/LICENSE +19 -0
- data/README.rdoc +7 -0
- data/lib/engineyard-cloud-client.rb +149 -0
- data/lib/engineyard-cloud-client/errors.rb +38 -0
- data/lib/engineyard-cloud-client/model_registry.rb +21 -0
- data/lib/engineyard-cloud-client/models.rb +14 -0
- data/lib/engineyard-cloud-client/models/account.rb +38 -0
- data/lib/engineyard-cloud-client/models/api_struct.rb +50 -0
- data/lib/engineyard-cloud-client/models/app.rb +77 -0
- data/lib/engineyard-cloud-client/models/app_environment.rb +85 -0
- data/lib/engineyard-cloud-client/models/deployment.rb +105 -0
- data/lib/engineyard-cloud-client/models/environment.rb +240 -0
- data/lib/engineyard-cloud-client/models/instance.rb +15 -0
- data/lib/engineyard-cloud-client/models/keypair.rb +32 -0
- data/lib/engineyard-cloud-client/models/log.rb +11 -0
- data/lib/engineyard-cloud-client/models/user.rb +11 -0
- data/lib/engineyard-cloud-client/resolver_result.rb +19 -0
- data/lib/engineyard-cloud-client/rest_client_ext.rb +11 -0
- data/lib/engineyard-cloud-client/ruby_ext.rb +9 -0
- data/lib/engineyard-cloud-client/test.rb +31 -0
- data/lib/engineyard-cloud-client/test/fake_awsm.rb +22 -0
- data/lib/engineyard-cloud-client/test/fake_awsm/config.ru +207 -0
- data/lib/engineyard-cloud-client/test/fake_awsm/models.rb +9 -0
- data/lib/engineyard-cloud-client/test/fake_awsm/models/account.rb +13 -0
- data/lib/engineyard-cloud-client/test/fake_awsm/models/app.rb +24 -0
- data/lib/engineyard-cloud-client/test/fake_awsm/models/app_environment.rb +19 -0
- data/lib/engineyard-cloud-client/test/fake_awsm/models/deployments.rb +15 -0
- data/lib/engineyard-cloud-client/test/fake_awsm/models/environment.rb +25 -0
- data/lib/engineyard-cloud-client/test/fake_awsm/models/instance.rb +23 -0
- data/lib/engineyard-cloud-client/test/fake_awsm/models/user.rb +15 -0
- data/lib/engineyard-cloud-client/test/fake_awsm/scenarios.rb +325 -0
- data/lib/engineyard-cloud-client/test/fake_awsm/views/accounts.rabl +2 -0
- data/lib/engineyard-cloud-client/test/fake_awsm/views/apps.rabl +10 -0
- data/lib/engineyard-cloud-client/test/fake_awsm/views/base_app_environment.rabl +13 -0
- data/lib/engineyard-cloud-client/test/fake_awsm/views/base_environment.rabl +4 -0
- data/lib/engineyard-cloud-client/test/fake_awsm/views/environments.rabl +11 -0
- data/lib/engineyard-cloud-client/test/fake_awsm/views/instances.rabl +2 -0
- data/lib/engineyard-cloud-client/test/fake_awsm/views/resolve_app_environments.rabl +7 -0
- data/lib/engineyard-cloud-client/test/fake_awsm/views/resolve_environments.rabl +7 -0
- data/lib/engineyard-cloud-client/test/fake_awsm/views/user.rabl +2 -0
- data/lib/engineyard-cloud-client/test/scenario.rb +43 -0
- data/lib/engineyard-cloud-client/test/ui.rb +33 -0
- data/lib/engineyard-cloud-client/version.rb +7 -0
- data/spec/engineyard-cloud-client/api_spec.rb +59 -0
- data/spec/engineyard-cloud-client/integration/account_spec.rb +18 -0
- data/spec/engineyard-cloud-client/integration/app_environment_spec.rb +38 -0
- data/spec/engineyard-cloud-client/integration/app_spec.rb +20 -0
- data/spec/engineyard-cloud-client/integration/environment_spec.rb +57 -0
- data/spec/engineyard-cloud-client/integration/user_spec.rb +18 -0
- data/spec/engineyard-cloud-client/models/api_struct_spec.rb +41 -0
- data/spec/engineyard-cloud-client/models/app_spec.rb +64 -0
- data/spec/engineyard-cloud-client/models/environment_spec.rb +300 -0
- data/spec/engineyard-cloud-client/models/instance_spec.rb +44 -0
- data/spec/engineyard-cloud-client/models/keypair_spec.rb +58 -0
- data/spec/spec_helper.rb +50 -0
- data/spec/support/helpers.rb +16 -0
- data/spec/support/matchers.rb +2 -0
- metadata +377 -0
data/LICENSE
ADDED
@@ -0,0 +1,19 @@
|
|
1
|
+
Copyright (c) 2010 Engine Yard, Inc
|
2
|
+
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
4
|
+
of this software and associated documentation files (the "Software"), to deal
|
5
|
+
in the Software without restriction, including without limitation the rights
|
6
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
7
|
+
copies of the Software, and to permit persons to whom the Software is
|
8
|
+
furnished to do so, subject to the following conditions:
|
9
|
+
|
10
|
+
The above copyright notice and this permission notice shall be included in
|
11
|
+
all copies or substantial portions of the Software.
|
12
|
+
|
13
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
14
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
15
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
16
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
17
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
18
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
19
|
+
THE SOFTWARE.
|
data/README.rdoc
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
= engineyard-cloud-client
|
2
|
+
|
3
|
+
The API client for awsm. Extracted from the engineyard gem because this piece is often all a project needs for EY Cloud API usage.
|
4
|
+
|
5
|
+
See engineyard gem for a usage example. Bother someone if this is released and the documentation is still not updated.
|
6
|
+
|
7
|
+
This is currently unreleased.
|
@@ -0,0 +1,149 @@
|
|
1
|
+
module EY
|
2
|
+
class CloudClient
|
3
|
+
end
|
4
|
+
end
|
5
|
+
|
6
|
+
require 'engineyard-cloud-client/ruby_ext'
|
7
|
+
require 'engineyard-cloud-client/model_registry'
|
8
|
+
require 'engineyard-cloud-client/models'
|
9
|
+
require 'engineyard-cloud-client/rest_client_ext'
|
10
|
+
require 'engineyard-cloud-client/resolver_result'
|
11
|
+
require 'engineyard-cloud-client/version'
|
12
|
+
require 'engineyard-cloud-client/errors'
|
13
|
+
require 'multi_json'
|
14
|
+
require 'pp'
|
15
|
+
|
16
|
+
module EY
|
17
|
+
class CloudClient
|
18
|
+
attr_reader :token, :registry
|
19
|
+
attr_accessor :ui
|
20
|
+
|
21
|
+
USER_AGENT_STRING = "EngineYardCloudClient/#{EY::CloudClient::VERSION}"
|
22
|
+
|
23
|
+
def self.endpoint
|
24
|
+
@endpoint
|
25
|
+
end
|
26
|
+
|
27
|
+
def self.endpoint=(endpoint)
|
28
|
+
@endpoint = URI.parse(endpoint)
|
29
|
+
unless @endpoint.absolute?
|
30
|
+
raise BadEndpointError.new(endpoint)
|
31
|
+
end
|
32
|
+
@endpoint
|
33
|
+
end
|
34
|
+
|
35
|
+
def self.default_endpoint!
|
36
|
+
self.endpoint = "https://cloud.engineyard.com/"
|
37
|
+
end
|
38
|
+
default_endpoint!
|
39
|
+
|
40
|
+
def initialize(token, ui)
|
41
|
+
self.token = token
|
42
|
+
self.ui = ui
|
43
|
+
end
|
44
|
+
|
45
|
+
def ==(other)
|
46
|
+
other.is_a?(self.class) && other.token == token
|
47
|
+
end
|
48
|
+
|
49
|
+
def registry
|
50
|
+
@registry ||= ModelRegistry.new
|
51
|
+
end
|
52
|
+
|
53
|
+
def token=(new_token)
|
54
|
+
unless new_token
|
55
|
+
raise ArgumentError, "EY Cloud API token required"
|
56
|
+
end
|
57
|
+
@token = new_token
|
58
|
+
end
|
59
|
+
|
60
|
+
def request(url, opts={})
|
61
|
+
opts[:headers] ||= {}
|
62
|
+
opts[:headers]["X-EY-Cloud-Token"] = token
|
63
|
+
ui.debug("Token", token)
|
64
|
+
self.class.request(url, ui, opts)
|
65
|
+
end
|
66
|
+
|
67
|
+
def resolve_environments(constraints)
|
68
|
+
EY::CloudClient::Environment.resolve(self, constraints)
|
69
|
+
end
|
70
|
+
|
71
|
+
def resolve_app_environments(constraints)
|
72
|
+
EY::CloudClient::AppEnvironment.resolve(self, constraints)
|
73
|
+
end
|
74
|
+
|
75
|
+
def environments
|
76
|
+
@environments ||= EY::CloudClient::Environment.all(self)
|
77
|
+
end
|
78
|
+
|
79
|
+
def apps
|
80
|
+
@apps ||= EY::CloudClient::App.all(self)
|
81
|
+
end
|
82
|
+
|
83
|
+
# TODO: unhaxor
|
84
|
+
# This should load an api endpoint that deals directly in app_deployments
|
85
|
+
def app_environments
|
86
|
+
@app_environments ||= apps.map { |app| app.app_environments }.flatten
|
87
|
+
end
|
88
|
+
|
89
|
+
def current_user
|
90
|
+
EY::CloudClient::User.from_hash(self, request('/current_user')['user'])
|
91
|
+
end
|
92
|
+
|
93
|
+
def self.request(path, ui, opts={})
|
94
|
+
url = self.endpoint + "api/v2#{path}"
|
95
|
+
method = (opts.delete(:method) || 'get').to_s.downcase.to_sym
|
96
|
+
params = opts.delete(:params) || {}
|
97
|
+
headers = opts.delete(:headers) || {}
|
98
|
+
headers["Accept"] ||= "application/json"
|
99
|
+
headers["User-Agent"] = USER_AGENT_STRING
|
100
|
+
|
101
|
+
begin
|
102
|
+
ui.debug("Request", "#{method.to_s.upcase} #{url}")
|
103
|
+
ui.debug("Params", params.inspect)
|
104
|
+
case method
|
105
|
+
when :get, :delete, :head
|
106
|
+
unless params.empty?
|
107
|
+
url.query = RestClient::Payload::UrlEncoded.new(params).to_s
|
108
|
+
end
|
109
|
+
resp = RestClient.send(method, url.to_s, headers)
|
110
|
+
else
|
111
|
+
resp = RestClient.send(method, url.to_s, params, headers)
|
112
|
+
end
|
113
|
+
rescue RestClient::Unauthorized
|
114
|
+
raise InvalidCredentials
|
115
|
+
rescue Errno::ECONNREFUSED
|
116
|
+
raise RequestFailed, "Could not reach the cloud API"
|
117
|
+
rescue RestClient::ResourceNotFound
|
118
|
+
raise ResourceNotFound, "The requested resource could not be found"
|
119
|
+
rescue RestClient::BadGateway
|
120
|
+
raise RequestFailed, "EY Cloud API is temporarily unavailable. Please try again soon."
|
121
|
+
rescue RestClient::RequestFailed => e
|
122
|
+
raise RequestFailed, "#{e.message} #{e.response}"
|
123
|
+
rescue OpenSSL::SSL::SSLError
|
124
|
+
raise RequestFailed, "SSL is misconfigured on your cloud"
|
125
|
+
end
|
126
|
+
|
127
|
+
if resp.body.empty?
|
128
|
+
data = ''
|
129
|
+
elsif resp.headers[:content_type] =~ /application\/json/
|
130
|
+
begin
|
131
|
+
data = MultiJson.decode(resp.body)
|
132
|
+
ui.debug("Response", "\n" + data.pretty_inspect)
|
133
|
+
rescue MultiJson::DecodeError
|
134
|
+
ui.debug("Raw response", resp.body)
|
135
|
+
raise RequestFailed, "Response was not valid JSON."
|
136
|
+
end
|
137
|
+
else
|
138
|
+
data = resp.body
|
139
|
+
end
|
140
|
+
|
141
|
+
data
|
142
|
+
end
|
143
|
+
|
144
|
+
def self.authenticate(email, password, ui)
|
145
|
+
request("/authenticate", ui, { :method => "post", :params => { :email => email, :password => password }})["api_token"]
|
146
|
+
end
|
147
|
+
|
148
|
+
end # API
|
149
|
+
end # EY
|
@@ -0,0 +1,38 @@
|
|
1
|
+
module EY
|
2
|
+
class CloudClient
|
3
|
+
class Error < RuntimeError
|
4
|
+
end
|
5
|
+
|
6
|
+
class RequestFailed < Error; end
|
7
|
+
class InvalidCredentials < RequestFailed; end
|
8
|
+
class ResourceNotFound < RequestFailed; end
|
9
|
+
|
10
|
+
class BadEndpointError < Error
|
11
|
+
def initialize(endpoint)
|
12
|
+
super "#{endpoint.inspect} is not a valid endpoint URI. Endpoint must be an absolute URI."
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
class AttributeRequiredError < Error
|
17
|
+
def initialize(attribute_name, klass = nil)
|
18
|
+
if klass
|
19
|
+
super "Attribute '#{attribute_name}' of class #{klass} is required for this action."
|
20
|
+
else
|
21
|
+
super "Attribute '#{attribute_name}' is required for this action."
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
class NoBridgeError < Error
|
27
|
+
def initialize(env_name)
|
28
|
+
super "The environment '#{env_name}' does not have a master instance."
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
class BadBridgeStatusError < Error
|
33
|
+
def initialize(bridge_status, endpoint)
|
34
|
+
super %|Application master's status is not "running" (green); it is "#{bridge_status}". Go to #{endpoint} to address this problem.|
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
module EY
|
2
|
+
class CloudClient
|
3
|
+
class ModelRegistry
|
4
|
+
def initialize
|
5
|
+
@registry = Hash.new { |h,k| h[k] = {} }
|
6
|
+
end
|
7
|
+
|
8
|
+
def find(klass, id)
|
9
|
+
if id
|
10
|
+
@registry[klass][id]
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
def set(klass, obj)
|
15
|
+
if obj.respond_to?(:id) && id = obj.id
|
16
|
+
@registry[klass][id] = obj
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,14 @@
|
|
1
|
+
module EY
|
2
|
+
class CloudClient
|
3
|
+
require 'engineyard-cloud-client/models/api_struct'
|
4
|
+
require 'engineyard-cloud-client/models/account'
|
5
|
+
require 'engineyard-cloud-client/models/app'
|
6
|
+
require 'engineyard-cloud-client/models/app_environment'
|
7
|
+
require 'engineyard-cloud-client/models/deployment'
|
8
|
+
require 'engineyard-cloud-client/models/environment'
|
9
|
+
require 'engineyard-cloud-client/models/log'
|
10
|
+
require 'engineyard-cloud-client/models/instance'
|
11
|
+
require 'engineyard-cloud-client/models/keypair'
|
12
|
+
require 'engineyard-cloud-client/models/user'
|
13
|
+
end
|
14
|
+
end
|
@@ -0,0 +1,38 @@
|
|
1
|
+
require 'engineyard-cloud-client/models/api_struct'
|
2
|
+
|
3
|
+
module EY
|
4
|
+
class CloudClient
|
5
|
+
class Account < ApiStruct.new(:id, :name)
|
6
|
+
|
7
|
+
def self.all(api)
|
8
|
+
self.from_array(api, api.request('/accounts')["accounts"])
|
9
|
+
end
|
10
|
+
|
11
|
+
def add_app(app)
|
12
|
+
@apps ||= []
|
13
|
+
existing_app = @apps.detect { |a| app.id == a.id }
|
14
|
+
unless existing_app
|
15
|
+
@apps << app
|
16
|
+
end
|
17
|
+
existing_app || app
|
18
|
+
end
|
19
|
+
|
20
|
+
def apps
|
21
|
+
@apps ||= []
|
22
|
+
end
|
23
|
+
|
24
|
+
def add_environment(environment)
|
25
|
+
@environments ||= []
|
26
|
+
existing_environment = @environments.detect { |env| environment.id == env.id }
|
27
|
+
unless existing_environment
|
28
|
+
@environments << environment
|
29
|
+
end
|
30
|
+
existing_environment || environment
|
31
|
+
end
|
32
|
+
|
33
|
+
def environments
|
34
|
+
@environments ||= []
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
@@ -0,0 +1,50 @@
|
|
1
|
+
module EY
|
2
|
+
class CloudClient
|
3
|
+
class ApiStruct < Struct
|
4
|
+
def self.new(*args, &block)
|
5
|
+
args = [:api] | args
|
6
|
+
super(*args) do |*block_args|
|
7
|
+
block.call(*block_args) if block
|
8
|
+
|
9
|
+
def self.from_array(api, array, common_values = {})
|
10
|
+
if array
|
11
|
+
array.map do |values|
|
12
|
+
from_hash(api, values.merge(common_values))
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
def self.from_hash(api, attrs_or_struct)
|
18
|
+
return nil unless attrs_or_struct
|
19
|
+
|
20
|
+
if attrs_or_struct.respond_to?(:attributes=)
|
21
|
+
# already a model
|
22
|
+
obj = attrs_or_struct
|
23
|
+
elsif obj = api.registry.find(self, attrs_or_struct['id'])
|
24
|
+
obj.attributes = attrs_or_struct
|
25
|
+
else
|
26
|
+
obj = new(api, attrs_or_struct)
|
27
|
+
api.registry.set(self, obj)
|
28
|
+
end
|
29
|
+
obj
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
def initialize(api, attrs)
|
35
|
+
self.api = api
|
36
|
+
self.attributes = attrs
|
37
|
+
end
|
38
|
+
|
39
|
+
def attributes=(attrs)
|
40
|
+
attrs.each do |key, val|
|
41
|
+
setter = :"#{key}="
|
42
|
+
if respond_to?(setter)
|
43
|
+
send(setter, val)
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
@@ -0,0 +1,77 @@
|
|
1
|
+
require 'engineyard-cloud-client/errors'
|
2
|
+
require 'engineyard-cloud-client/models'
|
3
|
+
|
4
|
+
module EY
|
5
|
+
class CloudClient
|
6
|
+
class App < ApiStruct.new(:id, :name, :repository_uri, :app_type_id)
|
7
|
+
|
8
|
+
attr_reader :app_environments, :account
|
9
|
+
|
10
|
+
# Return list of all Apps linked to all current user's accounts
|
11
|
+
def self.all(api)
|
12
|
+
self.from_array(api, api.request('/apps')["apps"])
|
13
|
+
end
|
14
|
+
|
15
|
+
# An everything-you-need helper to create an App
|
16
|
+
# If successful, returns new App
|
17
|
+
# If unsuccessful, raises +EY::CloudClient::RequestFailed+
|
18
|
+
#
|
19
|
+
# Usage
|
20
|
+
# App.create(api,
|
21
|
+
# account: account # requires: account.id
|
22
|
+
# name: "myapp",
|
23
|
+
# repository_uri: "git@github.com:mycompany/myapp.git",
|
24
|
+
# app_type_id: "rails3",
|
25
|
+
# )
|
26
|
+
#
|
27
|
+
# NOTE: Syntax above is for Ruby 1.9. In Ruby 1.8, keys must all be strings.
|
28
|
+
def self.create(api, attrs = {})
|
29
|
+
account = attrs.delete("account")
|
30
|
+
params = attrs.dup # no default fields
|
31
|
+
raise EY::CloudClient::AttributeRequiredError.new("account", EY::CloudClient::Account) unless account
|
32
|
+
raise EY::CloudClient::AttributeRequiredError.new("name") unless params["name"]
|
33
|
+
raise EY::CloudClient::AttributeRequiredError.new("repository_uri") unless params["repository_uri"]
|
34
|
+
raise EY::CloudClient::AttributeRequiredError.new("app_type_id") unless params["app_type_id"]
|
35
|
+
response = api.request("/accounts/#{account.id}/apps", :method => :post, :params => {"app" => params})
|
36
|
+
from_hash(api, response['app'])
|
37
|
+
end
|
38
|
+
|
39
|
+
def account_name
|
40
|
+
account && account.name
|
41
|
+
end
|
42
|
+
|
43
|
+
def environments
|
44
|
+
(app_environments || []).map { |app_env| app_env.environment }
|
45
|
+
end
|
46
|
+
|
47
|
+
def add_app_environment(app_env)
|
48
|
+
@app_environments ||= []
|
49
|
+
existing_app_env = @app_environments.detect { |ae| app_env.environment == ae.environment }
|
50
|
+
unless existing_app_env
|
51
|
+
@app_environments << app_env
|
52
|
+
end
|
53
|
+
existing_app_env || app_env
|
54
|
+
end
|
55
|
+
|
56
|
+
def set_account(account_attrs)
|
57
|
+
@account = Account.from_hash(api, account_attrs)
|
58
|
+
@account.add_app(self)
|
59
|
+
@account
|
60
|
+
end
|
61
|
+
|
62
|
+
def set_environments(environments_attrs)
|
63
|
+
(environments_attrs || []).each do |env|
|
64
|
+
AppEnvironment.from_hash(api, {'app' => self, 'environment' => env})
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
def attributes=(attrs)
|
69
|
+
account_attrs = attrs.delete('account')
|
70
|
+
environments_attrs = attrs.delete('environments')
|
71
|
+
super
|
72
|
+
set_account account_attrs if account_attrs
|
73
|
+
set_environments environments_attrs if environments_attrs
|
74
|
+
end
|
75
|
+
end
|
76
|
+
end
|
77
|
+
end
|
@@ -0,0 +1,85 @@
|
|
1
|
+
require 'launchy'
|
2
|
+
require 'engineyard-cloud-client/models'
|
3
|
+
require 'engineyard-cloud-client/errors'
|
4
|
+
|
5
|
+
module EY
|
6
|
+
class CloudClient
|
7
|
+
class AppEnvironment < ApiStruct.new(:id, :app, :environment, :uri, :domain_name, :migrate_command, :migrate)
|
8
|
+
|
9
|
+
# Return a constrained list of app_environments given a set of constraints like:
|
10
|
+
#
|
11
|
+
# * app_name
|
12
|
+
# * account_name
|
13
|
+
# * environment_name
|
14
|
+
# * remotes: An array of git remote URIs
|
15
|
+
#
|
16
|
+
def self.resolve(api, constraints)
|
17
|
+
clean_constraints = constraints.reject { |k,v| v.nil? }
|
18
|
+
params = {'constraints' => clean_constraints}
|
19
|
+
response = api.request("/app_environments/resolve", :method => :get, :params => params)['resolver']
|
20
|
+
matches = from_array(api, response['matches'])
|
21
|
+
ResolverResult.new(api, matches, response['errors'], response['suggestions'])
|
22
|
+
end
|
23
|
+
|
24
|
+
def initialize(api, attrs)
|
25
|
+
super
|
26
|
+
|
27
|
+
raise ArgumentError, 'AppEnvironment created without app!' unless app
|
28
|
+
raise ArgumentError, 'AppEnvironment created without environment!' unless environment
|
29
|
+
end
|
30
|
+
|
31
|
+
def set_app(app_or_hash)
|
32
|
+
self.app = App.from_hash(api, app_or_hash)
|
33
|
+
app.add_app_environment(self)
|
34
|
+
app
|
35
|
+
end
|
36
|
+
|
37
|
+
def set_environment(env_or_hash)
|
38
|
+
self.environment = Environment.from_hash(api, env_or_hash)
|
39
|
+
environment.add_app_environment(self)
|
40
|
+
environment
|
41
|
+
end
|
42
|
+
|
43
|
+
def attributes=(attrs)
|
44
|
+
app_attrs = attrs.delete('app')
|
45
|
+
environment_attrs = attrs.delete('environment')
|
46
|
+
super
|
47
|
+
set_app app_attrs if app_attrs
|
48
|
+
set_environment environment_attrs if environment_attrs
|
49
|
+
end
|
50
|
+
|
51
|
+
def account_name
|
52
|
+
app.account_name
|
53
|
+
end
|
54
|
+
|
55
|
+
def app_name
|
56
|
+
app.name
|
57
|
+
end
|
58
|
+
|
59
|
+
def environment_name
|
60
|
+
environment.name
|
61
|
+
end
|
62
|
+
|
63
|
+
def repository_uri
|
64
|
+
app.repository_uri
|
65
|
+
end
|
66
|
+
|
67
|
+
def to_hierarchy_str
|
68
|
+
[account_name, app_name, environment_name].join('/')
|
69
|
+
end
|
70
|
+
|
71
|
+
def last_deployment
|
72
|
+
Deployment.last(api, self)
|
73
|
+
end
|
74
|
+
|
75
|
+
def new_deployment(attrs)
|
76
|
+
Deployment.from_hash(api, attrs.merge(:app_environment => self))
|
77
|
+
end
|
78
|
+
|
79
|
+
def short_environment_name
|
80
|
+
environment.name.gsub(/^#{Regexp.quote(app.name)}_/, '')
|
81
|
+
end
|
82
|
+
|
83
|
+
end
|
84
|
+
end
|
85
|
+
end
|