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.
- checksums.yaml +4 -4
- data/app/clients/uffizzi_core/docker_hub_client.rb +2 -0
- data/app/clients/uffizzi_core/github_container_registry_client/request_result.rb +7 -0
- data/app/clients/uffizzi_core/github_container_registry_client.rb +52 -0
- data/app/controllers/concerns/uffizzi_core/dependency_injection_concern.rb +2 -2
- data/app/controllers/uffizzi_core/api/cli/v1/account/credentials_controller.rb +45 -9
- data/app/controllers/uffizzi_core/api/cli/v1/projects/compose_files_controller.rb +2 -2
- data/app/controllers/uffizzi_core/api/cli/v1/projects/deployments/application_controller.rb +1 -1
- data/app/controllers/uffizzi_core/api/cli/v1/projects/deployments_controller.rb +41 -10
- data/app/controllers/uffizzi_core/api/cli/v1/projects/secrets_controller.rb +18 -26
- data/app/controllers/uffizzi_core/application_controller.rb +9 -3
- data/app/errors/uffizzi_core/deployment/image_pull_error.rb +10 -0
- data/app/forms/uffizzi_core/api/cli/v1/account/credential/check_credential_form.rb +16 -0
- data/app/forms/uffizzi_core/api/cli/v1/account/credential/create_form.rb +1 -1
- data/app/forms/uffizzi_core/api/cli/v1/compose_file/check_credentials_form.rb +2 -2
- data/app/forms/uffizzi_core/api/cli/v1/compose_file/cli_form.rb +1 -18
- data/app/forms/uffizzi_core/api/cli/v1/compose_file/template_form.rb +1 -1
- data/app/forms/uffizzi_core/api/cli/v1/deployment/update_form.rb +90 -0
- data/app/forms/uffizzi_core/api/cli/v1/project/update_form.rb +1 -31
- data/app/forms/uffizzi_core/api/cli/v1/secret/bulk_assign_form.rb +39 -0
- data/app/jobs/uffizzi_core/deployment/manage_deploy_activity_item_job.rb +22 -3
- data/app/lib/uffizzi_core/rbac/user_access_service.rb +12 -14
- data/app/models/uffizzi_core/account.rb +1 -19
- data/app/models/uffizzi_core/activity_item.rb +1 -6
- data/app/models/uffizzi_core/build.rb +1 -1
- data/app/models/uffizzi_core/comment.rb +1 -1
- data/app/models/uffizzi_core/compose_file.rb +1 -1
- data/app/models/uffizzi_core/config_file.rb +1 -1
- data/app/models/uffizzi_core/container.rb +1 -1
- data/app/models/uffizzi_core/container_config_file.rb +1 -1
- data/app/models/uffizzi_core/coupon.rb +1 -1
- data/app/models/uffizzi_core/credential/github_container_registry.rb +4 -0
- data/app/models/uffizzi_core/credential.rb +3 -6
- data/app/models/uffizzi_core/deployment.rb +11 -2
- data/app/models/uffizzi_core/event.rb +1 -1
- data/app/models/uffizzi_core/invitation.rb +1 -1
- data/app/models/uffizzi_core/membership.rb +1 -1
- data/app/models/uffizzi_core/payment.rb +1 -1
- data/app/models/uffizzi_core/price.rb +1 -1
- data/app/models/uffizzi_core/product.rb +1 -1
- data/app/models/uffizzi_core/project.rb +5 -11
- data/app/models/uffizzi_core/rating.rb +1 -1
- data/app/models/uffizzi_core/repo/github_container_registry.rb +4 -0
- data/app/models/uffizzi_core/repo.rb +1 -11
- data/app/models/uffizzi_core/role.rb +2 -2
- data/app/models/uffizzi_core/secret.rb +9 -0
- data/app/models/uffizzi_core/template.rb +1 -1
- data/app/models/uffizzi_core/user.rb +1 -1
- data/app/models/uffizzi_core/user_project.rb +1 -1
- data/app/policies/uffizzi_core/api/cli/v1/account/credentials_policy.rb +8 -0
- data/app/policies/uffizzi_core/api/cli/v1/projects/deployments_policy.rb +4 -0
- data/app/repositories/uffizzi_core/credential_repo.rb +17 -22
- data/app/repositories/uffizzi_core/deployment_repo.rb +1 -0
- data/app/serializers/uffizzi_core/api/cli/v1/projects/deployment_serializer/container_serializer.rb +8 -0
- data/app/serializers/uffizzi_core/api/cli/v1/projects/secret_serializer.rb +5 -0
- data/app/serializers/uffizzi_core/controller/apply_config_file/config_file_serializer.rb +5 -0
- data/app/serializers/uffizzi_core/controller/create_credential/credential_serializer.rb +7 -3
- data/app/serializers/uffizzi_core/controller/deploy_containers/container_serializer/container_config_file_serializer/config_file_serializer.rb +8 -0
- data/app/serializers/uffizzi_core/controller/deploy_containers/container_serializer/container_config_file_serializer.rb +7 -0
- data/app/serializers/uffizzi_core/controller/deploy_containers/container_serializer.rb +4 -3
- data/app/services/uffizzi_core/activity_item_service.rb +16 -26
- data/app/services/uffizzi_core/compose_file/builders/container_builder_service.rb +11 -18
- data/app/services/uffizzi_core/compose_file/container_service.rb +13 -9
- data/app/services/uffizzi_core/compose_file/dependencies_service.rb +1 -0
- data/app/services/uffizzi_core/compose_file/services_options_service.rb +2 -2
- data/app/services/uffizzi_core/compose_file_service.rb +148 -0
- data/app/services/uffizzi_core/container_service.rb +1 -16
- data/app/services/uffizzi_core/controller_service.rb +7 -1
- data/app/services/uffizzi_core/credential_service.rb +2 -2
- data/app/services/uffizzi_core/deployment_service.rb +28 -7
- data/app/services/uffizzi_core/github_container_registry/credential_service.rb +24 -0
- data/app/services/uffizzi_core/manage_activity_items_service.rb +4 -19
- data/app/services/uffizzi_core/repo_service.rb +2 -137
- data/app/services/uffizzi_core/user_generator_service.rb +78 -0
- data/config/locales/en.activerecord.yml +5 -0
- data/config/locales/en.yml +4 -1
- data/config/routes.rb +6 -2
- data/db/migrate/20220309110201_remove_secrets_from_projects.rb +7 -0
- data/db/migrate/20220310110150_create_project_secrets.rb +14 -0
- data/db/migrate/20220329123323_rename_project_secrets_to_secrets.rb +7 -0
- data/db/migrate/20220329124542_add_resource_to_secrets.rb +7 -0
- data/db/migrate/20220329143241_remove_project_ref_from_secrets.rb +7 -0
- data/lib/tasks/uffizzi_core_tasks.rake +5 -0
- data/lib/uffizzi_core/engine.rb +35 -0
- data/lib/uffizzi_core/version.rb +1 -1
- data/lib/uffizzi_core.rb +1 -30
- data/swagger/v1/swagger.json +220 -11
- metadata +45 -25
- data/app/clients/uffizzi_core/github/app_client.rb +0 -19
- data/app/clients/uffizzi_core/github/installation_client.rb +0 -11
- data/app/clients/uffizzi_core/github/user_client.rb +0 -51
- data/app/errors/uffizzi_core/compose_file/not_found_error.rb +0 -4
- data/app/forms/uffizzi_core/api/cli/v1/project/delete_secret_form.rb +0 -27
- data/app/jobs/uffizzi_core/deployment/send_github_preview_message_job.rb +0 -13
- data/app/services/uffizzi_core/cli/compose_file_service.rb +0 -203
- data/app/services/uffizzi_core/compose_file/builders/github_repo_builder_service.rb +0 -59
- data/app/services/uffizzi_core/compose_file/services_options/build_service.rb +0 -93
- data/app/services/uffizzi_core/compose_file/update_service.rb +0 -29
- data/app/services/uffizzi_core/github/app_service.rb +0 -51
- data/app/services/uffizzi_core/github/credential_service.rb +0 -124
- data/app/services/uffizzi_core/github/message_service.rb +0 -20
- data/app/services/uffizzi_core/github_service.rb +0 -28
- 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,
|
|
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.
|
|
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, '
|
|
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.
|
|
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)
|
|
@@ -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,
|
|
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::
|
|
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 =
|
|
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
|
-
|
|
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::
|
|
10
|
-
UffizziCore::
|
|
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 =
|
|
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(
|
|
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 ['
|
|
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
|