uffizzi-core 0.1.12

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 (257) hide show
  1. checksums.yaml +7 -0
  2. data/LICENSE +201 -0
  3. data/README.md +52 -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 +141 -0
  14. data/app/clients/uffizzi_core/github_container_registry_client/request_result.rb +7 -0
  15. data/app/clients/uffizzi_core/github_container_registry_client.rb +52 -0
  16. data/app/clients/uffizzi_core/google_registry_client/request_result.rb +5 -0
  17. data/app/clients/uffizzi_core/google_registry_client.rb +42 -0
  18. data/app/contexts/uffizzi_core/base_context.rb +12 -0
  19. data/app/contexts/uffizzi_core/project_context.rb +13 -0
  20. data/app/contexts/uffizzi_core/webhooks_context.rb +9 -0
  21. data/app/controllers/concerns/uffizzi_core/auth_management.rb +23 -0
  22. data/app/controllers/concerns/uffizzi_core/authorization_concern.rb +38 -0
  23. data/app/controllers/concerns/uffizzi_core/dependency_injection_concern.rb +19 -0
  24. data/app/controllers/uffizzi_core/api/cli/v1/account/application_controller.rb +7 -0
  25. data/app/controllers/uffizzi_core/api/cli/v1/account/credentials_controller.rb +91 -0
  26. data/app/controllers/uffizzi_core/api/cli/v1/application_controller.rb +5 -0
  27. data/app/controllers/uffizzi_core/api/cli/v1/projects/application_controller.rb +11 -0
  28. data/app/controllers/uffizzi_core/api/cli/v1/projects/compose_files_controller.rb +93 -0
  29. data/app/controllers/uffizzi_core/api/cli/v1/projects/deployments/activity_items_controller.rb +36 -0
  30. data/app/controllers/uffizzi_core/api/cli/v1/projects/deployments/application_controller.rb +7 -0
  31. data/app/controllers/uffizzi_core/api/cli/v1/projects/deployments/containers/application_controller.rb +8 -0
  32. data/app/controllers/uffizzi_core/api/cli/v1/projects/deployments/containers/logs_controller.rb +27 -0
  33. data/app/controllers/uffizzi_core/api/cli/v1/projects/deployments/containers_controller.rb +24 -0
  34. data/app/controllers/uffizzi_core/api/cli/v1/projects/deployments/events_controller.rb +29 -0
  35. data/app/controllers/uffizzi_core/api/cli/v1/projects/deployments_controller.rb +179 -0
  36. data/app/controllers/uffizzi_core/api/cli/v1/projects/secrets_controller.rb +61 -0
  37. data/app/controllers/uffizzi_core/api/cli/v1/projects_controller.rb +85 -0
  38. data/app/controllers/uffizzi_core/api/cli/v1/sessions_controller.rb +43 -0
  39. data/app/controllers/uffizzi_core/application_controller.rb +57 -0
  40. data/app/errors/uffizzi_core/compose_file/build_error.rb +4 -0
  41. data/app/errors/uffizzi_core/compose_file/credential_error.rb +4 -0
  42. data/app/errors/uffizzi_core/compose_file/parse_error.rb +4 -0
  43. data/app/errors/uffizzi_core/compose_file/secrets_error.rb +4 -0
  44. data/app/errors/uffizzi_core/deployment/image_pull_error.rb +10 -0
  45. data/app/errors/uffizzi_core/deployment_not_found_error.rb +10 -0
  46. data/app/forms/uffizzi_core/api/cli/v1/account/credential/check_credential_form.rb +16 -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 +22 -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 +92 -0
  55. data/app/forms/uffizzi_core/api/cli/v1/deployment/update_form.rb +90 -0
  56. data/app/forms/uffizzi_core/api/cli/v1/project/create_form.rb +7 -0
  57. data/app/forms/uffizzi_core/api/cli/v1/project/update_form.rb +10 -0
  58. data/app/forms/uffizzi_core/api/cli/v1/secret/bulk_assign_form.rb +39 -0
  59. data/app/forms/uffizzi_core/api/cli/v1/session_create_form.rb +29 -0
  60. data/app/forms/uffizzi_core/api/cli/v1/template/create_form.rb +65 -0
  61. data/app/forms/uffizzi_core/application_form.rb +11 -0
  62. data/app/forms/uffizzi_core/application_form_without_active_record.rb +17 -0
  63. data/app/forms/uffizzi_core/mass_assignment_control_concern.rb +22 -0
  64. data/app/helpers/uffizzi_core/application_helper.rb +6 -0
  65. data/app/jobs/uffizzi_core/account/create_credential_job.rb +10 -0
  66. data/app/jobs/uffizzi_core/activity_item/docker/update_digest_job.rb +11 -0
  67. data/app/jobs/uffizzi_core/application_job.rb +7 -0
  68. data/app/jobs/uffizzi_core/config_file/apply_job.rb +31 -0
  69. data/app/jobs/uffizzi_core/credential/docker_hub/create_webhook_job.rb +15 -0
  70. data/app/jobs/uffizzi_core/deployment/create_credential_job.rb +32 -0
  71. data/app/jobs/uffizzi_core/deployment/create_credentials_job.rb +17 -0
  72. data/app/jobs/uffizzi_core/deployment/create_job.rb +15 -0
  73. data/app/jobs/uffizzi_core/deployment/create_webhooks_job.rb +13 -0
  74. data/app/jobs/uffizzi_core/deployment/delete_credential_job.rb +13 -0
  75. data/app/jobs/uffizzi_core/deployment/delete_job.rb +11 -0
  76. data/app/jobs/uffizzi_core/deployment/deploy_containers_job.rb +27 -0
  77. data/app/jobs/uffizzi_core/deployment/manage_deploy_activity_item_job.rb +38 -0
  78. data/app/lib/uffizzi_core/concerns/models/activity_item.rb +39 -0
  79. data/app/lib/uffizzi_core/concerns/models/credential.rb +65 -0
  80. data/app/lib/uffizzi_core/concerns/models/repo.rb +33 -0
  81. data/app/lib/uffizzi_core/rbac/user_access_service.rb +45 -0
  82. data/app/mailers/uffizzi_core/application_mailer.rb +8 -0
  83. data/app/models/concerns/uffizzi_core/hashid_concern.rb +25 -0
  84. data/app/models/concerns/uffizzi_core/state_machine_concern.rb +16 -0
  85. data/app/models/uffizzi_core/account.rb +83 -0
  86. data/app/models/uffizzi_core/activity_item/docker.rb +4 -0
  87. data/app/models/uffizzi_core/activity_item/github.rb +4 -0
  88. data/app/models/uffizzi_core/activity_item/memory_limit.rb +4 -0
  89. data/app/models/uffizzi_core/activity_item.rb +53 -0
  90. data/app/models/uffizzi_core/application_record.rb +7 -0
  91. data/app/models/uffizzi_core/build.rb +39 -0
  92. data/app/models/uffizzi_core/comment.rb +16 -0
  93. data/app/models/uffizzi_core/compose_file.rb +57 -0
  94. data/app/models/uffizzi_core/config_file.rb +24 -0
  95. data/app/models/uffizzi_core/container.rb +100 -0
  96. data/app/models/uffizzi_core/container_config_file.rb +8 -0
  97. data/app/models/uffizzi_core/continuous_preview.rb +4 -0
  98. data/app/models/uffizzi_core/coupon.rb +5 -0
  99. data/app/models/uffizzi_core/credential/amazon.rb +4 -0
  100. data/app/models/uffizzi_core/credential/azure.rb +4 -0
  101. data/app/models/uffizzi_core/credential/docker_hub.rb +4 -0
  102. data/app/models/uffizzi_core/credential/github.rb +4 -0
  103. data/app/models/uffizzi_core/credential/github_container_registry.rb +4 -0
  104. data/app/models/uffizzi_core/credential/google.rb +4 -0
  105. data/app/models/uffizzi_core/credential.rb +61 -0
  106. data/app/models/uffizzi_core/database.rb +4 -0
  107. data/app/models/uffizzi_core/database_offering.rb +4 -0
  108. data/app/models/uffizzi_core/deployment.rb +86 -0
  109. data/app/models/uffizzi_core/event.rb +13 -0
  110. data/app/models/uffizzi_core/invitation.rb +27 -0
  111. data/app/models/uffizzi_core/membership.rb +16 -0
  112. data/app/models/uffizzi_core/payment.rb +11 -0
  113. data/app/models/uffizzi_core/price.rb +9 -0
  114. data/app/models/uffizzi_core/product.rb +11 -0
  115. data/app/models/uffizzi_core/project.rb +67 -0
  116. data/app/models/uffizzi_core/rating.rb +20 -0
  117. data/app/models/uffizzi_core/repo/amazon.rb +4 -0
  118. data/app/models/uffizzi_core/repo/azure.rb +4 -0
  119. data/app/models/uffizzi_core/repo/docker_hub.rb +4 -0
  120. data/app/models/uffizzi_core/repo/github.rb +4 -0
  121. data/app/models/uffizzi_core/repo/github_container_registry.rb +4 -0
  122. data/app/models/uffizzi_core/repo/google.rb +4 -0
  123. data/app/models/uffizzi_core/repo.rb +29 -0
  124. data/app/models/uffizzi_core/role.rb +17 -0
  125. data/app/models/uffizzi_core/secret.rb +9 -0
  126. data/app/models/uffizzi_core/template.rb +19 -0
  127. data/app/models/uffizzi_core/user.rb +62 -0
  128. data/app/models/uffizzi_core/user_project.rb +14 -0
  129. data/app/policies/uffizzi_core/api/cli/v1/account/credentials_policy.rb +19 -0
  130. data/app/policies/uffizzi_core/api/cli/v1/projects/compose_files_policy.rb +15 -0
  131. data/app/policies/uffizzi_core/api/cli/v1/projects/deployments/activity_items_policy.rb +7 -0
  132. data/app/policies/uffizzi_core/api/cli/v1/projects/deployments/containers_policy.rb +7 -0
  133. data/app/policies/uffizzi_core/api/cli/v1/projects/deployments/events_policy.rb +7 -0
  134. data/app/policies/uffizzi_core/api/cli/v1/projects/deployments_policy.rb +27 -0
  135. data/app/policies/uffizzi_core/api/cli/v1/projects/secrets_policy.rb +15 -0
  136. data/app/policies/uffizzi_core/api/cli/v1/projects_policy.rb +19 -0
  137. data/app/policies/uffizzi_core/application_policy.rb +12 -0
  138. data/app/repositories/uffizzi_core/activity_item_repo.rb +9 -0
  139. data/app/repositories/uffizzi_core/basic_order_repo.rb +11 -0
  140. data/app/repositories/uffizzi_core/build_repo.rb +23 -0
  141. data/app/repositories/uffizzi_core/comment_repo.rb +11 -0
  142. data/app/repositories/uffizzi_core/compose_file_repo.rb +11 -0
  143. data/app/repositories/uffizzi_core/config_file_repo.rb +40 -0
  144. data/app/repositories/uffizzi_core/container_repo.rb +25 -0
  145. data/app/repositories/uffizzi_core/credential_repo.rb +31 -0
  146. data/app/repositories/uffizzi_core/deployment_repo.rb +24 -0
  147. data/app/repositories/uffizzi_core/event_repo.rb +9 -0
  148. data/app/repositories/uffizzi_core/membership_repo.rb +10 -0
  149. data/app/repositories/uffizzi_core/price_repo.rb +11 -0
  150. data/app/repositories/uffizzi_core/product_repo.rb +11 -0
  151. data/app/repositories/uffizzi_core/project_repo.rb +10 -0
  152. data/app/repositories/uffizzi_core/repo_repo.rb +10 -0
  153. data/app/repositories/uffizzi_core/template_repo.rb +87 -0
  154. data/app/repositories/uffizzi_core/usage_repo.rb +9 -0
  155. data/app/repositories/uffizzi_core/user_repo.rb +11 -0
  156. data/app/responders/uffizzi_core/json_responder.rb +13 -0
  157. data/app/serializers/uffizzi_core/api/cli/v1/account/credential_serializer.rb +9 -0
  158. data/app/serializers/uffizzi_core/api/cli/v1/project_serializer/compose_file_serializer.rb +7 -0
  159. data/app/serializers/uffizzi_core/api/cli/v1/project_serializer/deployment_serializer.rb +13 -0
  160. data/app/serializers/uffizzi_core/api/cli/v1/project_serializer.rb +30 -0
  161. data/app/serializers/uffizzi_core/api/cli/v1/projects/compose_file_serializer.rb +7 -0
  162. data/app/serializers/uffizzi_core/api/cli/v1/projects/deployment_serializer/container_serializer.rb +32 -0
  163. data/app/serializers/uffizzi_core/api/cli/v1/projects/deployment_serializer/user_serializer.rb +11 -0
  164. data/app/serializers/uffizzi_core/api/cli/v1/projects/deployment_serializer.rb +74 -0
  165. data/app/serializers/uffizzi_core/api/cli/v1/projects/deployments/activity_item_serializer.rb +24 -0
  166. data/app/serializers/uffizzi_core/api/cli/v1/projects/deployments/container_serializer/container_config_file_serializer/config_file_serializer.rb +6 -0
  167. data/app/serializers/uffizzi_core/api/cli/v1/projects/deployments/container_serializer/container_config_file_serializer.rb +7 -0
  168. data/app/serializers/uffizzi_core/api/cli/v1/projects/deployments/container_serializer.rb +30 -0
  169. data/app/serializers/uffizzi_core/api/cli/v1/projects/secret_serializer.rb +5 -0
  170. data/app/serializers/uffizzi_core/api/cli/v1/short_project_serializer.rb +7 -0
  171. data/app/serializers/uffizzi_core/api/cli/v1/user_serializer/account_serializer.rb +5 -0
  172. data/app/serializers/uffizzi_core/api/cli/v1/user_serializer.rb +7 -0
  173. data/app/serializers/uffizzi_core/base_serializer.rb +7 -0
  174. data/app/serializers/uffizzi_core/controller/apply_config_file/config_file_serializer.rb +5 -0
  175. data/app/serializers/uffizzi_core/controller/create_credential/credential_serializer.rb +19 -0
  176. data/app/serializers/uffizzi_core/controller/create_deployment/deployment_serializer.rb +5 -0
  177. data/app/serializers/uffizzi_core/controller/deploy_containers/container_serializer/container_config_file_serializer/config_file_serializer.rb +8 -0
  178. data/app/serializers/uffizzi_core/controller/deploy_containers/container_serializer/container_config_file_serializer.rb +7 -0
  179. data/app/serializers/uffizzi_core/controller/deploy_containers/container_serializer.rb +70 -0
  180. data/app/serializers/uffizzi_core/controller/deploy_containers/credential_serializer.rb +5 -0
  181. data/app/services/uffizzi_core/account_service.rb +21 -0
  182. data/app/services/uffizzi_core/activity_item_service.rb +88 -0
  183. data/app/services/uffizzi_core/amazon/credential_service.rb +31 -0
  184. data/app/services/uffizzi_core/amazon_service.rb +45 -0
  185. data/app/services/uffizzi_core/azure/credential_service.rb +18 -0
  186. data/app/services/uffizzi_core/compose_file/builders/config_files_builder_service.rb +31 -0
  187. data/app/services/uffizzi_core/compose_file/builders/container_builder_service.rb +222 -0
  188. data/app/services/uffizzi_core/compose_file/builders/docker_repo_builder_service.rb +25 -0
  189. data/app/services/uffizzi_core/compose_file/builders/template_builder_service.rb +45 -0
  190. data/app/services/uffizzi_core/compose_file/builders/variables_builder_service.rb +58 -0
  191. data/app/services/uffizzi_core/compose_file/config_files_service.rb +52 -0
  192. data/app/services/uffizzi_core/compose_file/config_option_service.rb +41 -0
  193. data/app/services/uffizzi_core/compose_file/configs_options_service.rb +26 -0
  194. data/app/services/uffizzi_core/compose_file/container_service.rb +68 -0
  195. data/app/services/uffizzi_core/compose_file/continuous_preview_options_service.rb +57 -0
  196. data/app/services/uffizzi_core/compose_file/dependencies_service.rb +56 -0
  197. data/app/services/uffizzi_core/compose_file/errors_service.rb +46 -0
  198. data/app/services/uffizzi_core/compose_file/github_dependencies_service.rb +38 -0
  199. data/app/services/uffizzi_core/compose_file/ingress_options_service.rb +51 -0
  200. data/app/services/uffizzi_core/compose_file/parsers/services/healthcheck_parser_service.rb +73 -0
  201. data/app/services/uffizzi_core/compose_file/secrets_options_service.rb +28 -0
  202. data/app/services/uffizzi_core/compose_file/services_options/command_service.rb +18 -0
  203. data/app/services/uffizzi_core/compose_file/services_options/configs_service.rb +51 -0
  204. data/app/services/uffizzi_core/compose_file/services_options/deploy_service.rb +44 -0
  205. data/app/services/uffizzi_core/compose_file/services_options/entrypoint_service.rb +18 -0
  206. data/app/services/uffizzi_core/compose_file/services_options/env_file_service.rb +34 -0
  207. data/app/services/uffizzi_core/compose_file/services_options/environment_service.rb +20 -0
  208. data/app/services/uffizzi_core/compose_file/services_options/image_service.rb +89 -0
  209. data/app/services/uffizzi_core/compose_file/services_options/secrets_service.rb +35 -0
  210. data/app/services/uffizzi_core/compose_file/services_options_service.rb +57 -0
  211. data/app/services/uffizzi_core/compose_file/template_service.rb +55 -0
  212. data/app/services/uffizzi_core/compose_file/variables_service.rb +25 -0
  213. data/app/services/uffizzi_core/compose_file_service.rb +181 -0
  214. data/app/services/uffizzi_core/container_service.rb +42 -0
  215. data/app/services/uffizzi_core/controller_service.rb +86 -0
  216. data/app/services/uffizzi_core/credential_service.rb +44 -0
  217. data/app/services/uffizzi_core/deployment_service.rb +307 -0
  218. data/app/services/uffizzi_core/docker_hub/credential_service.rb +15 -0
  219. data/app/services/uffizzi_core/docker_hub_service.rb +77 -0
  220. data/app/services/uffizzi_core/github_container_registry/credential_service.rb +24 -0
  221. data/app/services/uffizzi_core/google/credential_service.rb +18 -0
  222. data/app/services/uffizzi_core/logs_service.rb +33 -0
  223. data/app/services/uffizzi_core/manage_activity_items_service.rb +159 -0
  224. data/app/services/uffizzi_core/project_service.rb +48 -0
  225. data/app/services/uffizzi_core/repo_service.rb +43 -0
  226. data/app/services/uffizzi_core/response_service.rb +13 -0
  227. data/app/services/uffizzi_core/starter_template_service.rb +200 -0
  228. data/app/services/uffizzi_core/template_service.rb +21 -0
  229. data/app/services/uffizzi_core/token_service.rb +19 -0
  230. data/app/services/uffizzi_core/user_access_service.rb +14 -0
  231. data/app/services/uffizzi_core/user_generator_service.rb +84 -0
  232. data/app/utils/uffizzi_core/converters.rb +33 -0
  233. data/app/validators/uffizzi_core/email_validator.rb +9 -0
  234. data/app/validators/uffizzi_core/environment_variable_list_validator.rb +15 -0
  235. data/app/validators/uffizzi_core/image_command_args_validator.rb +21 -0
  236. data/config/initializers/rswag_api.rb +15 -0
  237. data/config/initializers/rswag_ui.rb +15 -0
  238. data/config/initializers/swagger_yard.rb +17 -0
  239. data/config/locales/en.activerecord.yml +23 -0
  240. data/config/locales/en.yml +66 -0
  241. data/config/routes.rb +69 -0
  242. data/db/migrate/20220218121438_create_uffizzi_core_tables.rb +375 -0
  243. data/db/migrate/20220309110201_remove_secrets_from_projects.rb +7 -0
  244. data/db/migrate/20220310110150_create_project_secrets.rb +14 -0
  245. data/db/migrate/20220325113342_add_name_to_uffizzi_containers.rb +7 -0
  246. data/db/migrate/20220329123323_rename_project_secrets_to_secrets.rb +7 -0
  247. data/db/migrate/20220329124542_add_resource_to_secrets.rb +7 -0
  248. data/db/migrate/20220329143241_remove_project_ref_from_secrets.rb +7 -0
  249. data/db/migrate/20220419074956_add_health_check_to_containers.rb +7 -0
  250. data/db/migrate/20220525113412_rename_name_to_uffizzi_containers.rb +7 -0
  251. data/db/seeds.rb +16 -0
  252. data/lib/tasks/uffizzi_core_tasks.rake +19 -0
  253. data/lib/uffizzi_core/engine.rb +15 -0
  254. data/lib/uffizzi_core/version.rb +5 -0
  255. data/lib/uffizzi_core.rb +61 -0
  256. data/swagger/v1/swagger.json +1659 -0
  257. metadata +966 -0
@@ -0,0 +1,159 @@
1
+ # frozen_string_literal: true
2
+
3
+ class UffizziCore::ManageActivityItemsService
4
+ attr_accessor :deployment, :containers, :pods, :namespace_data
5
+
6
+ def initialize(deployment)
7
+ @deployment = deployment
8
+ @containers = deployment.active_containers
9
+ @namespace_data = UffizziCore::ControllerService.fetch_namespace(deployment)
10
+ @pods = UffizziCore::ControllerService.fetch_pods(deployment)
11
+ end
12
+
13
+ def container_status_item(container)
14
+ container_status_items.detect { |container_statuses| container_statuses[:id] == container.id }
15
+ end
16
+
17
+ def container_status_items
18
+ network_connectivities = build_network_connectivities
19
+ containers_replicas = build_containers_replicas
20
+
21
+ build_container_status_items(network_connectivities, containers_replicas)
22
+ end
23
+
24
+ private
25
+
26
+ def build_network_connectivities
27
+ containers.with_public_access.map do |container|
28
+ { id: container.id, items: build_container_network_connectivity_items(container) }
29
+ end
30
+ end
31
+
32
+ def build_container_network_connectivity_items(container)
33
+ network_connectivities = container_network_connectivities(container)
34
+ return [] if network_connectivities.nil?
35
+
36
+ network_connectivities.map do |network_connectivity|
37
+ type, value = network_connectivity
38
+
39
+ { type: type, status: value.status }
40
+ end
41
+ end
42
+
43
+ def build_containers_replicas
44
+ containers.map do |container|
45
+ items = pods.map do |pod|
46
+ {
47
+ name: item_name(pod, container),
48
+ status: get_status(pod, container),
49
+ }
50
+ end
51
+
52
+ { id: container.id, items: items }
53
+ end
54
+ end
55
+
56
+ def build_container_status_items(network_connectivities, containers_replicas)
57
+ containers.map do |container|
58
+ network_connectivity = network_connectivities.detect { |item| item[:id] == container.id }
59
+ any_container_is_building = containers_replicas.any? do |container_replicas|
60
+ container_replicas[:items].any? do |item|
61
+ item[:status] == UffizziCore::Event.state.building
62
+ end
63
+ end
64
+ container_replicas = containers_replicas.detect { |item| item[:id] == container.id }
65
+
66
+ {
67
+ id: container.id,
68
+ status: build_container_status(container, network_connectivity, container_replicas, any_container_is_building),
69
+ }
70
+ end
71
+ end
72
+
73
+ def replicas_contains_status?(replicas, status)
74
+ replicas.any? { |replica| replica[:status] == status }
75
+ end
76
+
77
+ def build_container_status(container, network_connectivity, container_replicas, any_container_is_building)
78
+ return building_container_status(container) if any_container_is_building
79
+
80
+ error = replicas_contains_status?(container_replicas[:items], UffizziCore::Event.state.failed)
81
+ container_is_running = replicas_contains_status?(container_replicas[:items], UffizziCore::Event.state.deployed)
82
+ deployed = !error && container_is_running
83
+ return container_status(error, deployed) unless container.public?
84
+
85
+ network_connectivity[:items].each do |item|
86
+ status = item[:status].to_sym
87
+ error ||= status == :failed
88
+ deployed &&= status == :success
89
+ end
90
+
91
+ container_status(error, deployed)
92
+ end
93
+
94
+ def building_container_status(_container)
95
+ UffizziCore::Event.state.deploying
96
+ end
97
+
98
+ def container_status(error, deployed)
99
+ return UffizziCore::Event.state.failed if error
100
+ return UffizziCore::Event.state.deployed if deployed
101
+
102
+ UffizziCore::Event.state.deploying
103
+ end
104
+
105
+ def item_name(pod, container)
106
+ hash = pod.metadata.name.split('-').last
107
+ "#{container.image_name}-#{hash}"
108
+ end
109
+
110
+ def get_status(pod, container)
111
+ pod_container = pod_container(pod, container)
112
+
113
+ return UffizziCore::Event.state.deploying if pod_container.nil? || pod_container[:state].to_h.empty?
114
+
115
+ pod_container_status = pod_container[:state].keys.first
116
+ state = pod_container[:state][pod_container_status]
117
+ reason = state&.reason
118
+
119
+ Rails.logger.info("manage_activity_items get_status dep_id=#{container.deployment.id} pod_container_status: #{pod_container_status}")
120
+ Rails.logger.info("manage_activity_items get_status dep_id=#{container.deployment.id} state: #{state}")
121
+ ap(pod_container[:state])
122
+
123
+ case pod_container_status.to_sym
124
+ when :running
125
+ Rails.logger.info("manage_activity_items get_status dep_id=#{container.deployment.id} running")
126
+ UffizziCore::Event.state.deployed
127
+ when :terminated
128
+ Rails.logger.info("manage_activity_items get_status dep_id=#{container.deployment.id} terminated")
129
+ UffizziCore::Event.state.failed
130
+ when :waiting
131
+ Rails.logger.info("manage_activity_items get_status dep_id=#{container.deployment.id} waiting")
132
+ return UffizziCore::Event.state.failed if ['CrashLoopBackOff'].include?(reason)
133
+
134
+ raise UffizziCore::Deployment::ImagePullError, @deployment.id if ['ErrImagePull', 'ImagePullBackOff'].include?(reason)
135
+
136
+ UffizziCore::Event.state.deploying
137
+ else
138
+ Rails.logger.info("manage_activity_items get_status dep_id=#{container.deployment.id} else")
139
+ UffizziCore::Event.state.deploying
140
+ end
141
+ end
142
+
143
+ def pod_container(pod, container)
144
+ pod_name = UffizziCore::ContainerService.pod_name(container)
145
+
146
+ pod&.status&.container_statuses&.detect { |cs| cs.name.include?(pod_name) }
147
+ end
148
+
149
+ def container_network_connectivities(container)
150
+ network_connectivity = Hashie::Mash.new(JSON.parse(deployment_network_connectivity))
151
+ containers_network_connectivity = network_connectivity&.containers
152
+
153
+ containers_network_connectivity[container.id.to_s] if !containers_network_connectivity.nil?
154
+ end
155
+
156
+ def deployment_network_connectivity
157
+ namespace_data&.metadata&.annotations&.network_connectivity || '{}'
158
+ end
159
+ end
@@ -0,0 +1,48 @@
1
+ # frozen_string_literal: true
2
+
3
+ module UffizziCore::ProjectService
4
+ class << self
5
+ def update_compose_secrets(project)
6
+ compose_file = project.compose_file
7
+ return if compose_file&.template.nil?
8
+
9
+ project.secrets.each do |secret|
10
+ if UffizziCore::ComposeFileService.has_secret?(compose_file, secret)
11
+ UffizziCore::ComposeFileService.update_secret!(compose_file, secret)
12
+ end
13
+ end
14
+
15
+ return unless UffizziCore::ComposeFileService.secrets_valid?(compose_file, project.secrets)
16
+
17
+ secrets_error_key = UffizziCore::ComposeFile::ErrorsService::SECRETS_ERROR_KEY
18
+ return unless UffizziCore::ComposeFile::ErrorsService.has_error?(compose_file, secrets_error_key)
19
+
20
+ UffizziCore::ComposeFile::ErrorsService.reset_error!(compose_file, secrets_error_key)
21
+ compose_file.set_valid! unless UffizziCore::ComposeFile::ErrorsService.has_errors?(compose_file)
22
+ end
23
+
24
+ def update_compose_secret_errors(project, secret)
25
+ compose_file = project.compose_file
26
+ return if compose_file.nil?
27
+ return unless UffizziCore::ComposeFileService.has_secret?(compose_file, secret)
28
+
29
+ error_message = I18n.t('compose.project_secret_not_found', secret: secret['name'])
30
+ error = { UffizziCore::ComposeFile::ErrorsService::SECRETS_ERROR_KEY => [error_message] }
31
+
32
+ existing_errors = compose_file.payload['errors'].presence || {}
33
+ new_errors = existing_errors.merge(error)
34
+
35
+ UffizziCore::ComposeFile::ErrorsService.update_compose_errors!(compose_file, new_errors, compose_file.content)
36
+ end
37
+
38
+ def add_users_to_project!(project, current_user)
39
+ user_projects = []
40
+
41
+ current_user.organizational_account.memberships.where(role: UffizziCore::Membership.role.admin).map do |membership|
42
+ user_projects << { project: project, user: membership.user, role: UffizziCore::UserProject.role.admin }
43
+ end
44
+
45
+ UffizziCore::UserProject.create!(user_projects)
46
+ end
47
+ end
48
+ end
@@ -0,0 +1,43 @@
1
+ # frozen_string_literal: true
2
+
3
+ module UffizziCore::RepoService
4
+ class << self
5
+ def needs_target_port?(repo)
6
+ return false if repo.nil?
7
+
8
+ !repo.dockerfile?
9
+ end
10
+
11
+ def credential(repo)
12
+ credentials = repo.project.account.credentials
13
+
14
+ case repo.type
15
+ when UffizziCore::Repo::GithubContainerRegistry.name
16
+ credentials.github_container_registry.first
17
+ when UffizziCore::Repo::DockerHub.name
18
+ credentials.docker_hub.first
19
+ when UffizziCore::Repo::Azure.name
20
+ credentials.azure.first
21
+ when UffizziCore::Repo::Google.name
22
+ credentials.google.first
23
+ when UffizziCore::Repo::Amazon.name
24
+ credentials.amazon.first
25
+ end
26
+ end
27
+
28
+ def image_name(repo)
29
+ "e#{repo.container.deployment_id}r#{repo.id}-#{Digest::SHA256.hexdigest("#{self.class}:#{repo.branch}:
30
+ #{repo.project_id}:#{repo.id}")[0, 10]}"
31
+ end
32
+
33
+ def tag(repo)
34
+ repo&.builds&.deployed&.last&.commit || 'latest'
35
+ end
36
+
37
+ def image(repo)
38
+ repo_credential = credential(repo)
39
+
40
+ "#{repo_credential.registry_url}/#{image_name(repo)}"
41
+ end
42
+ end
43
+ end
@@ -0,0 +1,13 @@
1
+ # frozen_string_literal: true
2
+
3
+ module UffizziCore::ResponseService
4
+ def meta(collection)
5
+ {
6
+ total_count: collection.total_count,
7
+ current_page: collection.current_page,
8
+ per_page: collection.limit_value,
9
+ count: collection.to_a.count,
10
+ total_pages: collection.total_pages,
11
+ }
12
+ end
13
+ end
@@ -0,0 +1,200 @@
1
+ # frozen_string_literal: true
2
+
3
+ class UffizziCore::StarterTemplateService
4
+ class << self
5
+ def create(project, user)
6
+ voting_app_config_file = create_config_file(project, user)
7
+ create_containers(project, user, voting_app_config_file)
8
+ end
9
+
10
+ private
11
+
12
+ def create_config_file(project, user)
13
+ starter_template_config_file = config_file_attributes
14
+
15
+ starter_template_config_file_params = ActionController::Parameters.new(starter_template_config_file)
16
+
17
+ starter_template_config_file_form = UffizziCore::Api::Cli::V1::ConfigFile::CreateForm.new(starter_template_config_file_params)
18
+ starter_template_config_file_form.project = project
19
+ starter_template_config_file_form.added_by = user
20
+ starter_template_config_file_form.creation_source = UffizziCore::ConfigFile.creation_source.system
21
+ starter_template_config_file_form.save
22
+
23
+ starter_template_config_file_form
24
+ end
25
+
26
+ def create_containers(project, user, voting_app_config_file)
27
+ starter_template_containers = {
28
+ name: 'Voting App (from base images)',
29
+ payload: {
30
+ containers_attributes: containers_attributes(voting_app_config_file),
31
+ },
32
+ }
33
+
34
+ starter_template = ActionController::Parameters.new(starter_template_containers)
35
+
36
+ starter_template_form = UffizziCore::Api::Cli::V1::Template::CreateForm.new(starter_template)
37
+ starter_template_form.creation_source = UffizziCore::Template.creation_source.system
38
+ starter_template_form.added_by = user
39
+ starter_template_form.project = project
40
+ starter_template_form.save
41
+ end
42
+
43
+ def containers_attributes(voting_app_config_file)
44
+ [
45
+ postgres_container_attributes,
46
+ nginx_container_attributes(voting_app_config_file),
47
+ redis_container_attributes,
48
+ example_worker_container_attributes,
49
+ example_result_container_attributes,
50
+ example_vote_container_attributes,
51
+ ]
52
+ end
53
+
54
+ def postgres_container_attributes
55
+ {
56
+ image: 'library/postgres',
57
+ tag: '9.6',
58
+ port: nil,
59
+ public: false,
60
+ memory_limit: 250,
61
+ memory_request: 250,
62
+ receive_incoming_requests: false,
63
+ continuously_deploy: 'disabled',
64
+ secret_variables: nil,
65
+ variables: [
66
+ {
67
+ name: 'POSTGRES_USER',
68
+ value: 'postgres',
69
+ },
70
+ {
71
+ name: 'POSTGRES_PASSWORD',
72
+ value: 'postgres',
73
+ },
74
+ ],
75
+ repo_attributes: repo_attributes('library/postgres'),
76
+ container_config_files_attributes: [],
77
+ }
78
+ end
79
+
80
+ def nginx_container_attributes(voting_app_config_file)
81
+ {
82
+ image: 'library/nginx',
83
+ tag: 'latest',
84
+ port: 8080,
85
+ public: true,
86
+ memory_limit: 125,
87
+ memory_request: 125,
88
+ receive_incoming_requests: true,
89
+ continuously_deploy: 'disabled',
90
+ secret_variables: nil,
91
+ variables: nil,
92
+ repo_attributes: repo_attributes('library/nginx'),
93
+ container_config_files_attributes: [{
94
+ config_file_id: voting_app_config_file.id,
95
+ mount_path: '/etc/nginx/conf.d/',
96
+ }],
97
+ }
98
+ end
99
+
100
+ def redis_container_attributes
101
+ {
102
+ image: 'library/redis',
103
+ tag: 'latest',
104
+ port: nil,
105
+ public: false,
106
+ memory_limit: 125,
107
+ memory_request: 125,
108
+ receive_incoming_requests: false,
109
+ continuously_deploy: 'disabled',
110
+ secret_variables: nil,
111
+ variables: nil,
112
+ repo_attributes: repo_attributes('library/redis'),
113
+ container_config_files_attributes: [],
114
+ }
115
+ end
116
+
117
+ def example_worker_container_attributes
118
+ {
119
+ image: 'uffizzicloud/example-worker',
120
+ tag: 'latest',
121
+ port: nil,
122
+ public: false,
123
+ memory_limit: 250,
124
+ memory_request: 250,
125
+ receive_incoming_requests: false,
126
+ continuously_deploy: 'disabled',
127
+ secret_variables: nil,
128
+ variables: nil,
129
+ repo_attributes: repo_attributes('uffizzicloud/example-worker'),
130
+ container_config_files_attributes: [],
131
+ }
132
+ end
133
+
134
+ def example_result_container_attributes
135
+ {
136
+ image: 'uffizzicloud/example-result',
137
+ tag: 'latest',
138
+ port: nil,
139
+ public: false,
140
+ memory_limit: 125,
141
+ memory_request: 125,
142
+ receive_incoming_requests: false,
143
+ continuously_deploy: 'disabled',
144
+ secret_variables: nil,
145
+ variables: nil,
146
+ repo_attributes: repo_attributes('uffizzicloud/example-result'),
147
+ container_config_files_attributes: [],
148
+ }
149
+ end
150
+
151
+ def example_vote_container_attributes
152
+ {
153
+ image: 'uffizzicloud/example-vote',
154
+ tag: 'latest',
155
+ port: nil,
156
+ public: false,
157
+ memory_limit: 250,
158
+ memory_request: 250,
159
+ receive_incoming_requests: false,
160
+ continuously_deploy: 'disabled',
161
+ secret_variables: nil,
162
+ variables: nil,
163
+ repo_attributes: repo_attributes('uffizzicloud/example-vote'),
164
+ container_config_files_attributes: [],
165
+ }
166
+ end
167
+
168
+ def config_file_attributes
169
+ {
170
+ filename: 'vote.conf',
171
+ kind: 'config_map',
172
+ payload: "server {
173
+ listen 8080;
174
+ server_name example.com;
175
+ location / {
176
+ proxy_pass http://127.0.0.1:80/;
177
+ }
178
+ location /vote/ {
179
+ proxy_pass http://127.0.0.1:8888/;
180
+ }
181
+ }",
182
+ }
183
+ end
184
+
185
+ def repo_attributes(image)
186
+ namespace, name = image.split('/')
187
+ {
188
+ namespace: namespace,
189
+ name: name,
190
+ slug: name,
191
+ type: 'UffizziCore::Repo::DockerHub',
192
+ description: '',
193
+ is_private: false,
194
+ repository_id: nil,
195
+ branch: '',
196
+ kind: nil,
197
+ }
198
+ end
199
+ end
200
+ end
@@ -0,0 +1,21 @@
1
+ # frozen_string_literal: true
2
+
3
+ class UffizziCore::TemplateService
4
+ class << self
5
+ def valid_containers_memory_limit?(template)
6
+ containers_attributes = template.payload['containers_attributes']
7
+ container_memory_limit = template.project.account.container_memory_limit
8
+ return true if container_memory_limit.nil?
9
+
10
+ containers_attributes.all? { |container| container['memory_limit'].to_i <= container_memory_limit }
11
+ end
12
+
13
+ def valid_containers_memory_request?(template)
14
+ containers_attributes = template.payload['containers_attributes']
15
+ container_memory_limit = template.project.account.container_memory_limit
16
+ return true if container_memory_limit.nil?
17
+
18
+ containers_attributes.all? { |container| container['memory_request'].to_i <= container_memory_limit }
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,19 @@
1
+ # frozen_string_literal: true
2
+
3
+ module UffizziCore::TokenService
4
+ class << self
5
+ def encode(payload)
6
+ JWT.encode(payload, Settings.rails.secret_key_base, 'HS256')
7
+ end
8
+
9
+ def decode(token)
10
+ JWT.decode(token, Settings.rails.secret_key_base, true, algorithm: 'HS256')
11
+ rescue JWT::DecodeError
12
+ nil
13
+ end
14
+
15
+ def generate
16
+ SecureRandom.hex
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,14 @@
1
+ # frozen_string_literal: true
2
+
3
+ class UffizziCore::UserAccessService
4
+ attr_accessor :user_access_module
5
+
6
+ delegate :admin_access_to_account?, :developer_access_to_account?, :viewer_access_to_account?,
7
+ :admin_or_developer_access_to_account?, :any_access_to_account?, :admin_access_to_project?,
8
+ :developer_access_to_project?, :viewer_access_to_project?, :admin_or_developer_access_to_project?,
9
+ :any_access_to_project?, :global_admin?, to: :@user_access_module
10
+
11
+ def initialize(user_access_module)
12
+ @user_access_module = user_access_module
13
+ end
14
+ end
@@ -0,0 +1,84 @@
1
+ # frozen_string_literal: true
2
+
3
+ class UffizziCore::UserGeneratorService
4
+ DEFAULT_USER_EMAIL = 'user@example.com'
5
+ DEFAULT_PROJECT_NAME = 'default'
6
+ DEFAULT_ACCOUNT_NAME = 'default'
7
+
8
+ class << self
9
+ def safe_generate(email, password, project_name)
10
+ generate(email, password, project_name)
11
+ rescue StandardError => e
12
+ puts e.message
13
+ end
14
+
15
+ def generate(email, password, project_name)
16
+ user_attributes = build_user_attributes(email, password)
17
+ project_attributes = build_project_attributes(project_name)
18
+
19
+ ActiveRecord::Base.transaction do
20
+ user = UffizziCore::User.create!(user_attributes)
21
+
22
+ account_attributes = build_account_attributes(user)
23
+ account = UffizziCore::Account.create!(account_attributes)
24
+ user.memberships.create!(account: account, role: UffizziCore::Membership.role.admin)
25
+ project = account.projects.create!(project_attributes)
26
+ project.user_projects.create!(user: user, role: UffizziCore::UserProject.role.admin)
27
+ end
28
+ end
29
+
30
+ private
31
+
32
+ def build_user_attributes(email, password)
33
+ user_attributes = {
34
+ state: UffizziCore::User::STATE_ACTIVE,
35
+ creation_source: UffizziCore::User.creation_source.system,
36
+ }
37
+
38
+ if email.present?
39
+ user_attributes[:email] = email
40
+ elsif IO::console.present?
41
+ IO::console.write("Enter User Email (default: #{DEFAULT_USER_EMAIL}): ")
42
+ user_attributes[:email] = IO::console.gets.strip.presence || DEFAULT_USER_EMAIL
43
+ end
44
+
45
+ user_attributes[:password] = if password.present?
46
+ password
47
+ elsif IO::console.present?
48
+ IO::console.getpass('Enter Password: ')
49
+ end
50
+
51
+ user_attributes
52
+ end
53
+
54
+ def build_project_attributes(project_name)
55
+ project_attributes = {
56
+ state: UffizziCore::Project::STATE_ACTIVE,
57
+ }
58
+ if project_name.present?
59
+ project_attributes[:name] = project_name
60
+ elsif IO::console.present?
61
+ IO::console.write("Enter Project Name (default: #{DEFAULT_PROJECT_NAME}): ")
62
+ project_attributes[:name] = IO::console.gets.strip.presence || DEFAULT_PROJECT_NAME
63
+ else
64
+ project_attributes[:name] = DEFAULT_PROJECT_NAME
65
+ end
66
+
67
+ project_attributes[:slug] = prepare_project_slug(project_attributes[:name])
68
+ project_attributes
69
+ end
70
+
71
+ def build_account_attributes(user)
72
+ {
73
+ owner: user,
74
+ name: DEFAULT_ACCOUNT_NAME,
75
+ state: UffizziCore::Account::STATE_ACTIVE,
76
+ kind: UffizziCore::Account.kind.organizational,
77
+ }
78
+ end
79
+
80
+ def prepare_project_slug(project_name)
81
+ project_name.downcase.gsub(/[^A-Za-z0-9]/, '-')
82
+ end
83
+ end
84
+ end
@@ -0,0 +1,33 @@
1
+ # frozen_string_literal: true
2
+
3
+ module UffizziCore::Converters
4
+ class << self
5
+ include ActionView::Helpers::NumberHelper
6
+
7
+ def deep_lower_camelize_keys(object)
8
+ case object
9
+ when Array
10
+ object.map do |element|
11
+ element.deep_transform_keys { |key| key.to_s.camelize(:lower) }
12
+ end
13
+ when Hash
14
+ object.deep_transform_keys { |key| key.to_s.camelize(:lower) }
15
+ else
16
+ object
17
+ end
18
+ end
19
+
20
+ def deep_underscore_keys(object)
21
+ case object
22
+ when Array
23
+ object.map do |element|
24
+ element.deep_transform_keys { |key| key.to_s.underscore }
25
+ end
26
+ when Hash
27
+ object.deep_transform_keys { |key| key.to_s.underscore }
28
+ else
29
+ object
30
+ end
31
+ end
32
+ end
33
+ end
@@ -0,0 +1,9 @@
1
+ # frozen_string_literal: true
2
+
3
+ class UffizziCore::EmailValidator < ActiveModel::EachValidator
4
+ EMAIL_REGEXP = /\A([^@\s<>]+)@((?:[-a-z0-9]+\.)+[a-z]{2,})\z/i.freeze
5
+
6
+ def validate_each(record, attribute, value)
7
+ record.errors.add(attribute, (options[:message] || :invalid)) unless value&.match?(EMAIL_REGEXP)
8
+ end
9
+ end
@@ -0,0 +1,15 @@
1
+ # frozen_string_literal: true
2
+
3
+ class UffizziCore::EnvironmentVariableListValidator < ActiveModel::EachValidator
4
+ def validate_each(record, attribute, variables)
5
+ record.errors.add(attribute, :invalid) if variables.class != Array || !valid_variables?(variables)
6
+ end
7
+
8
+ def valid_variables?(variables)
9
+ variables.each do |variable|
10
+ return false if variable.class != Hash || !variable.key?('name') || variable['name'].nil? || !variable.key?('value')
11
+ end
12
+
13
+ true
14
+ end
15
+ end
@@ -0,0 +1,21 @@
1
+ # frozen_string_literal: true
2
+
3
+ class UffizziCore::ImageCommandArgsValidator < ActiveModel::EachValidator
4
+ def validate_each(record, attribute, command_args)
5
+ record.errors.add(attribute, :invalid) if !command_args.nil? && !valid_command_args?(command_args)
6
+ end
7
+
8
+ def valid_command_args?(raw_command_args)
9
+ return true if raw_command_args.empty?
10
+
11
+ begin
12
+ command_args = JSON.parse(raw_command_args)
13
+ rescue JSON::ParserError
14
+ return false
15
+ end
16
+
17
+ return false if command_args.class != Array || command_args.empty?
18
+
19
+ command_args.all? { |item| item.instance_of?(String) }
20
+ end
21
+ end