uffizzi_core 0.1.3 → 0.1.5

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 (103) hide show
  1. checksums.yaml +4 -4
  2. data/app/clients/uffizzi_core/docker_hub_client.rb +2 -0
  3. data/app/clients/uffizzi_core/github_container_registry_client/request_result.rb +7 -0
  4. data/app/clients/uffizzi_core/github_container_registry_client.rb +52 -0
  5. data/app/controllers/concerns/uffizzi_core/dependency_injection_concern.rb +2 -2
  6. data/app/controllers/uffizzi_core/api/cli/v1/account/credentials_controller.rb +45 -9
  7. data/app/controllers/uffizzi_core/api/cli/v1/projects/compose_files_controller.rb +2 -2
  8. data/app/controllers/uffizzi_core/api/cli/v1/projects/deployments/application_controller.rb +1 -1
  9. data/app/controllers/uffizzi_core/api/cli/v1/projects/deployments_controller.rb +41 -10
  10. data/app/controllers/uffizzi_core/api/cli/v1/projects/secrets_controller.rb +18 -26
  11. data/app/controllers/uffizzi_core/application_controller.rb +9 -3
  12. data/app/errors/uffizzi_core/deployment/image_pull_error.rb +10 -0
  13. data/app/forms/uffizzi_core/api/cli/v1/account/credential/check_credential_form.rb +16 -0
  14. data/app/forms/uffizzi_core/api/cli/v1/account/credential/create_form.rb +1 -1
  15. data/app/forms/uffizzi_core/api/cli/v1/compose_file/check_credentials_form.rb +2 -2
  16. data/app/forms/uffizzi_core/api/cli/v1/compose_file/cli_form.rb +1 -18
  17. data/app/forms/uffizzi_core/api/cli/v1/compose_file/template_form.rb +1 -1
  18. data/app/forms/uffizzi_core/api/cli/v1/deployment/update_form.rb +90 -0
  19. data/app/forms/uffizzi_core/api/cli/v1/project/update_form.rb +1 -31
  20. data/app/forms/uffizzi_core/api/cli/v1/secret/bulk_assign_form.rb +39 -0
  21. data/app/jobs/uffizzi_core/deployment/manage_deploy_activity_item_job.rb +22 -3
  22. data/app/lib/uffizzi_core/rbac/user_access_service.rb +12 -14
  23. data/app/models/uffizzi_core/account.rb +1 -19
  24. data/app/models/uffizzi_core/activity_item.rb +1 -6
  25. data/app/models/uffizzi_core/build.rb +1 -1
  26. data/app/models/uffizzi_core/comment.rb +1 -1
  27. data/app/models/uffizzi_core/compose_file.rb +1 -1
  28. data/app/models/uffizzi_core/config_file.rb +1 -1
  29. data/app/models/uffizzi_core/container.rb +1 -1
  30. data/app/models/uffizzi_core/container_config_file.rb +1 -1
  31. data/app/models/uffizzi_core/coupon.rb +1 -1
  32. data/app/models/uffizzi_core/credential/github_container_registry.rb +4 -0
  33. data/app/models/uffizzi_core/credential.rb +3 -6
  34. data/app/models/uffizzi_core/deployment.rb +11 -2
  35. data/app/models/uffizzi_core/event.rb +1 -1
  36. data/app/models/uffizzi_core/invitation.rb +1 -1
  37. data/app/models/uffizzi_core/membership.rb +1 -1
  38. data/app/models/uffizzi_core/payment.rb +1 -1
  39. data/app/models/uffizzi_core/price.rb +1 -1
  40. data/app/models/uffizzi_core/product.rb +1 -1
  41. data/app/models/uffizzi_core/project.rb +5 -11
  42. data/app/models/uffizzi_core/rating.rb +1 -1
  43. data/app/models/uffizzi_core/repo/github_container_registry.rb +4 -0
  44. data/app/models/uffizzi_core/repo.rb +1 -11
  45. data/app/models/uffizzi_core/role.rb +2 -2
  46. data/app/models/uffizzi_core/secret.rb +9 -0
  47. data/app/models/uffizzi_core/template.rb +1 -1
  48. data/app/models/uffizzi_core/user.rb +1 -1
  49. data/app/models/uffizzi_core/user_project.rb +1 -1
  50. data/app/policies/uffizzi_core/api/cli/v1/account/credentials_policy.rb +8 -0
  51. data/app/policies/uffizzi_core/api/cli/v1/projects/deployments_policy.rb +4 -0
  52. data/app/repositories/uffizzi_core/credential_repo.rb +17 -22
  53. data/app/repositories/uffizzi_core/deployment_repo.rb +1 -0
  54. data/app/serializers/uffizzi_core/api/cli/v1/projects/deployment_serializer/container_serializer.rb +8 -0
  55. data/app/serializers/uffizzi_core/api/cli/v1/projects/secret_serializer.rb +5 -0
  56. data/app/serializers/uffizzi_core/controller/apply_config_file/config_file_serializer.rb +5 -0
  57. data/app/serializers/uffizzi_core/controller/create_credential/credential_serializer.rb +7 -3
  58. data/app/serializers/uffizzi_core/controller/deploy_containers/container_serializer/container_config_file_serializer/config_file_serializer.rb +8 -0
  59. data/app/serializers/uffizzi_core/controller/deploy_containers/container_serializer/container_config_file_serializer.rb +7 -0
  60. data/app/serializers/uffizzi_core/controller/deploy_containers/container_serializer.rb +4 -3
  61. data/app/services/uffizzi_core/activity_item_service.rb +16 -26
  62. data/app/services/uffizzi_core/compose_file/builders/container_builder_service.rb +11 -18
  63. data/app/services/uffizzi_core/compose_file/container_service.rb +13 -9
  64. data/app/services/uffizzi_core/compose_file/dependencies_service.rb +1 -0
  65. data/app/services/uffizzi_core/compose_file/services_options_service.rb +2 -2
  66. data/app/services/uffizzi_core/compose_file_service.rb +148 -0
  67. data/app/services/uffizzi_core/container_service.rb +1 -16
  68. data/app/services/uffizzi_core/controller_service.rb +7 -1
  69. data/app/services/uffizzi_core/credential_service.rb +2 -2
  70. data/app/services/uffizzi_core/deployment_service.rb +28 -7
  71. data/app/services/uffizzi_core/github_container_registry/credential_service.rb +24 -0
  72. data/app/services/uffizzi_core/manage_activity_items_service.rb +4 -19
  73. data/app/services/uffizzi_core/repo_service.rb +2 -137
  74. data/app/services/uffizzi_core/user_generator_service.rb +78 -0
  75. data/config/locales/en.activerecord.yml +5 -0
  76. data/config/locales/en.yml +4 -1
  77. data/config/routes.rb +6 -2
  78. data/db/migrate/20220309110201_remove_secrets_from_projects.rb +7 -0
  79. data/db/migrate/20220310110150_create_project_secrets.rb +14 -0
  80. data/db/migrate/20220329123323_rename_project_secrets_to_secrets.rb +7 -0
  81. data/db/migrate/20220329124542_add_resource_to_secrets.rb +7 -0
  82. data/db/migrate/20220329143241_remove_project_ref_from_secrets.rb +7 -0
  83. data/lib/tasks/uffizzi_core_tasks.rake +5 -0
  84. data/lib/uffizzi_core/engine.rb +35 -0
  85. data/lib/uffizzi_core/version.rb +1 -1
  86. data/lib/uffizzi_core.rb +1 -30
  87. data/swagger/v1/swagger.json +220 -11
  88. metadata +45 -25
  89. data/app/clients/uffizzi_core/github/app_client.rb +0 -19
  90. data/app/clients/uffizzi_core/github/installation_client.rb +0 -11
  91. data/app/clients/uffizzi_core/github/user_client.rb +0 -51
  92. data/app/errors/uffizzi_core/compose_file/not_found_error.rb +0 -4
  93. data/app/forms/uffizzi_core/api/cli/v1/project/delete_secret_form.rb +0 -27
  94. data/app/jobs/uffizzi_core/deployment/send_github_preview_message_job.rb +0 -13
  95. data/app/services/uffizzi_core/cli/compose_file_service.rb +0 -203
  96. data/app/services/uffizzi_core/compose_file/builders/github_repo_builder_service.rb +0 -59
  97. data/app/services/uffizzi_core/compose_file/services_options/build_service.rb +0 -93
  98. data/app/services/uffizzi_core/compose_file/update_service.rb +0 -29
  99. data/app/services/uffizzi_core/github/app_service.rb +0 -51
  100. data/app/services/uffizzi_core/github/credential_service.rb +0 -124
  101. data/app/services/uffizzi_core/github/message_service.rb +0 -20
  102. data/app/services/uffizzi_core/github_service.rb +0 -28
  103. data/app/services/uffizzi_core/user_access_service.rb +0 -14
@@ -23,12 +23,13 @@ class UffizziCore::Controller::DeployContainers::ContainerSerializer < UffizziCo
23
23
  credential = UffizziCore::RepoService.credential(object.repo)
24
24
 
25
25
  case object.repo.type
26
- when UffizziCore::Repo::Github.name
27
- UffizziCore::RepoService.image(object.repo)
28
26
  when UffizziCore::Repo::Google.name, UffizziCore::Repo::Amazon.name, UffizziCore::Repo::Azure.name
29
27
  registry_host = URI.parse(credential.registry_url).host
30
28
 
31
29
  "#{registry_host}/#{object.image}"
30
+ when UffizziCore::Repo::GithubContainerRegistry.name
31
+ registry_host = URI.parse(credential.registry_url).host
32
+ "#{registry_host}/#{credential.username}/#{object.image}"
32
33
  else
33
34
  object.image
34
35
  end
@@ -36,7 +37,7 @@ class UffizziCore::Controller::DeployContainers::ContainerSerializer < UffizziCo
36
37
 
37
38
  def tag
38
39
  case object.repo.type
39
- when UffizziCore::Repo::Github.name
40
+ when UffizziCore::Repo::Github.name, UffizziCore::Repo::GithubContainerRegistry.name
40
41
  UffizziCore::RepoService.tag(object.repo)
41
42
  else
42
43
  object.tag
@@ -4,19 +4,6 @@ class UffizziCore::ActivityItemService
4
4
  COMPLETED_STATES = ['deployed', 'failed', 'cancelled'].freeze
5
5
 
6
6
  class << self
7
- def create_github_item!(repo, container)
8
- activity_item_attributes = {
9
- namespace: repo.namespace,
10
- name: repo.name,
11
- container: container,
12
- deployment_id: container.deployment_id,
13
- branch: repo.branch,
14
- type: UffizziCore::ActivityItem::Github.name,
15
- }
16
-
17
- create_item!(activity_item_attributes)
18
- end
19
-
20
7
  def create_docker_item!(repo, container)
21
8
  activity_item_attributes = {
22
9
  namespace: repo.namespace,
@@ -30,6 +17,22 @@ class UffizziCore::ActivityItemService
30
17
  create_item!(activity_item_attributes)
31
18
  end
32
19
 
20
+ def disable_deployment!(activity_item)
21
+ deployment = activity_item.container.deployment
22
+
23
+ activity_item.events.create(state: UffizziCore::Event.state.failed)
24
+
25
+ UffizziCore::DeploymentService.disable!(deployment)
26
+ end
27
+
28
+ def fail_deployment!(activity_item)
29
+ deployment = activity_item.container.deployment
30
+
31
+ activity_item.events.create(state: UffizziCore::Event.state.failed)
32
+
33
+ UffizziCore::DeploymentService.fail!(deployment)
34
+ end
35
+
33
36
  def update_docker_digest!(activity_item)
34
37
  container = activity_item.container
35
38
  repo = container.repo
@@ -61,11 +64,6 @@ class UffizziCore::ActivityItemService
61
64
 
62
65
  activity_item.events.create(state: status) if last_event&.state != status
63
66
 
64
- update_build_data(activity_item) if activity_item.github?
65
-
66
- if status == UffizziCore::Event.state.deployed && UffizziCore::DeploymentService.pull_request_payload_present?(deployment)
67
- UffizziCore::Deployment::SendGithubPreviewMessageJob.perform_async(deployment.id)
68
- end
69
67
  return unless [UffizziCore::Event.state.building, UffizziCore::Event.state.deploying].include?(status)
70
68
 
71
69
  UffizziCore::Deployment::ManageDeployActivityItemJob.perform_in(5.seconds, activity_item.id)
@@ -73,14 +71,6 @@ class UffizziCore::ActivityItemService
73
71
 
74
72
  private
75
73
 
76
- def update_build_data(activity_item)
77
- build = activity_item.container.repo.builds.deployed.last
78
-
79
- return if !build.present? || !activity_item.build_id.nil?
80
-
81
- activity_item.update(build_id: build.id, commit: build.commit, commit_message: build.message)
82
- end
83
-
84
74
  def create_item!(activity_item_attributes)
85
75
  activity_item = UffizziCore::ActivityItem.find_by(activity_item_attributes)
86
76
  return activity_item unless completed?(activity_item)
@@ -148,32 +148,36 @@ class UffizziCore::ComposeFile::Builders::ContainerBuilderService
148
148
  memory_value
149
149
  end
150
150
 
151
- def build_repo_attributes(container_data, image_data, build_data, credentials)
151
+ def build_repo_attributes(container_data, image_data, _build_data, credentials)
152
152
  repo_type = repo_type(container_data)
153
153
 
154
154
  case repo_type
155
- when UffizziCore::Repo::Github.name
156
- build_github_repo_attributes(build_data, credentials)
157
155
  when UffizziCore::Repo::DockerHub.name
158
156
  build_docker_repo_attributes(image_data, credentials, :docker_hub, UffizziCore::Repo::DockerHub.name)
159
157
  when UffizziCore::Repo::Azure.name
160
158
  build_docker_repo_attributes(image_data, credentials, :azure, UffizziCore::Repo::Azure.name)
161
159
  when UffizziCore::Repo::Google.name
162
160
  build_docker_repo_attributes(image_data, credentials, :google, UffizziCore::Repo::Google.name)
161
+ when UffizziCore::Repo::GithubContainerRegistry.name
162
+ build_docker_repo_attributes(image_data, credentials, :github_container_registry, UffizziCore::Repo::GithubContainerRegistry.name)
163
+ when UffizziCore::Repo::Amazon.name
164
+ build_docker_repo_attributes(image_data, credentials, :amazon, UffizziCore::Repo::Amazon.name)
163
165
  else
164
166
  raise UffizziCore::ComposeFile::BuildError, I18n.t('compose.invalid_repo_type')
165
167
  end
166
168
  end
167
169
 
168
170
  def repo_type(container_data)
169
- if UffizziCore::ComposeFile::ContainerService.github?(container_data)
170
- UffizziCore::Repo::Github.name
171
- elsif UffizziCore::ComposeFile::ContainerService.azure?(container_data)
171
+ if UffizziCore::ComposeFile::ContainerService.azure?(container_data)
172
172
  UffizziCore::Repo::Azure.name
173
173
  elsif UffizziCore::ComposeFile::ContainerService.docker_hub?(container_data)
174
174
  UffizziCore::Repo::DockerHub.name
175
175
  elsif UffizziCore::ComposeFile::ContainerService.google?(container_data)
176
176
  UffizziCore::Repo::Google.name
177
+ elsif UffizziCore::ComposeFile::ContainerService.github_container_registry?(container_data)
178
+ UffizziCore::Repo::GithubContainerRegistry.name
179
+ elsif UffizziCore::ComposeFile::ContainerService.amazon?(container_data)
180
+ UffizziCore::Repo::Amazon.name
177
181
  end
178
182
  end
179
183
 
@@ -183,16 +187,9 @@ class UffizziCore::ComposeFile::Builders::ContainerBuilderService
183
187
  :enabled
184
188
  end
185
189
 
186
- def build_github_repo_attributes(build_data, credentials)
187
- credential = credentials.github.first
188
- raise UffizziCore::ComposeFile::BuildError, 'Invalid credential: GitHub' if credential.nil?
189
-
190
- github_builder.build_attributes(build_data)
191
- end
192
-
193
190
  def build_docker_repo_attributes(image_data, credentials, scope, repo_type)
194
191
  credential = credentials.send(scope).first
195
- raise UffizziCore::ComposeFile::BuildError, 'Invalid credential: Docker' if credential.nil?
192
+ raise UffizziCore::ComposeFile::BuildError, I18n.t('compose.invalid_credential', value: scope) if credential.nil?
196
193
 
197
194
  docker_builder(repo_type).build_attributes(image_data)
198
195
  end
@@ -211,10 +208,6 @@ class UffizziCore::ComposeFile::Builders::ContainerBuilderService
211
208
  builder.build_attributes(config_files_data, dependencies)
212
209
  end
213
210
 
214
- def github_builder
215
- @github_builder ||= UffizziCore::ComposeFile::Builders::GithubRepoBuilderService.new(repositories)
216
- end
217
-
218
211
  def docker_builder(type)
219
212
  @docker_builder ||= UffizziCore::ComposeFile::Builders::DockerRepoBuilderService.new(type)
220
213
  end
@@ -2,12 +2,6 @@
2
2
 
3
3
  class UffizziCore::ComposeFile::ContainerService
4
4
  class << self
5
- def github?(container)
6
- repository_url = container.dig(:build, :repository_url)
7
-
8
- repository_url.present? && repository_url.include?('github.com')
9
- end
10
-
11
5
  def azure?(container)
12
6
  registry_url = container.dig(:image, :registry_url)
13
7
 
@@ -20,6 +14,12 @@ class UffizziCore::ComposeFile::ContainerService
20
14
  registry_url.present? && registry_url.include?('gcr.io')
21
15
  end
22
16
 
17
+ def amazon?(container)
18
+ registry_url = container.dig(:image, :registry_url)
19
+
20
+ registry_url.present? && registry_url.include?('amazonaws.com')
21
+ end
22
+
23
23
  def docker_hub?(container)
24
24
  registry_url = container.dig(:image, :registry_url)
25
25
  repository_url = container.dig(:build, :repository_url)
@@ -27,6 +27,12 @@ class UffizziCore::ComposeFile::ContainerService
27
27
  registry_url.nil? && repository_url.nil?
28
28
  end
29
29
 
30
+ def github_container_registry?(container)
31
+ registry_url = container.dig(:image, :registry_url)
32
+
33
+ registry_url.present? && registry_url.include?('ghcr.io')
34
+ end
35
+
30
36
  def has_secret?(container, secret)
31
37
  container['secret_variables'].any? { |container_secret| container_secret['name'] == secret['name'] }
32
38
  end
@@ -39,9 +45,7 @@ class UffizziCore::ComposeFile::ContainerService
39
45
  end
40
46
 
41
47
  def credential_for_container(container, credentials)
42
- if UffizziCore::ComposeFile::ContainerService.github?(container)
43
- detect_credential(credentials, :github)
44
- elsif UffizziCore::ComposeFile::ContainerService.azure?(container)
48
+ if UffizziCore::ComposeFile::ContainerService.azure?(container)
45
49
  detect_credential(credentials, :azure)
46
50
  elsif UffizziCore::ComposeFile::ContainerService.docker_hub?(container)
47
51
  detect_credential(credentials, :docker_hub)
@@ -3,6 +3,7 @@
3
3
  class UffizziCore::ComposeFile::DependenciesService
4
4
  ENV_FILE_TYPE = 'env_file'
5
5
  CONFIG_TYPE = 'config'
6
+
6
7
  class << self
7
8
  def build_dependencies(compose_data, compose_path, dependencies_params)
8
9
  dependencies = compose_data[:containers].map do |container|
@@ -18,7 +18,7 @@ class UffizziCore::ComposeFile::ServicesOptionsService
18
18
 
19
19
  private
20
20
 
21
- def prepare_service_data(service_name, service_data, global_configs_data, global_secrets_data, compose_payload)
21
+ def prepare_service_data(service_name, service_data, global_configs_data, global_secrets_data, _compose_payload)
22
22
  options_data = {}
23
23
  service_data.each_pair do |key, value|
24
24
  service_key = key.to_sym
@@ -27,7 +27,7 @@ class UffizziCore::ComposeFile::ServicesOptionsService
27
27
  when :image
28
28
  UffizziCore::ComposeFile::ServicesOptions::ImageService.parse(value)
29
29
  when :build
30
- UffizziCore::ComposeFile::ServicesOptions::BuildService.parse(value, compose_payload)
30
+ raise UffizziCore::ComposeFile::ParseError, I18n.t('compose.not_implemented', option: :build)
31
31
  when :env_file
32
32
  UffizziCore::ComposeFile::ServicesOptions::EnvFileService.parse(value)
33
33
  when :environment
@@ -2,6 +2,58 @@
2
2
 
3
3
  module UffizziCore::ComposeFileService
4
4
  class << self
5
+ def create(params, kind)
6
+ compose_file_form = create_compose_form(params, kind)
7
+
8
+ process_compose_file(compose_file_form, params)
9
+ end
10
+
11
+ def update(compose_file, params)
12
+ compose_file_form = create_update_compose_form(compose_file, params)
13
+
14
+ process_compose_file(compose_file_form, params)
15
+ end
16
+
17
+ def parse(compose_content, compose_payload = {})
18
+ compose_data = load_compose_data(compose_content)
19
+ check_config_options_format(compose_data)
20
+ configs_data = UffizziCore::ComposeFile::ConfigsOptionsService.parse(compose_data['configs'])
21
+ secrets_data = UffizziCore::ComposeFile::SecretsOptionsService.parse(compose_data['secrets'])
22
+ containers_data = UffizziCore::ComposeFile::ServicesOptionsService.parse(compose_data['services'], configs_data, secrets_data,
23
+ compose_payload)
24
+
25
+ continuous_preview_option = UffizziCore::ComposeFile::ConfigOptionService.continuous_preview_option(compose_data)
26
+ continuous_preview_data = UffizziCore::ComposeFile::ContinuousPreviewOptionsService.parse(continuous_preview_option)
27
+
28
+ ingress_option = UffizziCore::ComposeFile::ConfigOptionService.ingress_option(compose_data)
29
+ ingress_data = UffizziCore::ComposeFile::IngressOptionsService.parse(ingress_option, compose_data['services'])
30
+
31
+ {
32
+ containers: containers_data,
33
+ ingress: ingress_data,
34
+ continuous_preview: continuous_preview_data,
35
+ }
36
+ end
37
+
38
+ def build_template_attributes(compose_data, source, credentials, project, compose_dependencies = [], compose_repositories = [])
39
+ builder = UffizziCore::ComposeFile::Builders::TemplateBuilderService.new(credentials, project, compose_repositories)
40
+
41
+ builder.build_attributes(compose_data, compose_dependencies, source)
42
+ end
43
+
44
+ def containers_credentials(compose_data, credentials)
45
+ containers = compose_data[:containers]
46
+ detected_credentials = containers.map do |container|
47
+ UffizziCore::ComposeFile::ContainerService.credential_for_container(container, credentials)
48
+ end
49
+
50
+ result = []
51
+ detected_credentials.compact
52
+ .group_by { |credential| credential[:id] }
53
+ .each_pair { |_id, value| result << value.first }
54
+ result
55
+ end
56
+
5
57
  def has_secret?(compose_file, secret)
6
58
  containers = compose_file.template.payload['containers_attributes']
7
59
 
@@ -29,5 +81,101 @@ module UffizziCore::ComposeFileService
29
81
  container['secret_variables'].all? { |secret| secret_names.include?(secret['name']) }
30
82
  end
31
83
  end
84
+
85
+ private
86
+
87
+ def process_compose_file(compose_file_form, params)
88
+ cli_form = UffizziCore::Api::Cli::V1::ComposeFile::CliForm.new
89
+ cli_form.content = compose_file_form.content
90
+ return [compose_file_form, cli_form.errors] if cli_form.invalid?
91
+
92
+ dependencies = params[:dependencies].to_a
93
+ compose_data = cli_form.compose_data
94
+ compose_dependencies = build_compose_dependecies(compose_data, compose_file_form.path, dependencies)
95
+ cli_form.compose_dependencies = compose_dependencies
96
+
97
+ persist!(compose_file_form, cli_form)
98
+ end
99
+
100
+ def create_compose_form(params, kind)
101
+ compose_file_params = params[:compose_file_params]
102
+ compose_file_form = UffizziCore::Api::Cli::V1::ComposeFile::CreateForm.new(compose_file_params)
103
+ compose_file_form.project = params[:project]
104
+ compose_file_form.added_by = params[:user]
105
+ compose_file_form.content = compose_file_params[:content]
106
+ compose_file_form.kind = kind
107
+ payload_dependencies = prepare_compose_file_dependencies(params[:dependencies])
108
+ compose_file_form.payload['dependencies'] = payload_dependencies
109
+
110
+ compose_file_form
111
+ end
112
+
113
+ def create_update_compose_form(compose_file, params)
114
+ compose_file_form = compose_file.becomes(UffizziCore::Api::Cli::V1::ComposeFile::UpdateForm)
115
+ compose_file_params = params[:compose_file_params]
116
+ compose_file_form.assign_attributes(compose_file_params)
117
+ payload_dependencies = prepare_compose_file_dependencies(params[:dependencies])
118
+ compose_file_form.payload['dependencies'] = payload_dependencies
119
+
120
+ compose_file_form
121
+ end
122
+
123
+ def build_compose_dependecies(compose_data, compose_path, dependencies)
124
+ return [] if dependencies.empty?
125
+
126
+ UffizziCore::ComposeFile::DependenciesService.build_dependencies(compose_data, compose_path, dependencies)
127
+ end
128
+
129
+ def prepare_compose_file_dependencies(compose_dependencies)
130
+ compose_dependencies.map do |dependency|
131
+ {
132
+ path: dependency[:path],
133
+ }
134
+ end
135
+ end
136
+
137
+ def persist!(compose_file_form, cli_form)
138
+ errors = []
139
+ ActiveRecord::Base.transaction do
140
+ if !compose_file_form.save
141
+ errors = compose_file_form.errors
142
+ raise ActiveRecord::Rollback
143
+ end
144
+
145
+ config_files_service = UffizziCore::ComposeFile::ConfigFilesService.new(compose_file_form)
146
+ errors = config_files_service.create_config_files(cli_form.compose_dependencies)
147
+ raise ActiveRecord::Rollback if errors.present?
148
+
149
+ project = compose_file_form.project
150
+ user = compose_file_form.added_by
151
+ template_service = UffizziCore::ComposeFile::TemplateService.new(cli_form, project, user)
152
+ errors = template_service.create_template(compose_file_form)
153
+
154
+ raise ActiveRecord::Rollback if errors.present?
155
+ end
156
+ [compose_file_form, errors]
157
+ end
158
+
159
+ def load_compose_data(compose_content)
160
+ begin
161
+ compose_data = YAML.safe_load(compose_content)
162
+ rescue Psych::SyntaxError
163
+ raise UffizziCore::ComposeFile::ParseError, 'Invalid compose file'
164
+ end
165
+
166
+ raise UffizziCore::ComposeFile::ParseError, I18n.t('compose.unsupported_file') if compose_data.nil?
167
+
168
+ compose_data
169
+ end
170
+
171
+ def check_config_options_format(compose_data)
172
+ options = UffizziCore::ComposeFile::ConfigOptionService.config_options(compose_data)
173
+
174
+ options.each do |option|
175
+ next if UffizziCore::ComposeFile::ConfigOptionService.valid_option_format?(option)
176
+
177
+ raise UffizziCore::ComposeFile::ParseError, I18n.t('compose.invalid_config_option', value: option)
178
+ end
179
+ end
32
180
  end
33
181
  end
@@ -1,30 +1,15 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  class UffizziCore::ContainerService
4
- PRIVILEGED_PORT_MAX = 1024
5
-
6
4
  class << self
7
- def should_build?(container)
8
- container.repo_id && container.repo.github?
9
- end
10
-
11
5
  def pod_name(container)
12
6
  return container.controller_name if container.controller_name.present?
13
7
 
14
- formatted_name = if should_build?(container)
15
- "#{UffizziCore::RepoService.image(container.repo)}-#{UffizziCore::RepoService.tag(container.repo)}"
16
- else
17
- container.image_name
18
- end
19
-
8
+ formatted_name = container.image_name
20
9
  formatted_name.parameterize.gsub('_', '-')
21
10
  end
22
11
 
23
12
  def target_port_value(container)
24
- should_find_unused_port = container.repo&.github? && UffizziCore::RepoService.needs_target_port?(container.repo) &&
25
- container.public && container.port <= PRIVILEGED_PORT_MAX
26
- return UffizziCore::DeploymentService.find_unused_port(container.deployment) if should_find_unused_port
27
-
28
13
  container.port
29
14
  end
30
15
 
@@ -25,7 +25,13 @@ module UffizziCore::ControllerService
25
25
  end
26
26
 
27
27
  def apply_credential(deployment, credential)
28
- body = UffizziCore::Controller::CreateCredential::CredentialSerializer.new(credential).as_json
28
+ image = if credential.github_container_registry?
29
+ deployment.containers.by_repo_type(UffizziCore::Repo::GithubContainerRegistry.name).first&.image
30
+ end
31
+
32
+ options = { image: image }
33
+
34
+ body = UffizziCore::Controller::CreateCredential::CredentialSerializer.new(credential, options).as_json
29
35
  controller_client.apply_credential(deployment_id: deployment.id, body: body)
30
36
  end
31
37
 
@@ -6,8 +6,8 @@ module UffizziCore::CredentialService
6
6
  status = case credential.type
7
7
  when UffizziCore::Credential::DockerHub.name
8
8
  UffizziCore::DockerHub::CredentialService.credential_correct?(credential)
9
- when UffizziCore::Credential::Github.name
10
- UffizziCore::Github::CredentialService.credential_correct?(credential)
9
+ when UffizziCore::Credential::GithubContainerRegistry.name
10
+ UffizziCore::GithubContainerRegistry::CredentialService.credential_correct?(credential)
11
11
  when UffizziCore::Credential::Azure.name
12
12
  UffizziCore::Azure::CredentialService.credential_correct?(credential)
13
13
  when UffizziCore::Credential::Google.name
@@ -29,6 +29,25 @@ module UffizziCore::DeploymentService
29
29
  deployment_form
30
30
  end
31
31
 
32
+ def update_from_compose(compose_file, project, user, deployment_id)
33
+ deployment_attributes = ActionController::Parameters.new(compose_file.template.payload)
34
+
35
+ deployment_form = UffizziCore::Api::Cli::V1::Deployment::UpdateForm.new(deployment_attributes)
36
+ deployment_form.assign_dependences!(project, user)
37
+ deployment_form.compose_file = compose_file
38
+
39
+ if deployment_form.valid?
40
+ deployment = UffizziCore::Deployment.find(deployment_id)
41
+ deployment.containers.destroy_all
42
+ deployment.compose_file.destroy if deployment.compose_file.kind.temporary?
43
+ deployment.update!(containers: deployment_form.containers, compose_file_id: compose_file.id)
44
+
45
+ return deployment
46
+ end
47
+
48
+ deployment_form
49
+ end
50
+
32
51
  def deploy_containers(deployment, repeated = false)
33
52
  if !repeated
34
53
  create_activity_items(deployment)
@@ -59,6 +78,14 @@ module UffizziCore::DeploymentService
59
78
  compose_file.destroy!
60
79
  end
61
80
 
81
+ def fail!(deployment)
82
+ deployment.fail!
83
+ compose_file = deployment.compose_file || deployment.template&.compose_file
84
+ return unless compose_file&.kind&.temporary?
85
+
86
+ compose_file.destroy!
87
+ end
88
+
62
89
  def build_subdomain(deployment)
63
90
  if deployment.continuous_preview_payload.present?
64
91
  continuous_preview_payload = deployment.continuous_preview_payload
@@ -224,12 +251,7 @@ module UffizziCore::DeploymentService
224
251
  def create_activity_items(deployment)
225
252
  deployment.active_containers.each do |container|
226
253
  repo = container.repo
227
- activity_item = case repo.type
228
- when UffizziCore::Repo::Github.name
229
- UffizziCore::ActivityItemService.create_github_item!(repo, container)
230
- else
231
- UffizziCore::ActivityItemService.create_docker_item!(repo, container)
232
- end
254
+ activity_item = UffizziCore::ActivityItemService.create_docker_item!(repo, container)
233
255
 
234
256
  create_default_activity_item_event(activity_item)
235
257
 
@@ -241,7 +263,6 @@ module UffizziCore::DeploymentService
241
263
  end
242
264
 
243
265
  def create_default_activity_item_event(activity_item)
244
- activity_item.events.create(state: UffizziCore::Event.state.building) if activity_item.github?
245
266
  activity_item.events.create(state: UffizziCore::Event.state.deploying) if activity_item.docker?
246
267
  end
247
268
 
@@ -0,0 +1,24 @@
1
+ # frozen_string_literal: true
2
+
3
+ class UffizziCore::GithubContainerRegistry::CredentialService
4
+ class << self
5
+ def credential_correct?(credential)
6
+ client(credential).authentificated?
7
+ rescue URI::InvalidURIError, Faraday::ConnectionFailed
8
+ false
9
+ end
10
+
11
+ def access_token(credential)
12
+ client(credential).token
13
+ rescue URI::InvalidURIError, Faraday::ConnectionFailed
14
+ false
15
+ end
16
+
17
+ private
18
+
19
+ def client(credential)
20
+ UffizziCore::GithubContainerRegistryClient.new(registry_url: credential.registry_url, username: credential.username,
21
+ password: credential.password)
22
+ end
23
+ end
24
+ end
@@ -42,21 +42,6 @@ class UffizziCore::ManageActivityItemsService
42
42
 
43
43
  def build_containers_replicas
44
44
  containers.map do |container|
45
- repo = container.repo
46
-
47
- if repo.github?
48
- build = container.repo.builds.deployed.last
49
-
50
- if build.nil? || build.building?
51
- return [{ id: container.id,
52
- items: [{ name: container.image_name, status: UffizziCore::Event.state.building }] }]
53
- end
54
- if !build.successful?
55
- return [{ id: container.id,
56
- items: [{ name: container.image_name, status: UffizziCore::Event.state.failed }] }]
57
- end
58
- end
59
-
60
45
  items = pods.map do |pod|
61
46
  {
62
47
  name: item_name(pod, container),
@@ -106,9 +91,7 @@ class UffizziCore::ManageActivityItemsService
106
91
  container_status(error, deployed)
107
92
  end
108
93
 
109
- def building_container_status(container)
110
- return UffizziCore::Event.state.building if container.repo.github?
111
-
94
+ def building_container_status(_container)
112
95
  UffizziCore::Event.state.deploying
113
96
  end
114
97
 
@@ -139,7 +122,9 @@ class UffizziCore::ManageActivityItemsService
139
122
  when :terminated
140
123
  UffizziCore::Event.state.failed
141
124
  when :waiting
142
- return Event.state.failed if ['ErrImagePull', 'ImagePullBackOff', 'CrashLoopBackOff'].include?(reason)
125
+ return UffizziCore::Event.state.failed if ['CrashLoopBackOff'].include?(reason)
126
+
127
+ raise UffizziCore::Deployment::ImagePullError, @deployment.id if ['ErrImagePull', 'ImagePullBackOff'].include?(reason)
143
128
 
144
129
  UffizziCore::Event.state.deploying
145
130
  else