nucleus 0.1.0 → 0.2.0
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 +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
data/config/nucleus_config.rb
CHANGED
@@ -6,10 +6,6 @@
|
|
6
6
|
# Defaults to: File.expand_path(File.join(File.dirname(__FILE__), '..', 'log'))
|
7
7
|
# nucleus_config.logging.path = File.expand_path(File.join(File.dirname(__FILE__), '..', 'log'))
|
8
8
|
|
9
|
-
# [optional] Database backend to use. Choose one of: [:Daybreak, :LMDB]
|
10
|
-
# Defaults to: :Daybreak on Unix, :LMDB on windows systems.
|
11
|
-
# nucleus_config.db.backend = :Daybreak
|
12
|
-
|
13
9
|
# [optional] Options to start the backend.
|
14
10
|
# See http://www.rubydoc.info/gems/moneta/Moneta/Adapters for valid options on the chosen adapter.
|
15
11
|
# Defaults to: {}
|
@@ -1,115 +1,115 @@
|
|
1
|
-
module Nucleus
|
2
|
-
# The {AdapterResolver} can be used within Ruby applications to retrieve a Nucleus adapter.
|
3
|
-
# Returned adapters are patched so that each call enforces authentication and retries a call when a token was expired.
|
4
|
-
class AdapterResolver
|
5
|
-
include Nucleus::UrlConverter
|
6
|
-
|
7
|
-
def initialize(requested_version)
|
8
|
-
fail 'No such version supported' unless Nucleus::VersionDetector.api_versions.include?(requested_version)
|
9
|
-
@api_version = requested_version
|
10
|
-
end
|
11
|
-
|
12
|
-
# Get a list of all adapters that are currently supported.
|
13
|
-
# @return [Hash<String, Hash<String, Nucleus::Adapters::BaseAdapter>>] currently supported adapters
|
14
|
-
def adapters
|
15
|
-
setup
|
16
|
-
@adapters
|
17
|
-
end
|
18
|
-
|
19
|
-
# Load the adapter to interact with the platform of the vendor that is offered at the endpoint_url.
|
20
|
-
# @param [String] vendor The vendor / adapter name that shall be used to communicate with the endpoint.
|
21
|
-
# Must be
|
22
|
-
# @param [String] username The username that shall be used for authentication
|
23
|
-
# @param [String] password The password that shall be used for authentication
|
24
|
-
# @param [Hash<Symbol,?>] options Further options to apply when creating the adapter instance.
|
25
|
-
# If available, the default configuration of the vendor configuration is applied as default.
|
26
|
-
# @option options [String] :app_domain The domain where applications of the platform will be made available at.
|
27
|
-
# This option must be set for custom deployments of platforms like Cloud Foundry or Openshift.
|
28
|
-
# For IBM Bluemix this value would be: +eu-gb.mybluemix.net+ or +ng.mybluemix.net+, depending on the endpoint.
|
29
|
-
# @option options [String] :check_ssl Set to false if SSL certificates shall not be verified (trust self-signed)
|
30
|
-
# @option options [String] :api_url URL of the endpoint's API that shall be used.
|
31
|
-
# Must be specified if there are multiple endpoints available and will be forced to https://
|
32
|
-
# @raise [StandardError] if the vendor is unknown / not supported or no unique API endpoint could be identified
|
33
|
-
# @return [Nucleus::Adapters::BaseAdapter] loaded adapter implementation
|
34
|
-
def load(vendor, username, password, options = {})
|
35
|
-
setup
|
36
|
-
fail StandardError, "Could not find adapter for vendor '#{vendor}'" unless @adapters.key?(vendor)
|
37
|
-
|
38
|
-
# load the endpoint's HTTPS enabled API URL
|
39
|
-
endpoint_url = load_endpoint(vendor, options)
|
40
|
-
|
41
|
-
# load default configuration if available
|
42
|
-
if @configurations[vendor].key?(endpoint_url)
|
43
|
-
default_configuration = @configurations[vendor][endpoint_url]
|
44
|
-
options = default_configuration.merge(options)
|
45
|
-
end
|
46
|
-
|
47
|
-
check_ssl = options.key?(:check_ssl) ? options[:check_ssl] : true
|
48
|
-
adapter = @adapters[vendor].new(endpoint_url, options[:app_domain], check_ssl)
|
49
|
-
|
50
|
-
fake_env = { 'HTTP_AUTHORIZATION' => 'Basic ' + ["#{username}:#{password}"].pack('m*').
|
51
|
-
# patch the adapter so that calls are wrapped and expect valid authentication
|
52
|
-
AdapterAuthenticationInductor.patch(adapter, fake_env)
|
53
|
-
|
54
|
-
cache_key = adapter.cache_key(username, password)
|
55
|
-
# no auth object available, perform authentication first
|
56
|
-
auth_object = adapter.auth_client
|
57
|
-
# throws an error if the authentication failed
|
58
|
-
auth_object.authenticate(username, password)
|
59
|
-
# cache the auth object so it does not have to be retrieved per request
|
60
|
-
adapter.cache(cache_key, auth_object)
|
61
|
-
|
62
|
-
# return patched and initially authenticated adapter
|
63
|
-
adapter
|
64
|
-
end
|
65
|
-
|
66
|
-
private
|
67
|
-
|
68
|
-
def load_endpoint(vendor, options)
|
69
|
-
if options.key?(:api_url)
|
70
|
-
# use chosen url endpoint
|
71
|
-
endpoint_url = options[:api_url]
|
72
|
-
elsif @configurations[vendor].length == 1
|
73
|
-
# use default endpoint
|
74
|
-
endpoint_url = @configurations[vendor].keys.first
|
75
|
-
else
|
76
|
-
fail StandardError, "Could not identify an API endpoint for the vendor '#{vendor}'. "\
|
77
|
-
"Please specify the API URL to use with the ':api_url' option."
|
78
|
-
end
|
79
|
-
|
80
|
-
# make sure url uses https
|
81
|
-
secure_url(endpoint_url)
|
82
|
-
end
|
83
|
-
|
84
|
-
def setup
|
85
|
-
# perform the setup only once
|
86
|
-
return if @adapters
|
87
|
-
|
88
|
-
# Initialize the application (import adapters, load DAOs, ...)
|
89
|
-
require 'nucleus/scripts/initialize'
|
90
|
-
# load the configuration values
|
91
|
-
require 'nucleus/scripts/initialize_config_defaults'
|
92
|
-
# Once invoked the configuration is locked
|
93
|
-
require 'nucleus/scripts/finalize'
|
94
|
-
|
95
|
-
@adapters = {}
|
96
|
-
@configurations = {}
|
97
|
-
Nucleus::Adapters.configuration_files.each do |adapter_config|
|
98
|
-
vendor = Nucleus::VendorParser.parse(adapter_config)
|
99
|
-
next unless vendor
|
100
|
-
adapter_clazz = Nucleus::Adapters.adapter_clazz(adapter_config, @api_version)
|
101
|
-
next unless adapter_clazz
|
102
|
-
@adapters[vendor.id] = adapter_clazz
|
103
|
-
@configurations[vendor.id] = {}
|
104
|
-
|
105
|
-
# now load the default configurations for this vendor
|
106
|
-
vendor.providers.each do |provider|
|
107
|
-
provider.endpoints.each do |endpoint|
|
108
|
-
@configurations[vendor.id][secure_url(endpoint.url)] = { check_ssl: !endpoint.trust,
|
109
|
-
app_domain: endpoint.app_domain }
|
110
|
-
end
|
111
|
-
end
|
112
|
-
end
|
113
|
-
end
|
114
|
-
end
|
115
|
-
end
|
1
|
+
module Nucleus
|
2
|
+
# The {AdapterResolver} can be used within Ruby applications to retrieve a Nucleus adapter.
|
3
|
+
# Returned adapters are patched so that each call enforces authentication and retries a call when a token was expired.
|
4
|
+
class AdapterResolver
|
5
|
+
include Nucleus::UrlConverter
|
6
|
+
|
7
|
+
def initialize(requested_version)
|
8
|
+
fail 'No such version supported' unless Nucleus::VersionDetector.api_versions.include?(requested_version)
|
9
|
+
@api_version = requested_version
|
10
|
+
end
|
11
|
+
|
12
|
+
# Get a list of all adapters that are currently supported.
|
13
|
+
# @return [Hash<String, Hash<String, Nucleus::Adapters::BaseAdapter>>] currently supported adapters
|
14
|
+
def adapters
|
15
|
+
setup
|
16
|
+
@adapters
|
17
|
+
end
|
18
|
+
|
19
|
+
# Load the adapter to interact with the platform of the vendor that is offered at the endpoint_url.
|
20
|
+
# @param [String] vendor The vendor / adapter name that shall be used to communicate with the endpoint.
|
21
|
+
# Must be provided, otherwise a +StandardError+ will be thrown.
|
22
|
+
# @param [String] username The username that shall be used for authentication
|
23
|
+
# @param [String] password The password that shall be used for authentication
|
24
|
+
# @param [Hash<Symbol,?>] options Further options to apply when creating the adapter instance.
|
25
|
+
# If available, the default configuration of the vendor configuration is applied as default.
|
26
|
+
# @option options [String] :app_domain The domain where applications of the platform will be made available at.
|
27
|
+
# This option must be set for custom deployments of platforms like Cloud Foundry or Openshift.
|
28
|
+
# For IBM Bluemix this value would be: +eu-gb.mybluemix.net+ or +ng.mybluemix.net+, depending on the endpoint.
|
29
|
+
# @option options [String] :check_ssl Set to false if SSL certificates shall not be verified (trust self-signed)
|
30
|
+
# @option options [String] :api_url URL of the endpoint's API that shall be used.
|
31
|
+
# Must be specified if there are multiple endpoints available and will be forced to https://
|
32
|
+
# @raise [StandardError] if the vendor is unknown / not supported or no unique API endpoint could be identified
|
33
|
+
# @return [Nucleus::Adapters::BaseAdapter] loaded adapter implementation
|
34
|
+
def load(vendor, username, password, options = {})
|
35
|
+
setup
|
36
|
+
fail StandardError, "Could not find adapter for vendor '#{vendor}'" unless @adapters.key?(vendor)
|
37
|
+
|
38
|
+
# load the endpoint's HTTPS enabled API URL
|
39
|
+
endpoint_url = load_endpoint(vendor, options)
|
40
|
+
|
41
|
+
# load default configuration if available
|
42
|
+
if @configurations[vendor].key?(endpoint_url)
|
43
|
+
default_configuration = @configurations[vendor][endpoint_url]
|
44
|
+
options = default_configuration.merge(options)
|
45
|
+
end
|
46
|
+
|
47
|
+
check_ssl = options.key?(:check_ssl) ? options[:check_ssl] : true
|
48
|
+
adapter = @adapters[vendor].new(endpoint_url, options[:app_domain], check_ssl)
|
49
|
+
|
50
|
+
fake_env = { 'HTTP_AUTHORIZATION' => 'Basic ' + ["#{username}:#{password}"].pack('m*').delete("\n") }
|
51
|
+
# patch the adapter so that calls are wrapped and expect valid authentication
|
52
|
+
AdapterAuthenticationInductor.patch(adapter, fake_env)
|
53
|
+
|
54
|
+
cache_key = adapter.cache_key(username, password)
|
55
|
+
# no auth object available, perform authentication first
|
56
|
+
auth_object = adapter.auth_client
|
57
|
+
# throws an error if the authentication failed
|
58
|
+
auth_object.authenticate(username, password)
|
59
|
+
# cache the auth object so it does not have to be retrieved per request
|
60
|
+
adapter.cache(cache_key, auth_object)
|
61
|
+
|
62
|
+
# return patched and initially authenticated adapter
|
63
|
+
adapter
|
64
|
+
end
|
65
|
+
|
66
|
+
private
|
67
|
+
|
68
|
+
def load_endpoint(vendor, options)
|
69
|
+
if options.key?(:api_url)
|
70
|
+
# use chosen url endpoint
|
71
|
+
endpoint_url = options[:api_url]
|
72
|
+
elsif @configurations[vendor].length == 1
|
73
|
+
# use default endpoint
|
74
|
+
endpoint_url = @configurations[vendor].keys.first
|
75
|
+
else
|
76
|
+
fail StandardError, "Could not identify an API endpoint for the vendor '#{vendor}'. "\
|
77
|
+
"Please specify the API URL to use with the ':api_url' option."
|
78
|
+
end
|
79
|
+
|
80
|
+
# make sure url uses https
|
81
|
+
secure_url(endpoint_url)
|
82
|
+
end
|
83
|
+
|
84
|
+
def setup
|
85
|
+
# perform the setup only once
|
86
|
+
return if @adapters
|
87
|
+
|
88
|
+
# Initialize the application (import adapters, load DAOs, ...)
|
89
|
+
require 'nucleus/scripts/initialize'
|
90
|
+
# load the configuration values
|
91
|
+
require 'nucleus/scripts/initialize_config_defaults'
|
92
|
+
# Once invoked the configuration is locked
|
93
|
+
require 'nucleus/scripts/finalize'
|
94
|
+
|
95
|
+
@adapters = {}
|
96
|
+
@configurations = {}
|
97
|
+
Nucleus::Adapters.configuration_files.each do |adapter_config|
|
98
|
+
vendor = Nucleus::VendorParser.parse(adapter_config)
|
99
|
+
next unless vendor
|
100
|
+
adapter_clazz = Nucleus::Adapters.adapter_clazz(adapter_config, @api_version)
|
101
|
+
next unless adapter_clazz
|
102
|
+
@adapters[vendor.id] = adapter_clazz
|
103
|
+
@configurations[vendor.id] = {}
|
104
|
+
|
105
|
+
# now load the default configurations for this vendor
|
106
|
+
vendor.providers.each do |provider|
|
107
|
+
provider.endpoints.each do |endpoint|
|
108
|
+
@configurations[vendor.id][secure_url(endpoint.url)] = { check_ssl: !endpoint.trust,
|
109
|
+
app_domain: endpoint.app_domain }
|
110
|
+
end
|
111
|
+
end
|
112
|
+
end
|
113
|
+
end
|
114
|
+
end
|
115
|
+
end
|
@@ -1,79 +1,79 @@
|
|
1
|
-
module Nucleus
|
2
|
-
module Adapters
|
3
|
-
# The {BuildpackTranslator} provides convenience methods for the user to handle the installation
|
4
|
-
# of application runtimes. Common runtime names can be applied and are automatically translated to a
|
5
|
-
# platform native runtime name / url (if applicable).
|
6
|
-
module BuildpackTranslator
|
7
|
-
# List of common buildpacks that are available GitHub.
|
8
|
-
# However, they are not guaranteed to work with every platform that utilized buildpacks.
|
9
|
-
PUBLIC_BUILDPACKS = {
|
10
|
-
'c' => 'https://github.com/atris/heroku-buildpack-c',
|
11
|
-
'common_lisp' => 'https://github.com/mtravers/heroku-buildpack-cl',
|
12
|
-
'core_data' => 'https://github.com/heroku/heroku-buildpack-core-data',
|
13
|
-
'dart' => 'https://github.com/igrigorik/heroku-buildpack-dart',
|
14
|
-
'eiffel' => 'https://github.com/mbustosorg/heroku-buildpack-eiffel',
|
15
|
-
'elixir' => 'https://github.com/hashnuke/heroku-buildpack-elixir',
|
16
|
-
'emacs' => 'https://github.com/technomancy/heroku-buildpack-emacs',
|
17
|
-
'embedded_proxy' => 'https://github.com/ryanbrainard/heroku-buildpack-embedded-proxy',
|
18
|
-
'erlang' => 'https://github.com/archaelus/heroku-buildpack-erlang',
|
19
|
-
'factor' => 'https://github.com/ryanbrainard/heroku-buildpack-factor',
|
20
|
-
'fakesu' => 'https://github.com/fabiokung/heroku-buildpack-fakesu',
|
21
|
-
'geodjango' => 'https://github.com/cirlabs/heroku-buildpack-geodjango',
|
22
|
-
'go' => 'https://github.com/kr/heroku-buildpack-go',
|
23
|
-
'haskell' => 'https://github.com/mietek/haskell-on-heroku',
|
24
|
-
'inline' => 'https://github.com/kr/heroku-buildpack-inline',
|
25
|
-
'java_ant' => 'https://github.com/dennisg/heroku-buildpack-ant',
|
26
|
-
# introduced by IBM Bluemix, shall also work in Heroku
|
27
|
-
'java_liberty' => 'https://github.com/cloudfoundry/ibm-websphere-liberty-buildpack',
|
28
|
-
'jekyll' => 'https://github.com/mattmanning/heroku-buildpack-ruby-jekyll',
|
29
|
-
'lua' => 'https://github.com/leafo/heroku-buildpack-lua',
|
30
|
-
'luvit' => 'https://github.com/skomski/heroku-buildpack-luvit',
|
31
|
-
'meteor' => 'https://github.com/jordansissel/heroku-buildpack-meteor',
|
32
|
-
'middleman' => 'https://github.com/hashicorp/heroku-buildpack-middleman',
|
33
|
-
'monit' => 'https://github.com/k33l0r/monit-buildpack',
|
34
|
-
'multi' => 'https://github.com/heroku/heroku-buildpack-multi',
|
35
|
-
'nanoc' => 'https://github.com/bobthecow/heroku-buildpack-nanoc',
|
36
|
-
'dot_net' => 'https://github.com/friism/heroku-buildpack-mono',
|
37
|
-
'null' => 'https://github.com/ryandotsmith/null-buildpack',
|
38
|
-
'opa' => 'https://github.com/tsloughter/heroku-buildpack-opa',
|
39
|
-
'perl' => 'https://github.com/miyagawa/heroku-buildpack-perl',
|
40
|
-
'phantomjs' => 'https://github.com/stomita/heroku-buildpack-phantomjs',
|
41
|
-
'phing' => 'https://github.com/ryanbrainard/heroku-buildpack-phing',
|
42
|
-
'r' => 'https://github.com/virtualstaticvoid/heroku-buildpack-r',
|
43
|
-
'rust' => 'https://github.com/emk/heroku-buildpack-rust',
|
44
|
-
'redline' => 'https://github.com/will/heroku-buildpack-redline',
|
45
|
-
'silex' => 'https://github.com/klaussilveira/heroku-buildpack-silex',
|
46
|
-
'sphinx' => 'https://github.com/kennethreitz/sphinx-buildpack',
|
47
|
-
'test' => 'https://github.com/ddollar/buildpack-test',
|
48
|
-
'testing' => 'https://github.com/ryanbrainard/heroku-buildpack-testrunner'
|
49
|
-
}
|
50
|
-
|
51
|
-
# Search the list of known buildpacks, both vendor specific and public, to match the desires runtime name.
|
52
|
-
# @param [String] name of the runtime to look out for
|
53
|
-
# @return [Boolean] returns true if a vendor specific or public buildpack was found for the runtime
|
54
|
-
def find_runtime(name)
|
55
|
-
if respond_to? :vendor_specific_runtimes
|
56
|
-
runtime = vendor_specific_runtimes[name.downcase.underscore]
|
57
|
-
return runtime unless runtime.nil?
|
58
|
-
end
|
59
|
-
|
60
|
-
# if no vendor specific runtime was found, use the general definitions
|
61
|
-
PUBLIC_BUILDPACKS[name.downcase.underscore]
|
62
|
-
end
|
63
|
-
|
64
|
-
# Checks if the name of the runtime is matching a vendor specific runtime / buildpack.
|
65
|
-
# @param [String] name of the runtime for which to check if it matches a vendor specific runtime
|
66
|
-
# @return [Boolean] returns true if the name matches a vendor specific runtime, false otherwise
|
67
|
-
def native_runtime?(name)
|
68
|
-
if respond_to? :vendor_specific_runtimes
|
69
|
-
# case A: name is a key
|
70
|
-
return true if vendor_specific_runtimes.keys.include? name
|
71
|
-
# case B: name is a specific runtime name or a URL and one of the values
|
72
|
-
return vendor_specific_runtimes.values.include? name
|
73
|
-
end
|
74
|
-
# cant be native if there are no vendor specific runtimes
|
75
|
-
false
|
76
|
-
end
|
77
|
-
end
|
78
|
-
end
|
79
|
-
end
|
1
|
+
module Nucleus
|
2
|
+
module Adapters
|
3
|
+
# The {BuildpackTranslator} provides convenience methods for the user to handle the installation
|
4
|
+
# of application runtimes. Common runtime names can be applied and are automatically translated to a
|
5
|
+
# platform native runtime name / url (if applicable).
|
6
|
+
module BuildpackTranslator
|
7
|
+
# List of common buildpacks that are available GitHub.
|
8
|
+
# However, they are not guaranteed to work with every platform that utilized buildpacks.
|
9
|
+
PUBLIC_BUILDPACKS = {
|
10
|
+
'c' => 'https://github.com/atris/heroku-buildpack-c',
|
11
|
+
'common_lisp' => 'https://github.com/mtravers/heroku-buildpack-cl',
|
12
|
+
'core_data' => 'https://github.com/heroku/heroku-buildpack-core-data',
|
13
|
+
'dart' => 'https://github.com/igrigorik/heroku-buildpack-dart',
|
14
|
+
'eiffel' => 'https://github.com/mbustosorg/heroku-buildpack-eiffel',
|
15
|
+
'elixir' => 'https://github.com/hashnuke/heroku-buildpack-elixir',
|
16
|
+
'emacs' => 'https://github.com/technomancy/heroku-buildpack-emacs',
|
17
|
+
'embedded_proxy' => 'https://github.com/ryanbrainard/heroku-buildpack-embedded-proxy',
|
18
|
+
'erlang' => 'https://github.com/archaelus/heroku-buildpack-erlang',
|
19
|
+
'factor' => 'https://github.com/ryanbrainard/heroku-buildpack-factor',
|
20
|
+
'fakesu' => 'https://github.com/fabiokung/heroku-buildpack-fakesu',
|
21
|
+
'geodjango' => 'https://github.com/cirlabs/heroku-buildpack-geodjango',
|
22
|
+
'go' => 'https://github.com/kr/heroku-buildpack-go',
|
23
|
+
'haskell' => 'https://github.com/mietek/haskell-on-heroku',
|
24
|
+
'inline' => 'https://github.com/kr/heroku-buildpack-inline',
|
25
|
+
'java_ant' => 'https://github.com/dennisg/heroku-buildpack-ant',
|
26
|
+
# introduced by IBM Bluemix, shall also work in Heroku
|
27
|
+
'java_liberty' => 'https://github.com/cloudfoundry/ibm-websphere-liberty-buildpack',
|
28
|
+
'jekyll' => 'https://github.com/mattmanning/heroku-buildpack-ruby-jekyll',
|
29
|
+
'lua' => 'https://github.com/leafo/heroku-buildpack-lua',
|
30
|
+
'luvit' => 'https://github.com/skomski/heroku-buildpack-luvit',
|
31
|
+
'meteor' => 'https://github.com/jordansissel/heroku-buildpack-meteor',
|
32
|
+
'middleman' => 'https://github.com/hashicorp/heroku-buildpack-middleman',
|
33
|
+
'monit' => 'https://github.com/k33l0r/monit-buildpack',
|
34
|
+
'multi' => 'https://github.com/heroku/heroku-buildpack-multi',
|
35
|
+
'nanoc' => 'https://github.com/bobthecow/heroku-buildpack-nanoc',
|
36
|
+
'dot_net' => 'https://github.com/friism/heroku-buildpack-mono',
|
37
|
+
'null' => 'https://github.com/ryandotsmith/null-buildpack',
|
38
|
+
'opa' => 'https://github.com/tsloughter/heroku-buildpack-opa',
|
39
|
+
'perl' => 'https://github.com/miyagawa/heroku-buildpack-perl',
|
40
|
+
'phantomjs' => 'https://github.com/stomita/heroku-buildpack-phantomjs',
|
41
|
+
'phing' => 'https://github.com/ryanbrainard/heroku-buildpack-phing',
|
42
|
+
'r' => 'https://github.com/virtualstaticvoid/heroku-buildpack-r',
|
43
|
+
'rust' => 'https://github.com/emk/heroku-buildpack-rust',
|
44
|
+
'redline' => 'https://github.com/will/heroku-buildpack-redline',
|
45
|
+
'silex' => 'https://github.com/klaussilveira/heroku-buildpack-silex',
|
46
|
+
'sphinx' => 'https://github.com/kennethreitz/sphinx-buildpack',
|
47
|
+
'test' => 'https://github.com/ddollar/buildpack-test',
|
48
|
+
'testing' => 'https://github.com/ryanbrainard/heroku-buildpack-testrunner'
|
49
|
+
}.freeze
|
50
|
+
|
51
|
+
# Search the list of known buildpacks, both vendor specific and public, to match the desires runtime name.
|
52
|
+
# @param [String] name of the runtime to look out for
|
53
|
+
# @return [Boolean] returns true if a vendor specific or public buildpack was found for the runtime
|
54
|
+
def find_runtime(name)
|
55
|
+
if respond_to? :vendor_specific_runtimes
|
56
|
+
runtime = vendor_specific_runtimes[name.downcase.underscore]
|
57
|
+
return runtime unless runtime.nil?
|
58
|
+
end
|
59
|
+
|
60
|
+
# if no vendor specific runtime was found, use the general definitions
|
61
|
+
PUBLIC_BUILDPACKS[name.downcase.underscore]
|
62
|
+
end
|
63
|
+
|
64
|
+
# Checks if the name of the runtime is matching a vendor specific runtime / buildpack.
|
65
|
+
# @param [String] name of the runtime for which to check if it matches a vendor specific runtime
|
66
|
+
# @return [Boolean] returns true if the name matches a vendor specific runtime, false otherwise
|
67
|
+
def native_runtime?(name)
|
68
|
+
if respond_to? :vendor_specific_runtimes
|
69
|
+
# case A: name is a key
|
70
|
+
return true if vendor_specific_runtimes.keys.include? name
|
71
|
+
# case B: name is a specific runtime name or a URL and one of the values
|
72
|
+
return vendor_specific_runtimes.values.include? name
|
73
|
+
end
|
74
|
+
# cant be native if there are no vendor specific runtimes
|
75
|
+
false
|
76
|
+
end
|
77
|
+
end
|
78
|
+
end
|
79
|
+
end
|
@@ -1,108 +1,108 @@
|
|
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:
|
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
|
+
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
|