nucleus 0.2.0 → 0.3.1
Sign up to get free protection for your applications and to get access to all the features.
- 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
|