nucleus 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (224) hide show
  1. checksums.yaml +7 -0
  2. data/.gitattributes +1 -0
  3. data/.gitignore +19 -0
  4. data/.rspec +3 -0
  5. data/.rubocop.yml +44 -0
  6. data/.travis.yml +21 -0
  7. data/CHANGELOG.md +19 -0
  8. data/CONTRIBUTING.md +13 -0
  9. data/Gemfile +16 -0
  10. data/Guardfile +22 -0
  11. data/LICENSE +21 -0
  12. data/README.md +675 -0
  13. data/Rakefile +137 -0
  14. data/bin/nucleus +91 -0
  15. data/bin/nucleus.bat +1 -0
  16. data/config.ru +18 -0
  17. data/config/adapters/cloud_control.yml +32 -0
  18. data/config/adapters/cloud_foundry_v2.yml +61 -0
  19. data/config/adapters/heroku.yml +13 -0
  20. data/config/adapters/openshift_v2.yml +20 -0
  21. data/config/nucleus_config.rb +47 -0
  22. data/lib/nucleus.rb +13 -0
  23. data/lib/nucleus/adapter_resolver.rb +115 -0
  24. data/lib/nucleus/adapters/base_adapter.rb +109 -0
  25. data/lib/nucleus/adapters/buildpack_translator.rb +79 -0
  26. data/lib/nucleus/adapters/v1/cloud_control/application.rb +108 -0
  27. data/lib/nucleus/adapters/v1/cloud_control/authentication.rb +27 -0
  28. data/lib/nucleus/adapters/v1/cloud_control/buildpacks.rb +23 -0
  29. data/lib/nucleus/adapters/v1/cloud_control/cloud_control.rb +153 -0
  30. data/lib/nucleus/adapters/v1/cloud_control/data.rb +76 -0
  31. data/lib/nucleus/adapters/v1/cloud_control/domains.rb +68 -0
  32. data/lib/nucleus/adapters/v1/cloud_control/lifecycle.rb +27 -0
  33. data/lib/nucleus/adapters/v1/cloud_control/log_poller.rb +71 -0
  34. data/lib/nucleus/adapters/v1/cloud_control/logs.rb +103 -0
  35. data/lib/nucleus/adapters/v1/cloud_control/regions.rb +32 -0
  36. data/lib/nucleus/adapters/v1/cloud_control/scaling.rb +17 -0
  37. data/lib/nucleus/adapters/v1/cloud_control/semantic_errors.rb +31 -0
  38. data/lib/nucleus/adapters/v1/cloud_control/services.rb +162 -0
  39. data/lib/nucleus/adapters/v1/cloud_control/token.rb +17 -0
  40. data/lib/nucleus/adapters/v1/cloud_control/vars.rb +88 -0
  41. data/lib/nucleus/adapters/v1/cloud_foundry_v2/app_states.rb +28 -0
  42. data/lib/nucleus/adapters/v1/cloud_foundry_v2/application.rb +111 -0
  43. data/lib/nucleus/adapters/v1/cloud_foundry_v2/authentication.rb +17 -0
  44. data/lib/nucleus/adapters/v1/cloud_foundry_v2/buildpacks.rb +23 -0
  45. data/lib/nucleus/adapters/v1/cloud_foundry_v2/cloud_foundry_v2.rb +141 -0
  46. data/lib/nucleus/adapters/v1/cloud_foundry_v2/data.rb +97 -0
  47. data/lib/nucleus/adapters/v1/cloud_foundry_v2/domains.rb +149 -0
  48. data/lib/nucleus/adapters/v1/cloud_foundry_v2/lifecycle.rb +41 -0
  49. data/lib/nucleus/adapters/v1/cloud_foundry_v2/logs.rb +303 -0
  50. data/lib/nucleus/adapters/v1/cloud_foundry_v2/regions.rb +33 -0
  51. data/lib/nucleus/adapters/v1/cloud_foundry_v2/scaling.rb +15 -0
  52. data/lib/nucleus/adapters/v1/cloud_foundry_v2/semantic_errors.rb +27 -0
  53. data/lib/nucleus/adapters/v1/cloud_foundry_v2/services.rb +286 -0
  54. data/lib/nucleus/adapters/v1/cloud_foundry_v2/vars.rb +80 -0
  55. data/lib/nucleus/adapters/v1/heroku/app_states.rb +57 -0
  56. data/lib/nucleus/adapters/v1/heroku/application.rb +93 -0
  57. data/lib/nucleus/adapters/v1/heroku/authentication.rb +27 -0
  58. data/lib/nucleus/adapters/v1/heroku/buildpacks.rb +27 -0
  59. data/lib/nucleus/adapters/v1/heroku/data.rb +78 -0
  60. data/lib/nucleus/adapters/v1/heroku/domains.rb +43 -0
  61. data/lib/nucleus/adapters/v1/heroku/heroku.rb +146 -0
  62. data/lib/nucleus/adapters/v1/heroku/lifecycle.rb +51 -0
  63. data/lib/nucleus/adapters/v1/heroku/logs.rb +108 -0
  64. data/lib/nucleus/adapters/v1/heroku/regions.rb +42 -0
  65. data/lib/nucleus/adapters/v1/heroku/scaling.rb +28 -0
  66. data/lib/nucleus/adapters/v1/heroku/semantic_errors.rb +23 -0
  67. data/lib/nucleus/adapters/v1/heroku/services.rb +168 -0
  68. data/lib/nucleus/adapters/v1/heroku/vars.rb +65 -0
  69. data/lib/nucleus/adapters/v1/openshift_v2/app_states.rb +68 -0
  70. data/lib/nucleus/adapters/v1/openshift_v2/application.rb +108 -0
  71. data/lib/nucleus/adapters/v1/openshift_v2/authentication.rb +21 -0
  72. data/lib/nucleus/adapters/v1/openshift_v2/data.rb +96 -0
  73. data/lib/nucleus/adapters/v1/openshift_v2/domains.rb +37 -0
  74. data/lib/nucleus/adapters/v1/openshift_v2/lifecycle.rb +60 -0
  75. data/lib/nucleus/adapters/v1/openshift_v2/logs.rb +106 -0
  76. data/lib/nucleus/adapters/v1/openshift_v2/openshift_v2.rb +125 -0
  77. data/lib/nucleus/adapters/v1/openshift_v2/regions.rb +58 -0
  78. data/lib/nucleus/adapters/v1/openshift_v2/scaling.rb +39 -0
  79. data/lib/nucleus/adapters/v1/openshift_v2/semantic_errors.rb +40 -0
  80. data/lib/nucleus/adapters/v1/openshift_v2/services.rb +173 -0
  81. data/lib/nucleus/adapters/v1/openshift_v2/vars.rb +49 -0
  82. data/lib/nucleus/adapters/v1/stub_adapter.rb +464 -0
  83. data/lib/nucleus/core/adapter_authentication_inductor.rb +62 -0
  84. data/lib/nucleus/core/adapter_extensions/auth/auth_client.rb +44 -0
  85. data/lib/nucleus/core/adapter_extensions/auth/authentication_retry_wrapper.rb +79 -0
  86. data/lib/nucleus/core/adapter_extensions/auth/expiring_token_auth_client.rb +53 -0
  87. data/lib/nucleus/core/adapter_extensions/auth/http_basic_auth_client.rb +37 -0
  88. data/lib/nucleus/core/adapter_extensions/auth/o_auth2_auth_client.rb +95 -0
  89. data/lib/nucleus/core/adapter_extensions/auth/token_auth_client.rb +36 -0
  90. data/lib/nucleus/core/adapter_extensions/http_client.rb +177 -0
  91. data/lib/nucleus/core/adapter_extensions/http_tail_client.rb +26 -0
  92. data/lib/nucleus/core/adapter_extensions/tail_stopper.rb +25 -0
  93. data/lib/nucleus/core/common/errors/ambiguous_adapter_error.rb +7 -0
  94. data/lib/nucleus/core/common/errors/file_existence_error.rb +7 -0
  95. data/lib/nucleus/core/common/errors/startup_error.rb +12 -0
  96. data/lib/nucleus/core/common/exit_codes.rb +25 -0
  97. data/lib/nucleus/core/common/files/application_repo_sanitizer.rb +52 -0
  98. data/lib/nucleus/core/common/files/archive_extractor.rb +112 -0
  99. data/lib/nucleus/core/common/files/archiver.rb +91 -0
  100. data/lib/nucleus/core/common/link_generator.rb +46 -0
  101. data/lib/nucleus/core/common/logging/logging.rb +52 -0
  102. data/lib/nucleus/core/common/logging/multi_logger.rb +59 -0
  103. data/lib/nucleus/core/common/logging/request_log_formatter.rb +48 -0
  104. data/lib/nucleus/core/common/ssh_handler.rb +108 -0
  105. data/lib/nucleus/core/common/stream_callback.rb +27 -0
  106. data/lib/nucleus/core/common/thread_config_accessor.rb +85 -0
  107. data/lib/nucleus/core/common/url_converter.rb +28 -0
  108. data/lib/nucleus/core/enums/application_states.rb +26 -0
  109. data/lib/nucleus/core/enums/logfile_types.rb +28 -0
  110. data/lib/nucleus/core/error_messages.rb +127 -0
  111. data/lib/nucleus/core/errors/adapter_error.rb +13 -0
  112. data/lib/nucleus/core/errors/adapter_missing_implementation_error.rb +12 -0
  113. data/lib/nucleus/core/errors/adapter_request_error.rb +10 -0
  114. data/lib/nucleus/core/errors/adapter_resource_not_found_error.rb +10 -0
  115. data/lib/nucleus/core/errors/endpoint_authentication_error.rb +10 -0
  116. data/lib/nucleus/core/errors/platform_specific_semantic_error.rb +12 -0
  117. data/lib/nucleus/core/errors/platform_timeout_error.rb +10 -0
  118. data/lib/nucleus/core/errors/platform_unavailable_error.rb +10 -0
  119. data/lib/nucleus/core/errors/semantic_adapter_request_error.rb +19 -0
  120. data/lib/nucleus/core/errors/unknown_adapter_call_error.rb +10 -0
  121. data/lib/nucleus/core/file_handling/archive_converter.rb +29 -0
  122. data/lib/nucleus/core/file_handling/file_manager.rb +64 -0
  123. data/lib/nucleus/core/file_handling/git_deployer.rb +133 -0
  124. data/lib/nucleus/core/file_handling/git_repo_analyzer.rb +23 -0
  125. data/lib/nucleus/core/import/adapter_configuration.rb +53 -0
  126. data/lib/nucleus/core/import/vendor_parser.rb +28 -0
  127. data/lib/nucleus/core/import/version_detector.rb +18 -0
  128. data/lib/nucleus/core/models/abstract_model.rb +29 -0
  129. data/lib/nucleus/core/models/endpoint.rb +30 -0
  130. data/lib/nucleus/core/models/provider.rb +26 -0
  131. data/lib/nucleus/core/models/vendor.rb +22 -0
  132. data/lib/nucleus/ext/kernel.rb +5 -0
  133. data/lib/nucleus/ext/regexp.rb +49 -0
  134. data/lib/nucleus/os.rb +15 -0
  135. data/lib/nucleus/root_dir.rb +13 -0
  136. data/lib/nucleus/scripts/finalize.rb +8 -0
  137. data/lib/nucleus/scripts/initialize.rb +9 -0
  138. data/lib/nucleus/scripts/initialize_config_defaults.rb +26 -0
  139. data/lib/nucleus/scripts/load.rb +17 -0
  140. data/lib/nucleus/scripts/load_dependencies.rb +43 -0
  141. data/lib/nucleus/scripts/setup_config.rb +28 -0
  142. data/lib/nucleus/scripts/shutdown.rb +11 -0
  143. data/lib/nucleus/version.rb +3 -0
  144. data/nucleus.gemspec +88 -0
  145. data/public/robots.txt +2 -0
  146. data/public/swagger-ui/css/reset.css +125 -0
  147. data/public/swagger-ui/css/screen.css +1224 -0
  148. data/public/swagger-ui/images/apple-touch-icon-114x114.png +0 -0
  149. data/public/swagger-ui/images/apple-touch-icon-120x120.png +0 -0
  150. data/public/swagger-ui/images/apple-touch-icon-144x144.png +0 -0
  151. data/public/swagger-ui/images/apple-touch-icon-152x152.png +0 -0
  152. data/public/swagger-ui/images/apple-touch-icon-57x57.png +0 -0
  153. data/public/swagger-ui/images/apple-touch-icon-60x60.png +0 -0
  154. data/public/swagger-ui/images/apple-touch-icon-72x72.png +0 -0
  155. data/public/swagger-ui/images/apple-touch-icon-76x76.png +0 -0
  156. data/public/swagger-ui/images/explorer_icons.png +0 -0
  157. data/public/swagger-ui/images/favicon-128.png +0 -0
  158. data/public/swagger-ui/images/favicon-16x16.png +0 -0
  159. data/public/swagger-ui/images/favicon-196x196.png +0 -0
  160. data/public/swagger-ui/images/favicon-32x32.png +0 -0
  161. data/public/swagger-ui/images/favicon-96x96.png +0 -0
  162. data/public/swagger-ui/images/favicon.ico +0 -0
  163. data/public/swagger-ui/images/logo_small.png +0 -0
  164. data/public/swagger-ui/images/mstile-144x144.png +0 -0
  165. data/public/swagger-ui/images/mstile-150x150.png +0 -0
  166. data/public/swagger-ui/images/mstile-310x150.png +0 -0
  167. data/public/swagger-ui/images/mstile-310x310.png +0 -0
  168. data/public/swagger-ui/images/mstile-70x70.png +0 -0
  169. data/public/swagger-ui/images/pet_store_api.png +0 -0
  170. data/public/swagger-ui/images/throbber.gif +0 -0
  171. data/public/swagger-ui/images/wordnik_api.png +0 -0
  172. data/public/swagger-ui/index.html +107 -0
  173. data/public/swagger-ui/lib/backbone-min.js +38 -0
  174. data/public/swagger-ui/lib/handlebars-1.0.0.js +2278 -0
  175. data/public/swagger-ui/lib/highlight.7.3.pack.js +1 -0
  176. data/public/swagger-ui/lib/jquery-1.8.0.min.js +2 -0
  177. data/public/swagger-ui/lib/jquery.ba-bbq.min.js +18 -0
  178. data/public/swagger-ui/lib/jquery.slideto.min.js +1 -0
  179. data/public/swagger-ui/lib/jquery.wiggle.min.js +8 -0
  180. data/public/swagger-ui/lib/shred.bundle.js +2765 -0
  181. data/public/swagger-ui/lib/shred/content.js +193 -0
  182. data/public/swagger-ui/lib/swagger-oauth.js +211 -0
  183. data/public/swagger-ui/lib/swagger.js +1653 -0
  184. data/public/swagger-ui/lib/underscore-min.js +32 -0
  185. data/public/swagger-ui/o2c.html +15 -0
  186. data/public/swagger-ui/redirect.html +14 -0
  187. data/public/swagger-ui/swagger-ui.js +2324 -0
  188. data/public/swagger-ui/swagger-ui.min.js +1 -0
  189. data/schemas/api.adapter.schema.yml +31 -0
  190. data/schemas/api.requirements.schema.yml +17 -0
  191. data/spec/factories/models.rb +61 -0
  192. data/spec/integration/api/auth_spec.rb +58 -0
  193. data/spec/integration/api/endpoints_spec.rb +167 -0
  194. data/spec/integration/api/errors_spec.rb +47 -0
  195. data/spec/integration/api/providers_spec.rb +157 -0
  196. data/spec/integration/api/swagger_schema_spec.rb +64 -0
  197. data/spec/integration/api/vendors_spec.rb +45 -0
  198. data/spec/integration/integration_spec_helper.rb +27 -0
  199. data/spec/integration/test_data_generator.rb +55 -0
  200. data/spec/nucleus_git_key.pem +51 -0
  201. data/spec/spec_helper.rb +98 -0
  202. data/spec/support/shared_example_request_types.rb +99 -0
  203. data/spec/test_suites.rake +31 -0
  204. data/spec/unit/adapters/archive_converter_spec.rb +25 -0
  205. data/spec/unit/adapters/file_manager_spec.rb +93 -0
  206. data/spec/unit/adapters/git_deployer_spec.rb +262 -0
  207. data/spec/unit/adapters/v1/stub_spec.rb +14 -0
  208. data/spec/unit/common/helpers/auth_helper_spec.rb +73 -0
  209. data/spec/unit/common/oauth2_auth_client_spec.rb +108 -0
  210. data/spec/unit/common/regexp_spec.rb +33 -0
  211. data/spec/unit/common/request_log_formatter_spec.rb +108 -0
  212. data/spec/unit/common/thread_config_accessor_spec.rb +97 -0
  213. data/spec/unit/models/endpoint_spec.rb +83 -0
  214. data/spec/unit/models/provider_spec.rb +102 -0
  215. data/spec/unit/models/vendor_spec.rb +100 -0
  216. data/spec/unit/schemas/adapter_schema_spec.rb +16 -0
  217. data/spec/unit/schemas/adapter_validation_spec.rb +56 -0
  218. data/spec/unit/schemas/requirements_schema_spec.rb +16 -0
  219. data/spec/unit/unit_spec_helper.rb +11 -0
  220. data/tasks/compatibility.rake +113 -0
  221. data/tasks/evaluation.rake +162 -0
  222. data/wiki/adapter_tests.md +99 -0
  223. data/wiki/implement_new_adapter.md +155 -0
  224. metadata +836 -0
@@ -0,0 +1,58 @@
1
+ module Nucleus
2
+ module Adapters
3
+ module V1
4
+ class OpenshiftV2 < Stub
5
+ module Regions
6
+ # @see Stub#regions
7
+ def regions
8
+ response = get('/regions').body[:data]
9
+ response.each { |region| to_nucleus_region(region) }
10
+ # filter all non-available regions
11
+ response.delete_if { |region| region[:allow_selection] == false }
12
+ response
13
+ end
14
+
15
+ # @see Stub#region
16
+ def region(region_name)
17
+ region = convert_region(region_name)
18
+ fail Errors::AdapterResourceNotFoundError,
19
+ "Region '#{region_name}' does not exist at the endpoint" if region.nil?
20
+ region
21
+ end
22
+
23
+ private
24
+
25
+ # Retrieve a native region for the abstracted ID and assign its name to the application entity
26
+ def retrieve_region(application)
27
+ return unless application.key?(:region)
28
+ found_region = native_region(application[:region])
29
+ fail Errors::SemanticAdapterRequestError,
30
+ "Region '#{application[:region]}' does not exist at the endpoint" if found_region.nil?
31
+ application[:region] = found_region[:name]
32
+ end
33
+
34
+ def convert_region(region_name)
35
+ found_region = native_region(region_name)
36
+ found_region = to_nucleus_region(found_region) unless found_region.nil?
37
+ found_region
38
+ end
39
+
40
+ def native_region(region_name)
41
+ response = get('/regions').body[:data]
42
+ response.delete_if { |region| region[:allow_selection] == false }
43
+ response.find { |region| region[:name].casecmp(region_name) == 0 }
44
+ end
45
+
46
+ def to_nucleus_region(region)
47
+ region[:id] = region.delete(:name)
48
+ # first created zone
49
+ region[:created_at] = region[:zones].min_by { |v| v[:created_at] }
50
+ # last updated zone
51
+ region[:updated_at] = region[:zones].max_by { |v| v[:updated_at] }
52
+ region
53
+ end
54
+ end
55
+ end
56
+ end
57
+ end
58
+ end
@@ -0,0 +1,39 @@
1
+ module Nucleus
2
+ module Adapters
3
+ module V1
4
+ class OpenshiftV2 < Stub
5
+ module Scaling
6
+ # @see Stub#scale
7
+ def scale(application_id, instances)
8
+ id = app_id_by_name(application_id)
9
+ app = get("/application/#{id}").body[:data]
10
+ fail_with(:not_scalable, [application_id]) unless app[:scalable]
11
+
12
+ # check if scaling would exceed the available gears
13
+ user = get('/user').body[:data]
14
+ available_gears = user[:max_gears] - user[:consumed_gears]
15
+ requires_additional_gears = instances - app[:gear_count]
16
+ if requires_additional_gears > available_gears
17
+ fail_with(:insufficient_gears, [application_id, instances, requires_additional_gears, available_gears])
18
+ end
19
+
20
+ # scale up if we require more gears
21
+ while requires_additional_gears > 0
22
+ send_event(id, 'scale-up')
23
+ requires_additional_gears -= 1
24
+ end
25
+
26
+ # scale down if we have too much gears
27
+ while requires_additional_gears < 0
28
+ send_event(id, 'scale-down')
29
+ requires_additional_gears += 1
30
+ end
31
+
32
+ # reload the app to see if all operations were taken into account
33
+ application(id)
34
+ end
35
+ end
36
+ end
37
+ end
38
+ end
39
+ end
@@ -0,0 +1,40 @@
1
+ module Nucleus
2
+ module Adapters
3
+ module V1
4
+ class OpenshiftV2 < Stub
5
+ # Semantic error messages that are specific for Openshift V2
6
+ module SemanticErrors
7
+ # Get all Openshift V2 specific semantic error definitions.
8
+ # @return [Hash<Symbol,Hash<Symbol,String>>] the error message definitions, including the error +code+,
9
+ # e.g. +422_200_1+ and the +message+ that shall be formatted when used.
10
+ def semantic_error_messages
11
+ {
12
+ # Error code '400_1': Only one runtime is allowed per Openshift V2 application
13
+ only_one_runtime: { code: 422_400_1, message: 'Openshift V2 only allows 1 runtime per '\
14
+ 'application' },
15
+
16
+ must_have_runtime: { code: 422_400_2, message: 'Openshift V2 requires you to specify exactly one '\
17
+ 'runtime when creating the application. Please provide a valid runtime in the next request.' },
18
+
19
+ # Error code '400_3': Application is not scalable
20
+ not_scalable: { code: 422_400_3, message: "Application '%s' is not scalable, "\
21
+ "instances can't be adjusted" },
22
+
23
+ # Error code '400_4': Quota exceeded, scaling would require more gears than available to the user
24
+ insufficient_gears: { code: 422_400_4, message: "Application '%s' can't be, "\
25
+ 'scaled to %s instances, requires %s gears but only %s gears are available' },
26
+
27
+ no_user_domain: { code: 422_400_5, message: "Openshift V2 requires you to create a 'domain' before "\
28
+ 'any application can be created' },
29
+
30
+ ambiguous_runtime: { code: 422_400_6, message: 'Runtime could not be identified, there are multiple '\
31
+ "matches for '%s': %s" },
32
+
33
+ invalid_runtime: { code: 422_400_7, message: "Invalid runtime, could not identify cartridge for '%s'." }
34
+ }
35
+ end
36
+ end
37
+ end
38
+ end
39
+ end
40
+ end
@@ -0,0 +1,173 @@
1
+ module Nucleus
2
+ module Adapters
3
+ module V1
4
+ class OpenshiftV2 < Stub
5
+ # Openshift V2, operations for the application's addons
6
+ module Services
7
+ # @see Stub#services
8
+ def services
9
+ embedded_cartridges.collect { |cartridge| to_nucleus_service(cartridge) }
10
+ end
11
+
12
+ # @see Stub#service
13
+ def service(service_id)
14
+ to_nucleus_service(embedded_cartridge(service_id))
15
+ end
16
+
17
+ # @see Stub#service_plans
18
+ def service_plans(service_id)
19
+ cartridge = embedded_cartridge(service_id)
20
+ # Currently there are no plans, implement when required...
21
+ return [default_plan(cartridge)] if cartridge[:usage_rates].empty?
22
+ cartridge[:usage_rates].collect { |usage_rate| to_nucleus_plan(cartridge, usage_rate) }
23
+ end
24
+
25
+ # @see Stub#service_plan
26
+ def service_plan(service_id, plan_id)
27
+ cartridge = embedded_cartridge(service_id)
28
+ if (cartridge[:usage_rates].empty? && plan_id != 'default') ||
29
+ (!cartridge[:usage_rates].empty? && !cartridge[:usage_rates].any? { |rate| rate[:plan_id] == plan_id })
30
+ # Currently there are no plans, implement when required...
31
+ fail Errors::AdapterResourceNotFoundError, "No such service plan name '#{plan_id}' for service "\
32
+ "'#{service_id}'"
33
+ end
34
+
35
+ return default_plan(cartridge) if cartridge[:usage_rates].empty?
36
+ to_nucleus_plan(cartridge, cartridge[:usage_rates].find { |rate| rate[:plan_id] == plan_id })
37
+ end
38
+
39
+ # @see Stub#installed_services
40
+ def installed_services(application_id)
41
+ installed_cartridges(application_id).collect do |installed|
42
+ to_nucleus_installed_service(installed)
43
+ end
44
+ end
45
+
46
+ # @see Stub#installed_service
47
+ def installed_service(application_id, service_id)
48
+ installed = get("/application/#{app_id_by_name(application_id)}/cartridge/#{service_id}").body[:data]
49
+ to_nucleus_installed_service(installed)
50
+ end
51
+
52
+ # @see Stub#add_service
53
+ def add_service(application_id, service_entity, plan_entity)
54
+ # make sure dependencies are installed
55
+ app_id = app_id_by_name(application_id)
56
+ begin
57
+ service_to_add = embedded_cartridge(service_entity[:id])
58
+ rescue Errors::AdapterResourceNotFoundError
59
+ raise Errors::SemanticAdapterRequestError, "Invalid service: '#{service_entity[:id]}' could not be found"
60
+ end
61
+ # verify dependencies are installed, throws error if not
62
+ verify_cartridge_dependencies(app_id, service_entity[:id], service_to_add)
63
+
64
+ # check plan (if there are some)
65
+ # no plans, chosen plan must be 'default'
66
+ plan_name = service_to_add[:usage_rates].find { |plan| plan[:plan_id] == plan_entity[:id] }
67
+ if (service_to_add[:usage_rates].empty? && plan_entity[:id] != 'default') ||
68
+ (!service_to_add[:usage_rates].empty? && plan_name.nil?)
69
+ fail Errors::SemanticAdapterRequestError, "No such service plan name '#{plan_entity[:id]}' for service "\
70
+ "'#{service_entity[:id]}' and application '#{application_id}'"
71
+ end
72
+
73
+ # TODO: if a different plan than 'default' is chosen, we can't use it yet :/
74
+ # However, only 'standalone' cartridges showed different plans as of April, 15th 2015
75
+ to_nucleus_installed_service(post("/application/#{app_id}/cartridges",
76
+ body: { cartridge: service_entity[:id] }).body[:data])
77
+ end
78
+
79
+ # @see Stub#remove_service
80
+ def remove_service(application_id, service_id)
81
+ delete("/application/#{app_id_by_name(application_id)}/cartridge/#{service_id}")
82
+ end
83
+
84
+ private
85
+
86
+ def verify_cartridge_dependencies(application_id, service_id, service_to_add)
87
+ missing_dependencies = service_to_add.key?(:requires) ? service_to_add[:requires] : []
88
+ already_installed = installed_cartridges(application_id)
89
+ already_installed.each { |installed_cartridge| missing_dependencies.delete(installed_cartridge[:name]) }
90
+ fail Errors::SemanticAdapterRequestError, "Failed to add service '#{service_id}' for application "\
91
+ "'#{application_id}'. The service's dependencies '#{missing_dependencies}' are not, "\
92
+ 'but have to be installed.' unless missing_dependencies.empty?
93
+ end
94
+
95
+ def installed_cartridges(application_id)
96
+ installed = get("/application/#{app_id_by_name(application_id)}/cartridges").body[:data]
97
+ installed.find_all do |cartridge|
98
+ # exclude the 'haproxy' addon from the list. It is a core part of the application and can't be modified
99
+ # exclude all standalone cartridges, we do not yet support them
100
+ cartridge[:type] == 'embedded' && !cartridge[:name].start_with?('haproxy-')
101
+ end
102
+ end
103
+
104
+ def embedded_cartridges
105
+ get('/cartridges').body[:data].find_all { |cartridge| cartridge[:type] == 'embedded' }
106
+ end
107
+
108
+ def embedded_cartridge(service_id)
109
+ get("/cartridge/#{service_id}").body[:data]
110
+ end
111
+
112
+ def to_nucleus_service(cartridge)
113
+ # id, description and name is already contained
114
+ cartridge[:required_services] = cartridge.key?(:requires) ? cartridge[:requires] : []
115
+ cartridge[:documentation_url] = nil
116
+ cartridge[:release] = cartridge[:version]
117
+ cartridge[:free_plan] = cartridge[:usage_rates] == []
118
+ cartridge[:created_at] = cartridge[:creation_time]
119
+ cartridge[:updated_at] = cartridge[:creation_time]
120
+ cartridge
121
+ end
122
+
123
+ def to_nucleus_installed_service(installed_service)
124
+ installed_service = to_nucleus_service(installed_service)
125
+ # Currently there are no plans, implement when required...
126
+ installed_service[:active_plan] = 'default'
127
+ installed_service[:properties] = installed_service.key?(:properties) ? installed_service[:properties] : []
128
+ installed_service[:web_url] = nil
129
+ installed_service
130
+ end
131
+
132
+ def to_nucleus_plan(cartridge, usage_rate)
133
+ {
134
+ id: usage_rate[:plan_id],
135
+ name: usage_rate[:plan_id],
136
+ description: nil,
137
+ free: false,
138
+ costs: [{
139
+ # Openshift online currently bills in USD, EUR and CAD
140
+ price: [{ amount: usage_rate[:cad], currency: 'CAD' },
141
+ { amount: usage_rate[:eur], currency: 'EUR' },
142
+ { amount: usage_rate[:usd], currency: 'USD' }],
143
+ per_instance: false,
144
+ period: usage_rate[:duration]
145
+ }],
146
+ created_at: cartridge[:creation_time],
147
+ updated_at: cartridge[:creation_time]
148
+ }
149
+ end
150
+
151
+ def default_plan(cartridge)
152
+ {
153
+ id: 'default',
154
+ name: 'default',
155
+ description: 'Default plan, cartridge does not offer different plans',
156
+ free: true,
157
+ costs: [{
158
+ # Openshift online currently bills in USD, EUR and CAD
159
+ price: [{ amount: 0.00, currency: 'CAD' },
160
+ { amount: 0.00, currency: 'EUR' },
161
+ { amount: 0.00, currency: 'USD' }],
162
+ per_instance: false,
163
+ period: 'hour'
164
+ }],
165
+ created_at: cartridge[:creation_time],
166
+ updated_at: cartridge[:creation_time]
167
+ }
168
+ end
169
+ end
170
+ end
171
+ end
172
+ end
173
+ end
@@ -0,0 +1,49 @@
1
+ module Nucleus
2
+ module Adapters
3
+ module V1
4
+ class OpenshiftV2 < Stub
5
+ module Vars
6
+ # @see Stub#env_vars
7
+ def env_vars(application_id)
8
+ all_vars = get("/application/#{app_id_by_name(application_id)}/environment-variables").body[:data]
9
+ all_vars.collect { |var| to_nucleus_var(var) }
10
+ end
11
+
12
+ # @see Stub#env_var
13
+ def env_var(application_id, env_var_key)
14
+ response = get("/application/#{app_id_by_name(application_id)}/environment-variable/#{env_var_key}")
15
+ to_nucleus_var(response.body[:data])
16
+ end
17
+
18
+ # @see Stub#create_env_var
19
+ def create_env_var(application_id, env_var)
20
+ to_nucleus_var(post("/application/#{app_id_by_name(application_id)}/environment-variables",
21
+ body: { name: env_var[:key], value: env_var[:value] }).body[:data])
22
+ end
23
+
24
+ # @see Stub#update_env_var
25
+ def update_env_var(application_id, env_var_key, env_var)
26
+ to_nucleus_var(put("/application/#{app_id_by_name(application_id)}/environment-variable/#{env_var_key}",
27
+ body: { value: env_var[:value] }).body[:data])
28
+ end
29
+
30
+ # @see Stub#delete_env_var
31
+ def delete_env_var(application_id, env_var_key)
32
+ id = app_id_by_name(application_id)
33
+ # Openshift returns 204 even if the key did not exist
34
+ if get("/application/#{id}/environment-variable/#{env_var_key}", expects: [200, 404]).status == 404
35
+ fail Errors::AdapterResourceNotFoundError, "Env. var key '#{env_var_key}' does not exist"
36
+ end
37
+ delete("/application/#{id}/environment-variable/#{env_var_key}")
38
+ end
39
+
40
+ private
41
+
42
+ def to_nucleus_var(var)
43
+ { id: var[:name], key: var[:name], value: var[:value] }
44
+ end
45
+ end
46
+ end
47
+ end
48
+ end
49
+ end
@@ -0,0 +1,464 @@
1
+ module Nucleus
2
+ module Adapters
3
+ # Version 1, or the first release of the Nucleus API.<br>
4
+ # It provides basic management functionality to handle:<br>
5
+ # * applications
6
+ # * domains
7
+ # * environment variables
8
+ # * logging
9
+ # * deployment
10
+ # * scaling (horizontal and vertical)
11
+ module V1
12
+ # Stub adapter for Nucleus API version 1.<br>
13
+ # The stub provides all methods that an actual adapter should implement.<br>
14
+ # It also contains the documentation that describes the expected method behaviour,
15
+ # which must be matched by the adapters.<br>
16
+ # <br>
17
+ # Adapter methods shall raise:<br>
18
+ # {Errors::EndpointAuthenticationError} == 401 if a endpoint call failed due to bad credentials<br>
19
+ # {Errors::AdapterResourceNotFoundError} == 404 if a resource could not be found<br>
20
+ # {Errors::SemanticAdapterRequestError} == 422 if the request could not be processed due to
21
+ # common semantic errors<br>
22
+ # {Errors::PlatformSpecificSemanticError} == 422 if the request could not be processed due to
23
+ # semantic errors that are specific to the endpoint / platform, for instance quota restrictions.<br>
24
+ # {Errors::UnknownAdapterCallError} == 500 if the endpoint API shows unexpected behavior,
25
+ # not matching the implementation<br>
26
+ # {Errors::AdapterMissingImplementationError} == 501 if a feature is not (yet) implemented by the adapter<br>
27
+ #
28
+ # If embedded in the Grape Restful API, authentication errors and bad requests are handled by Grape.<br>
29
+ # If an adapter is used within the +gem+, the developer must take care of authentication handling and
30
+ # missing form data.
31
+ #
32
+ # @abstract
33
+ class Stub < BaseAdapter
34
+ # Error message saying that the adapter feature has not been implemented yet.
35
+ NOT_IMPLEMENTED_ERROR = Errors::AdapterMissingImplementationError.new(
36
+ 'Adapter is missing an implementation to support this feature')
37
+
38
+ # Build an Authentication client that can handle the authentication to the endpoint
39
+ # given the username and a matching password.
40
+ # @return [Nucleus::Adapters::AuthClient] authentication client
41
+ def auth_client
42
+ fail NOT_IMPLEMENTED_ERROR
43
+ end
44
+
45
+ # Return a list of all {Nucleus::API::Models::Region class} compatible objects
46
+ # that are available on the current endpoint.<br>
47
+ # If the platform does not offer multi-region support, one 'default' region shall be returned.
48
+ # @raise [Nucleus::Errors::EndpointAuthenticationError] if the authentication on the endpoint failed
49
+ # @return [Hash, Nucleus::API::Models::Regions] region entity compatible Hash of available regions
50
+ def regions
51
+ fail NOT_IMPLEMENTED_ERROR
52
+ end
53
+
54
+ # Return the {Nucleus::API::Models::Region class} compatible information
55
+ # regarding the region with the given region_id.
56
+ #
57
+ # @param [String] region_id Id of the region object to retrieve
58
+ # @raise [Nucleus::Errors::AdapterResourceNotFoundError] if no region matching the region_id could be found
59
+ # @raise [Nucleus::Errors::EndpointAuthenticationError] if the authentication on the endpoint failed
60
+ # @return [Hash, Nucleus::API::Models::Region] region entity compatible Hash with the id region_id
61
+ def region(region_id)
62
+ fail NOT_IMPLEMENTED_ERROR
63
+ end
64
+
65
+ # Get a list of all applications that are accessible to the authenticated user account.
66
+ # @raise [Nucleus::Errors::EndpointAuthenticationError] if the authentication on the endpoint failed
67
+ # @return [Hash, Nucleus::API::Models::Applications] application entity list compatible hash
68
+ def applications
69
+ fail NOT_IMPLEMENTED_ERROR
70
+ end
71
+
72
+ # Retrieve the application entity of the application with the given application_id.
73
+ # @param [String] application_id Id of the application object to retrieve
74
+ # @raise [Nucleus::Errors::AdapterResourceNotFoundError] if no app matching the application_id could be found
75
+ # @raise [Nucleus::Errors::EndpointAuthenticationError] if the authentication on the endpoint failed
76
+ # @return [Hash, Nucleus::API::Models::Application] application entity compatible Hash with the application_id
77
+ def application(application_id)
78
+ fail NOT_IMPLEMENTED_ERROR
79
+ end
80
+
81
+ # Create a new application on the endpoint using the given application entity.
82
+ # @param [Hash, Nucleus::API::Models::Application] application entity compatible Hash.
83
+ # @option application [String] :name The name of the application
84
+ # @option application [Array<String>] :runtimes Runtimes (buildpacks) to use with the application
85
+ # @option application [String] :region Region where the application shall be deployed,
86
+ # call {#regions} for a list of allowed values
87
+ # @option application [Boolean] :autoscaled True if the application shall scale automatically,
88
+ # false if manual scaling shall be used. WARNING: This option is currently not supported by most vendors!
89
+ # @raise [Nucleus::Errors::EndpointAuthenticationError] if the authentication on the endpoint failed
90
+ # @return [Hash, Nucleus::API::Models::Application] application entity compatible Hash
91
+ # of the created application
92
+ def create_application(application)
93
+ fail NOT_IMPLEMENTED_ERROR
94
+ end
95
+
96
+ # Update an application on the endpoint using the given application entity.
97
+ # @param [Hash, Nucleus::API::Models::Application] application application entity compatible Hash.
98
+ # @option application [String] :name The updated name of the application
99
+ # @option application [Array<String>] :runtimes Runtimes (buildpacks) to use with the application
100
+ # @param [String] application_id Id of the application object that shall be updated
101
+ # @raise [Nucleus::Errors::AdapterResourceNotFoundError] if no app matching the application_id could be found
102
+ # @raise [Nucleus::Errors::EndpointAuthenticationError] if the authentication on the endpoint failed
103
+ # @return [Hash, Nucleus::API::Models::Application] application entity compatible Hash with the application_id
104
+ def update_application(application_id, application)
105
+ fail NOT_IMPLEMENTED_ERROR
106
+ end
107
+
108
+ # Delete the application with the given application_id on the endpoint.
109
+ # @param [String] application_id Id of the application object that shall be deleted
110
+ # @raise [Nucleus::Errors::AdapterResourceNotFoundError] if no app matching the application_id could be found
111
+ # @raise [Nucleus::Errors::EndpointAuthenticationError] if the authentication on the endpoint failed
112
+ # @return [void]
113
+ def delete_application(application_id)
114
+ fail NOT_IMPLEMENTED_ERROR
115
+ end
116
+
117
+ # Get a list of all domains that are assigned to the application.
118
+ # @param [String] application_id Id of the application for which the domains are to be retrieved
119
+ # @raise [Nucleus::Errors::AdapterResourceNotFoundError] if no app matching the application_id could be found
120
+ # @raise [Nucleus::Errors::EndpointAuthenticationError] if the authentication on the endpoint failed
121
+ # @return [Hash, Nucleus::API::Models::Domains] domain entity list compatible hash
122
+ def domains(application_id)
123
+ fail NOT_IMPLEMENTED_ERROR
124
+ end
125
+
126
+ # Retrieve the domain entity of the application with the given application_id and the domain with the domain_id.
127
+ # @param [String] application_id Id of the application for which the domain is to be retrieved
128
+ # @param [String] domain_id Id of the domain object to retrieve
129
+ # @raise [Nucleus::Errors::AdapterResourceNotFoundError] if no app matching the application_id,
130
+ # or no domain matching the domain_id could be found
131
+ # @raise [Nucleus::Errors::EndpointAuthenticationError] if the authentication on the endpoint failed
132
+ # @return [Hash, Nucleus::API::Models::Domain] domain entity compatible hash of the domain with the domain_id
133
+ def domain(application_id, domain_id)
134
+ fail NOT_IMPLEMENTED_ERROR
135
+ end
136
+
137
+ # Create a new domain using the given domain entity and assign it to the application.
138
+ # @param [String] application_id Id of the application for which the domain is to be created
139
+ # @param [Hash, Nucleus::API::Models::Domain] domain domain entity compatible Hash.
140
+ # @option application [String] :name The domain name, e.g. +myapplication.example.org+
141
+ # @raise [Nucleus::Errors::AdapterResourceNotFoundError] if no app matching the application_id,
142
+ # or no domain matching the domain_id could be found
143
+ # @raise [Nucleus::Errors::EndpointAuthenticationError] if the authentication on the endpoint failed
144
+ # @return [Hash, Nucleus::API::Models::Domain] domain entity compatible hash of the created domain
145
+ def create_domain(application_id, domain)
146
+ fail NOT_IMPLEMENTED_ERROR
147
+ end
148
+
149
+ # Delete the domain of the application with the domain_id.
150
+ # @param [String] application_id Id of the application for which the domain is to be deleted
151
+ # @param [String] domain_id Id of the domain object to delete
152
+ # @raise [Nucleus::Errors::AdapterResourceNotFoundError] if no app matching the application_id,
153
+ # or no domain matching the domain_id could be found
154
+ # @raise [Nucleus::Errors::EndpointAuthenticationError] if the authentication on the endpoint failed
155
+ # @return [void]
156
+ def delete_domain(application_id, domain_id)
157
+ fail NOT_IMPLEMENTED_ERROR
158
+ end
159
+
160
+ # Get a list of all environment variables that are assigned to the application.
161
+ # @param [String] application_id Id of the application for which the env_vars are to be retrieved
162
+ # @raise [Nucleus::Errors::AdapterResourceNotFoundError] if no app matching the application_id could be found
163
+ # @raise [Nucleus::Errors::EndpointAuthenticationError] if the authentication on the endpoint failed
164
+ # @return [Hash, Nucleus::API::Models::EnvironmentVariables] environment variable entity list compatible hash
165
+ def env_vars(application_id)
166
+ fail NOT_IMPLEMENTED_ERROR
167
+ end
168
+
169
+ # Retrieve the environment variable entity of the application with the given application_id and the env. var
170
+ # with the env_var_id.
171
+ # @param [String] application_id Id of the application for which the env_var is to be retrieved
172
+ # @param [String] env_var_id Id of the env_var object to retrieve
173
+ # @raise [Nucleus::Errors::AdapterResourceNotFoundError] if no app matching the application_id,
174
+ # or no environment variable matching the env_var_id could be found
175
+ # @raise [Nucleus::Errors::EndpointAuthenticationError] if the authentication on the endpoint failed
176
+ # @return [Hash, Nucleus::API::Models::EnvironmentVariable] environment variable entity compatible hash
177
+ # of the env. var with the env_var_id
178
+ def env_var(application_id, env_var_id)
179
+ fail NOT_IMPLEMENTED_ERROR
180
+ end
181
+
182
+ # Create a new environment variable using the given env. var entity and assign it to the application.
183
+ # @param [String] application_id Id of the application for which the env_var is to be created
184
+ # @param [Hash, Nucleus::API::Models::EnvironmentVariable] env_var env. var entity compatible Hash.
185
+ # @option env_var [String] :key Key of the environment variable, e.g. +IP+
186
+ # @option env_var [String] :value Value of the environment variable, e.g. +0.0.0.0+
187
+ # @raise [Nucleus::Errors::AdapterResourceNotFoundError] if no app matching the application_id could be found
188
+ # @raise [Nucleus::Errors::EndpointAuthenticationError] if the authentication on the endpoint failed
189
+ # @return [Hash, Nucleus::API::Models::EnvironmentVariable] environment variable entity compatible hash
190
+ # of the created env. var
191
+ def create_env_var(application_id, env_var)
192
+ fail NOT_IMPLEMENTED_ERROR
193
+ end
194
+
195
+ # Update the environment variable of the application, using the given env. var entity.
196
+ # @param [String] application_id Id of the application for which the env_var is to be updated
197
+ # @param [String] env_var_id Id of the env_var object to update
198
+ # @param [Hash, Nucleus::API::Models::EnvironmentVariable] env_var env. var entity compatible Hash.
199
+ # @option env_var [String] :value Value of the environment variable, e.g. +0.0.0.0+
200
+ # @raise [Nucleus::Errors::AdapterResourceNotFoundError] if no app matching the application_id,
201
+ # or no environment variable matching the env_var_id could be found
202
+ # @raise [Nucleus::Errors::EndpointAuthenticationError] if the authentication on the endpoint failed
203
+ # @return [Hash, Nucleus::API::Models::EnvironmentVariable] environment variable entity compatible hash
204
+ # of the updated env. var
205
+ def update_env_var(application_id, env_var_id, env_var)
206
+ fail NOT_IMPLEMENTED_ERROR
207
+ end
208
+
209
+ # Delete the environment variable of the application with the env_var_id.
210
+ # @param [String] application_id Id of the application for which the env_var is to be deleted
211
+ # @param [String] env_var_id Id of the env_var object to delete
212
+ # @raise [Nucleus::Errors::AdapterResourceNotFoundError] if no app matching the application_id,
213
+ # or no environment variable matching the env_var_id could be found
214
+ # @raise [Nucleus::Errors::EndpointAuthenticationError] if the authentication on the endpoint failed
215
+ # @return [void]
216
+ def delete_env_var(application_id, env_var_id)
217
+ fail NOT_IMPLEMENTED_ERROR
218
+ end
219
+
220
+ # Start all instances of the application with the application_id.
221
+ # The state of all application instances should become +running+ when all actions are finished
222
+ # (unless there are technical errors preventing the application to start).
223
+ # Preconditions:<br>
224
+ # * application must have been deployed
225
+ # Postconditions (delayed):<br>
226
+ # * state == running
227
+ # @param [String] application_id Id of the application which is to be started
228
+ # @raise [Nucleus::Errors::AdapterResourceNotFoundError] if the application could not be found
229
+ # @raise [Nucleus::Errors::EndpointAuthenticationError] if the authentication on the endpoint failed
230
+ # @raise [Nucleus::Errors::SemanticAdapterRequestError] if the application is not deployed
231
+ # @return [Hash, Nucleus::API::Models::Application] application entity compatible Hash
232
+ def start(application_id)
233
+ fail NOT_IMPLEMENTED_ERROR
234
+ end
235
+
236
+ # Stop all instances of the application with the application_id.
237
+ # The state of all application instances will become +stopped+ when all actions are finished.
238
+ # Preconditions:<br>
239
+ # * application must have been deployed
240
+ # Postconditions (delayed):<br>
241
+ # * state == stopped
242
+ # @param [String] application_id Id of the application which is to be stopped
243
+ # @raise [Nucleus::Errors::AdapterResourceNotFoundError] if the application could not be found
244
+ # @raise [Nucleus::Errors::EndpointAuthenticationError] if the authentication on the endpoint failed
245
+ # @raise [Nucleus::Errors::SemanticAdapterRequestError] if the application is not deployed
246
+ # @return [Hash, Nucleus::API::Models::Application] application entity compatible Hash
247
+ def stop(application_id)
248
+ fail NOT_IMPLEMENTED_ERROR
249
+ end
250
+
251
+ # Restart all instances of the application with the application_id.
252
+ # The state of all application instances should become +running+ when all actions are finished
253
+ # (unless there are technical errors preventing the application to start).
254
+ # Preconditions:<br>
255
+ # * application must have been deployed
256
+ # Postconditions (delayed):<br>
257
+ # * state == running
258
+ # @param [String] application_id Id of the application which is to be restarted
259
+ # @raise [Nucleus::Errors::AdapterResourceNotFoundError] if the application could not be found
260
+ # @raise [Nucleus::Errors::EndpointAuthenticationError] if the authentication on the endpoint failed
261
+ # @raise [Nucleus::Errors::SemanticAdapterRequestError] if the application is not deployed
262
+ # @return [Hash, Nucleus::API::Models::Application] application entity compatible Hash
263
+ def restart(application_id)
264
+ fail NOT_IMPLEMENTED_ERROR
265
+ end
266
+
267
+ # Deploy the data of the application given the compressed application archive.<br>
268
+ # The application shall not be running when the deployment is finished.
269
+ # Postconditions (delayed):<br>
270
+ # * state == deployed
271
+ # @param [String] application_id Id of the application for which the data is to be deployed
272
+ # @param [Tempfile] application_archive compressed application archive that shall be deployed
273
+ # @param [Symbol] compression_format archive formats, see {Nucleus::API::Enums::CompressionFormats.all}
274
+ # for a list of all allowed values
275
+ # @raise [Nucleus::Errors::AdapterResourceNotFoundError] if the application could not be found
276
+ # @raise [Nucleus::Errors::EndpointAuthenticationError] if the authentication on the endpoint failed
277
+ # @raise [Nucleus::Errors::AdapterRequestError] if the application archive that shall be deployed is no
278
+ # valid application archive, or if the application_archive / compression_format are not supported
279
+ # @return [void]
280
+ def deploy(application_id, application_archive, compression_format)
281
+ fail NOT_IMPLEMENTED_ERROR
282
+ end
283
+
284
+ # Rebuild the recently deployed bits of the application.<br>
285
+ # The rebuild can be used to update the application to use a new version of the underlying runtime or fix a
286
+ # previously failed application start after the issues have been resolved.
287
+ # @param [String] application_id Id of the application which is to be rebuild
288
+ # @raise [Nucleus::Errors::AdapterResourceNotFoundError] if the application could not be found
289
+ # @raise [Nucleus::Errors::EndpointAuthenticationError] if the authentication on the endpoint failed
290
+ # @return [Hash, Nucleus::API::Models::Application] application entity compatible Hash
291
+ def rebuild(application_id)
292
+ fail NOT_IMPLEMENTED_ERROR
293
+ end
294
+
295
+ # Download the application data that is currently deployed on the platform.
296
+ # The downloaded application archive must contain at least all files that were originally deployed,
297
+ # but can also contain additional files, for instance log files.
298
+ # @param [String] application_id Id of the application of which the data is to be downloaded
299
+ # @param [Symbol] compression_format archive formats, see {Nucleus::API::Enums::CompressionFormats.all}
300
+ # for a list of all allowed values
301
+ # @raise [Nucleus::Errors::AdapterResourceNotFoundError] if the application could not be found
302
+ # @raise [Nucleus::Errors::EndpointAuthenticationError] if the authentication on the endpoint failed
303
+ # @raise [Nucleus::Errors::AdapterRequestError] if the application archive that shall be deployed is no
304
+ # valid application archive, or if the compression_format is not supported
305
+ # @return [StringIO] binary application data
306
+ def download(application_id, compression_format)
307
+ fail NOT_IMPLEMENTED_ERROR
308
+ end
309
+
310
+ # TODO: Finish documentation when vertical scaling is added
311
+ # Scale the application and adjust the number of instances that shall be running.
312
+ # @param [String] application_id Id of the application which is to be scaled
313
+ # @raise [Nucleus::Errors::AdapterResourceNotFoundError] if the application could not be found
314
+ # @raise [Nucleus::Errors::EndpointAuthenticationError] if the authentication on the endpoint failed
315
+ # @raise [Nucleus::Errors::SemanticAdapterRequestError] if the number of instances is disallowed on the platform
316
+ # @return [Hash, Nucleus::API::Models::Application] application entity compatible Hash
317
+ def scale(application_id, instances)
318
+ fail NOT_IMPLEMENTED_ERROR
319
+ end
320
+
321
+ # Assert whether the given log_id is valid for the application_id.
322
+ # @param [String] application_id Id of the application of which the log existence is to be checked
323
+ # @param [String] log_id Id of the log whose existence is to be checked
324
+ # @raise [Nucleus::Errors::AdapterResourceNotFoundError] if the application could not be found
325
+ # @raise [Nucleus::Errors::EndpointAuthenticationError] if the authentication on the endpoint failed
326
+ # @return [Boolean] returns true if there is a log for the application with the log_id,
327
+ # false if it does not exist
328
+ def log?(application_id, log_id)
329
+ fail NOT_IMPLEMENTED_ERROR
330
+ end
331
+
332
+ # Get a list of all logs that are available for the application.
333
+ # @param [String] application_id Id of the application of which the logs are to be listed
334
+ # @raise [Nucleus::Errors::AdapterResourceNotFoundError] if the application could not be found
335
+ # @raise [Nucleus::Errors::EndpointAuthenticationError] if the authentication on the endpoint failed
336
+ # @return [Hash, Nucleus::API::Models::Logs] log entity list compatible hash
337
+ def logs(application_id)
338
+ fail NOT_IMPLEMENTED_ERROR
339
+ end
340
+
341
+ # Retrieve all log entries of the log.
342
+ # @param [String] application_id Id of the application of which the log_entries are to be retrieved
343
+ # @param [String] log_id Id of the log for which the entries are to be retrieved
344
+ # @raise [Nucleus::Errors::AdapterResourceNotFoundError] if the application or log could not be found
345
+ # @raise [Nucleus::Errors::EndpointAuthenticationError] if the authentication on the endpoint failed
346
+ # @return [Array<String>] array of log entries, starting with the earliest entry at pos [0]
347
+ def log_entries(application_id, log_id)
348
+ fail NOT_IMPLEMENTED_ERROR
349
+ end
350
+
351
+ # Tail the logfile of the application and send each retrieved chunk, which can be a line of a file,
352
+ # a new chunk in a received http message, or a websocket message, to the stream. The deferred tailing
353
+ # process shall be stoppable when the +stop+ method of the returned {Nucleus::Adapters::TailStopper TailStopper}
354
+ # is called.
355
+ # @param [String] application_id Id of the application of which the log is to be tailed
356
+ # @param [String] log_id Id of the log that is to be tailed
357
+ # @param [Nucleus::StreamCallback] stream stream callback to which messages can be sent via
358
+ # the +send_message+ method
359
+ # @raise [Nucleus::Errors::AdapterResourceNotFoundError] if the application or log could not be found
360
+ # @raise [Nucleus::Errors::EndpointAuthenticationError] if the authentication on the endpoint failed
361
+ # @return [Nucleus::Adapters::TailStopper] callback object to stop the ongoing tail process
362
+ def tail(application_id, log_id, stream)
363
+ fail NOT_IMPLEMENTED_ERROR
364
+ end
365
+
366
+ # List all services that are available at the endpoint.
367
+ # @raise [Nucleus::Errors::EndpointAuthenticationError] if the authentication on the endpoint failed
368
+ # @return [Hash, Nucleus::API::Models::Services] services list compatible hash
369
+ def services
370
+ fail NOT_IMPLEMENTED_ERROR
371
+ end
372
+
373
+ # Retrieve the service entity matching the given service_id.
374
+ # @param [String] service_id Id of the service that is to be retrieved
375
+ # @raise [Nucleus::Errors::AdapterResourceNotFoundError] if the service could not be found
376
+ # @raise [Nucleus::Errors::EndpointAuthenticationError] if the authentication on the endpoint failed
377
+ # @return [Hash, Nucleus::API::Models::Service] service entity compatible hash
378
+ def service(service_id)
379
+ fail NOT_IMPLEMENTED_ERROR
380
+ end
381
+
382
+ # List all plans that can be chosen for the service with the service_id, ascending order on the price.
383
+ # @param [String] service_id Id of the service the plans belong to
384
+ # @raise [Nucleus::Errors::AdapterResourceNotFoundError] if the service could not be found
385
+ # @raise [Nucleus::Errors::EndpointAuthenticationError] if the authentication on the endpoint failed
386
+ # @return [Hash, Nucleus::API::Models::ServicePlans] service plan list compatible hash
387
+ def service_plans(service_id)
388
+ fail NOT_IMPLEMENTED_ERROR
389
+ end
390
+
391
+ # Show the plan with the plan_id that is applicable to the service with the service_id.
392
+ # @param [String] service_id Id of the service the plans belongs to
393
+ # @raise [Nucleus::Errors::AdapterResourceNotFoundError] if the service or the plan could not be found
394
+ # @raise [Nucleus::Errors::EndpointAuthenticationError] if the authentication on the endpoint failed
395
+ # @return [Hash, Nucleus::API::Models::ServicePlan] service plan entity compatible hash
396
+ def service_plan(service_id, plan_id)
397
+ fail NOT_IMPLEMENTED_ERROR
398
+ end
399
+
400
+ # List all services that are installed on the application with the given application_id.
401
+ # @param [String] application_id Id of the application of which the services are to be listed of
402
+ # @raise [Nucleus::Errors::AdapterResourceNotFoundError] if the application could not be found
403
+ # @raise [Nucleus::Errors::EndpointAuthenticationError] if the authentication on the endpoint failed
404
+ # @return [Hash, Nucleus::API::Models::InstalledServices] installed services list compatible hash
405
+ def installed_services(application_id)
406
+ fail NOT_IMPLEMENTED_ERROR
407
+ end
408
+
409
+ # Retrieve the installed service entity matching the given service_id that is installed
410
+ # on the application with the given application_id.
411
+ # @param [String] service_id Id of the installed service that is to be retrieved
412
+ # @raise [Nucleus::Errors::AdapterResourceNotFoundError] if the application or service could not be found
413
+ # @raise [Nucleus::Errors::EndpointAuthenticationError] if the authentication on the endpoint failed
414
+ # @return [Hash, Nucleus::API::Models::InstalledService] installed service entity compatible hash
415
+ def installed_service(application_id, service_id)
416
+ fail NOT_IMPLEMENTED_ERROR
417
+ end
418
+
419
+ # Add the service with the service_id to the application with the application_id.
420
+ # @param [String] application_id Id of the application of which the service is to be added to
421
+ # @param [Hash, Nucleus::API::Models::Service] service_entity service entity compatible Hash.
422
+ # @option env_var [String] :id ID of the service to add to the application
423
+ # @param [Hash, Nucleus::API::Models::ServicePlan] plan_entity service plan entity compatible Hash.
424
+ # @option env_var [String] :id ID of the service plan that shall be applied
425
+ # @raise [Nucleus::Errors::AdapterResourceNotFoundError] if the application could not be found
426
+ # @raise [Nucleus::Errors::EndpointAuthenticationError] if the authentication on the endpoint failed
427
+ # @raise [Nucleus::Errors::SemanticAdapterRequestError] if the service to add or the plan to use
428
+ # could not be found
429
+ # @return [Hash, Nucleus::API::Models::InstalledService] installed service entity compatible hash
430
+ def add_service(application_id, service_entity, plan_entity)
431
+ fail NOT_IMPLEMENTED_ERROR
432
+ end
433
+
434
+ # Change the service, e.g. the active plan, of the service with the service_id for
435
+ # the application with the application_id. Use the fields of the service_entity to execute the update.
436
+ # @param [String] application_id Id of the application of which the service is to be changed
437
+ # @param [String] service_id Id of the installed service that is to be updated. The id must not (but can) be
438
+ # identical to the id of the service the installed service is based on.
439
+ # @param [Hash, Nucleus::API::Models::ServicePlan] plan_entity service plan entity compatible Hash.
440
+ # @option env_var [String] :id ID of the service plan that shall be applied
441
+ # @raise [Nucleus::Errors::AdapterResourceNotFoundError] if the application could not be found or
442
+ # the service was not installed on this application
443
+ # @raise [Nucleus::Errors::EndpointAuthenticationError] if the authentication on the endpoint failed
444
+ # @raise [Nucleus::Errors::SemanticAdapterRequestError] if the plan to use could not be found
445
+ # @return [Hash, Nucleus::API::Models::InstalledService] installed service entity compatible hash
446
+ def change_service(application_id, service_id, plan_entity)
447
+ fail NOT_IMPLEMENTED_ERROR
448
+ end
449
+
450
+ # Remove the installed service with the service_id from the application with the application_id.
451
+ # @param [String] application_id Id of the application of which the service is to be removed from
452
+ # @param [String] service_id Id of the installed service that is to be removed from the application. The id
453
+ # must not (but can) be identical to the id of the service the installed service is based on.
454
+ # @raise [Nucleus::Errors::AdapterResourceNotFoundError] if the application could not be found or
455
+ # the service was not installed on this application
456
+ # @raise [Nucleus::Errors::EndpointAuthenticationError] if the authentication on the endpoint failed
457
+ # @return [void]
458
+ def remove_service(application_id, service_id)
459
+ fail NOT_IMPLEMENTED_ERROR
460
+ end
461
+ end
462
+ end
463
+ end
464
+ end