nucleus 0.1.0 → 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.rubocop.yml +3 -0
- data/CHANGELOG.md +18 -4
- data/README.md +28 -40
- data/Rakefile +137 -137
- data/config/nucleus_config.rb +0 -4
- data/lib/nucleus/adapter_resolver.rb +115 -115
- data/lib/nucleus/adapters/buildpack_translator.rb +79 -79
- data/lib/nucleus/adapters/v1/cloud_control/application.rb +108 -108
- data/lib/nucleus/adapters/v1/cloud_control/authentication.rb +27 -27
- data/lib/nucleus/adapters/v1/cloud_control/cloud_control.rb +153 -153
- data/lib/nucleus/adapters/v1/cloud_control/domains.rb +68 -68
- data/lib/nucleus/adapters/v1/cloud_control/logs.rb +103 -103
- data/lib/nucleus/adapters/v1/cloud_control/vars.rb +88 -88
- data/lib/nucleus/adapters/v1/cloud_foundry_v2/domains.rb +149 -149
- data/lib/nucleus/adapters/v1/cloud_foundry_v2/logs.rb +303 -303
- data/lib/nucleus/adapters/v1/cloud_foundry_v2/services.rb +286 -286
- data/lib/nucleus/adapters/v1/heroku/heroku.rb +2 -2
- data/lib/nucleus/adapters/v1/heroku/logs.rb +108 -108
- data/lib/nucleus/core/adapter_authentication_inductor.rb +0 -2
- data/lib/nucleus/core/adapter_extensions/auth/http_basic_auth_client.rb +37 -37
- data/lib/nucleus/core/adapter_extensions/http_client.rb +177 -177
- data/lib/nucleus/core/common/files/archive_extractor.rb +112 -112
- data/lib/nucleus/core/common/files/archiver.rb +91 -91
- data/lib/nucleus/core/common/logging/request_log_formatter.rb +48 -48
- data/lib/nucleus/core/error_messages.rb +127 -127
- data/lib/nucleus/core/models/abstract_model.rb +29 -29
- data/lib/nucleus/scripts/load_dependencies.rb +0 -1
- data/lib/nucleus/scripts/setup_config.rb +28 -28
- data/lib/nucleus/version.rb +3 -3
- data/nucleus.gemspec +10 -12
- data/spec/factories/models.rb +63 -61
- data/spec/integration/api/auth_spec.rb +58 -58
- data/spec/test_suites.rake +31 -31
- data/spec/unit/common/helpers/auth_helper_spec.rb +73 -73
- data/spec/unit/common/oauth2_auth_client_spec.rb +1 -1
- data/tasks/compatibility.rake +113 -113
- data/tasks/evaluation.rake +162 -162
- metadata +16 -30
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
|