nucleus 0.1.0 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (39) hide show
  1. checksums.yaml +4 -4
  2. data/.rubocop.yml +3 -0
  3. data/CHANGELOG.md +18 -4
  4. data/README.md +28 -40
  5. data/Rakefile +137 -137
  6. data/config/nucleus_config.rb +0 -4
  7. data/lib/nucleus/adapter_resolver.rb +115 -115
  8. data/lib/nucleus/adapters/buildpack_translator.rb +79 -79
  9. data/lib/nucleus/adapters/v1/cloud_control/application.rb +108 -108
  10. data/lib/nucleus/adapters/v1/cloud_control/authentication.rb +27 -27
  11. data/lib/nucleus/adapters/v1/cloud_control/cloud_control.rb +153 -153
  12. data/lib/nucleus/adapters/v1/cloud_control/domains.rb +68 -68
  13. data/lib/nucleus/adapters/v1/cloud_control/logs.rb +103 -103
  14. data/lib/nucleus/adapters/v1/cloud_control/vars.rb +88 -88
  15. data/lib/nucleus/adapters/v1/cloud_foundry_v2/domains.rb +149 -149
  16. data/lib/nucleus/adapters/v1/cloud_foundry_v2/logs.rb +303 -303
  17. data/lib/nucleus/adapters/v1/cloud_foundry_v2/services.rb +286 -286
  18. data/lib/nucleus/adapters/v1/heroku/heroku.rb +2 -2
  19. data/lib/nucleus/adapters/v1/heroku/logs.rb +108 -108
  20. data/lib/nucleus/core/adapter_authentication_inductor.rb +0 -2
  21. data/lib/nucleus/core/adapter_extensions/auth/http_basic_auth_client.rb +37 -37
  22. data/lib/nucleus/core/adapter_extensions/http_client.rb +177 -177
  23. data/lib/nucleus/core/common/files/archive_extractor.rb +112 -112
  24. data/lib/nucleus/core/common/files/archiver.rb +91 -91
  25. data/lib/nucleus/core/common/logging/request_log_formatter.rb +48 -48
  26. data/lib/nucleus/core/error_messages.rb +127 -127
  27. data/lib/nucleus/core/models/abstract_model.rb +29 -29
  28. data/lib/nucleus/scripts/load_dependencies.rb +0 -1
  29. data/lib/nucleus/scripts/setup_config.rb +28 -28
  30. data/lib/nucleus/version.rb +3 -3
  31. data/nucleus.gemspec +10 -12
  32. data/spec/factories/models.rb +63 -61
  33. data/spec/integration/api/auth_spec.rb +58 -58
  34. data/spec/test_suites.rake +31 -31
  35. data/spec/unit/common/helpers/auth_helper_spec.rb +73 -73
  36. data/spec/unit/common/oauth2_auth_client_spec.rb +1 -1
  37. data/tasks/compatibility.rake +113 -113
  38. data/tasks/evaluation.rake +162 -162
  39. 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*').gsub(/\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
+ 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].downcase == '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].downcase == '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
+ 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