uffizzi_core 0.1.3 → 0.1.5

Sign up to get free protection for your applications and to get access to all the features.
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