uffizzi-cli 1.0.2 → 1.0.4

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: aec0603c01f8385a1793a1017e7bc9c7624a1941389b04410aab4072ca9ba01e
4
- data.tar.gz: d3376a7c58bf38d1cb3a6b2947855f1c787f739c2384484ef150d3be0a45acbf
3
+ metadata.gz: 5aa0242e35791e35a51a850316bb18a97f1651aa345c64ee05264cb6b7faa702
4
+ data.tar.gz: bc9a8c8176c2969edf8728be715a0d45c38dab6a3d0e6da37c8022e04d9e8e24
5
5
  SHA512:
6
- metadata.gz: aa475005282e38146f1f699b6721ec0f9695fb6351f1dff84b4b226da16446b15ef8a4b30b7098828e48f56d5b2182bbc2c4a3ea4f1483fe5255acbb8083a3a9
7
- data.tar.gz: 53a8cdb71069aa0d42cb41246ffe6fb9e01681a4a541a0f421ff6fe8111b233e4067e9365110eecc09705aa5ae4c75ca2f828e88df16c8a425092de0e878ed9c
6
+ metadata.gz: 993d29e07d6fe739cd3ab82383a948ed2d251f7b00662b02b87cd3a9b1b556ee2e1ed16f224f857ce0689ac64b84d02b74aa711f24f477d546d1f13c378938a1
7
+ data.tar.gz: d91befdb081561d8395800f672918518397a70734abc3ff1ec2b57faa0180063f808722afc14de85e056507972d97eb4ef774614d1dd72a54311f5f34629abf0
@@ -270,6 +270,7 @@ module Uffizzi
270
270
  'UffizziCore::Credential::Amazon' => 'ecr',
271
271
  'UffizziCore::Credential::GithubContainerRegistry' => 'ghcr',
272
272
  'UffizziCore::Credential::Google' => 'gcr',
273
+ 'UffizziCore::Credential::DockerRegistry' => 'docker-registry',
273
274
  }
274
275
 
275
276
  map[credential]
@@ -3,30 +3,45 @@
3
3
  require 'psych'
4
4
  require 'pathname'
5
5
  require 'base64'
6
+ require 'minitar'
7
+ require 'zlib'
8
+ require 'uffizzi/services/project_service'
9
+ require 'uffizzi/services/volume_parser_service'
6
10
 
7
11
  class ComposeFileService
12
+ MAX_HOST_VOLUME_GZIP_FILE_SIZE = 1024 * 900
13
+ DEPENDENCY_CONFIG_USE_KIND = :config_map
14
+ DEPENDENCY_VOLUME_USE_KIND = :volume
15
+
8
16
  class << self
9
- def parse(compose_content, compose_file_path)
17
+ def parse(compose_content, compose_file_dir)
10
18
  compose_data = parse_compose_content_to_object(compose_content)
11
19
 
12
- env_files = prepare_services_env_files(compose_data['services']).flatten.uniq
13
- config_files = fetch_configs(compose_data['configs'])
14
- prepare_dependencies(env_files, config_files, compose_file_path)
20
+ services = compose_data['services']
21
+ env_files_paths = prepare_env_files_paths(services).flatten.uniq
22
+ config_files_paths = prepare_config_files_paths(compose_data['configs'])
23
+ host_volumes_paths = prepare_host_volumes_paths(services)
24
+ prepare_dependencies(compose_file_dir, env_files_paths, config_files_paths, host_volumes_paths)
15
25
  end
16
26
 
17
27
  private
18
28
 
19
- def prepare_dependencies(env_files, config_files, compose_file_path)
20
- prepare_dependency_files_data(env_files + config_files, compose_file_path)
29
+ def prepare_dependencies(compose_file_dir, env_files_paths, config_files_paths, host_volumes_paths)
30
+ config_files_attrs = prepare_dependency_configs_files(env_files_paths + config_files_paths, compose_file_dir)
31
+ host_volumes_attrs = prepare_dependency_host_volumes_files(host_volumes_paths, compose_file_dir)
32
+
33
+ config_files_attrs + host_volumes_attrs
21
34
  end
22
35
 
23
- def prepare_dependency_files_data(dependency_files, compose_file_path)
24
- dependency_files.map do |dependency_file|
25
- dependency_file_data = Psych.load(File.read("#{compose_file_path}/#{dependency_file}"))
36
+ def prepare_dependency_configs_files(dependency_file_paths, compose_file_dir)
37
+ dependency_file_paths.map do |dependency_file_path|
38
+ dependency_file_content = Psych.load(File.read("#{compose_file_dir}/#{dependency_file_path}"))
39
+
26
40
  {
27
- path: dependency_file,
28
- source: dependency_file,
29
- content: Base64.encode64(dependency_file_data),
41
+ path: dependency_file_path,
42
+ source: dependency_file_path,
43
+ content: Base64.encode64(dependency_file_content),
44
+ use_kind: DEPENDENCY_CONFIG_USE_KIND,
30
45
  }
31
46
  end
32
47
  rescue Errno::ENOENT => e
@@ -34,7 +49,48 @@ class ComposeFileService
34
49
  raise Uffizzi::Error.new("The config file #{dependency_path} does not exist")
35
50
  end
36
51
 
37
- def fetch_configs(configs_data)
52
+ def prepare_dependency_host_volumes_files(dependency_file_paths, compose_file_dir)
53
+ base_dependency_paths = dependency_file_paths.map do |dependency_file_path|
54
+ dependency_pathname = Pathname.new(dependency_file_path)
55
+ next dependency_file_path if dependency_pathname.absolute?
56
+ next "#{compose_file_dir}/#{dependency_pathname.cleanpath}" if dependency_file_path.start_with?('./')
57
+ next "#{compose_file_dir}/#{dependency_pathname}" if dependency_file_path.start_with?('../')
58
+
59
+ raise Uffizzi::Error.new("Unsupported path #{dependency_pathname}")
60
+ end
61
+
62
+ base_dependency_paths.zip(dependency_file_paths).map do |base_dependency_path, dependency_file_path|
63
+ absolute_dependency_path = Pathname.new(base_dependency_path).realpath.to_s
64
+ dependency_file_content = prepare_host_volume_file_content(absolute_dependency_path)
65
+
66
+ {
67
+ path: absolute_dependency_path,
68
+ source: dependency_file_path,
69
+ content: dependency_file_content,
70
+ use_kind: DEPENDENCY_VOLUME_USE_KIND,
71
+ is_file: Pathname.new(absolute_dependency_path).file?,
72
+ }
73
+ end
74
+ rescue Errno::ENOENT => e
75
+ dependency_path = e.message.split('- ').last
76
+ raise Uffizzi::Error.new("No such file or directory: #{dependency_path}")
77
+ end
78
+
79
+ def prepare_host_volume_file_content(path)
80
+ tmp_tar_name = Base64.encode64(path)[0..20]
81
+ tmp_tar_path = "/tmp/#{tmp_tar_name}.tar.gz"
82
+
83
+ Minitar.pack(path, Zlib::GzipWriter.new(File.open(tmp_tar_path, 'wb')))
84
+ gzipped_file_size = Pathname.new(tmp_tar_path).size
85
+
86
+ if gzipped_file_size > MAX_HOST_VOLUME_GZIP_FILE_SIZE
87
+ Uffizzi.ui.say("File/Directory too big by path: #{path}. Gzipped tar archive size is #{gzipped_file_size}")
88
+ end
89
+
90
+ Base64.encode64(File.binread(tmp_tar_path))
91
+ end
92
+
93
+ def prepare_config_files_paths(configs_data)
38
94
  return [] if configs_data.nil?
39
95
 
40
96
  Uffizzi.ui.say("Unsupported type of #{:configs} option") unless configs_data.is_a?(Hash)
@@ -68,26 +124,16 @@ class ComposeFileService
68
124
  end
69
125
  end
70
126
 
71
- def prepare_services_env_files(services)
127
+ def prepare_env_files_paths(services)
72
128
  return [] if services.nil?
73
129
 
74
- services.keys.map do |service|
75
- service_env_files = prepare_service_env_files(services.fetch(service))
76
-
77
- service_env_files
78
- end
79
- end
80
-
81
- def prepare_service_env_files(service_data)
82
- env_files_data = []
83
- service_data.each_pair do |key, value|
84
- key_sym = key.to_sym
85
- if key_sym == :env_file
86
- env_files_data << parse_env_file(value)
87
- end
88
- end
89
-
90
- env_files_data
130
+ services
131
+ .values
132
+ .select { |s| s.has_key?('env_file') }
133
+ .map { |s| parse_env_file(s['env_file']) }
134
+ .flatten
135
+ .compact
136
+ .uniq
91
137
  end
92
138
 
93
139
  def parse_compose_content_to_object(compose_content)
@@ -101,5 +147,17 @@ class ComposeFileService
101
147
 
102
148
  compose_data
103
149
  end
150
+
151
+ def prepare_host_volumes_paths(services)
152
+ return [] if services.nil?
153
+
154
+ services
155
+ .values
156
+ .select { |s| s.has_key?('volumes') }
157
+ .map { |s| VolumeParserService.parse(s['volumes']) }
158
+ .flatten
159
+ .compact
160
+ .uniq
161
+ end
104
162
  end
105
163
  end
@@ -0,0 +1,47 @@
1
+ # frozen_string_literal: true
2
+
3
+ class VolumeParserService
4
+ class << self
5
+ def parse(volumes)
6
+ return [] if volumes.empty?
7
+
8
+ Uffizzi.ui.say("Volumes '#{volumes}' should be an array") unless volumes.is_a?(Array)
9
+
10
+ volumes.map { |volume| parse_volume(volume) }
11
+ end
12
+
13
+ private
14
+
15
+ def parse_volume(volume)
16
+ case volume
17
+ when String
18
+ process_short_syntax(volume)
19
+ when Hash
20
+ process_long_syntax(volume)
21
+ else
22
+ Uffizzi.ui.say("Unsupported type of '#{volumes}' option")
23
+ end
24
+ end
25
+
26
+ def process_short_syntax(volume_data)
27
+ path_part1, path_part2 = volume_data.split(':').map(&:strip)
28
+
29
+ path_part1 if host_volume?(path_part1, path_part2)
30
+ end
31
+
32
+ def process_long_syntax(volume_data)
33
+ source_path = volume_data['source'].to_s.strip
34
+ target_path = volume_data['target'].to_s.strip
35
+
36
+ source_path if host_volume?(source_path, target_path)
37
+ end
38
+
39
+ def host_volume?(source_path, target_path)
40
+ path?(source_path) && path?(target_path)
41
+ end
42
+
43
+ def path?(path)
44
+ path.to_s.start_with?('/', './', '../')
45
+ end
46
+ end
47
+ end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Uffizzi
4
- VERSION = '1.0.2'
4
+ VERSION = '1.0.4'
5
5
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: uffizzi-cli
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.2
4
+ version: 1.0.4
5
5
  platform: ruby
6
6
  authors:
7
7
  - Josh Thurman
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: exe
11
11
  cert_chain: []
12
- date: 2022-09-14 00:00:00.000000000 Z
12
+ date: 2022-10-18 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: awesome_print
@@ -25,6 +25,20 @@ dependencies:
25
25
  - - ">="
26
26
  - !ruby/object:Gem::Version
27
27
  version: '0'
28
+ - !ruby/object:Gem::Dependency
29
+ name: minitar
30
+ requirement: !ruby/object:Gem::Requirement
31
+ requirements:
32
+ - - ">="
33
+ - !ruby/object:Gem::Version
34
+ version: '0'
35
+ type: :runtime
36
+ prerelease: false
37
+ version_requirements: !ruby/object:Gem::Requirement
38
+ requirements:
39
+ - - ">="
40
+ - !ruby/object:Gem::Version
41
+ version: '0'
28
42
  - !ruby/object:Gem::Dependency
29
43
  name: thor
30
44
  requirement: !ruby/object:Gem::Requirement
@@ -109,6 +123,20 @@ dependencies:
109
123
  - - ">="
110
124
  - !ruby/object:Gem::Version
111
125
  version: '0'
126
+ - !ruby/object:Gem::Dependency
127
+ name: deepsort
128
+ requirement: !ruby/object:Gem::Requirement
129
+ requirements:
130
+ - - "~>"
131
+ - !ruby/object:Gem::Version
132
+ version: 0.4.5
133
+ type: :development
134
+ prerelease: false
135
+ version_requirements: !ruby/object:Gem::Requirement
136
+ requirements:
137
+ - - "~>"
138
+ - !ruby/object:Gem::Version
139
+ version: 0.4.5
112
140
  - !ruby/object:Gem::Dependency
113
141
  name: factory_bot
114
142
  requirement: !ruby/object:Gem::Requirement
@@ -123,6 +151,20 @@ dependencies:
123
151
  - - ">="
124
152
  - !ruby/object:Gem::Version
125
153
  version: '0'
154
+ - !ruby/object:Gem::Dependency
155
+ name: fakefs
156
+ requirement: !ruby/object:Gem::Requirement
157
+ requirements:
158
+ - - ">="
159
+ - !ruby/object:Gem::Version
160
+ version: '0'
161
+ type: :development
162
+ prerelease: false
163
+ version_requirements: !ruby/object:Gem::Requirement
164
+ requirements:
165
+ - - ">="
166
+ - !ruby/object:Gem::Version
167
+ version: '0'
126
168
  - !ruby/object:Gem::Dependency
127
169
  name: faker
128
170
  requirement: !ruby/object:Gem::Requirement
@@ -347,6 +389,7 @@ files:
347
389
  - lib/uffizzi/services/env_variables_service.rb
348
390
  - lib/uffizzi/services/preview_service.rb
349
391
  - lib/uffizzi/services/project_service.rb
392
+ - lib/uffizzi/services/volume_parser_service.rb
350
393
  - lib/uffizzi/shell.rb
351
394
  - lib/uffizzi/version.rb
352
395
  - man/uffizzi