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,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: b172d0919bd9a0948cfa81bb640a3bbae2c42d39
4
+ data.tar.gz: 4ca095496dddee1c67aa285ea58dadda92b0648b
5
+ SHA512:
6
+ metadata.gz: 8e1a3ed688b3ece1bb464c0891802a5ad653d3e88094c8aa41845dc42951b149adf8bc2930273e05e9ed5d93d6a0bd3a02704d245efc716e50bc40235fc12dbc
7
+ data.tar.gz: 18cb846d9e27ce9aa053351f809353df68133b7939b7f27d55f737f914c35a1a9431f80e280c039b4474b5535b337f44cc47240f08a77f868613469d23867599
@@ -0,0 +1 @@
1
+ CHANGELOG.md merge=union
@@ -0,0 +1,19 @@
1
+ /.bundle/
2
+ /.yardoc
3
+ /Gemfile.lock
4
+ /_yardoc/
5
+ /coverage/
6
+ /doc/
7
+ /pkg/
8
+ /spec/reports/
9
+ /tmp/
10
+ /log/
11
+ *.bundle
12
+ *.so
13
+ *.o
14
+ *.a
15
+ mkmf.log
16
+ .idea
17
+ store
18
+ rspec.txt
19
+ .credentials
data/.rspec ADDED
@@ -0,0 +1,3 @@
1
+ --color
2
+ --require spec_helper
3
+ --format progress
@@ -0,0 +1,44 @@
1
+ AllCops:
2
+ Exclude:
3
+ - bin/**/*
4
+ - vendor/**/*
5
+
6
+ Metrics/BlockNesting:
7
+ Max: 4
8
+
9
+ Metrics/AbcSize:
10
+ Max: 20
11
+
12
+ Metrics/LineLength:
13
+ Max: 200
14
+
15
+ Metrics/MethodLength:
16
+ Max: 25
17
+
18
+ Metrics/AbcSize:
19
+ Max: 30
20
+
21
+ Metrics/CyclomaticComplexity:
22
+ Max: 8
23
+
24
+ Metrics/PerceivedComplexity:
25
+ Max: 8
26
+
27
+ Metrics/ClassLength:
28
+ Max: 150
29
+
30
+ Metrics/ModuleLength:
31
+ Max: 200
32
+
33
+ Style/Documentation:
34
+ Enabled: false
35
+
36
+ Style/AlignHash:
37
+ Enabled: false
38
+
39
+ Style/ExtraSpacing:
40
+ Exclude:
41
+ - nucleus.gemspec
42
+
43
+ Lint/UnusedMethodArgument:
44
+ Enabled: false
@@ -0,0 +1,21 @@
1
+ language: ruby
2
+ cache: bundler
3
+ # use docker based environment
4
+ sudo: false
5
+
6
+ rvm:
7
+ - 2.2
8
+ - 2.1
9
+ - 2.0.0
10
+ - ruby-head
11
+
12
+ matrix:
13
+ allow_failures:
14
+ - rvm: ruby-head
15
+
16
+ gemfile:
17
+ - Gemfile
18
+
19
+ addons:
20
+ code_climate:
21
+ repo_token: 3a3d0c72cae4846855221615e1d8690c0dd08336ef8904b8a8d109e51037ee2b
@@ -0,0 +1,19 @@
1
+ # Change Log
2
+ All notable changes to the Nucleus project will be documented in this file.
3
+ This project adheres to [Semantic Versioning](http://semver.org/).
4
+
5
+ ## Unreleased - Next
6
+
7
+ ### Added / Features
8
+ * Add basic logging functionality for OpenShift v2
9
+
10
+ ### Changed / Fixes
11
+ * Add your contribution here
12
+
13
+ ## [0.1.0] - 2015-08-04
14
+
15
+ ### Added / Features
16
+ * Initial development release of the Platform as a Service abstraction layer - [@croeck](https://github.com/croeck)
17
+
18
+
19
+ [0.1.0]: https://github.com/stefan-kolb/nucleus/releases/tag/0.1.0
@@ -0,0 +1,13 @@
1
+ # Contributing
2
+
3
+ We love contributions from everyone!
4
+
5
+ Fork, then clone the repo:
6
+
7
+ git clone git@github.com:your-username/nucleus.git
8
+
9
+ Make your change. Add tests for your change. Make sure the tests and code style validations pass:
10
+
11
+ bundle exec rake
12
+
13
+ Push to your fork and submit a pull request.
data/Gemfile ADDED
@@ -0,0 +1,16 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in nucleus.gemspec
4
+ gemspec
5
+
6
+ group :test do
7
+ gem 'airborne', '=0.1.15'
8
+ gem 'codeclimate-test-reporter', require: false
9
+ gem 'factory_girl'
10
+ gem 'faker'
11
+ gem 'memfs'
12
+ # includes required fix for empty arrays as param value, see issue #122 and pull request #125,
13
+ gem 'rack-test', git: 'https://github.com/croeck/rack-test.git', branch: 'empty-array-param'
14
+ gem 'rspec-wait'
15
+ gem 'simplecov', require: false
16
+ end
@@ -0,0 +1,22 @@
1
+ interactor :simple
2
+
3
+ guard 'bundler' do
4
+ watch('Gemfile')
5
+ end
6
+
7
+ guard 'rack', server: 'thin' do
8
+ watch('Gemfile.lock')
9
+ watch('config.ru')
10
+ watch(%r{^config|app|public|lib|schemas|scripts\/.*})
11
+ end
12
+
13
+ guard 'yard', port: '8808', cli: '--reload' do
14
+ watch(%r{app\/.+\.rb})
15
+ watch(%r{lib\/.+\.rb})
16
+ watch(/.+\.md/)
17
+ end
18
+
19
+ guard :rubocop do
20
+ watch(/.+\.rb$/)
21
+ watch(%r{(?:.+\/)?\.rubocop\.yml$}) { |m| File.dirname(m[0]) }
22
+ end
data/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ The MIT License (MIT)
2
+
3
+ Copyright (c) 2014-2015 Stefan Kolb, Cedric Röck
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in
13
+ all copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21
+ THE SOFTWARE.
@@ -0,0 +1,675 @@
1
+ # Nucleus
2
+
3
+ [![Build Status](https://travis-ci.org/stefan-kolb/nucleus.svg)](https://travis-ci.org/stefan-kolb/nucleus)
4
+ [![Dependency Status](https://gemnasium.com/stefan-kolb/nucleus.svg)](https://gemnasium.com/stefan-kolb/nucleus)
5
+ [![Code Climate](https://codeclimate.com/github/stefan-kolb/nucleus/badges/gpa.svg)](https://codeclimate.com/github/stefan-kolb/nucleus)
6
+ [![Test Coverage](https://codeclimate.com/github/stefan-kolb/nucleus/badges/coverage.svg)](https://codeclimate.com/github/stefan-kolb/nucleus/coverage)
7
+
8
+ _Nucleus_ is a RESTful abstraction layer to unify core management functions of Platform-as-a-Service (PaaS) systems.
9
+ The API is build using [Ruby](https://www.ruby-lang.org) and the [grape framework](https://github.com/intridea/grape).
10
+ It provides fully compliant [swagger](http://swagger.io/) schemas that serve for documentation and client generation.
11
+
12
+ Nucleus differentiates between Vendors, Providers and Endpoints.
13
+ A *Vendor* is the organization that developed the platform software.
14
+ A *Provider* runs the platform, which always has at least one *Endpoint*, but can also have multiple endpoints for different regions.
15
+
16
+ ## Table of Contents
17
+
18
+ * [Supported Vendors](#supported-vendors)
19
+ * [Usage](#usage)
20
+ * [Ruby Interpreter Compatibility](#ruby-interpreter-compatibility)
21
+ * [Installation instructions](#installation-instructions)
22
+ * [Use in your application](#use-in-your-application)
23
+ * [Use the API](#use-the-api)
24
+ * [Start the server](#start-the-server)
25
+ * [API endpoints](#api-endpoints)
26
+ * [Functionality](#functionality)
27
+ * [Authentication](#authentication)
28
+ * [Special characters (umlauts, ....)](#special-characters-umlauts-)
29
+ * [Core constructs](#core-constructs)
30
+ * [Vendors](#vendors)
31
+ * [Providers and Endpoints](#providers-and-endpoints)
32
+ * [Custom API calls (experimental)](#custom-api-calls-experimental)
33
+ * [Execute a custom API call against the endpoint](#execute-a-native-api-call-against-the-endpoint)
34
+ * [Execute a custom API call against an endpoint's application](#execute-a-native-api-call-against-an-endpoints-application)
35
+ * [Adapters](#adapters)
36
+ * [Heroku](#heroku)
37
+ * [Cloud Foundry v2](#cloud-foundry-v2)
38
+ * [Openshift v2](#openshift-v2)
39
+ * [cloudControl](#cloudcontrol)
40
+ * [Configuration](#configuration)
41
+ * [Vendors, Providers and Endpoints](#vendors-providers-and-endpoints)
42
+ * [Application configuration](#application-configuration)
43
+ * [API client(s)](#api-clients)
44
+ * [Accept Header](#accept-header)
45
+ * [Error codes](#error-codes)
46
+ * [Language specific clients](#language-specific-clients)
47
+ * [Tests](#tests)
48
+ * [Schema validation](#schema-validation)
49
+ * [Versioning](#versioning)
50
+ * [Security](#security)
51
+ * [Project structure](#project-structure)
52
+ * [Contributing](#contributing)
53
+ * [Further documentation](#further-documentation)
54
+
55
+ ## Supported Vendors
56
+
57
+ - [Heroku][heroku]
58
+ - [Cloud Foundry][cloud_foundry] (v2)
59
+ - [AppFog][appfog], [Anynines][anynines], [IBM Bluemix][bluemix], [Pivotal Web Services][pivotal_ws], [HP Helion][hp_helion]
60
+ - [Openshift][openshift_v2] (v2)
61
+ - [OpenShift Online][openshift_online], [getup Cloud][getup]
62
+ - [cloudControl][cloudcontrol]
63
+ - [dotCloud][dotcloud], [Cloud&Heat App Elevator][cloud&heat], [exoscale Apps][exoscale]
64
+
65
+ [heroku]: https://www.heroku.com
66
+
67
+ [cloud_foundry]: https://www.cloudfoundry.org/
68
+ [appfog]: https://www.ctl.io/appfog/
69
+ [anynines]: http://www.anynines.com/
70
+ [bluemix]: https://console.ng.bluemix.net/
71
+ [pivotal_ws]: https://run.pivotal.io/
72
+ [hp_helion]: http://www8.hp.com/de/de/cloud/helion-devplatform-overview.html
73
+
74
+ [openshift_v2]: https://www.openshift.com/
75
+ [openshift_online]: https://www.openshift.com/features/index.html
76
+ [getup]: https://getupcloud.com/index_en.html
77
+
78
+ [cloudcontrol]: https://www.cloudcontrol.com
79
+ [dotcloud]: https://www.dotcloud.com/
80
+ [cloud&heat]: https://www.cloudandheat.com/de/paas.html
81
+ [exoscale]: https://www.exoscale.ch/add-on/apps/
82
+
83
+ More information on the vendors and the associated adapter can be found in the [adapters section](#adapters).
84
+
85
+ ## Usage
86
+
87
+ Nucleus can either be used as standalone application/service, or as part of another ruby application.
88
+ Please make sure to obey the following installation instructions before starting to use Nucleus.
89
+
90
+ ### Ruby Interpreter Compatibility
91
+
92
+ Nucleus is supposed to run on Ruby >= 2.0.
93
+ **It currently won't work on JRuby.**
94
+
95
+ ### Installation instructions
96
+
97
+ 1) The following (executable) files must be available on the system's *PATH*:
98
+
99
+ - git
100
+ - ssh
101
+
102
+ #### Platform-specific notes
103
+
104
+ Unix systems should run fine out of the box, whereas Windows systems might need some adjustments:
105
+
106
+ ##### Windows
107
+
108
+ Both files should be located in the `Git/bin` installation directory of [msysGit](https://msysgit.github.io/).
109
+ Nucleus is verified to work with [msysGit](https://msysgit.github.io/) and the included version of `OpenSSH`.
110
+ We did not verify other alternatives, e.g. PuTTY's `plink.exe`.
111
+ PuTTY is supposed to (maybe anyone knows how to fix this?) not work due to the lack of the `-o UserKnownHostsFile=NUL -o StrictHostKeyChecking=no` options that allow to connect any git repository without confirmation of the host's identity.
112
+
113
+ ###### Troubleshooting
114
+
115
+ **Eventmachine**:
116
+
117
+ Eventmachine sometimes fails with the error `Encryption not available on this event-machine`.
118
+ A fix is available, but requires a few steps:
119
+
120
+ 1) Uninstall the gem
121
+
122
+ ```shell
123
+ $ gem uninstall eventmachine
124
+ ```
125
+
126
+ 2) Download the OpenSSL package from [http://packages.openknapsack.org/openssl/openssl-1.0.0k-x86-windows.tar.lzma](http://packages.openknapsack.org/openssl/openssl-1.0.0k-x86-windows.tar.lzma)
127
+
128
+ 3) Extract it to a desired location
129
+
130
+ 4) Re-install the gem and point to the OpenSSL installation directory. Escape backslashes or use forward slashes.
131
+
132
+ ```shell
133
+ $ gem install eventmachine -- --with-ssl-dir=C:/SSL
134
+ ```
135
+
136
+ ### Use in your application
137
+
138
+ #### Require nucleus and mark as dependency
139
+
140
+ Add a dependency on the Nucleus gem, for instance in your application's Gemfile,
141
+
142
+ ```ruby
143
+ gem 'nucleus'
144
+ ```
145
+
146
+ upon which you would update your bundle.
147
+
148
+ ```shell
149
+ $ bundle install
150
+ ```
151
+
152
+ Of course you could also install the gem yourself as:
153
+
154
+ ```shell
155
+ $ gem install nucleus
156
+ ```
157
+
158
+ Finally require the gem in your application
159
+
160
+ ```ruby
161
+ require 'nucleus'
162
+ ```
163
+
164
+ #### Communicate with an endpoint
165
+
166
+ 1) Configuration [optional]
167
+
168
+ Adapt the configuration to your needs and adjust the values via `nucleus_config`.
169
+ The configuration *must* be changed before initializing the `AdapterResolver`, otherwise the configuration is locked and can't be changed anymore.
170
+
171
+ For more information have a look at the [configuration](#configuration) section.
172
+
173
+ 2) Show all currently available API versions:
174
+
175
+ ```ruby
176
+ Nucleus::VersionDetector.api_versions
177
+ ```
178
+
179
+ 3) Instantiate the AdapterResolver for the desired API version:
180
+
181
+ ```ruby
182
+ resolver = Nucleus::AdapterResolver.new('v1')
183
+ ```
184
+
185
+ 4) Show all adapters that are supported by Nucleus by this specific API version:
186
+
187
+ ```ruby
188
+ resolver.adapters
189
+ ```
190
+
191
+ ```ruby
192
+ {"cloudcontrol"=>Nucleus::Adapters::V1::CloudControl, "cloud_foundry_v2"=>Nucleus::Adapters::V1::CloudFoundryV2, "heroku"=>Nucleus::Adapters::V1::Heroku, "openshift_v2"=>Nucleus::Adapters::V1::OpenshiftV2}
193
+ ```
194
+
195
+ 5) Load your desired adapter implementation:
196
+
197
+ ```ruby
198
+ adapter = resolver.load('cloudcontrol', 'api.cloudcontrol.com', 'your_username', 'your_password')
199
+ ```
200
+
201
+ By default, the adapter will be populated with the default configuration options that are defined in the vendor's configuration for the selected endpoint_url.
202
+ If you are using a custom installation, e.g. of *Openshift* or *Cloud Foundry*, make sure to pass the option that describe the `app_domain` for deployed applications.
203
+ Otherwise, the `web_url` links created by Nucleus will be malformed.
204
+
205
+ ```ruby
206
+ adapter = resolver.load('cloud_foundry_v2', 'api.example.org', 'your_username', 'your_password', app_domain: 'apps.example.org', check_ssl: false)
207
+ ```
208
+
209
+ 6) Start using the platform and invoke commands:
210
+
211
+ ```ruby
212
+ # Show available regions
213
+ adapter.regions
214
+ # Create our first application
215
+ app = adapter.create_application(region: 'default', name: 'myusersfirstapplication', runtimes: ['nodejs'])
216
+ # And delete the application again
217
+ adapter.delete_application(app[:id])
218
+ ```
219
+
220
+ Check the **documentation** of the `Nucleus::Adapters::V1::Stub` adapter (or any other API version) for a complete list of the supported actions.
221
+ You can also refer to the documentation of the REST interface to get detailed information about the parameter options of `post` and `put` commands,
222
+ including which fields are required and those that are only optional.
223
+
224
+ ### Use the API
225
+
226
+ Besides including the abstraction layer in your application, Nucleus can also be started and serve a RESTful API:
227
+ For detailed usage information go to the section [API client(s)](#api-clients).
228
+
229
+ #### Start the server
230
+
231
+ A rack server can be started in multiple ways.
232
+ The most convenient solution is to use the provided script:
233
+
234
+ ```shell
235
+ $ ./bin/nucleus
236
+ ```
237
+
238
+ However, you can also start the API using the [thin](http://code.macournoyer.com/thin/) server:
239
+
240
+ ```shell
241
+ $ rackup -s thin config.ru
242
+ ```
243
+
244
+ Due to limitations in the log tailing process, Nucleus currently requires `thin` and does not work on other Rack servers.
245
+ In theory, it should be possible to make other Rack servers work that also utilize [eventmachine](https://github.com/eventmachine/eventmachine).
246
+
247
+ #### HTTPS
248
+
249
+ We highly encourage you to **only use https connections** when your application is running in production or used outside of your local computer.
250
+ This is due to the fact that all passwords are passed via the HTTP basic authentication, which does not encrypt your data so that any third party could log and identify your credentials.
251
+
252
+ To enforce this policy, Nucleus will automatically redirect all connections on plain HTTP to HTTPS connections if it is running in production (detected via *RACK_ENV*).
253
+
254
+ #### API endpoints
255
+
256
+ The API of Nucleus is documented via [swagger](http://swagger.io).
257
+ After you started a server instance, you can access an interactive [swagger-ui](https://github.com/swagger-api/swagger-ui) at the `/docs` path.
258
+
259
+ ## Functionality
260
+
261
+ The following list shows the degree to which the adapters implement the offered methods.
262
+ This list is auto-generated and can be shown via:
263
+
264
+ ```
265
+ $ bundle exec rake evaluation:compatibility:markdown
266
+ ```
267
+
268
+ **State: 10/14/2015**
269
+
270
+ Method / Vendor|cloudControl|Cloud Foundry v2|Heroku|Openshift v2
271
+ :--|:-:|:-:|:-:|:-:
272
+ auth_client|✓|✓|✓|✓
273
+ regions|✓|✓|✓|✓
274
+ region|✓|✓|✓|✓
275
+ applications|✓|✓|✓|✓
276
+ application|✓|✓|✓|✓
277
+ create_application|✓|✓|✓|✓
278
+ update_application|✗|✓|✓|✗
279
+ delete_application|✓|✓|✓|✓
280
+ domains|✓|✓|✓|✓
281
+ domain|✓|✓|✓|✓
282
+ create_domain|✓|✓|✓|✓
283
+ delete_domain|✓|✓|✓|✓
284
+ env_vars|✓|✓|✓|✓
285
+ env_var|✓|✓|✓|✓
286
+ create_env_var|✓|✓|✓|✓
287
+ update_env_var|✓|✓|✓|✓
288
+ delete_env_var|✓|✓|✓|✓
289
+ start|✓|✓|✓|✓
290
+ stop|✗|✓|✓|✓
291
+ restart|✗|✓|✓|✓
292
+ deploy|✓|✓|✓|✓
293
+ rebuild|✓|✓|✓|✓
294
+ download|✓|✓|✓|✓
295
+ scale|✓|✓|✓|✓
296
+ log?|✓|✓|✓|✓
297
+ logs|✓|✓|✓|✓
298
+ log_entries|✓|✓|✓|✓
299
+ tail|✓|✓|✓|✗
300
+ services|✓|✓|✓|✓
301
+ service|✓|✓|✓|✓
302
+ service_plans|✓|✓|✓|✓
303
+ service_plan|✓|✓|✓|✓
304
+ installed_services|✓|✓|✓|✓
305
+ installed_service|✓|✓|✓|✓
306
+ add_service|✓|✓|✓|✓
307
+ change_service|✓|✓|✓|✗
308
+ remove_service|✓|✓|✓|✓
309
+
310
+ ### Core constructs
311
+
312
+ Nucleus could support any constellation of PaaS offers that are currently available.
313
+ In order to do so, we differentiate between three types:
314
+
315
+ The **vendor**, or the PaaS platform, which determines the functionality,
316
+ a **provider** that runs the vendor's platform and offers it to its customers and finally
317
+ the **endpoint** of the provider's offer.
318
+
319
+ For most scenarios the *endpoint* is identical to the *provider*, but in some cases,
320
+ for instance on [IBM Bluemix][bluemix], *endpoints* distinguish different deployment regions.
321
+
322
+ If running Nucleus as web service, all changes made to these entities at runtime will be discarded,
323
+ unless you enable the functionality in the configuration and specify a location where to persist the data to.
324
+
325
+ #### Vendors
326
+
327
+ You can use the API of Nucleus to show a list of all supported vendors.
328
+ This request is publicly available and does not require any authentication.
329
+
330
+ However, you can't create, delete or update a vendor at runtime because it represents the logic to communicate with the associated platform.
331
+ All developers that want to have more information on how to add a new vendor can take a look at the instructions: [Add a vendor (or implement a new adapter)](wiki/implement_new_adapter.md)
332
+
333
+ #### Providers and Endpoints
334
+
335
+ Providers and Endpoints can be managed *without authentication* and support `GET`, `POST`, `PATCH`, `DELETE` requests.
336
+
337
+ A new entity can be registered at runtime by sending a `POST` request.
338
+ Whereas a provider only requires a `name`, an endpoint also needs a further attribute, the `url`.
339
+ Please refer to the swagger-ui documentation for additional information about the requests.
340
+
341
+ ### Authentication
342
+
343
+ Authentication against the endpoint is managed by Nucleus.
344
+ The credentials must be provided as [Basic authentication](https://en.wikipedia.org/wiki/Basic_access_authentication) header **within each single request**.
345
+
346
+ Authorization: Basic thebase64encodedcredentialsstring
347
+
348
+ #### Special characters (umlauts, ...)
349
+
350
+ The usage of special characters, for instance german umlauts as ä, ö and ü may cause issues with some platforms.
351
+ Please make sure to select the correct encoding for your credentials before encoding them with base64:
352
+
353
+ * Stackato 3.4.2
354
+ * Different encodings cause the requests to crash and return status 500
355
+
356
+ ### Application logs
357
+
358
+ Below are some examples how to use the API in order to obtain detailed application logs.
359
+
360
+ #### Download a selected logfile of an application
361
+
362
+ ```shell
363
+ curl -X "GET" "http://localhost:9292/api/endpoints/cf-bosh-local/applications/{app_id}/logs/{log_id}/download" -H "Authorization: {auth_header}" -O -J
364
+ ```
365
+
366
+ #### Download all logfiles of an application
367
+
368
+ ```shell
369
+ curl -X "GET" "http://localhost:9292/api/endpoints/cf-bosh-local/applications/{app_id}/logs/download" -H "Authorization: {auth_header}" -O -J
370
+ ```
371
+
372
+ #### Tail a selected logfile of an application
373
+
374
+ ```shell
375
+ curl -X "GET" "http://localhost:9292/api/endpoints/cf-bosh-local/applications/{app_id}/logs/{log_id}/tail" -H "Authorization: {auth_header}" --raw -v
376
+ ```
377
+
378
+ ### Custom API calls (experimental)
379
+
380
+ Sometimes you might want to call proprietary functionality that goes beyond Nucleus' unified API approach.
381
+ You can also execute such custom API calls against the endpoint's API with Nucleus.
382
+ This feature is included as experimental functionality and **does not return unified objects or errors**.
383
+ The response of the API is passed 1:1 to the REST client.
384
+
385
+ The custom calls can be made either against the endpoint or against an application.
386
+ Allowed HTTP methods are `GET`, `POST`,`PATCH`, `PUT` and `DELETE`.
387
+ Data embedded in a requests body is used 1:1 in the API call, header information are going to be discarded.
388
+
389
+ Please be aware that you must also include the API version in the path if required by the platform.
390
+ For instance, Cloud Foundry requests would have to look like: `.../call/v2/app_usage_events`
391
+
392
+ ##### Execute a custom API call against the endpoint
393
+
394
+ In this example, we want to get the current user's account information.
395
+ Therefore, we append the `call` action to the endpoint, followed by the API's native path to the resource: `account`
396
+
397
+ ```
398
+ GET /api/endpoints/heroku/call/account
399
+ ```
400
+
401
+ ```json
402
+ {
403
+ "allow_tracking": true,
404
+ "beta": false,
405
+ "email": "theusersemail@provider.domain",
406
+ "id": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
407
+ "last_login": "2014-11-25T08:52:59Z",
408
+ "name": " ",
409
+ "two_factor_authentication": false,
410
+ "verified": false,
411
+ "created_at": "2014-11-18T09:37:21Z",
412
+ "updated_at": "2015-02-18T18:57:33Z",
413
+ "default_organization": null
414
+ }
415
+ ```
416
+
417
+ ##### Execute a custom API call against an endpoint's application
418
+
419
+ In this example we try to list the builds of an Heroku application.
420
+ Therefore, we append the `call` action to the application at the endpoint, followed by the API's native path to the resource: `builds`
421
+
422
+ ```
423
+ GET /api/endpoints/heroku/applications/the_application_name/call/builds
424
+ ```
425
+
426
+ The response is the unprocessed response of the Heroku API as shown in the previous example.
427
+
428
+ ## Adapters
429
+
430
+ The functionality to communicate with different platforms is implemented in so called *adapters*.
431
+ However, not each adapter can fully support the abstract Nucleus definitions.
432
+ Please refer to the [functionality section](#functionality) for more information about the supported features.
433
+
434
+ ### Heroku
435
+
436
+ Providers: [Heroku](http://heroku.com)
437
+
438
+ *No known issues*
439
+
440
+ ### Cloud Foundry v2
441
+
442
+ Providers: [AppFog][appfog], [Anynines][anynines], [IBM Bluemix][bluemix], [Pivotal Web Services][pivotal_ws], [HP Helion][hp_helion]
443
+
444
+ #### Issues
445
+
446
+ **Logs**
447
+
448
+ CF stopped to provide the `stdout` and `stderr` files in the `logs` directory.
449
+ Currently, we do not know of an approach to fetch recent log entries without registering an additional service on the application.
450
+
451
+ Moreover, logs can only be retrieved as long as at least once instance of the CF application is running, hence the application state is `running`.
452
+ If there are no logs that can be retrieved, the log list will be empty and the request for a particular log file will result in an 404 error.
453
+
454
+ **Services**
455
+
456
+ - As of now, we only allow bindable services and create a new instance of the service to add
457
+ - Therefore, services must be `active` and `bindable`
458
+ - Only one instance of the same service can be bound to the application
459
+
460
+ ### Openshift v2
461
+
462
+ Providers: [OpenShift Online][openshift_online], [getup Cloud][getup]
463
+
464
+ #### Issues
465
+
466
+ **Application update**
467
+
468
+ An application can't be updated, the `name` and `runtimes` can't be changed once created.
469
+
470
+ **Application scaling**
471
+
472
+ Applications not created with Nucleus can't be scaled if they were created with the attribute `scalable = false`
473
+
474
+ **Services**
475
+
476
+ - Services can be added to the application, but scaling (gears, memory allocation, ...) and
477
+ further configuration are not supported as of now.
478
+ - We focus on the `embedded` cartridges and omit `standalone` services such as *Jenkins*.
479
+ - With no service plans and therefore nothing to change, the *change service* function is not implemented.
480
+
481
+ **Performance**
482
+
483
+ Recording is really slow. Even worse, actions quite often fail with Openshift internal timeouts.
484
+
485
+ ### cloudControl
486
+
487
+ Providers: [cloudControl][cloudcontrol], [dotCloud][dotcloud], [Cloud&Heat App Elevator][cloud&heat], [exoscale Apps][exoscale]
488
+
489
+ #### Issues
490
+
491
+ **Application update**
492
+
493
+ An application can't be updated, the `name` and `runtimes` can't be changed once created.
494
+
495
+ **Application lifecycle**
496
+
497
+ Applications on cloudControl can't be explicitly stopped or restarted.
498
+ They start after a successful build of the application, which is therefore postponed to the first invocation of the start operation.
499
+ Applications only stop once the corresponding _deployment_ has been deleted.
500
+
501
+ **Logs**
502
+
503
+ Log messages, for instance the request entries, do not appear instantly in the log.
504
+ It may take some seconds or even minutes for them to show up.
505
+
506
+ ## Configuration
507
+
508
+ Several parts of Nucleus can be configured, e.g. whether to persist your data or always start with a clean instance.
509
+ There are two different locations at which the configuration files can be placed.
510
+ They are described with increasing importance, meaning that the last option overwrites keys that were also configured in the previous files:
511
+
512
+ 1. A file in user account's home directory. On UNIX systems this file must be placed at `~/.nucleus/nucleus_config.rb`, whereas it is expected at `~/nucleus/nucleus_config.rb` if running Windows.
513
+ 2. The `config/nucleus_config.rb` file in the project's directory
514
+
515
+ #### Database backend
516
+
517
+ The database backend can be specified in the `config/nucleus_config.rb` configuration file.
518
+ It defaults to [Daybreak](https://github.com/propublica/daybreak) on Unix systems and [LMDB](https://github.com/minad/lmdb) on Windows.
519
+
520
+ Note: *[Daybreak](https://github.com/propublica/daybreak) does not run on Windows*
521
+
522
+ ### Vendors, Providers, and Endpoints
523
+
524
+ A vendor is reflected by an adapter implementation, but the providers and their endpoints can either be changed at runtime or via `.yaml` configuration files.
525
+ These adapter configuration files are located in the project directory at `config/adapters`.
526
+
527
+ #### Add a new Provider
528
+
529
+ To add a new provider, open the `config/adapters` directory and select the platform that the provider is using.
530
+ For more explanations of the fields, or if the platform is not listed, please refer to the Guide [how to implement a new adapter)](wiki/implement_new_adapter.md).
531
+
532
+ Next, add your provider and its endpoint(s) to the configuration file.
533
+
534
+ ###### Example adapter configuration
535
+
536
+ ```yaml
537
+ ---
538
+ name: "Openshift 2"
539
+ id: "openshift_v2"
540
+ providers:
541
+ -
542
+ name: "Openshift Online"
543
+ id: "openshift-online"
544
+ endpoints:
545
+ -
546
+ name: "Openshift Online"
547
+ id: "openshift-online"
548
+ url: "openshift.redhat.com/broker/rest"
549
+ ```
550
+
551
+ ## API clients
552
+
553
+ The API can be used with the REST client of your choice.
554
+
555
+ ### Accept Header
556
+
557
+ Nucleus always uses the latest API version if no `Accept` header is specified.
558
+ We therefore **strongly encourage** you to always specify the `Accept` header.
559
+ The vendor thereby must be set to `nucleus` and the version must be available.
560
+ Otherwise an error with the HTTP status `406` is returned.
561
+ A sample `Accept` header would be:
562
+
563
+ ```
564
+ Accept = application/vnd.nucleus-v1
565
+ ```
566
+
567
+ ### Error codes
568
+
569
+ The application uses the following subset of error codes:
570
+
571
+ ```
572
+ 400: Bad Request
573
+ 401: Unauthorized
574
+ 404: Resource not found
575
+ 406: API vendor or version not found
576
+ 422: Unprocessable Entity due to invalid parameters
577
+ 500: Internal processing error
578
+ 501: Not implemented, adapter does not provide this feature
579
+ 503: Destination service temporarily unavailable
580
+ 504: Gateway Time-out
581
+ ```
582
+
583
+ All errors are returned in a common schema:
584
+
585
+ ```ruby
586
+ {
587
+ "status": HTTP_STATUS_CODE,
588
+ "message": SIMPLE_ERROR_MESSAGE,
589
+ "dev_message": DEVELOPER_MESSAGE_WITH_TECHNICAL_DETAILS_TO_RESOLUTION,
590
+ "error_code": UNIQUE_ERROR_CODE,
591
+ "more_info": LINK_TO_DOCUMENTATION_DESCRIBING_THE_ERROR
592
+ }
593
+ ```
594
+
595
+ ### Language-specific clients
596
+
597
+ As of now, there is no language-specific API client available.
598
+ As a reward of providing swagger-compatible API docs, clients can be generated for several languages.
599
+ For detailed information, please have a look at the [swagger-codegen project](https://github.com/swagger-api/swagger-codegen).
600
+
601
+ ## Tests
602
+
603
+ The tests are divided into 3 categories, _unit_, _integration_ and _adapter_ tests.
604
+ You can either call all tests or each suite separately.
605
+
606
+ ```
607
+ bundle exec rake spec
608
+ bundle exec rake spec:suite:unit
609
+ bundle exec rake spec:suite:integration
610
+ bundle exec rake spec:suite:adapters
611
+ ```
612
+
613
+ ## Schema validation
614
+
615
+ The generated schema can be validated against the [swagger specification](https://github.com/swagger-api/swagger-spec).
616
+ Please have a look at the [swagger-codegen project](https://github.com/swagger-api/swagger-codegen).
617
+
618
+ ## Versioning
619
+
620
+ Nucleus follows the [Semantic Versioning](http://semver.org/) standard.
621
+ Therefore, Nucleus also allows to serve multiple versions of the API and provide legacy support.
622
+
623
+ However, be aware that
624
+ __each non-backward compatible change of the application must result in an increase of the major version.__
625
+
626
+ Until the first release (v1), the initial version is: `0.1.0`.
627
+
628
+ ## Security
629
+
630
+ As described in the [HTTPS](#https) section, we strongly encourage you to only run Nucleus with HTTPS.
631
+
632
+ ### Public key registration
633
+
634
+ Nucleus uses the SSH key authentication for Git deployments.
635
+ The private (!) key that will be used is located at `config/nucleus_git_key.pem`.
636
+ Using the pre-generated key mitigates issues with the key usage/generation on various platforms.
637
+ To prevent abuse we register the key before each command and immediately remove the key once the command has been executed.
638
+
639
+ **To improve the security of your deployment, you can use your own custom private key.
640
+ To do so, set the `nucleus_config.ssh.custom_key` option in the [common configuration](#configuration) to the location of the private key file.
641
+ For reasons of automation, the key must not be password encrypted.**
642
+
643
+ ## Project structure
644
+
645
+ ```
646
+ bin # Binary startup files and GIT__SSH env. agents
647
+ config # Configuration files for Nucleus and its adapters
648
+ doc # Generated YARD documentation
649
+ lib # The Nucleus application source code
650
+ lib/nucleus # Gem compatible directory of the core, includes the AdapterResolver class
651
+ lib/nucleus/adapters # The adapter implementations to communicate with the vendor's platforms, grouped by API version.
652
+ lib/nucleus/core # All other functionality used throughout the application, but rather unrelated to the Grape API: http requests, authentication, errors, etc.
653
+ lib/nucleus/ext # Monkey patched classed and extensions
654
+ lib/nucleus/scripts # Initialization scripts, bootstrapping and shutdown hooks
655
+ lib/nucleus_api/api # Everything that is directly related to the RESTful Grape API: entities, embedded helpers and the actual API version's definitions
656
+ lib/nucleus_api/ext # Monkey patched classed and extensions related only to the API
657
+ lib/nucleus_api/import # Import management of the adapter configuration files
658
+ lib/nucleus_api/persistence # The persistence layer, including the DAOs and the entity's models (Vendor, Provider, Endpoint, ...)
659
+ lib/nucleus_api/rack_middleware # Rack middleware layers for authentication, request ids and logging
660
+ lib/nucleus_api/scripts # Initialization scripts, bootstrapping, rackup and shutdown hooks of the API
661
+ public # public directory for rack, hosts the swagger-ui files for the live API documentation
662
+ schemas # Kwalify schemas, used to parse the configuration and load new vendors at startup
663
+ spec # All rspec test suites
664
+ tasks # Rake tasks, mostly related to generate tables and statistics
665
+ wiki # Further documentation files
666
+ ```
667
+
668
+ ## Contributing
669
+
670
+ We love contributions from everyone! See our [contribution guidelines](CONTRIBUTING.md) for details.
671
+
672
+ ## Further documentation
673
+
674
+ - [Add a vendor (or implement a new adapter)](wiki/implement_new_adapter.md)
675
+ - [Adapter Tests](wiki/adapter_tests.md)