nucleus 0.1.0 → 0.2.0
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.
- checksums.yaml +4 -4
- data/.rubocop.yml +3 -0
- data/CHANGELOG.md +18 -4
- data/README.md +28 -40
- data/Rakefile +137 -137
- data/config/nucleus_config.rb +0 -4
- data/lib/nucleus/adapter_resolver.rb +115 -115
- data/lib/nucleus/adapters/buildpack_translator.rb +79 -79
- data/lib/nucleus/adapters/v1/cloud_control/application.rb +108 -108
- data/lib/nucleus/adapters/v1/cloud_control/authentication.rb +27 -27
- data/lib/nucleus/adapters/v1/cloud_control/cloud_control.rb +153 -153
- data/lib/nucleus/adapters/v1/cloud_control/domains.rb +68 -68
- data/lib/nucleus/adapters/v1/cloud_control/logs.rb +103 -103
- data/lib/nucleus/adapters/v1/cloud_control/vars.rb +88 -88
- data/lib/nucleus/adapters/v1/cloud_foundry_v2/domains.rb +149 -149
- data/lib/nucleus/adapters/v1/cloud_foundry_v2/logs.rb +303 -303
- data/lib/nucleus/adapters/v1/cloud_foundry_v2/services.rb +286 -286
- data/lib/nucleus/adapters/v1/heroku/heroku.rb +2 -2
- data/lib/nucleus/adapters/v1/heroku/logs.rb +108 -108
- data/lib/nucleus/core/adapter_authentication_inductor.rb +0 -2
- data/lib/nucleus/core/adapter_extensions/auth/http_basic_auth_client.rb +37 -37
- data/lib/nucleus/core/adapter_extensions/http_client.rb +177 -177
- data/lib/nucleus/core/common/files/archive_extractor.rb +112 -112
- data/lib/nucleus/core/common/files/archiver.rb +91 -91
- data/lib/nucleus/core/common/logging/request_log_formatter.rb +48 -48
- data/lib/nucleus/core/error_messages.rb +127 -127
- data/lib/nucleus/core/models/abstract_model.rb +29 -29
- data/lib/nucleus/scripts/load_dependencies.rb +0 -1
- data/lib/nucleus/scripts/setup_config.rb +28 -28
- data/lib/nucleus/version.rb +3 -3
- data/nucleus.gemspec +10 -12
- data/spec/factories/models.rb +63 -61
- data/spec/integration/api/auth_spec.rb +58 -58
- data/spec/test_suites.rake +31 -31
- data/spec/unit/common/helpers/auth_helper_spec.rb +73 -73
- data/spec/unit/common/oauth2_auth_client_spec.rb +1 -1
- data/tasks/compatibility.rake +113 -113
- data/tasks/evaluation.rake +162 -162
- metadata +16 -30
@@ -1,27 +1,27 @@
|
|
1
|
-
module Nucleus
|
2
|
-
module Adapters
|
3
|
-
module V1
|
4
|
-
class CloudControl < Stub
|
5
|
-
# Authentication functionality to support the cloudControl API
|
6
|
-
module Authentication
|
7
|
-
# @see Stub#auth_client
|
8
|
-
def auth_client
|
9
|
-
Token.new @check_certificates do |_verify_ssl, username, password|
|
10
|
-
auth_headers = { 'Authorization' => 'Basic ' + ["#{username}:#{password}"].pack('m*').
|
11
|
-
begin
|
12
|
-
# ssl verification is implemented by the HttpClient itself
|
13
|
-
response = post('/token', headers: auth_headers)
|
14
|
-
# parse to retrieve the token and expiration date
|
15
|
-
expires = Time.parse(response.body[:expires])
|
16
|
-
[response.body[:token], expires]
|
17
|
-
rescue Errors::AdapterError
|
18
|
-
# ignore the error, return nil for failed authentication
|
19
|
-
nil
|
20
|
-
end
|
21
|
-
end
|
22
|
-
end
|
23
|
-
end
|
24
|
-
end
|
25
|
-
end
|
26
|
-
end
|
27
|
-
end
|
1
|
+
module Nucleus
|
2
|
+
module Adapters
|
3
|
+
module V1
|
4
|
+
class CloudControl < Stub
|
5
|
+
# Authentication functionality to support the cloudControl API
|
6
|
+
module Authentication
|
7
|
+
# @see Stub#auth_client
|
8
|
+
def auth_client
|
9
|
+
Token.new @check_certificates do |_verify_ssl, username, password|
|
10
|
+
auth_headers = { 'Authorization' => 'Basic ' + ["#{username}:#{password}"].pack('m*').delete("\n") }
|
11
|
+
begin
|
12
|
+
# ssl verification is implemented by the HttpClient itself
|
13
|
+
response = post('/token', headers: auth_headers)
|
14
|
+
# parse to retrieve the token and expiration date
|
15
|
+
expires = Time.parse(response.body[:expires])
|
16
|
+
[response.body[:token], expires]
|
17
|
+
rescue Errors::AdapterError
|
18
|
+
# ignore the error, return nil for failed authentication
|
19
|
+
nil
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
@@ -1,153 +1,153 @@
|
|
1
|
-
require 'net/ssh'
|
2
|
-
|
3
|
-
module Nucleus
|
4
|
-
module Adapters
|
5
|
-
module V1
|
6
|
-
class CloudControl < Stub
|
7
|
-
include Nucleus::Logging
|
8
|
-
include Nucleus::Adapters::V1::CloudControl::Authentication
|
9
|
-
include Nucleus::Adapters::V1::CloudControl::Application
|
10
|
-
include Nucleus::Adapters::V1::CloudControl::Buildpacks
|
11
|
-
include Nucleus::Adapters::V1::CloudControl::Domains
|
12
|
-
include Nucleus::Adapters::V1::CloudControl::Data
|
13
|
-
include Nucleus::Adapters::V1::CloudControl::Lifecycle
|
14
|
-
include Nucleus::Adapters::V1::CloudControl::Logs
|
15
|
-
include Nucleus::Adapters::V1::CloudControl::Regions
|
16
|
-
include Nucleus::Adapters::V1::CloudControl::Scaling
|
17
|
-
include Nucleus::Adapters::V1::CloudControl::SemanticErrors
|
18
|
-
include Nucleus::Adapters::V1::CloudControl::Services
|
19
|
-
include Nucleus::Adapters::V1::CloudControl::Vars
|
20
|
-
|
21
|
-
# The default deployment name of cloud control applications that is used by Nucleus
|
22
|
-
NUCLEUS_DEPLOYMENT = 'nucleus'
|
23
|
-
# Error messages of semantic errors that are platform specific
|
24
|
-
CC_EXCLUSIVE_SEMANTIC_ERROR_MSGS = ['cannot use this name', 'may only contain', 'this field has no more than']
|
25
|
-
# Error messages of common semantic errors
|
26
|
-
CC_SEMANTIC_ERROR_MSGS = ['must be unique', 'already exists',
|
27
|
-
'not a valid addon name', 'not a valid addon option']
|
28
|
-
CC_CONFLICT_ERROR_MSGS = ['Addon already exists']
|
29
|
-
|
30
|
-
def initialize(endpoint_url, endpoint_app_domain = nil, check_certificates = true)
|
31
|
-
super(endpoint_url, endpoint_app_domain, check_certificates)
|
32
|
-
end
|
33
|
-
|
34
|
-
def handle_error(error_response)
|
35
|
-
message = error_response.body.match(/{(.*?)}/)
|
36
|
-
message = message[1] if message
|
37
|
-
|
38
|
-
# cloud control responds almost every time with 400...
|
39
|
-
if error_response.status == 400
|
40
|
-
handle_400(message)
|
41
|
-
elsif error_response.status == 409 && CC_CONFLICT_ERROR_MSGS.any? { |msg| message.include? msg }
|
42
|
-
fail Errors::SemanticAdapterRequestError, message
|
43
|
-
elsif error_response.status == 410
|
44
|
-
fail Errors::AdapterResourceNotFoundError, 'Resource not found'
|
45
|
-
elsif error_response.status == 503
|
46
|
-
fail Errors::PlatformUnavailableError, 'The cloudControl API is currently not available'
|
47
|
-
end
|
48
|
-
# error still unhandled, will result in a 500, server error
|
49
|
-
log.warn "cloudControl error still unhandled: #{error_response}"
|
50
|
-
end
|
51
|
-
|
52
|
-
private
|
53
|
-
|
54
|
-
def handle_400(message)
|
55
|
-
fail Errors::AdapterResourceNotFoundError, 'Resource not found' if message.nil?
|
56
|
-
|
57
|
-
if message.include?('Billing account required')
|
58
|
-
fail_with(:billing_required, [message])
|
59
|
-
elsif CC_EXCLUSIVE_SEMANTIC_ERROR_MSGS.any? { |msg| message.include? msg }
|
60
|
-
# all these errors are limited to cloud control, e.g. the allowed name characters and max name length
|
61
|
-
fail_with(:bad_name, [message])
|
62
|
-
elsif CC_SEMANTIC_ERROR_MSGS.any? { |msg| message.include? msg }
|
63
|
-
fail Errors::SemanticAdapterRequestError, message
|
64
|
-
end
|
65
|
-
fail Errors::AdapterRequestError, message
|
66
|
-
end
|
67
|
-
|
68
|
-
def username
|
69
|
-
get('/user').body.first[:username]
|
70
|
-
end
|
71
|
-
|
72
|
-
def data_uploaded?(deployment)
|
73
|
-
application_id = deployment[:name].split(%r{/})[0]
|
74
|
-
repo_host = URI.parse(deployment[:branch]).host
|
75
|
-
repo_path = URI.parse(deployment[:branch]).path.gsub(%r{^/}, '').chomp('.git')
|
76
|
-
attempts = 0
|
77
|
-
with_ssh_key do
|
78
|
-
loop do
|
79
|
-
begin
|
80
|
-
return GitRepoAnalyzer.any_branch?(repo_host, repo_path, application_id)
|
81
|
-
rescue Net::SSH::AuthenticationFailed => e
|
82
|
-
attempts += 1
|
83
|
-
# wait up to 30 seconds
|
84
|
-
raise e if attempts >= 15
|
85
|
-
log.debug('SSH authentication failed, sleep and repeat')
|
86
|
-
# authentication is not yet ready, wait a short time
|
87
|
-
sleep(2.0)
|
88
|
-
end
|
89
|
-
end
|
90
|
-
end
|
91
|
-
end
|
92
|
-
|
93
|
-
def application_state(deployment)
|
94
|
-
# With cloud control not supporting the Nucleus application lifecycle, only 3 actual states remain:<br>
|
95
|
-
# * created, when no data deployment (not to confuse with cloud control deployment object) has been made yet
|
96
|
-
# * deployed, when only the data has been pushed into the repository (no build)
|
97
|
-
# * running, if a data deployment was pushed
|
98
|
-
if deployment[:version] == '-1'
|
99
|
-
return Enums::ApplicationStates::DEPLOYED if data_uploaded?(deployment)
|
100
|
-
return Enums::ApplicationStates::CREATED
|
101
|
-
end
|
102
|
-
return Enums::ApplicationStates::IDLE if deployment[:state] == 'idle'
|
103
|
-
Enums::ApplicationStates::RUNNING
|
104
|
-
# return Enums::ApplicationStates::STOPPED
|
105
|
-
|
106
|
-
# arriving here the above states do not catch all states of the cloudControl app, which should not happen ;-)
|
107
|
-
# fail Errors::UnknownAdapterCallError, 'Could not determine application state. '\
|
108
|
-
# 'Please verify the cloudControl adapter'
|
109
|
-
end
|
110
|
-
|
111
|
-
def default_deployment(application_id)
|
112
|
-
# get and return nucleus deployment, but catch arising 404 errors
|
113
|
-
return get("/app/#{application_id}/deployment/#{NUCLEUS_DEPLOYMENT}").body
|
114
|
-
rescue Errors::AdapterResourceNotFoundError
|
115
|
-
# if 404, list all deployments
|
116
|
-
all_deployments = get("/app/#{application_id}/deployment").body
|
117
|
-
|
118
|
-
# fail 422 (platform specific) if no deployment is available at all
|
119
|
-
fail_with(:no_deployment) if all_deployments.length == 0
|
120
|
-
|
121
|
-
# return deployment[0] if collection size is 1
|
122
|
-
return all_deployments[0] if all_deployments.length == 1
|
123
|
-
|
124
|
-
# return 'default' if more than 1 deployment and 'default' is included
|
125
|
-
def_deployment = all_deployments.find { |d| d[:name].split(%r{/})[1].
|
126
|
-
return def_deployment if def_deployment
|
127
|
-
|
128
|
-
# return 'nucleus' if more than 1 deployment, but no 'default' is included
|
129
|
-
nucleus_deployment = all_deployments.find { |d| d[:name].split(%r{/})[1].
|
130
|
-
return nucleus_deployment if nucleus_deployment
|
131
|
-
|
132
|
-
# fail 422 if no 'default', no 'nucleus', and more than 1 deployment is available (could not identify default)
|
133
|
-
fail_with(:ambiguous_deployments)
|
134
|
-
end
|
135
|
-
|
136
|
-
def headers
|
137
|
-
super.merge('Content-Type' => 'application/json')
|
138
|
-
end
|
139
|
-
|
140
|
-
def with_ssh_key
|
141
|
-
user = username
|
142
|
-
# load ssh key into cloud control
|
143
|
-
matches = nucleus_config.ssh.handler.public_key.match(/(.*)\s{1}(.*)\s{1}(.*)/)
|
144
|
-
key_id = register_key(user, matches[1], matches[2])
|
145
|
-
return yield
|
146
|
-
ensure
|
147
|
-
# unload ssh key, allow 404 if the key couldn't be registered at first
|
148
|
-
delete("/user/#{user}/key/#{key_id}") if key_id
|
149
|
-
end
|
150
|
-
end
|
151
|
-
end
|
152
|
-
end
|
153
|
-
end
|
1
|
+
require 'net/ssh'
|
2
|
+
|
3
|
+
module Nucleus
|
4
|
+
module Adapters
|
5
|
+
module V1
|
6
|
+
class CloudControl < Stub
|
7
|
+
include Nucleus::Logging
|
8
|
+
include Nucleus::Adapters::V1::CloudControl::Authentication
|
9
|
+
include Nucleus::Adapters::V1::CloudControl::Application
|
10
|
+
include Nucleus::Adapters::V1::CloudControl::Buildpacks
|
11
|
+
include Nucleus::Adapters::V1::CloudControl::Domains
|
12
|
+
include Nucleus::Adapters::V1::CloudControl::Data
|
13
|
+
include Nucleus::Adapters::V1::CloudControl::Lifecycle
|
14
|
+
include Nucleus::Adapters::V1::CloudControl::Logs
|
15
|
+
include Nucleus::Adapters::V1::CloudControl::Regions
|
16
|
+
include Nucleus::Adapters::V1::CloudControl::Scaling
|
17
|
+
include Nucleus::Adapters::V1::CloudControl::SemanticErrors
|
18
|
+
include Nucleus::Adapters::V1::CloudControl::Services
|
19
|
+
include Nucleus::Adapters::V1::CloudControl::Vars
|
20
|
+
|
21
|
+
# The default deployment name of cloud control applications that is used by Nucleus
|
22
|
+
NUCLEUS_DEPLOYMENT = 'nucleus'.freeze
|
23
|
+
# Error messages of semantic errors that are platform specific
|
24
|
+
CC_EXCLUSIVE_SEMANTIC_ERROR_MSGS = ['cannot use this name', 'may only contain', 'this field has no more than'].freeze
|
25
|
+
# Error messages of common semantic errors
|
26
|
+
CC_SEMANTIC_ERROR_MSGS = ['must be unique', 'already exists',
|
27
|
+
'not a valid addon name', 'not a valid addon option'].freeze
|
28
|
+
CC_CONFLICT_ERROR_MSGS = ['Addon already exists'].freeze
|
29
|
+
|
30
|
+
def initialize(endpoint_url, endpoint_app_domain = nil, check_certificates = true)
|
31
|
+
super(endpoint_url, endpoint_app_domain, check_certificates)
|
32
|
+
end
|
33
|
+
|
34
|
+
def handle_error(error_response)
|
35
|
+
message = error_response.body.match(/{(.*?)}/)
|
36
|
+
message = message[1] if message
|
37
|
+
|
38
|
+
# cloud control responds almost every time with 400...
|
39
|
+
if error_response.status == 400
|
40
|
+
handle_400(message)
|
41
|
+
elsif error_response.status == 409 && CC_CONFLICT_ERROR_MSGS.any? { |msg| message.include? msg }
|
42
|
+
fail Errors::SemanticAdapterRequestError, message
|
43
|
+
elsif error_response.status == 410
|
44
|
+
fail Errors::AdapterResourceNotFoundError, 'Resource not found'
|
45
|
+
elsif error_response.status == 503
|
46
|
+
fail Errors::PlatformUnavailableError, 'The cloudControl API is currently not available'
|
47
|
+
end
|
48
|
+
# error still unhandled, will result in a 500, server error
|
49
|
+
log.warn "cloudControl error still unhandled: #{error_response}"
|
50
|
+
end
|
51
|
+
|
52
|
+
private
|
53
|
+
|
54
|
+
def handle_400(message)
|
55
|
+
fail Errors::AdapterResourceNotFoundError, 'Resource not found' if message.nil?
|
56
|
+
|
57
|
+
if message.include?('Billing account required')
|
58
|
+
fail_with(:billing_required, [message])
|
59
|
+
elsif CC_EXCLUSIVE_SEMANTIC_ERROR_MSGS.any? { |msg| message.include? msg }
|
60
|
+
# all these errors are limited to cloud control, e.g. the allowed name characters and max name length
|
61
|
+
fail_with(:bad_name, [message])
|
62
|
+
elsif CC_SEMANTIC_ERROR_MSGS.any? { |msg| message.include? msg }
|
63
|
+
fail Errors::SemanticAdapterRequestError, message
|
64
|
+
end
|
65
|
+
fail Errors::AdapterRequestError, message
|
66
|
+
end
|
67
|
+
|
68
|
+
def username
|
69
|
+
get('/user').body.first[:username]
|
70
|
+
end
|
71
|
+
|
72
|
+
def data_uploaded?(deployment)
|
73
|
+
application_id = deployment[:name].split(%r{/})[0]
|
74
|
+
repo_host = URI.parse(deployment[:branch]).host
|
75
|
+
repo_path = URI.parse(deployment[:branch]).path.gsub(%r{^/}, '').chomp('.git')
|
76
|
+
attempts = 0
|
77
|
+
with_ssh_key do
|
78
|
+
loop do
|
79
|
+
begin
|
80
|
+
return GitRepoAnalyzer.any_branch?(repo_host, repo_path, application_id)
|
81
|
+
rescue Net::SSH::AuthenticationFailed => e
|
82
|
+
attempts += 1
|
83
|
+
# wait up to 30 seconds
|
84
|
+
raise e if attempts >= 15
|
85
|
+
log.debug('SSH authentication failed, sleep and repeat')
|
86
|
+
# authentication is not yet ready, wait a short time
|
87
|
+
sleep(2.0)
|
88
|
+
end
|
89
|
+
end
|
90
|
+
end
|
91
|
+
end
|
92
|
+
|
93
|
+
def application_state(deployment)
|
94
|
+
# With cloud control not supporting the Nucleus application lifecycle, only 3 actual states remain:<br>
|
95
|
+
# * created, when no data deployment (not to confuse with cloud control deployment object) has been made yet
|
96
|
+
# * deployed, when only the data has been pushed into the repository (no build)
|
97
|
+
# * running, if a data deployment was pushed
|
98
|
+
if deployment[:version] == '-1'
|
99
|
+
return Enums::ApplicationStates::DEPLOYED if data_uploaded?(deployment)
|
100
|
+
return Enums::ApplicationStates::CREATED
|
101
|
+
end
|
102
|
+
return Enums::ApplicationStates::IDLE if deployment[:state] == 'idle'
|
103
|
+
Enums::ApplicationStates::RUNNING
|
104
|
+
# return Enums::ApplicationStates::STOPPED
|
105
|
+
|
106
|
+
# arriving here the above states do not catch all states of the cloudControl app, which should not happen ;-)
|
107
|
+
# fail Errors::UnknownAdapterCallError, 'Could not determine application state. '\
|
108
|
+
# 'Please verify the cloudControl adapter'
|
109
|
+
end
|
110
|
+
|
111
|
+
def default_deployment(application_id)
|
112
|
+
# get and return nucleus deployment, but catch arising 404 errors
|
113
|
+
return get("/app/#{application_id}/deployment/#{NUCLEUS_DEPLOYMENT}").body
|
114
|
+
rescue Errors::AdapterResourceNotFoundError
|
115
|
+
# if 404, list all deployments
|
116
|
+
all_deployments = get("/app/#{application_id}/deployment").body
|
117
|
+
|
118
|
+
# fail 422 (platform specific) if no deployment is available at all
|
119
|
+
fail_with(:no_deployment) if all_deployments.length == 0
|
120
|
+
|
121
|
+
# return deployment[0] if collection size is 1
|
122
|
+
return all_deployments[0] if all_deployments.length == 1
|
123
|
+
|
124
|
+
# return 'default' if more than 1 deployment and 'default' is included
|
125
|
+
def_deployment = all_deployments.find { |d| d[:name].split(%r{/})[1].casecmp('default') }
|
126
|
+
return def_deployment if def_deployment
|
127
|
+
|
128
|
+
# return 'nucleus' if more than 1 deployment, but no 'default' is included
|
129
|
+
nucleus_deployment = all_deployments.find { |d| d[:name].split(%r{/})[1].casecmp('nucleus') }
|
130
|
+
return nucleus_deployment if nucleus_deployment
|
131
|
+
|
132
|
+
# fail 422 if no 'default', no 'nucleus', and more than 1 deployment is available (could not identify default)
|
133
|
+
fail_with(:ambiguous_deployments)
|
134
|
+
end
|
135
|
+
|
136
|
+
def headers
|
137
|
+
super.merge('Content-Type' => 'application/json')
|
138
|
+
end
|
139
|
+
|
140
|
+
def with_ssh_key
|
141
|
+
user = username
|
142
|
+
# load ssh key into cloud control
|
143
|
+
matches = nucleus_config.ssh.handler.public_key.match(/(.*)\s{1}(.*)\s{1}(.*)/)
|
144
|
+
key_id = register_key(user, matches[1], matches[2])
|
145
|
+
return yield
|
146
|
+
ensure
|
147
|
+
# unload ssh key, allow 404 if the key couldn't be registered at first
|
148
|
+
delete("/user/#{user}/key/#{key_id}") if key_id
|
149
|
+
end
|
150
|
+
end
|
151
|
+
end
|
152
|
+
end
|
153
|
+
end
|
@@ -1,68 +1,68 @@
|
|
1
|
-
module Nucleus
|
2
|
-
module Adapters
|
3
|
-
module V1
|
4
|
-
class CloudControl < Stub
|
5
|
-
# cloud control, CRUD operations for the application's domain object
|
6
|
-
module Domains
|
7
|
-
# cloud control URLs that are automatically assigned to applications as domain but can't be managed
|
8
|
-
CC_URLS = %w(cloudcontrolapp.com cloudcontrolled.com)
|
9
|
-
|
10
|
-
# @see Stub#domains
|
11
|
-
def domains(application_id)
|
12
|
-
# no conversion needed, cc domains already have :name value
|
13
|
-
cc_domains = get("/app/#{application_id}/deployment/#{NUCLEUS_DEPLOYMENT}/alias").body
|
14
|
-
# the domain shall NOT be a CC system domain
|
15
|
-
cc_domains = cc_domains.find_all do |domain|
|
16
|
-
!CC_URLS.any? { |cc_domain| domain[:name].include? cc_domain }
|
17
|
-
end
|
18
|
-
# the list does not include the timestamps, fetch all
|
19
|
-
cc_domains.compact.collect { |domain| domain(application_id, domain[:name]) }
|
20
|
-
end
|
21
|
-
|
22
|
-
# @see Stub#domain
|
23
|
-
def domain(application_id, alias_name)
|
24
|
-
# no conversion needed, cc domains already have :name value
|
25
|
-
cc_domain = get("/app/#{application_id}/deployment/#{NUCLEUS_DEPLOYMENT}/alias/#{alias_name}").body
|
26
|
-
to_nucleus_domain(cc_domain)
|
27
|
-
end
|
28
|
-
|
29
|
-
# @see Stub#create_domain
|
30
|
-
def create_domain(application_id, domain)
|
31
|
-
# check if name is available
|
32
|
-
if domain?(application_id, domain[:name])
|
33
|
-
fail Errors::SemanticAdapterRequestError,
|
34
|
-
"Domain '#{domain[:name]}' is already assigned to the application"
|
35
|
-
end
|
36
|
-
|
37
|
-
# no conversion needed, cc domains already have :name value
|
38
|
-
cc_domain = post("/app/#{application_id}/deployment/#{NUCLEUS_DEPLOYMENT}/alias",
|
39
|
-
body: { name: domain[:name] }).body
|
40
|
-
log.info("Please use this code to verify your custom application domain: #{cc_domain[:verification_code]}")
|
41
|
-
log.info('More information about the domain verification can be found at: '\
|
42
|
-
'https://www.cloudcontrol.com/dev-center/add-on-documentation/alias')
|
43
|
-
to_nucleus_domain(cc_domain)
|
44
|
-
end
|
45
|
-
|
46
|
-
# @see Stub#delete_domain
|
47
|
-
def delete_domain(application_id, alias_name)
|
48
|
-
delete("/app/#{application_id}/deployment/#{NUCLEUS_DEPLOYMENT}/alias/#{alias_name}")
|
49
|
-
end
|
50
|
-
|
51
|
-
private
|
52
|
-
|
53
|
-
def domain?(application_id, alias_name)
|
54
|
-
cc_domains = get("/app/#{application_id}/deployment/#{NUCLEUS_DEPLOYMENT}/alias").body
|
55
|
-
cc_domains.any? { |domain| domain[:name] == alias_name }
|
56
|
-
end
|
57
|
-
|
58
|
-
def to_nucleus_domain(domain)
|
59
|
-
domain[:id] = domain[:name]
|
60
|
-
domain[:created_at] = domain.delete(:date_created)
|
61
|
-
domain[:updated_at] = domain.delete(:date_modified)
|
62
|
-
domain
|
63
|
-
end
|
64
|
-
end
|
65
|
-
end
|
66
|
-
end
|
67
|
-
end
|
68
|
-
end
|
1
|
+
module Nucleus
|
2
|
+
module Adapters
|
3
|
+
module V1
|
4
|
+
class CloudControl < Stub
|
5
|
+
# cloud control, CRUD operations for the application's domain object
|
6
|
+
module Domains
|
7
|
+
# cloud control URLs that are automatically assigned to applications as domain but can't be managed
|
8
|
+
CC_URLS = %w(cloudcontrolapp.com cloudcontrolled.com).freeze
|
9
|
+
|
10
|
+
# @see Stub#domains
|
11
|
+
def domains(application_id)
|
12
|
+
# no conversion needed, cc domains already have :name value
|
13
|
+
cc_domains = get("/app/#{application_id}/deployment/#{NUCLEUS_DEPLOYMENT}/alias").body
|
14
|
+
# the domain shall NOT be a CC system domain
|
15
|
+
cc_domains = cc_domains.find_all do |domain|
|
16
|
+
!CC_URLS.any? { |cc_domain| domain[:name].include? cc_domain }
|
17
|
+
end
|
18
|
+
# the list does not include the timestamps, fetch all
|
19
|
+
cc_domains.compact.collect { |domain| domain(application_id, domain[:name]) }
|
20
|
+
end
|
21
|
+
|
22
|
+
# @see Stub#domain
|
23
|
+
def domain(application_id, alias_name)
|
24
|
+
# no conversion needed, cc domains already have :name value
|
25
|
+
cc_domain = get("/app/#{application_id}/deployment/#{NUCLEUS_DEPLOYMENT}/alias/#{alias_name}").body
|
26
|
+
to_nucleus_domain(cc_domain)
|
27
|
+
end
|
28
|
+
|
29
|
+
# @see Stub#create_domain
|
30
|
+
def create_domain(application_id, domain)
|
31
|
+
# check if name is available
|
32
|
+
if domain?(application_id, domain[:name])
|
33
|
+
fail Errors::SemanticAdapterRequestError,
|
34
|
+
"Domain '#{domain[:name]}' is already assigned to the application"
|
35
|
+
end
|
36
|
+
|
37
|
+
# no conversion needed, cc domains already have :name value
|
38
|
+
cc_domain = post("/app/#{application_id}/deployment/#{NUCLEUS_DEPLOYMENT}/alias",
|
39
|
+
body: { name: domain[:name] }).body
|
40
|
+
log.info("Please use this code to verify your custom application domain: #{cc_domain[:verification_code]}")
|
41
|
+
log.info('More information about the domain verification can be found at: '\
|
42
|
+
'https://www.cloudcontrol.com/dev-center/add-on-documentation/alias')
|
43
|
+
to_nucleus_domain(cc_domain)
|
44
|
+
end
|
45
|
+
|
46
|
+
# @see Stub#delete_domain
|
47
|
+
def delete_domain(application_id, alias_name)
|
48
|
+
delete("/app/#{application_id}/deployment/#{NUCLEUS_DEPLOYMENT}/alias/#{alias_name}")
|
49
|
+
end
|
50
|
+
|
51
|
+
private
|
52
|
+
|
53
|
+
def domain?(application_id, alias_name)
|
54
|
+
cc_domains = get("/app/#{application_id}/deployment/#{NUCLEUS_DEPLOYMENT}/alias").body
|
55
|
+
cc_domains.any? { |domain| domain[:name] == alias_name }
|
56
|
+
end
|
57
|
+
|
58
|
+
def to_nucleus_domain(domain)
|
59
|
+
domain[:id] = domain[:name]
|
60
|
+
domain[:created_at] = domain.delete(:date_created)
|
61
|
+
domain[:updated_at] = domain.delete(:date_modified)
|
62
|
+
domain
|
63
|
+
end
|
64
|
+
end
|
65
|
+
end
|
66
|
+
end
|
67
|
+
end
|
68
|
+
end
|