uffizzi_core 0.4.0 → 0.5.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/app/controllers/concerns/uffizzi_core/dependency_injection_concern.rb +5 -3
- data/app/forms/uffizzi_core/api/cli/v1/compose_file/cli_form.rb +1 -0
- data/app/services/uffizzi_core/compose_file/builders/container_builder_service.rb +2 -2
- data/app/services/uffizzi_core/compose_file/parsers/services/image_parser_service.rb +1 -1
- data/app/services/uffizzi_core/compose_file/parsers/services/{volumes_service.rb → volumes_parser_service.rb} +38 -23
- data/app/services/uffizzi_core/compose_file/parsers/services_parser_service.rb +13 -3
- data/app/services/uffizzi_core/deployment_service.rb +10 -3
- data/config/locales/en.activerecord.yml +4 -0
- data/config/locales/en.yml +1 -0
- data/lib/uffizzi_core/version.rb +1 -1
- metadata +3 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 377c1d90c271757c6d8728d3f4d3dd6c7499b22f606bfbf37c4e6545b074bc90
|
4
|
+
data.tar.gz: 4cbaac6e361d336cd4c13f004e2b76b9df0ac44638f2eeaa2e94afaff203c75b
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: e68d968cd53a9ee833092724977d6b0752988225640488bf3c03af081bbcc00173c9e62a85ccf3403ef174a196bc86edbd4f1065dfc25c93dcbf4029015ee003
|
7
|
+
data.tar.gz: 39cf4ac688207af05cdc2c7cdcc8451d2bcdd00d202e014fe9c275d63c53780868f7f2ad7bd4b1243fe6e2ac18389dde06b24e485d464338d4d776a91c34a849
|
@@ -7,10 +7,12 @@ module UffizziCore::DependencyInjectionConcern
|
|
7
7
|
UffizziCore::UserAccessService.new(module_class(:rbac))
|
8
8
|
end
|
9
9
|
|
10
|
-
def
|
11
|
-
|
10
|
+
def find_build_parser_module
|
11
|
+
module_class(:build_parser)
|
12
|
+
end
|
12
13
|
|
13
|
-
|
14
|
+
def find_volume_parser_module
|
15
|
+
module_class(:volume_parser)
|
14
16
|
end
|
15
17
|
|
16
18
|
def password_protection_module
|
@@ -19,7 +19,7 @@ class UffizziCore::ComposeFile::Builders::ContainerBuilderService
|
|
19
19
|
secrets = container_data[:secrets] || []
|
20
20
|
container_name = container_data[:container_name]
|
21
21
|
healthcheck_data = container_data[:healthcheck] || {}
|
22
|
-
|
22
|
+
volumes_data = container_data[:volumes] || []
|
23
23
|
|
24
24
|
env_file_dependencies = UffizziCore::ComposeFile::GithubDependenciesService.env_file_dependencies_for_container(compose_dependencies,
|
25
25
|
container_name)
|
@@ -46,7 +46,7 @@ class UffizziCore::ComposeFile::Builders::ContainerBuilderService
|
|
46
46
|
service_name: container_name,
|
47
47
|
name: container_name,
|
48
48
|
healthcheck: healthcheck_data,
|
49
|
-
volumes:
|
49
|
+
volumes: volumes_data,
|
50
50
|
}
|
51
51
|
end
|
52
52
|
# rubocop:enable Metrics/PerceivedComplexity
|
@@ -33,7 +33,7 @@ class UffizziCore::ComposeFile::Parsers::Services::ImageParserService
|
|
33
33
|
when 1
|
34
34
|
image_path_parts[0]
|
35
35
|
when 2
|
36
|
-
uri_pattern = /\A\w[\w.-]+:\d
|
36
|
+
uri_pattern = /\A\w[\w.-]+:\d+\//
|
37
37
|
tag_pattern = /:\w[\w.-]*\z/
|
38
38
|
if uri_pattern.match?(value)
|
39
39
|
"#{image_path_parts[0]}:#{image_path_parts[1]}"
|
@@ -1,6 +1,6 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
class UffizziCore::ComposeFile::Parsers::Services::
|
3
|
+
class UffizziCore::ComposeFile::Parsers::Services::VolumesParserService
|
4
4
|
HOST_VOLUME_TYPE = :host
|
5
5
|
NAMED_VOLUME_TYPE = :named
|
6
6
|
ANONYMOUS_VOLUME_TYPE = :anonymous
|
@@ -8,15 +8,15 @@ class UffizziCore::ComposeFile::Parsers::Services::VolumesService
|
|
8
8
|
READ_WRITE_OPTION = 'rw'
|
9
9
|
|
10
10
|
class << self
|
11
|
-
def parse(volumes,
|
11
|
+
def parse(volumes, volumes_payload)
|
12
12
|
return [] if volumes.blank?
|
13
13
|
|
14
14
|
volumes.map do |volume|
|
15
15
|
volume_data = case volume
|
16
16
|
when String
|
17
|
-
process_short_syntax(volume,
|
17
|
+
process_short_syntax(volume, volumes_payload)
|
18
18
|
when Hash
|
19
|
-
process_long_syntax(volume,
|
19
|
+
process_long_syntax(volume, volumes_payload)
|
20
20
|
else
|
21
21
|
raise UffizziCore::ComposeFile::ParseError, I18n.t('compose.invalid_type', option: :volumes)
|
22
22
|
end
|
@@ -27,48 +27,49 @@ class UffizziCore::ComposeFile::Parsers::Services::VolumesService
|
|
27
27
|
|
28
28
|
private
|
29
29
|
|
30
|
-
def process_short_syntax(volume_data,
|
30
|
+
def process_short_syntax(volume_data, volumes_payload)
|
31
31
|
volume_parts = volume_data.split(':').map(&:strip)
|
32
|
-
|
32
|
+
read_only = volume_parts.last.to_s.downcase == READONLY_OPTION
|
33
33
|
part1, part2 = volume_parts
|
34
34
|
source_path = part1
|
35
35
|
target_path = [READONLY_OPTION, READ_WRITE_OPTION].include?(part2.to_s.downcase) ? nil : part2
|
36
36
|
|
37
37
|
raise UffizziCore::ComposeFile::ParseError, I18n.t('compose.volume_prop_is_required', prop_name: 'source') if source_path.blank?
|
38
38
|
|
39
|
-
|
40
|
-
|
41
|
-
check_named_volume_existence(source_path, target_path, named_volumes_names, service_name) if volume_type == NAMED_VOLUME_TYPE
|
42
|
-
|
43
|
-
{
|
44
|
-
source: source_path,
|
45
|
-
target: target_path,
|
46
|
-
type: volume_type,
|
47
|
-
read_only: has_read_only,
|
48
|
-
}
|
39
|
+
build_volume_attributes(source_path, target_path, read_only, volumes_payload)
|
49
40
|
end
|
50
41
|
|
51
|
-
def process_long_syntax(volume_data,
|
42
|
+
def process_long_syntax(volume_data, volumes_payload)
|
52
43
|
source_path = volume_data['source'].to_s.strip
|
53
44
|
target_path = volume_data['target'].to_s.strip
|
54
|
-
|
45
|
+
read_only = volume_data['read_only'].present?
|
55
46
|
|
56
47
|
raise UffizziCore::ComposeFile::ParseError, I18n.t('compose.volume_prop_is_required', prop_name: 'source') if source_path.blank?
|
57
48
|
raise UffizziCore::ComposeFile::ParseError, I18n.t('compose.volume_prop_is_required', prop_name: 'target') if target_path.blank?
|
58
49
|
|
59
|
-
|
50
|
+
build_volume_attributes(source_path, target_path, read_only, volumes_payload)
|
51
|
+
end
|
60
52
|
|
61
|
-
|
53
|
+
def build_volume_attributes(source_path, target_path, read_only, params = {})
|
54
|
+
volume_type = build_volume_type(source_path, target_path)
|
55
|
+
|
56
|
+
if volume_type == NAMED_VOLUME_TYPE
|
57
|
+
validate_named_volume(source_path, target_path, params[:named_volumes_names], params[:service_name])
|
58
|
+
end
|
59
|
+
|
60
|
+
if volume_type == ANONYMOUS_VOLUME_TYPE
|
61
|
+
validate_anonymous_volume(source_path)
|
62
|
+
end
|
62
63
|
|
63
64
|
{
|
64
65
|
source: source_path,
|
65
66
|
target: target_path,
|
66
67
|
type: volume_type,
|
67
|
-
read_only:
|
68
|
+
read_only: read_only,
|
68
69
|
}
|
69
70
|
end
|
70
71
|
|
71
|
-
def
|
72
|
+
def build_volume_type(source_path, target_path)
|
72
73
|
if path?(source_path) && path?(target_path)
|
73
74
|
raise UffizziCore::ComposeFile::ParseError, I18n.t('compose.volume_type_not_supported', type: HOST_VOLUME_TYPE)
|
74
75
|
end
|
@@ -83,12 +84,26 @@ class UffizziCore::ComposeFile::Parsers::Services::VolumesService
|
|
83
84
|
/^(\/|\.\/|~\/)/.match?(path)
|
84
85
|
end
|
85
86
|
|
86
|
-
def
|
87
|
+
def validate_named_volume(source_path, target_path, named_volumes_names, service_name)
|
88
|
+
if path_has_only_root?(target_path)
|
89
|
+
raise UffizziCore::ComposeFile::ParseError, I18n.t('compose.invalid_volume_destination', spec: "#{source_path}:#{target_path}")
|
90
|
+
end
|
91
|
+
|
87
92
|
return if named_volumes_names.include?(source_path)
|
88
93
|
|
89
94
|
raise UffizziCore::ComposeFile::ParseError, I18n.t('compose.named_volume_not_exists', source_path: source_path,
|
90
95
|
target_path: target_path,
|
91
96
|
service_name: service_name)
|
92
97
|
end
|
98
|
+
|
99
|
+
def validate_anonymous_volume(path)
|
100
|
+
if path_has_only_root?(path)
|
101
|
+
raise UffizziCore::ComposeFile::ParseError, I18n.t('compose.invalid_volume_destination', spec: path)
|
102
|
+
end
|
103
|
+
end
|
104
|
+
|
105
|
+
def path_has_only_root?(path)
|
106
|
+
path.size == 1 && path.include?('/')
|
107
|
+
end
|
93
108
|
end
|
94
109
|
end
|
@@ -51,9 +51,9 @@ class UffizziCore::ComposeFile::Parsers::ServicesParserService
|
|
51
51
|
when :'x-uffizzi-continuous-preview', :'x-uffizzi-continuous-previews'
|
52
52
|
UffizziCore::ComposeFile::Parsers::ContinuousPreviewParserService.parse(value)
|
53
53
|
when :volumes
|
54
|
-
|
55
|
-
|
56
|
-
|
54
|
+
parse_volumes(value, named_volumes_names: global_named_volume_names,
|
55
|
+
service_name: service_name,
|
56
|
+
compose_payload: compose_payload)
|
57
57
|
end
|
58
58
|
end
|
59
59
|
|
@@ -63,9 +63,19 @@ class UffizziCore::ComposeFile::Parsers::ServicesParserService
|
|
63
63
|
end
|
64
64
|
|
65
65
|
def check_and_parse_build_option(value, compose_payload)
|
66
|
+
build_parser_module = find_build_parser_module
|
67
|
+
|
66
68
|
raise UffizziCore::ComposeFile::ParseError, I18n.t('compose.not_implemented', option: :build) unless build_parser_module
|
67
69
|
|
68
70
|
build_parser_module.parse(value, compose_payload)
|
69
71
|
end
|
72
|
+
|
73
|
+
def parse_volumes(value, volumes_payload)
|
74
|
+
volume_parser_module = find_volume_parser_module
|
75
|
+
|
76
|
+
return UffizziCore::ComposeFile::Parsers::Services::VolumesParserService.parse(value, volumes_payload) unless volume_parser_module
|
77
|
+
|
78
|
+
volume_parser_module.parse(value, volumes_payload)
|
79
|
+
end
|
70
80
|
end
|
71
81
|
end
|
@@ -38,9 +38,13 @@ class UffizziCore::DeploymentService
|
|
38
38
|
|
39
39
|
ActiveRecord::Base.transaction do
|
40
40
|
deployment.containers.destroy_all
|
41
|
-
deployment.compose_file.destroy! if deployment.compose_file
|
41
|
+
deployment.compose_file.destroy! if deployment.compose_file&.kind&.temporary?
|
42
42
|
|
43
|
-
deployment.update!(
|
43
|
+
deployment.update!(
|
44
|
+
containers: deployment_form.containers,
|
45
|
+
compose_file_id: compose_file.id,
|
46
|
+
creation_source: UffizziCore::Deployment.creation_source.compose_file_manual,
|
47
|
+
)
|
44
48
|
end
|
45
49
|
|
46
50
|
deployment
|
@@ -304,7 +308,10 @@ class UffizziCore::DeploymentService
|
|
304
308
|
subdomain_length_limit = Settings.deployment.subdomain.length_limit
|
305
309
|
return rfc_subdomain if rfc_subdomain.length <= subdomain_length_limit
|
306
310
|
|
307
|
-
rfc_subdomain.slice(0, subdomain_length_limit)
|
311
|
+
sliced_subdomain = rfc_subdomain.slice(0, subdomain_length_limit)
|
312
|
+
return sliced_subdomain.chop if sliced_subdomain.end_with?('-')
|
313
|
+
|
314
|
+
sliced_subdomain
|
308
315
|
end
|
309
316
|
end
|
310
317
|
end
|
@@ -21,3 +21,7 @@ en:
|
|
21
21
|
containers:
|
22
22
|
max_memory_limit_error: 'Memory limit of containers must be less than %{max}'
|
23
23
|
max_memory_request_error: 'Memory request of containers must be less than %{max}'
|
24
|
+
uffizzi_core/user:
|
25
|
+
attributes:
|
26
|
+
email:
|
27
|
+
invalid: Invalid email address
|
data/config/locales/en.yml
CHANGED
@@ -66,6 +66,7 @@ en:
|
|
66
66
|
volume_invalid_name: "Volumes value '%{name}' does not match any of the regexes: '^[a-zA-Z0-9._-]+$'"
|
67
67
|
volume_type_not_supported: Volumes with type '%{type}' does not supported
|
68
68
|
named_volume_not_exists: Named volume '%{source_path}:%{target_path}' is used in service '%{service_name}' but no declaration was found in the volumes section.
|
69
|
+
invalid_volume_destination: Invalid volume specification '%{spec}' destination can't be '/'
|
69
70
|
secrets:
|
70
71
|
duplicates_exists: Secret with key %{secrets} already exist.
|
71
72
|
invalid_key_length: A secret key must be no longer than 256 characters.
|
data/lib/uffizzi_core/version.rb
CHANGED
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: uffizzi_core
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.5.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Josh Thurman
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2022-08-
|
12
|
+
date: 2022-08-15 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: aasm
|
@@ -920,7 +920,7 @@ files:
|
|
920
920
|
- app/services/uffizzi_core/compose_file/parsers/services/healthcheck_parser_service.rb
|
921
921
|
- app/services/uffizzi_core/compose_file/parsers/services/image_parser_service.rb
|
922
922
|
- app/services/uffizzi_core/compose_file/parsers/services/secrets_parser_service.rb
|
923
|
-
- app/services/uffizzi_core/compose_file/parsers/services/
|
923
|
+
- app/services/uffizzi_core/compose_file/parsers/services/volumes_parser_service.rb
|
924
924
|
- app/services/uffizzi_core/compose_file/parsers/services_parser_service.rb
|
925
925
|
- app/services/uffizzi_core/compose_file/parsers/variables_parser_service.rb
|
926
926
|
- app/services/uffizzi_core/compose_file/parsers/volumes_parser_service.rb
|