uffizzi_core 0.1.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (240) hide show
  1. checksums.yaml +7 -0
  2. data/LICENSE +201 -0
  3. data/README.md +46 -0
  4. data/Rakefile +31 -0
  5. data/app/assets/config/uffizzi_core_manifest.js +1 -0
  6. data/app/assets/stylesheets/uffizzi_core/application.css +15 -0
  7. data/app/clients/uffizzi_core/amazon_registry_client.rb +18 -0
  8. data/app/clients/uffizzi_core/azure_registry_client/request_result.rb +5 -0
  9. data/app/clients/uffizzi_core/azure_registry_client.rb +42 -0
  10. data/app/clients/uffizzi_core/controller_client/request_result.rb +5 -0
  11. data/app/clients/uffizzi_core/controller_client.rb +106 -0
  12. data/app/clients/uffizzi_core/docker_hub_client/request_result.rb +7 -0
  13. data/app/clients/uffizzi_core/docker_hub_client.rb +139 -0
  14. data/app/clients/uffizzi_core/github/app_client.rb +19 -0
  15. data/app/clients/uffizzi_core/github/installation_client.rb +11 -0
  16. data/app/clients/uffizzi_core/github/user_client.rb +51 -0
  17. data/app/clients/uffizzi_core/google_registry_client/request_result.rb +5 -0
  18. data/app/clients/uffizzi_core/google_registry_client.rb +42 -0
  19. data/app/contexts/uffizzi_core/base_context.rb +12 -0
  20. data/app/contexts/uffizzi_core/project_context.rb +13 -0
  21. data/app/contexts/uffizzi_core/webhooks_context.rb +9 -0
  22. data/app/controllers/concerns/uffizzi_core/auth_management.rb +23 -0
  23. data/app/controllers/concerns/uffizzi_core/authorization_concern.rb +38 -0
  24. data/app/controllers/concerns/uffizzi_core/dependency_injection_concern.rb +19 -0
  25. data/app/controllers/uffizzi_core/api/cli/v1/account/application_controller.rb +7 -0
  26. data/app/controllers/uffizzi_core/api/cli/v1/account/credentials_controller.rb +55 -0
  27. data/app/controllers/uffizzi_core/api/cli/v1/application_controller.rb +5 -0
  28. data/app/controllers/uffizzi_core/api/cli/v1/projects/application_controller.rb +11 -0
  29. data/app/controllers/uffizzi_core/api/cli/v1/projects/compose_files_controller.rb +93 -0
  30. data/app/controllers/uffizzi_core/api/cli/v1/projects/deployments/activity_items_controller.rb +36 -0
  31. data/app/controllers/uffizzi_core/api/cli/v1/projects/deployments/application_controller.rb +7 -0
  32. data/app/controllers/uffizzi_core/api/cli/v1/projects/deployments/containers/application_controller.rb +8 -0
  33. data/app/controllers/uffizzi_core/api/cli/v1/projects/deployments/containers/logs_controller.rb +27 -0
  34. data/app/controllers/uffizzi_core/api/cli/v1/projects/deployments/containers_controller.rb +24 -0
  35. data/app/controllers/uffizzi_core/api/cli/v1/projects/deployments/events_controller.rb +29 -0
  36. data/app/controllers/uffizzi_core/api/cli/v1/projects/deployments_controller.rb +148 -0
  37. data/app/controllers/uffizzi_core/api/cli/v1/projects/secrets_controller.rb +69 -0
  38. data/app/controllers/uffizzi_core/api/cli/v1/projects_controller.rb +19 -0
  39. data/app/controllers/uffizzi_core/api/cli/v1/sessions_controller.rb +43 -0
  40. data/app/controllers/uffizzi_core/application_controller.rb +51 -0
  41. data/app/errors/uffizzi_core/compose_file/build_error.rb +4 -0
  42. data/app/errors/uffizzi_core/compose_file/credential_error.rb +4 -0
  43. data/app/errors/uffizzi_core/compose_file/not_found_error.rb +4 -0
  44. data/app/errors/uffizzi_core/compose_file/parse_error.rb +4 -0
  45. data/app/errors/uffizzi_core/compose_file/secrets_error.rb +4 -0
  46. data/app/errors/uffizzi_core/deployment_not_found_error.rb +10 -0
  47. data/app/forms/uffizzi_core/api/cli/v1/account/credential/create_form.rb +26 -0
  48. data/app/forms/uffizzi_core/api/cli/v1/compose_file/check_credentials_form.rb +21 -0
  49. data/app/forms/uffizzi_core/api/cli/v1/compose_file/cli_form.rb +39 -0
  50. data/app/forms/uffizzi_core/api/cli/v1/compose_file/create_form.rb +13 -0
  51. data/app/forms/uffizzi_core/api/cli/v1/compose_file/template_form.rb +44 -0
  52. data/app/forms/uffizzi_core/api/cli/v1/compose_file/update_form.rb +9 -0
  53. data/app/forms/uffizzi_core/api/cli/v1/config_file/create_form.rb +11 -0
  54. data/app/forms/uffizzi_core/api/cli/v1/deployment/create_form.rb +91 -0
  55. data/app/forms/uffizzi_core/api/cli/v1/project/delete_secret_form.rb +27 -0
  56. data/app/forms/uffizzi_core/api/cli/v1/project/update_form.rb +40 -0
  57. data/app/forms/uffizzi_core/api/cli/v1/session_create_form.rb +29 -0
  58. data/app/forms/uffizzi_core/api/cli/v1/template/create_form.rb +65 -0
  59. data/app/forms/uffizzi_core/application_form.rb +11 -0
  60. data/app/forms/uffizzi_core/application_form_without_active_record.rb +17 -0
  61. data/app/forms/uffizzi_core/mass_assignment_control_concern.rb +22 -0
  62. data/app/helpers/uffizzi_core/application_helper.rb +6 -0
  63. data/app/jobs/uffizzi_core/account/create_credential_job.rb +10 -0
  64. data/app/jobs/uffizzi_core/activity_item/docker/update_digest_job.rb +11 -0
  65. data/app/jobs/uffizzi_core/application_job.rb +7 -0
  66. data/app/jobs/uffizzi_core/config_file/apply_job.rb +31 -0
  67. data/app/jobs/uffizzi_core/credential/docker_hub/create_webhook_job.rb +15 -0
  68. data/app/jobs/uffizzi_core/deployment/create_credential_job.rb +32 -0
  69. data/app/jobs/uffizzi_core/deployment/create_credentials_job.rb +17 -0
  70. data/app/jobs/uffizzi_core/deployment/create_job.rb +15 -0
  71. data/app/jobs/uffizzi_core/deployment/create_webhooks_job.rb +13 -0
  72. data/app/jobs/uffizzi_core/deployment/delete_credential_job.rb +13 -0
  73. data/app/jobs/uffizzi_core/deployment/delete_job.rb +11 -0
  74. data/app/jobs/uffizzi_core/deployment/deploy_containers_job.rb +27 -0
  75. data/app/jobs/uffizzi_core/deployment/manage_deploy_activity_item_job.rb +19 -0
  76. data/app/jobs/uffizzi_core/deployment/send_github_preview_message_job.rb +13 -0
  77. data/app/lib/uffizzi_core/rbac/user_access_service.rb +21 -0
  78. data/app/mailers/uffizzi_core/application_mailer.rb +8 -0
  79. data/app/models/concerns/uffizzi_core/hashid_concern.rb +25 -0
  80. data/app/models/concerns/uffizzi_core/state_machine_concern.rb +16 -0
  81. data/app/models/uffizzi_core/account.rb +101 -0
  82. data/app/models/uffizzi_core/activity_item/docker.rb +4 -0
  83. data/app/models/uffizzi_core/activity_item/github.rb +4 -0
  84. data/app/models/uffizzi_core/activity_item/memory_limit.rb +4 -0
  85. data/app/models/uffizzi_core/activity_item.rb +58 -0
  86. data/app/models/uffizzi_core/application_record.rb +7 -0
  87. data/app/models/uffizzi_core/build.rb +39 -0
  88. data/app/models/uffizzi_core/comment.rb +16 -0
  89. data/app/models/uffizzi_core/compose_file.rb +57 -0
  90. data/app/models/uffizzi_core/config_file.rb +24 -0
  91. data/app/models/uffizzi_core/container.rb +100 -0
  92. data/app/models/uffizzi_core/container_config_file.rb +8 -0
  93. data/app/models/uffizzi_core/continuous_preview.rb +4 -0
  94. data/app/models/uffizzi_core/coupon.rb +5 -0
  95. data/app/models/uffizzi_core/credential/amazon.rb +4 -0
  96. data/app/models/uffizzi_core/credential/azure.rb +4 -0
  97. data/app/models/uffizzi_core/credential/docker_hub.rb +4 -0
  98. data/app/models/uffizzi_core/credential/github.rb +4 -0
  99. data/app/models/uffizzi_core/credential/google.rb +4 -0
  100. data/app/models/uffizzi_core/credential.rb +64 -0
  101. data/app/models/uffizzi_core/database.rb +4 -0
  102. data/app/models/uffizzi_core/database_offering.rb +4 -0
  103. data/app/models/uffizzi_core/deployment.rb +77 -0
  104. data/app/models/uffizzi_core/event.rb +13 -0
  105. data/app/models/uffizzi_core/invitation.rb +27 -0
  106. data/app/models/uffizzi_core/membership.rb +16 -0
  107. data/app/models/uffizzi_core/payment.rb +11 -0
  108. data/app/models/uffizzi_core/price.rb +9 -0
  109. data/app/models/uffizzi_core/product.rb +11 -0
  110. data/app/models/uffizzi_core/project.rb +66 -0
  111. data/app/models/uffizzi_core/rating.rb +20 -0
  112. data/app/models/uffizzi_core/repo/amazon.rb +4 -0
  113. data/app/models/uffizzi_core/repo/azure.rb +4 -0
  114. data/app/models/uffizzi_core/repo/docker_hub.rb +4 -0
  115. data/app/models/uffizzi_core/repo/github.rb +4 -0
  116. data/app/models/uffizzi_core/repo/google.rb +4 -0
  117. data/app/models/uffizzi_core/repo.rb +39 -0
  118. data/app/models/uffizzi_core/role.rb +17 -0
  119. data/app/models/uffizzi_core/template.rb +19 -0
  120. data/app/models/uffizzi_core/user.rb +62 -0
  121. data/app/models/uffizzi_core/user_project.rb +14 -0
  122. data/app/policies/uffizzi_core/api/cli/v1/account/credentials_policy.rb +11 -0
  123. data/app/policies/uffizzi_core/api/cli/v1/projects/compose_files_policy.rb +15 -0
  124. data/app/policies/uffizzi_core/api/cli/v1/projects/deployments/activity_items_policy.rb +7 -0
  125. data/app/policies/uffizzi_core/api/cli/v1/projects/deployments/containers_policy.rb +7 -0
  126. data/app/policies/uffizzi_core/api/cli/v1/projects/deployments/events_policy.rb +7 -0
  127. data/app/policies/uffizzi_core/api/cli/v1/projects/deployments_policy.rb +23 -0
  128. data/app/policies/uffizzi_core/api/cli/v1/projects/secrets_policy.rb +15 -0
  129. data/app/policies/uffizzi_core/api/cli/v1/projects_policy.rb +7 -0
  130. data/app/policies/uffizzi_core/application_policy.rb +12 -0
  131. data/app/repositories/uffizzi_core/activity_item_repo.rb +9 -0
  132. data/app/repositories/uffizzi_core/basic_order_repo.rb +11 -0
  133. data/app/repositories/uffizzi_core/build_repo.rb +23 -0
  134. data/app/repositories/uffizzi_core/comment_repo.rb +11 -0
  135. data/app/repositories/uffizzi_core/compose_file_repo.rb +11 -0
  136. data/app/repositories/uffizzi_core/config_file_repo.rb +40 -0
  137. data/app/repositories/uffizzi_core/container_repo.rb +25 -0
  138. data/app/repositories/uffizzi_core/credential_repo.rb +36 -0
  139. data/app/repositories/uffizzi_core/deployment_repo.rb +23 -0
  140. data/app/repositories/uffizzi_core/event_repo.rb +9 -0
  141. data/app/repositories/uffizzi_core/membership_repo.rb +10 -0
  142. data/app/repositories/uffizzi_core/price_repo.rb +11 -0
  143. data/app/repositories/uffizzi_core/product_repo.rb +11 -0
  144. data/app/repositories/uffizzi_core/project_repo.rb +10 -0
  145. data/app/repositories/uffizzi_core/repo_repo.rb +10 -0
  146. data/app/repositories/uffizzi_core/template_repo.rb +87 -0
  147. data/app/repositories/uffizzi_core/usage_repo.rb +9 -0
  148. data/app/repositories/uffizzi_core/user_repo.rb +11 -0
  149. data/app/responders/uffizzi_core/json_responder.rb +13 -0
  150. data/app/serializers/uffizzi_core/api/cli/v1/account/credential_serializer.rb +9 -0
  151. data/app/serializers/uffizzi_core/api/cli/v1/project_serializer.rb +7 -0
  152. data/app/serializers/uffizzi_core/api/cli/v1/projects/compose_file_serializer.rb +7 -0
  153. data/app/serializers/uffizzi_core/api/cli/v1/projects/deployment_serializer/container_serializer.rb +23 -0
  154. data/app/serializers/uffizzi_core/api/cli/v1/projects/deployment_serializer/user_serializer.rb +11 -0
  155. data/app/serializers/uffizzi_core/api/cli/v1/projects/deployment_serializer.rb +74 -0
  156. data/app/serializers/uffizzi_core/api/cli/v1/projects/deployments/activity_item_serializer.rb +24 -0
  157. data/app/serializers/uffizzi_core/api/cli/v1/projects/deployments/container_serializer/container_config_file_serializer/config_file_serializer.rb +6 -0
  158. data/app/serializers/uffizzi_core/api/cli/v1/projects/deployments/container_serializer/container_config_file_serializer.rb +7 -0
  159. data/app/serializers/uffizzi_core/api/cli/v1/projects/deployments/container_serializer.rb +30 -0
  160. data/app/serializers/uffizzi_core/api/cli/v1/user_serializer/account_serializer.rb +5 -0
  161. data/app/serializers/uffizzi_core/api/cli/v1/user_serializer.rb +7 -0
  162. data/app/serializers/uffizzi_core/base_serializer.rb +7 -0
  163. data/app/serializers/uffizzi_core/controller/create_credential/credential_serializer.rb +17 -0
  164. data/app/serializers/uffizzi_core/controller/create_deployment/deployment_serializer.rb +5 -0
  165. data/app/serializers/uffizzi_core/controller/deploy_containers/container_serializer.rb +53 -0
  166. data/app/serializers/uffizzi_core/controller/deploy_containers/credential_serializer.rb +5 -0
  167. data/app/services/uffizzi_core/account_service.rb +21 -0
  168. data/app/services/uffizzi_core/activity_item_service.rb +98 -0
  169. data/app/services/uffizzi_core/amazon/credential_service.rb +31 -0
  170. data/app/services/uffizzi_core/amazon_service.rb +45 -0
  171. data/app/services/uffizzi_core/azure/credential_service.rb +18 -0
  172. data/app/services/uffizzi_core/cli/compose_file_service.rb +203 -0
  173. data/app/services/uffizzi_core/compose_file/builders/config_files_builder_service.rb +31 -0
  174. data/app/services/uffizzi_core/compose_file/builders/container_builder_service.rb +225 -0
  175. data/app/services/uffizzi_core/compose_file/builders/docker_repo_builder_service.rb +25 -0
  176. data/app/services/uffizzi_core/compose_file/builders/github_repo_builder_service.rb +59 -0
  177. data/app/services/uffizzi_core/compose_file/builders/template_builder_service.rb +45 -0
  178. data/app/services/uffizzi_core/compose_file/builders/variables_builder_service.rb +58 -0
  179. data/app/services/uffizzi_core/compose_file/config_files_service.rb +52 -0
  180. data/app/services/uffizzi_core/compose_file/config_option_service.rb +37 -0
  181. data/app/services/uffizzi_core/compose_file/configs_options_service.rb +26 -0
  182. data/app/services/uffizzi_core/compose_file/container_service.rb +64 -0
  183. data/app/services/uffizzi_core/compose_file/continuous_preview_options_service.rb +57 -0
  184. data/app/services/uffizzi_core/compose_file/dependencies_service.rb +55 -0
  185. data/app/services/uffizzi_core/compose_file/errors_service.rb +46 -0
  186. data/app/services/uffizzi_core/compose_file/github_dependencies_service.rb +38 -0
  187. data/app/services/uffizzi_core/compose_file/ingress_options_service.rb +49 -0
  188. data/app/services/uffizzi_core/compose_file/secrets_options_service.rb +28 -0
  189. data/app/services/uffizzi_core/compose_file/services_options/build_service.rb +93 -0
  190. data/app/services/uffizzi_core/compose_file/services_options/command_service.rb +18 -0
  191. data/app/services/uffizzi_core/compose_file/services_options/configs_service.rb +51 -0
  192. data/app/services/uffizzi_core/compose_file/services_options/deploy_service.rb +44 -0
  193. data/app/services/uffizzi_core/compose_file/services_options/entrypoint_service.rb +18 -0
  194. data/app/services/uffizzi_core/compose_file/services_options/env_file_service.rb +34 -0
  195. data/app/services/uffizzi_core/compose_file/services_options/environment_service.rb +20 -0
  196. data/app/services/uffizzi_core/compose_file/services_options/image_service.rb +89 -0
  197. data/app/services/uffizzi_core/compose_file/services_options/secrets_service.rb +35 -0
  198. data/app/services/uffizzi_core/compose_file/services_options_service.rb +55 -0
  199. data/app/services/uffizzi_core/compose_file/template_service.rb +55 -0
  200. data/app/services/uffizzi_core/compose_file/update_service.rb +29 -0
  201. data/app/services/uffizzi_core/compose_file/variables_service.rb +25 -0
  202. data/app/services/uffizzi_core/compose_file_service.rb +33 -0
  203. data/app/services/uffizzi_core/container_service.rb +57 -0
  204. data/app/services/uffizzi_core/controller_service.rb +80 -0
  205. data/app/services/uffizzi_core/credential_service.rb +44 -0
  206. data/app/services/uffizzi_core/deployment_service.rb +274 -0
  207. data/app/services/uffizzi_core/docker_hub/credential_service.rb +15 -0
  208. data/app/services/uffizzi_core/docker_hub_service.rb +77 -0
  209. data/app/services/uffizzi_core/github/app_service.rb +51 -0
  210. data/app/services/uffizzi_core/github/credential_service.rb +124 -0
  211. data/app/services/uffizzi_core/github/message_service.rb +20 -0
  212. data/app/services/uffizzi_core/github_service.rb +28 -0
  213. data/app/services/uffizzi_core/google/credential_service.rb +18 -0
  214. data/app/services/uffizzi_core/logs_service.rb +33 -0
  215. data/app/services/uffizzi_core/manage_activity_items_service.rb +166 -0
  216. data/app/services/uffizzi_core/project_service.rb +38 -0
  217. data/app/services/uffizzi_core/repo_service.rb +178 -0
  218. data/app/services/uffizzi_core/response_service.rb +13 -0
  219. data/app/services/uffizzi_core/template_service.rb +21 -0
  220. data/app/services/uffizzi_core/token_service.rb +19 -0
  221. data/app/services/uffizzi_core/user_access_service.rb +14 -0
  222. data/app/utils/uffizzi_core/converters.rb +33 -0
  223. data/app/validators/uffizzi_core/email_validator.rb +9 -0
  224. data/app/validators/uffizzi_core/environment_variable_list_validator.rb +15 -0
  225. data/app/validators/uffizzi_core/image_command_args_validator.rb +21 -0
  226. data/config/initializers/rswag_api.rb +15 -0
  227. data/config/initializers/rswag_ui.rb +15 -0
  228. data/config/initializers/swagger_yard.rb +17 -0
  229. data/config/locales/en.activerecord.yml +18 -0
  230. data/config/locales/en.yml +61 -0
  231. data/config/routes.rb +55 -0
  232. data/db/migrate/20220218121438_create_uffizzi_core_tables.rb +375 -0
  233. data/db/migrate/20220325113342_add_name_to_uffizzi_containers.rb +7 -0
  234. data/db/seeds.rb +16 -0
  235. data/lib/tasks/uffizzi_core_tasks.rake +14 -0
  236. data/lib/uffizzi_core/engine.rb +15 -0
  237. data/lib/uffizzi_core/version.rb +5 -0
  238. data/lib/uffizzi_core.rb +60 -0
  239. data/swagger/v1/swagger.json +1278 -0
  240. metadata +935 -0
@@ -0,0 +1,51 @@
1
+ # frozen_string_literal: true
2
+
3
+ class UffizziCore::Github::UserClient
4
+ PER_PAGE = 100
5
+
6
+ def initialize(access_token, per_page = PER_PAGE)
7
+ @client = Octokit::Client.new(access_token: access_token, per_page: per_page)
8
+ end
9
+
10
+ def contents?(repository_id, params)
11
+ @client.contents?(repository_id, params)
12
+ end
13
+
14
+ def contents(repository_id, options)
15
+ @client.contents(repository_id, options)
16
+ end
17
+
18
+ def user_installations
19
+ response = @client.find_user_installations
20
+
21
+ response[:installations]
22
+ end
23
+
24
+ def installation_repositories(installation_id, repo_attributes)
25
+ response = @client.find_installation_repositories_for_user(installation_id, repo_attributes)
26
+
27
+ response[:repositories]
28
+ end
29
+
30
+ def branch(repository_id, branch)
31
+ @client.branch(repository_id, branch)
32
+ end
33
+
34
+ def commit(repository_id, commit_sha)
35
+ response = @client.commit(repository_id, commit_sha)
36
+
37
+ response[:commit]
38
+ end
39
+
40
+ def branches(repository_id)
41
+ @client.branches(repository_id)
42
+ end
43
+
44
+ def repo(repository_id)
45
+ @client.repo(repository_id)
46
+ end
47
+
48
+ def search_repositories(query)
49
+ @client.search_repositories(query)
50
+ end
51
+ end
@@ -0,0 +1,5 @@
1
+ # frozen_string_literal: true
2
+
3
+ class UffizziCore::GoogleRegistryClient::RequestResult < Hashie::Mash
4
+ disable_warnings :key
5
+ end
@@ -0,0 +1,42 @@
1
+ # frozen_string_literal: true
2
+
3
+ class UffizziCore::GoogleRegistryClient
4
+ attr_accessor :connection, :token, :registry_url
5
+
6
+ def initialize(registry_url:, username:, password:)
7
+ @registry_url = registry_url
8
+ @connection = build_connection(registry_url, username, password)
9
+ @token = access_token&.result&.token
10
+ end
11
+
12
+ def manifests(image:, tag:)
13
+ url = "/v2/#{image}/manifests/#{tag}"
14
+ response = connection.get(url)
15
+
16
+ RequestResult.quiet.new(result: response.body, headers: response.headers)
17
+ end
18
+
19
+ def access_token
20
+ service = URI.parse(registry_url).hostname
21
+ url = "/v2/token?service=#{service}"
22
+
23
+ response = connection.get(url, {})
24
+
25
+ RequestResult.new(result: response.body)
26
+ end
27
+
28
+ def authentificated?
29
+ token.present?
30
+ end
31
+
32
+ private
33
+
34
+ def build_connection(registry_url, username, password)
35
+ Faraday.new(registry_url) do |conn|
36
+ conn.request(:basic_auth, username, password)
37
+ conn.request(:json)
38
+ conn.response(:json)
39
+ conn.adapter(Faraday.default_adapter)
40
+ end
41
+ end
42
+ end
@@ -0,0 +1,12 @@
1
+ # frozen_string_literal: true
2
+
3
+ class UffizziCore::BaseContext
4
+ attr_reader :user, :user_access_module, :params, :account
5
+
6
+ def initialize(user, user_access_module, params)
7
+ @user = user
8
+ @user_access_module = user_access_module
9
+ @account = user.organizational_account
10
+ @params = params
11
+ end
12
+ end
@@ -0,0 +1,13 @@
1
+ # frozen_string_literal: true
2
+
3
+ class UffizziCore::ProjectContext
4
+ attr_reader :user, :user_access_module, :project, :account, :params
5
+
6
+ def initialize(user, user_access_module, project, params)
7
+ @user = user
8
+ @user_access_module = user_access_module
9
+ @account = user.organizational_account
10
+ @project = project
11
+ @params = params
12
+ end
13
+ end
@@ -0,0 +1,9 @@
1
+ # frozen_string_literal: true
2
+
3
+ class UffizziCore::WebhooksContext
4
+ attr_reader :request
5
+
6
+ def initialize(request)
7
+ @request = request
8
+ end
9
+ end
@@ -0,0 +1,23 @@
1
+ # frozen_string_literal: true
2
+
3
+ module UffizziCore::AuthManagement
4
+ def sign_in(user)
5
+ session[:user_id] = user.id
6
+ end
7
+
8
+ def sign_out
9
+ session[:user_id] = @current_user = nil
10
+ end
11
+
12
+ def signed_in?
13
+ session[:user_id].present? && current_user.present?
14
+ end
15
+
16
+ def current_user
17
+ @current_user ||= UffizziCore::User.find_by(id: session[:user_id])
18
+ end
19
+
20
+ def authenticate_request!
21
+ current_user ? true : head(:unauthorized)
22
+ end
23
+ end
@@ -0,0 +1,38 @@
1
+ # frozen_string_literal: true
2
+
3
+ module UffizziCore::AuthorizationConcern
4
+ extend ActiveSupport::Concern
5
+
6
+ included do
7
+ before_action :init_authorize
8
+ end
9
+
10
+ def init_authorize
11
+ return unless self.class.ancestors.include?(UffizziCore::ApplicationController)
12
+
13
+ self.class.send(:define_method, policy_method_name) { send(:authorize, policy_method_params) }
14
+ end
15
+
16
+ def pundit_user
17
+ policy_context
18
+ end
19
+
20
+ private
21
+
22
+ def policy_method_name
23
+ [:authorize, policy_name].join('_')
24
+ end
25
+
26
+ def policy_name
27
+ controller_class = self.class.to_s
28
+
29
+ controller_class.gsub(/::|Controller/, '').underscore
30
+ end
31
+
32
+ def policy_method_params
33
+ controller_class = self.class.to_s
34
+
35
+ params = controller_class.gsub(/Controller/, '').split('::')
36
+ params.map(&:underscore).map(&:downcase).map(&:to_sym)
37
+ end
38
+ end
@@ -0,0 +1,19 @@
1
+ # frozen_string_literal: true
2
+
3
+ module UffizziCore::DependencyInjectionConcern
4
+ def user_access_module
5
+ return unless module_exists?(:rbac)
6
+
7
+ UffizziCore::UserAccessService.new(module_class(:rbac))
8
+ end
9
+
10
+ private
11
+
12
+ def module_exists?(module_name)
13
+ module_class(module_name).present?
14
+ end
15
+
16
+ def module_class(module_name)
17
+ UffizziCore.dependencies[module_name]&.constantize
18
+ end
19
+ end
@@ -0,0 +1,7 @@
1
+ # frozen_string_literal: true
2
+
3
+ class UffizziCore::Api::Cli::V1::Account::ApplicationController < UffizziCore::Api::Cli::V1::ApplicationController
4
+ def resource_account
5
+ @resource_account ||= current_user.organizational_account
6
+ end
7
+ end
@@ -0,0 +1,55 @@
1
+ # frozen_string_literal: true
2
+
3
+ # @resource Account/Credential
4
+ class UffizziCore::Api::Cli::V1::Account::CredentialsController < UffizziCore::Api::Cli::V1::Account::ApplicationController
5
+ before_action :authorize_uffizzi_core_api_cli_v1_account_credentials
6
+
7
+ # rubocop:disable Layout/LineLength
8
+ # Create account credential
9
+ #
10
+ # @path [POST] /api/cli/v1/account/credentials
11
+ #
12
+ # @parameter credential(required,body) [object<username:string, password: string, type:string>]
13
+ # @response [object<id:integer, username:string, password:string, type:string, state:string>] 201 Created successfully
14
+ # @response [object<errors>] 422 Unprocessable entity
15
+ #
16
+ # @example
17
+ # type can be one of UffizziCore::Credential::Amazon, UffizziCore::Credential::Azure, UffizziCore::Credential::DockerHub, UffizziCore::Credential::Google
18
+ # rubocop:enable Layout/LineLength
19
+ def create
20
+ credential_form = UffizziCore::Api::Cli::V1::Account::Credential::CreateForm.new
21
+ credential_form.assign_attributes(credential_params)
22
+ credential_form.account = resource_account
23
+ credential_form.registry_url = Settings.docker_hub.registry_url if credential_form.docker_hub?
24
+ if credential_form.google?
25
+ credential_form.registry_url = Settings.google.registry_url
26
+ credential_form.username = '_json_key'
27
+ end
28
+ credential_form.activate
29
+
30
+ if credential_form.save
31
+ UffizziCore::Account::CreateCredentialJob.perform_async(credential_form.id)
32
+ end
33
+
34
+ respond_with credential_form
35
+ end
36
+
37
+ # Delete account credential
38
+ #
39
+ # @path [DELETE] /api/cli/v1/account/credentials/{type}
40
+ #
41
+ # @parameter type(required,path) [string] Type of the credential
42
+ # @response 204 No Content
43
+ # @response 401 Not authorized
44
+ # @response [object<errors: object<title: string>>] 404 Not found
45
+ def destroy
46
+ credential = resource_account.credentials.find_by!(type: params[:type])
47
+ credential.destroy
48
+ end
49
+
50
+ private
51
+
52
+ def credential_params
53
+ params.require(:credential)
54
+ end
55
+ end
@@ -0,0 +1,5 @@
1
+ # frozen_string_literal: true
2
+
3
+ class UffizziCore::Api::Cli::V1::ApplicationController < UffizziCore::ApplicationController
4
+ before_action :authenticate_request!
5
+ end
@@ -0,0 +1,11 @@
1
+ # frozen_string_literal: true
2
+
3
+ class UffizziCore::Api::Cli::V1::Projects::ApplicationController < UffizziCore::Api::Cli::V1::ApplicationController
4
+ def resource_project
5
+ @resource_project ||= current_user.projects.find_by!(slug: params[:project_slug])
6
+ end
7
+
8
+ def policy_context
9
+ UffizziCore::ProjectContext.new(current_user, user_access_module, resource_project, params)
10
+ end
11
+ end
@@ -0,0 +1,93 @@
1
+ # frozen_string_literal: true
2
+
3
+ # @resource ComposeFile
4
+ class UffizziCore::Api::Cli::V1::Projects::ComposeFilesController < UffizziCore::Api::Cli::V1::Projects::ApplicationController
5
+ before_action :authorize_uffizzi_core_api_cli_v1_projects_compose_files
6
+
7
+ # Get the compose file for the project
8
+ #
9
+ # @path [GET] /api/cli/v1/projects/{project_slug}/compose_file
10
+ #
11
+ # @parameter project_slug(required,path) [string] The project slug
12
+ #
13
+ # @response [ComposeFile] 200 OK
14
+ # @response 401 Not authorized
15
+ # @response [object<errors: object<title: string>>] 404 Not found
16
+ def show
17
+ respond_with compose_file
18
+ end
19
+
20
+ # Create a compose file for the project
21
+ #
22
+ # @path [POST] /api/cli/v1/projects/{project_slug}/compose_file
23
+ #
24
+ # @parameter project_slug(required,path) [string] The project slug
25
+ # @parameter params(required,body) [object <
26
+ # compose_file: object<path: string, source: string, content: string>,
27
+ # dependencies: Array<object<path: string, source: string, content: string>>>]
28
+ #
29
+ # @response [ComposeFile] 201 OK
30
+ # @response 422 A compose file already exists for this project
31
+ # @response [ComposeFile] 422 Invalid compose file
32
+ # @response 401 Not authorized
33
+ def create
34
+ params = {
35
+ project: resource_project,
36
+ user: current_user,
37
+ compose_file_params: compose_file_params,
38
+ dependencies: dependencies_params[:dependencies] || [],
39
+ }
40
+
41
+ compose_file_form, errors = create_or_update_compose_file(params)
42
+ return render_errors(errors) if errors.present?
43
+
44
+ respond_with compose_file_form
45
+ end
46
+
47
+ # Delete the compose file for the project
48
+ #
49
+ # @path [DELETE] /api/cli/v1/projects/{project_slug}/compose_file
50
+ #
51
+ # @parameter project_slug(required,path) [string] The project slug
52
+ #
53
+ # @response 204 No Content
54
+ # @response 401 Not authorized
55
+ def destroy
56
+ compose_file.destroy
57
+
58
+ head :no_content
59
+ end
60
+
61
+ private
62
+
63
+ def compose_file
64
+ compose_file = resource_project.compose_file
65
+ raise ActiveRecord::RecordNotFound if compose_file.blank?
66
+
67
+ compose_file
68
+ end
69
+
70
+ def compose_file_params
71
+ params.require(:compose_file)
72
+ end
73
+
74
+ def dependencies_params
75
+ params.permit(dependencies: [:name, :path, :source, :content])
76
+ end
77
+
78
+ def create_or_update_compose_file(params)
79
+ existing_compose_file = resource_project.compose_file
80
+ if existing_compose_file.present?
81
+ UffizziCore::Cli::ComposeFileService.update(existing_compose_file, params)
82
+ else
83
+ kind = UffizziCore::ComposeFile.kind.main
84
+ UffizziCore::Cli::ComposeFileService.create(params, kind)
85
+ end
86
+ end
87
+
88
+ def render_errors(errors)
89
+ json = { errors: errors }
90
+
91
+ render json: json, status: :unprocessable_entity
92
+ end
93
+ end
@@ -0,0 +1,36 @@
1
+ # frozen_string_literal: true
2
+
3
+ class UffizziCore::Api::Cli::V1::Projects::Deployments::ActivityItemsController <
4
+ UffizziCore::Api::Cli::V1::Projects::Deployments::ApplicationController
5
+ before_action :authorize_uffizzi_core_api_cli_v1_projects_deployments_activity_items
6
+
7
+ # Get activity items for a deployment
8
+ #
9
+ # @path [GET] /api/cli/v1/projects/{project_slug}/deployment/{deployment_id}/actiivity_items
10
+ #
11
+ # @parameter project_slug(required,path) [string] The project slug
12
+ # @parameter deployment_d(required,path) [integer] The id of the deployment
13
+ #
14
+ # @response [ActivtyItem] 200 OK
15
+ # @response 401 Not authorized
16
+ # @response 404 Not found
17
+ def index
18
+ activity_items = resource_deployment
19
+ .activity_items
20
+ .page(page)
21
+ .per(per_page)
22
+ .order(updated_at: :desc)
23
+ .ransack(q_param)
24
+ .result
25
+
26
+ meta = meta(activity_items)
27
+ activity_items = activity_items.map do |activity_item|
28
+ UffizziCore::Api::Cli::V1::Projects::Deployments::ActivityItemSerializer.new(activity_item).as_json
29
+ end
30
+
31
+ render json: {
32
+ activity_items: activity_items,
33
+ meta: meta,
34
+ }
35
+ end
36
+ end
@@ -0,0 +1,7 @@
1
+ # frozen_string_literal: true
2
+
3
+ class UffizziCore::Api::Cli::V1::Projects::Deployments::ApplicationController < UffizziCore::Api::Cli::V1::Projects::ApplicationController
4
+ def resource_deployment
5
+ @resource_deployment ||= resource_project.deployments.find(params[:deployment_id])
6
+ end
7
+ end
@@ -0,0 +1,8 @@
1
+ # frozen_string_literal: true
2
+
3
+ class UffizziCore::Api::Cli::V1::Projects::Deployments::Containers::ApplicationController <
4
+ UffizziCore::Api::Cli::V1::Projects::Deployments::ApplicationController
5
+ def resource_container
6
+ @resource_container ||= resource_deployment.active_containers.find_by!(name: params[:container_name])
7
+ end
8
+ end
@@ -0,0 +1,27 @@
1
+ # frozen_string_literal: true
2
+
3
+ # @resource Project/Deployment/Container/Log
4
+
5
+ class UffizziCore::Api::Cli::V1::Projects::Deployments::Containers::LogsController <
6
+ UffizziCore::Api::Cli::V1::Projects::Deployments::Containers::ApplicationController
7
+ # @path [GET] /api/cli/v1/projects/{project_slug}/deployments/{deployment_id}/containers/{container_name}/logs
8
+ #
9
+ # @parameter project_slug(required,path) [string] The slug of the project
10
+ # @parameter deployment_id(required,path) [integer] The id of the deployment
11
+ # @parameter container_name(required,path) [integer] The name of the container
12
+ #
13
+ # @response [object <logs: Array<object<insert_id: string, payload: string>>>] 200 OK
14
+ # @response [object<errors: object<title: string>>] 404 Not found
15
+ # @response 401 Not authorized
16
+ def index
17
+ response = UffizziCore::LogsService.fetch_container_logs(resource_container, logs_params)
18
+
19
+ render json: response
20
+ end
21
+
22
+ private
23
+
24
+ def logs_params
25
+ params.permit(:limit)
26
+ end
27
+ end
@@ -0,0 +1,24 @@
1
+ # frozen_string_literal: true
2
+
3
+ # @resource Container
4
+
5
+ class UffizziCore::Api::Cli::V1::Projects::Deployments::ContainersController <
6
+ UffizziCore::Api::Cli::V1::Projects::Deployments::ApplicationController
7
+ before_action :authorize_uffizzi_core_api_cli_v1_projects_deployments_containers
8
+
9
+ # Get a list of container services for a deployment
10
+ #
11
+ # @path [GET] /api/cli/v1/projects/{project_slug}/deployments/{deployment_id}/containers
12
+ #
13
+ # @parameter project_slug(required,path) [string] The project slug
14
+ # @parameter deployment_id(required,path) [integer] The id of the deployment
15
+ #
16
+ # @response [Container] 200 OK
17
+ # @response 401 Not authorized
18
+ # @response 404 Not found
19
+ def index
20
+ containers = resource_deployment.containers.active
21
+
22
+ respond_with containers
23
+ end
24
+ end
@@ -0,0 +1,29 @@
1
+ # frozen_string_literal: true
2
+
3
+ # @resource Event
4
+ class UffizziCore::Api::Cli::V1::Projects::Deployments::EventsController <
5
+ UffizziCore::Api::Cli::V1::Projects::Deployments::ApplicationController
6
+ before_action :authorize_uffizzi_core_api_cli_v1_projects_deployments_events
7
+
8
+ # Get the events associated with deployment
9
+ #
10
+ # @path [GET] /api/cli/v1/projects/{project_slug}/deployments/{deployment_id}/events
11
+ #
12
+ # @parameter project_slug(required,path) [string] The project_slug for the project
13
+ # @parameter deployment_id(required,path) [integer] The id of the deployment
14
+ #
15
+ # @response [object<
16
+ # events: Array<object
17
+ # <first_timestamp: string, last_timestamp: string, reason: string, message: string>
18
+ # > >] 200 OK
19
+ #
20
+ # @response 401 Not authorized
21
+ # @response 404 Not found
22
+ def index
23
+ response = UffizziCore::ControllerService.fetch_deployment_events(resource_deployment)
24
+
25
+ events = { events: response }
26
+
27
+ render json: events
28
+ end
29
+ end
@@ -0,0 +1,148 @@
1
+ # frozen_string_literal: true
2
+
3
+ # @resource Deployment
4
+
5
+ class UffizziCore::Api::Cli::V1::Projects::DeploymentsController < UffizziCore::Api::Cli::V1::Projects::ApplicationController
6
+ before_action :authorize_uffizzi_core_api_cli_v1_projects_deployments
7
+
8
+ # Get a list of active deployements for a project
9
+ #
10
+ # @path [GET] /api/cli/v1/projects/{project_slug}/deployments
11
+ #
12
+ # @parameter project_slug(required,path) [string] The project slug
13
+ #
14
+ # @response [Array<Deployment>] 200 OK
15
+ # @response 401 Not authorized
16
+ def index
17
+ respond_with deployments
18
+ end
19
+
20
+ # Get deployment information by id
21
+ #
22
+ # @path [GET] /api/cli/v1/projects/{project_slug}/deployments/{id}
23
+ #
24
+ # @parameter project_slug(required,path) [string] The project slug
25
+ #
26
+ # @response [Deployment] 200 OK
27
+ # @response [object<errors: object<title: string>>] 404 Not found
28
+ # @response 401 Not authorized
29
+ def show
30
+ respond_with deployment
31
+ end
32
+
33
+ # Create a deployment from a compose file
34
+ #
35
+ # @path [POST] /api/cli/v1/projects/{project_slug}/deployments
36
+ #
37
+ # @parameter project_slug(required,path) [string] The project slug
38
+ # @parameter params(required,body) [object<
39
+ # compose_file: object<path: string, source: string, content: string>,
40
+ # dependencies: Array<object<path: string, source: string, content: string>>>]
41
+ #
42
+ # @response [Deployment] 201 OK
43
+ # @response [object<errors: object<state: string>>] 422 Unprocessable Entity
44
+ # @response [object<errors: object<title: string>>] 404 Not found
45
+ # @response 401 Not authorized
46
+ def create
47
+ compose_file, errors = find_or_create_compose_file
48
+ return render_invalid_file if compose_file.invalid_file?
49
+ return render_errors(errors) if errors.present?
50
+
51
+ errors = check_credentials(compose_file)
52
+ return render_errors(errors) if errors.present?
53
+
54
+ deployment = UffizziCore::DeploymentService.create_from_compose(compose_file, resource_project, current_user)
55
+
56
+ respond_with deployment
57
+ end
58
+
59
+ # @path [POST] /api/cli/v1/projects/{project_slug}/deployments/{id}/deploy_containers
60
+ #
61
+ # @parameter project_slug(required,path) [string] The project slug
62
+ # @parameter id(required,path) [string] The id of the deployment
63
+ #
64
+ # @response 204 No Content
65
+ # @response [object<errors: object<title: string>>] 404 Not found
66
+ # @response 401 Not authorized
67
+ def deploy_containers
68
+ deployment = resource_project.deployments.active.find(params[:id])
69
+
70
+ deployment.update(deployed_by: current_user)
71
+
72
+ resource_project.config_files.by_deployment(deployment).each do |config_file|
73
+ UffizziCore::ConfigFile::ApplyJob.perform_async(deployment.id, config_file.id)
74
+ end
75
+
76
+ UffizziCore::Deployment::DeployContainersJob.perform_async(deployment.id)
77
+ end
78
+
79
+ # Disable deployment by id
80
+ #
81
+ # @path [DELETE] /api/cli/v1/projects/{project_slug}/deployments/{id}
82
+ #
83
+ # @parameter project_slug(required,path) [string] The project slug
84
+ #
85
+ # @response 204 No Content
86
+ # @response 401 Not authorized
87
+ def destroy
88
+ UffizziCore::DeploymentService.disable!(deployment)
89
+
90
+ head :no_content
91
+ end
92
+
93
+ private
94
+
95
+ def deployment
96
+ @deployment ||= deployments.find(params[:id])
97
+ end
98
+
99
+ def find_or_create_compose_file
100
+ existing_compose_file = resource_project.compose_file
101
+ if compose_file_params.present?
102
+ create_params = {
103
+ project: resource_project,
104
+ user: current_user,
105
+ compose_file_params: compose_file_params,
106
+ dependencies: dependencies_params[:dependencies] || [],
107
+ }
108
+
109
+ kind = UffizziCore::ComposeFile.kind.temporary
110
+ UffizziCore::Cli::ComposeFileService.create(create_params, kind)
111
+ else
112
+ raise ActiveRecord::RecordNotFound if existing_compose_file.blank?
113
+
114
+ errors = []
115
+ [existing_compose_file, errors]
116
+ end
117
+ end
118
+
119
+ def check_credentials(compose_file)
120
+ credentials = resource_project.account.credentials
121
+ check_credentials_form = UffizziCore::Api::Cli::V1::ComposeFile::CheckCredentialsForm.new
122
+ check_credentials_form.compose_file = compose_file
123
+ check_credentials_form.credentials = credentials
124
+ return check_credentials_form.errors if check_credentials_form.invalid?
125
+
126
+ nil
127
+ end
128
+
129
+ def deployments
130
+ @deployments ||= resource_project.deployments.active
131
+ end
132
+
133
+ def deployment_params
134
+ params.required(:deployment)
135
+ end
136
+
137
+ def compose_file_params
138
+ params[:compose_file]
139
+ end
140
+
141
+ def dependencies_params
142
+ params.permit(dependencies: [:name, :path, :source, :content])
143
+ end
144
+
145
+ def render_invalid_file
146
+ render json: { errors: { state: ['Invalid compose file'] } }, status: :unprocessable_entity
147
+ end
148
+ end