nucleus 0.2.0 → 0.3.1
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 +9 -0
- data/README.md +43 -72
- data/lib/nucleus/adapter_resolver.rb +3 -3
- data/lib/nucleus/adapters/base_adapter.rb +109 -109
- data/lib/nucleus/adapters/v1/cloud_foundry_v2/application.rb +111 -111
- data/lib/nucleus/adapters/v1/cloud_foundry_v2/cloud_foundry_v2.rb +141 -141
- data/lib/nucleus/adapters/v1/cloud_foundry_v2/data.rb +97 -97
- data/lib/nucleus/adapters/v1/cloud_foundry_v2/domains.rb +5 -5
- data/lib/nucleus/adapters/v1/cloud_foundry_v2/lifecycle.rb +41 -41
- data/lib/nucleus/adapters/v1/cloud_foundry_v2/logs.rb +6 -6
- data/lib/nucleus/adapters/v1/cloud_foundry_v2/regions.rb +33 -33
- data/lib/nucleus/adapters/v1/cloud_foundry_v2/services.rb +6 -6
- data/lib/nucleus/adapters/v1/cloud_foundry_v2/vars.rb +80 -80
- data/lib/nucleus/adapters/v1/heroku/app_states.rb +57 -57
- data/lib/nucleus/adapters/v1/heroku/data.rb +78 -78
- data/lib/nucleus/adapters/v1/heroku/heroku.rb +146 -146
- data/lib/nucleus/adapters/v1/heroku/lifecycle.rb +51 -51
- data/lib/nucleus/adapters/v1/heroku/logs.rb +2 -2
- data/lib/nucleus/adapters/v1/heroku/regions.rb +42 -42
- data/lib/nucleus/adapters/v1/heroku/services.rb +168 -168
- data/lib/nucleus/adapters/v1/heroku/vars.rb +65 -65
- data/lib/nucleus/adapters/v1/openshift_v2/app_states.rb +68 -68
- data/lib/nucleus/adapters/v1/openshift_v2/application.rb +1 -1
- data/lib/nucleus/adapters/v1/openshift_v2/data.rb +96 -96
- data/lib/nucleus/adapters/v1/openshift_v2/lifecycle.rb +60 -60
- data/lib/nucleus/adapters/v1/openshift_v2/logs.rb +106 -106
- data/lib/nucleus/adapters/v1/openshift_v2/openshift_v2.rb +125 -125
- data/lib/nucleus/adapters/v1/openshift_v2/regions.rb +58 -58
- data/lib/nucleus/adapters/v1/openshift_v2/services.rb +173 -173
- data/lib/nucleus/adapters/v1/openshift_v2/vars.rb +49 -49
- data/lib/nucleus/adapters/v1/stub_adapter.rb +464 -464
- data/lib/nucleus/core/adapter_extensions/auth/auth_client.rb +44 -44
- data/lib/nucleus/core/adapter_extensions/auth/expiring_token_auth_client.rb +53 -53
- data/lib/nucleus/core/adapter_extensions/auth/http_basic_auth_client.rb +3 -3
- data/lib/nucleus/core/adapter_extensions/auth/o_auth2_auth_client.rb +95 -95
- data/lib/nucleus/core/adapter_extensions/auth/token_auth_client.rb +36 -36
- data/lib/nucleus/core/adapter_extensions/http_client.rb +5 -5
- data/lib/nucleus/core/common/files/archive_extractor.rb +1 -1
- data/lib/nucleus/core/common/files/archiver.rb +2 -2
- data/lib/nucleus/core/file_handling/file_manager.rb +64 -64
- data/lib/nucleus/core/file_handling/git_deployer.rb +133 -133
- data/lib/nucleus/core/import/adapter_configuration.rb +53 -53
- data/lib/nucleus/scripts/initialize_config_defaults.rb +26 -26
- data/lib/nucleus/version.rb +1 -1
- data/nucleus.gemspec +2 -2
- data/spec/integration/api/auth_spec.rb +3 -3
- data/spec/spec_helper.rb +98 -98
- data/spec/test_suites.rake +1 -1
- data/spec/unit/adapters/git_deployer_spec.rb +262 -262
- data/spec/unit/common/helpers/auth_helper_spec.rb +1 -1
- data/tasks/evaluation.rake +1 -1
- data/wiki/adapter_tests.md +0 -7
- data/wiki/implement_new_adapter.md +1 -1
- metadata +4 -20
- data/config/adapters/cloud_control.yml +0 -32
- data/lib/nucleus/adapters/v1/cloud_control/application.rb +0 -108
- data/lib/nucleus/adapters/v1/cloud_control/authentication.rb +0 -27
- data/lib/nucleus/adapters/v1/cloud_control/buildpacks.rb +0 -23
- data/lib/nucleus/adapters/v1/cloud_control/cloud_control.rb +0 -153
- data/lib/nucleus/adapters/v1/cloud_control/data.rb +0 -76
- data/lib/nucleus/adapters/v1/cloud_control/domains.rb +0 -68
- data/lib/nucleus/adapters/v1/cloud_control/lifecycle.rb +0 -27
- data/lib/nucleus/adapters/v1/cloud_control/log_poller.rb +0 -71
- data/lib/nucleus/adapters/v1/cloud_control/logs.rb +0 -103
- data/lib/nucleus/adapters/v1/cloud_control/regions.rb +0 -32
- data/lib/nucleus/adapters/v1/cloud_control/scaling.rb +0 -17
- data/lib/nucleus/adapters/v1/cloud_control/semantic_errors.rb +0 -31
- data/lib/nucleus/adapters/v1/cloud_control/services.rb +0 -162
- data/lib/nucleus/adapters/v1/cloud_control/token.rb +0 -17
- data/lib/nucleus/adapters/v1/cloud_control/vars.rb +0 -88
@@ -25,7 +25,7 @@ describe Nucleus::Adapters::AuthenticationRetryWrapper do
|
|
25
25
|
counted = 0
|
26
26
|
expect = 1
|
27
27
|
allow(calculator).to receive(:calc) do
|
28
|
-
|
28
|
+
raise(Nucleus::Errors::EndpointAuthenticationError.new('error', auth_client)) if (counted += 1) <= expect
|
29
29
|
1
|
30
30
|
end
|
31
31
|
end
|
data/tasks/evaluation.rake
CHANGED
@@ -17,7 +17,7 @@ namespace :evaluation do
|
|
17
17
|
|
18
18
|
adapter_dao.all.each do |adapter_index_entry|
|
19
19
|
vendor_name = vendor_dao.get(provider_dao.get(endpoint_dao.get(adapter_index_entry.id).provider).vendor).name
|
20
|
-
# from camel to
|
20
|
+
# from camel to snake case
|
21
21
|
adapter_file_name = vendor_name.gsub(/\s/, '_').gsub(/([A-Z]+)([A-Z][a-z])/, '\1_\2')
|
22
22
|
.gsub(/([a-z\d])([A-Z])/, '\1_\2').downcase
|
23
23
|
next if @vendor_results.key?(vendor_name)
|
data/wiki/adapter_tests.md
CHANGED
@@ -59,11 +59,6 @@ bluemix-eu-gb:
|
|
59
59
|
password: 'my_bluemix_usernames_password'
|
60
60
|
username: 'my_bluemix_username_with_encoded_umlauts'
|
61
61
|
|
62
|
-
cloudcontrol:
|
63
|
-
user: 'my_cc_email'
|
64
|
-
password: 'my_cc_usernames_password'
|
65
|
-
username: 'my_cc_username'
|
66
|
-
|
67
62
|
openshift-online:
|
68
63
|
user: 'my_os_email'
|
69
64
|
password: 'my_os_usernames_password'
|
@@ -86,8 +81,6 @@ bundle exec rake record:heroku
|
|
86
81
|
* You must be allowed to create at least 3 additional applications with your account, otherwise the quota restrictions will invalidate the test results.
|
87
82
|
* A complete recording of a single vendor usually takes 5 up to 15 minutes. Openshift currently takes more than 30 minutes.
|
88
83
|
If you only require a certain functionality to be tested (during development), make sure to comment out irrelevant sections in the `spec/adapter/support/shared_example_adapters_valid.rb` file.
|
89
|
-
* cloudControl requires you to change the application names if the previous recording was made within the last 2 days, otherwise if fails because the name is still locked.
|
90
|
-
Change the name in the `spec/adapter/v1/cloud_control_spec.rb`.
|
91
84
|
|
92
85
|
### Missing or invalid VCR recording
|
93
86
|
|
@@ -88,7 +88,7 @@ describe Nucleus::Adapters::{API_VERSION}::{VENDOR_CLASS} do
|
|
88
88
|
end
|
89
89
|
before do |example|
|
90
90
|
if skip_example?(described_class, example.metadata[:full_description], @unsupported)
|
91
|
-
skip('This feature is currently not supported by
|
91
|
+
skip('This feature is currently not supported by Heroku - 501')
|
92
92
|
end
|
93
93
|
# reload adapter for each test
|
94
94
|
@adapter = load_adapter(@endpoint, @api_version)
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: nucleus
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.3.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Stefan Kolb
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2016-
|
12
|
+
date: 2016-03-07 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: configatron
|
@@ -483,14 +483,14 @@ dependencies:
|
|
483
483
|
requirements:
|
484
484
|
- - "~>"
|
485
485
|
- !ruby/object:Gem::Version
|
486
|
-
version: 0.
|
486
|
+
version: 0.37.2
|
487
487
|
type: :development
|
488
488
|
prerelease: false
|
489
489
|
version_requirements: !ruby/object:Gem::Requirement
|
490
490
|
requirements:
|
491
491
|
- - "~>"
|
492
492
|
- !ruby/object:Gem::Version
|
493
|
-
version: 0.
|
493
|
+
version: 0.37.2
|
494
494
|
- !ruby/object:Gem::Dependency
|
495
495
|
name: vcr
|
496
496
|
requirement: !ruby/object:Gem::Requirement
|
@@ -557,7 +557,6 @@ files:
|
|
557
557
|
- bin/nucleus
|
558
558
|
- bin/nucleus.bat
|
559
559
|
- config.ru
|
560
|
-
- config/adapters/cloud_control.yml
|
561
560
|
- config/adapters/cloud_foundry_v2.yml
|
562
561
|
- config/adapters/heroku.yml
|
563
562
|
- config/adapters/openshift_v2.yml
|
@@ -566,21 +565,6 @@ files:
|
|
566
565
|
- lib/nucleus/adapter_resolver.rb
|
567
566
|
- lib/nucleus/adapters/base_adapter.rb
|
568
567
|
- lib/nucleus/adapters/buildpack_translator.rb
|
569
|
-
- lib/nucleus/adapters/v1/cloud_control/application.rb
|
570
|
-
- lib/nucleus/adapters/v1/cloud_control/authentication.rb
|
571
|
-
- lib/nucleus/adapters/v1/cloud_control/buildpacks.rb
|
572
|
-
- lib/nucleus/adapters/v1/cloud_control/cloud_control.rb
|
573
|
-
- lib/nucleus/adapters/v1/cloud_control/data.rb
|
574
|
-
- lib/nucleus/adapters/v1/cloud_control/domains.rb
|
575
|
-
- lib/nucleus/adapters/v1/cloud_control/lifecycle.rb
|
576
|
-
- lib/nucleus/adapters/v1/cloud_control/log_poller.rb
|
577
|
-
- lib/nucleus/adapters/v1/cloud_control/logs.rb
|
578
|
-
- lib/nucleus/adapters/v1/cloud_control/regions.rb
|
579
|
-
- lib/nucleus/adapters/v1/cloud_control/scaling.rb
|
580
|
-
- lib/nucleus/adapters/v1/cloud_control/semantic_errors.rb
|
581
|
-
- lib/nucleus/adapters/v1/cloud_control/services.rb
|
582
|
-
- lib/nucleus/adapters/v1/cloud_control/token.rb
|
583
|
-
- lib/nucleus/adapters/v1/cloud_control/vars.rb
|
584
568
|
- lib/nucleus/adapters/v1/cloud_foundry_v2/app_states.rb
|
585
569
|
- lib/nucleus/adapters/v1/cloud_foundry_v2/application.rb
|
586
570
|
- lib/nucleus/adapters/v1/cloud_foundry_v2/authentication.rb
|
@@ -1,32 +0,0 @@
|
|
1
|
-
---
|
2
|
-
name: "cloudControl"
|
3
|
-
id: "cloudcontrol"
|
4
|
-
providers:
|
5
|
-
-
|
6
|
-
name: "cloudControl"
|
7
|
-
id: "cloudcontrol"
|
8
|
-
endpoints:
|
9
|
-
-
|
10
|
-
name: "cloudControl"
|
11
|
-
id: "cloudcontrol"
|
12
|
-
url: "api.cloudcontrol.com"
|
13
|
-
-
|
14
|
-
name: "dotCloud"
|
15
|
-
id: "dotcloud"
|
16
|
-
url: "api.dotcloudapp.com"
|
17
|
-
-
|
18
|
-
name: "exoscale Apps"
|
19
|
-
id: "exoscale"
|
20
|
-
endpoints:
|
21
|
-
-
|
22
|
-
name: "exoscale Apps"
|
23
|
-
id: "exoscale"
|
24
|
-
url: "api.app.exo.io"
|
25
|
-
-
|
26
|
-
name: "Cloud&Heat App Elevator"
|
27
|
-
id: "cloudandheat"
|
28
|
-
endpoints:
|
29
|
-
-
|
30
|
-
name: "Cloud&Heat App Elevator"
|
31
|
-
id: "cloudandheat"
|
32
|
-
url: "api.cnh-apps.com"
|
@@ -1,108 +0,0 @@
|
|
1
|
-
module Nucleus
|
2
|
-
module Adapters
|
3
|
-
module V1
|
4
|
-
class CloudControl < Stub
|
5
|
-
# cloud control, CRUD operations for the application object
|
6
|
-
module Application
|
7
|
-
# @see Stub#applications
|
8
|
-
def applications
|
9
|
-
response = get('/app')
|
10
|
-
apps = []
|
11
|
-
response.body.each do |application|
|
12
|
-
apps << to_nucleus_app(application, default_deployment(application[:name]))
|
13
|
-
end
|
14
|
-
apps
|
15
|
-
end
|
16
|
-
|
17
|
-
# @see Stub#application
|
18
|
-
def application(application_id)
|
19
|
-
response = get("/app/#{application_id}").body
|
20
|
-
to_nucleus_app(response, default_deployment(response[:name]))
|
21
|
-
end
|
22
|
-
|
23
|
-
# @see Stub#create_application
|
24
|
-
def create_application(application)
|
25
|
-
if application.key? :region
|
26
|
-
unless application[:region].casecmp('default') == 0
|
27
|
-
fail Errors::SemanticAdapterRequestError,
|
28
|
-
"Region '#{application[:region]}' does not exist at the endpoint. "\
|
29
|
-
'Please check which regions are actually available on this endpoint.'
|
30
|
-
end
|
31
|
-
# there is no region in cloudControl --> remove from request
|
32
|
-
application.delete :region
|
33
|
-
end
|
34
|
-
|
35
|
-
apply_buildpack(application)
|
36
|
-
|
37
|
-
# force the use of repository type 'git', unless overridden by the params
|
38
|
-
default_params = { repository_type: 'git' }
|
39
|
-
cc_application = default_params.merge(application)
|
40
|
-
|
41
|
-
create_app_response = post('/app', body: cc_application).body
|
42
|
-
|
43
|
-
# create the default deployment, name will automatically become 'default'
|
44
|
-
created_deployment = post("/app/#{create_app_response[:name]}/deployment", body: { name: 'nucleus' }).body
|
45
|
-
|
46
|
-
# activate the variables addon. However, the activation explicitly requires an initial key value pair...
|
47
|
-
post("/app/#{create_app_response[:name]}/deployment/#{NUCLEUS_DEPLOYMENT}/addon",
|
48
|
-
body: { addon: 'config.free', options: '{"nucleus-initialized": "true"}' }).body
|
49
|
-
# ...now delete the initial key value pair to have the desired clean setup
|
50
|
-
delete_env_var(create_app_response[:name], 'nucleus-initialized')
|
51
|
-
|
52
|
-
to_nucleus_app(create_app_response, created_deployment)
|
53
|
-
end
|
54
|
-
|
55
|
-
# @see Stub#delete_application
|
56
|
-
def delete_application(application_id)
|
57
|
-
# delete all deployments first
|
58
|
-
deployments = get("/app/#{application_id}/deployment").body
|
59
|
-
deployments.each do |deployment|
|
60
|
-
deployment_name = %r{(\w+)\/(\w+)}.match(deployment[:name])[2]
|
61
|
-
delete("/app/#{application_id}/deployment/#{deployment_name}")
|
62
|
-
end
|
63
|
-
delete("/app/#{application_id}")
|
64
|
-
end
|
65
|
-
|
66
|
-
private
|
67
|
-
|
68
|
-
def apply_buildpack(application)
|
69
|
-
runtimes = application.delete(:runtimes)
|
70
|
-
return unless runtimes
|
71
|
-
fail_with(:only_one_runtime) if runtimes.length > 1
|
72
|
-
buildpack = find_runtime(runtimes[0])
|
73
|
-
if native_runtime?(buildpack)
|
74
|
-
application[:type] = buildpack
|
75
|
-
elsif buildpack
|
76
|
-
application[:type] = 'custom'
|
77
|
-
application[:buildpack_url] = buildpack
|
78
|
-
else
|
79
|
-
# 3rd party buildpack must be a valid URL
|
80
|
-
unless Regexp::PERFECT_URL_PATTERN =~ runtimes[0]
|
81
|
-
fail Errors::SemanticAdapterRequestError,
|
82
|
-
"Invalid buildpack: '#{runtimes[0]}'. Please provide a valid buildpack URL for all "\
|
83
|
-
'custom buildpacks that are not provided by cloud control.'
|
84
|
-
end
|
85
|
-
application[:type] = 'custom'
|
86
|
-
application[:buildpack_url] = runtimes[0]
|
87
|
-
end
|
88
|
-
end
|
89
|
-
|
90
|
-
def to_nucleus_app(app, deployment)
|
91
|
-
app[:id] = app[:name]
|
92
|
-
app[:created_at] = app.delete :date_created
|
93
|
-
app[:updated_at] = app.delete :date_modified
|
94
|
-
app[:state] = application_state(deployment)
|
95
|
-
app[:web_url] = "http://#{deployment[:default_subdomain]}"
|
96
|
-
app[:autoscaled] = false
|
97
|
-
app[:region] = 'default'
|
98
|
-
app[:instances] = deployment[:min_boxes]
|
99
|
-
app[:active_runtime] = app[:type][:name] == 'custom' ? app[:buildpack_url] : app[:type][:name]
|
100
|
-
app[:runtimes] = [app[:active_runtime]]
|
101
|
-
app[:release_version] = deployment[:version] != '-1' ? deployment[:version] : nil
|
102
|
-
app
|
103
|
-
end
|
104
|
-
end
|
105
|
-
end
|
106
|
-
end
|
107
|
-
end
|
108
|
-
end
|
@@ -1,27 +0,0 @@
|
|
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,23 +0,0 @@
|
|
1
|
-
module Nucleus
|
2
|
-
module Adapters
|
3
|
-
module V1
|
4
|
-
class CloudControl < Stub
|
5
|
-
# cloud control specific buildpacks
|
6
|
-
module Buildpacks
|
7
|
-
include Nucleus::Adapters::BuildpackTranslator
|
8
|
-
|
9
|
-
# @see BuildpackTranslator#vendor_specific_runtimes
|
10
|
-
def vendor_specific_runtimes
|
11
|
-
{
|
12
|
-
'java' => 'java',
|
13
|
-
'nodejs' => 'nodejs',
|
14
|
-
'ruby' => 'ruby',
|
15
|
-
'php' => 'php',
|
16
|
-
'python' => 'python'
|
17
|
-
}
|
18
|
-
end
|
19
|
-
end
|
20
|
-
end
|
21
|
-
end
|
22
|
-
end
|
23
|
-
end
|
@@ -1,153 +0,0 @@
|
|
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
|