uffizzi_core 2.1.17 → 2.1.19

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: 4581c984a5b49487e44a090db8d04c38bf2dd9203926c7e5087596d1492fc691
4
- data.tar.gz: 41c7640b4bf9f855eafda79e05e057a45fb6f4951751bdde9e9e719017f2196d
3
+ metadata.gz: ba797af235e97eb6e8a82885dfa26e5ef451333937c874c6aaa958bfdc128efc
4
+ data.tar.gz: abbfad0cbba592e5230c2e2a5ac4ca4b2220e343a6ba36b770d52430a9836fb8
5
5
  SHA512:
6
- metadata.gz: 99b3267e848c4c8e78210147e6954c9e8c5ef1a329ef82f37bef79b39a0d662cc6b599a5fbdc682743ad1cfee038971d74139aea283b0745b2950174b0b9530a
7
- data.tar.gz: 8c7d55bb0bc141b1eac76103f6f3b7f0ba80275501d322674451e73cee29f6ac14aa41cce4cdcca4f8992f425e6888c5354c01f952a6625616b814564c981f9a
6
+ metadata.gz: 6fa933fd65908f6313e68d5f91de1f5f4c7b99d946c9d6f486207677baee8f8518a266875d4cec4f5a95a39f40553595c1d5cd9290ffd37db8bcfa0e1d2fe61a
7
+ data.tar.gz: 00bd7079d17e53872cf3ff6e3b1ffda37bd445f47930e85737bff4bd1990dcb0f9d286f76e7b027854c6bd4e063f74b3318e3057408904abaead27c627713e6d
@@ -9,6 +9,7 @@ class UffizziCore::Api::Cli::V1::Deployment::CreateForm < UffizziCore::Deploymen
9
9
  :image,
10
10
  :service_name,
11
11
  :tag,
12
+ :full_image_name,
12
13
  :port,
13
14
  :public,
14
15
  :memory_limit,
@@ -9,6 +9,7 @@ class UffizziCore::Api::Cli::V1::Deployment::UpdateForm < UffizziCore::Deploymen
9
9
  :service_name,
10
10
  :tag,
11
11
  :port,
12
+ :full_image_name,
12
13
  :public,
13
14
  :memory_limit,
14
15
  :memory_request,
@@ -24,12 +24,8 @@ module UffizziCore::Concerns::Models::Deployment
24
24
  has_many :activity_items, dependent: :destroy
25
25
 
26
26
  has_one :ingress_container, -> { where(receive_incoming_requests: true) }, class_name: UffizziCore::Container.name
27
-
28
27
  validates :kind, presence: true
29
28
 
30
- enumerize :creation_source, in: [:manual, :demo, :continuous_preview, :compose_file_manual, :compose_file_continuous_preview],
31
- predicates: true, scope: true, default: :manual
32
-
33
29
  accepts_nested_attributes_for :containers, allow_destroy: true
34
30
 
35
31
  after_destroy_commit :clean
@@ -21,4 +21,7 @@
21
21
 
22
22
  class UffizziCore::Deployment < UffizziCore::ApplicationRecord
23
23
  include UffizziCore::Concerns::Models::Deployment
24
+
25
+ const_set(:COMPOSE_FILE_MANUAL, :compose_file_manual)
26
+ validates :creation_source, presence: true
24
27
  end
@@ -3,8 +3,7 @@
3
3
  class UffizziCore::Controller::DeployContainers::ContainerSerializer < UffizziCore::BaseSerializer
4
4
  attributes :id,
5
5
  :kind,
6
- :image,
7
- :tag,
6
+ :full_image_name,
8
7
  :variables,
9
8
  :secret_variables,
10
9
  :memory_limit,
@@ -24,26 +23,6 @@ class UffizziCore::Controller::DeployContainers::ContainerSerializer < UffizziCo
24
23
  has_many :container_config_files
25
24
  has_many :container_host_volume_files
26
25
 
27
- def image
28
- repo = object.repo
29
- case repo.type
30
- when
31
- UffizziCore::Repo::Google.name,
32
- UffizziCore::Repo::Amazon.name,
33
- UffizziCore::Repo::Azure.name,
34
- UffizziCore::Repo::GithubContainerRegistry.name,
35
- UffizziCore::Repo::DockerRegistry.name
36
-
37
- build_registry_image(repo)
38
- else
39
- object.image
40
- end
41
- end
42
-
43
- def tag
44
- object.tag
45
- end
46
-
47
26
  def entrypoint
48
27
  object.entrypoint.blank? ? nil : JSON.parse(object.entrypoint)
49
28
  end
@@ -65,15 +44,4 @@ class UffizziCore::Controller::DeployContainers::ContainerSerializer < UffizziCo
65
44
 
66
45
  object.healthcheck.merge('test' => new_command)
67
46
  end
68
-
69
- private
70
-
71
- def build_registry_image(repo)
72
- credential = UffizziCore::RepoService.credential(repo)
73
- return object.image if credential.blank?
74
-
75
- registry_host = URI.parse(credential.registry_url).host
76
-
77
- "#{registry_host}/#{object.image}"
78
- end
79
47
  end
@@ -33,6 +33,7 @@ class UffizziCore::ComposeFile::Builders::ContainerBuilderService
33
33
  {
34
34
  tag: tag(image_data, repo_attributes),
35
35
  port: port(container_name, ingress_data),
36
+ full_image_name: full_image_name(image_data, build_data, repo_attributes),
36
37
  image: image(container_data, image_data, build_data, credentials),
37
38
  public: is_ingress,
38
39
  entrypoint: entrypoint(container_data),
@@ -134,6 +135,12 @@ class UffizziCore::ComposeFile::Builders::ContainerBuilderService
134
135
  container_registry.image_name(credentials)
135
136
  end
136
137
 
138
+ def full_image_name(image_data, build_data, repo_attributes)
139
+ return image_data[:full_image_name] if image_data.present?
140
+
141
+ "#{build_data[:account_name]}/#{build_data[:repository_name]}:#{repo_attributes[:branch]}"
142
+ end
143
+
137
144
  def ingress_container?(container_name, ingress)
138
145
  ingress[:container_name] == container_name
139
146
  end
@@ -1,104 +1,41 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require 'docker_distribution'
4
+
3
5
  class UffizziCore::ComposeFile::Parsers::Services::ImageParserService
6
+ DEFAULT_TAG = Settings.compose.default_tag
4
7
  class << self
5
8
  def parse(value)
6
9
  return {} if value.blank?
7
10
 
8
- image_path, tag = get_image_path_and_tag(value)
9
- raise_parse_error(value) if image_path.blank?
10
-
11
- tag = Settings.compose.default_tag if tag.blank?
12
-
13
- formatted_image_path = image_path.downcase
14
- if url?(formatted_image_path)
15
- host, namespace, name = parse_image_url(formatted_image_path)
16
- else
17
- namespace, name = parse_docker_hub_image(formatted_image_path)
18
- end
11
+ parsed_image = DockerDistribution::Normalize.parse_docker_ref(value)
12
+ image_path = parsed_image.path
13
+ namespace, name = get_namespace_and_name(image_path)
14
+ full_image_name = "#{[parsed_image.domain, parsed_image.path].compact.join('/')}:#{parsed_image.tag}"
19
15
 
20
16
  {
21
- registry_url: host,
17
+ registry_url: parsed_image.domain,
22
18
  namespace: namespace,
23
19
  name: name,
24
- tag: tag,
20
+ tag: parsed_image.tag,
21
+ full_image_name: full_image_name,
25
22
  }
23
+ rescue DockerDistribution::NameContainsUppercase
24
+ raise_parse_error(I18n.t('compose.image_name_contains_uppercase_value', value: value))
25
+ rescue DockerDistribution::ReferenceInvalidFormat, DockerDistribution::ParseNormalizedNamedError
26
+ raise_parse_error(I18n.t('compose.invalid_image_value', value: value))
26
27
  end
27
28
 
28
29
  private
29
30
 
30
- def raise_parse_error(value)
31
- raise UffizziCore::ComposeFile::ParseError, I18n.t('compose.invalid_image_value', value: value)
32
- end
33
-
34
- def get_image_path_and_tag(value)
35
- image_path_parts = value.split(':')
36
-
37
- case image_path_parts.size
38
- when 1
39
- image_path_parts[0]
40
- when 2
41
- uri_pattern = /\A\w[\w.-]+:\d+\//
42
- tag_pattern = /:\w[\w.-]*\z/
43
- if uri_pattern.match?(value)
44
- "#{image_path_parts[0]}:#{image_path_parts[1]}"
45
- elsif tag_pattern.match?(value)
46
- [image_path_parts[0], image_path_parts[1]]
47
- else
48
- raise_parse_error(value)
49
- end
50
- when 3
51
- ["#{image_path_parts[0]}:#{image_path_parts[1]}", image_path_parts[2]]
52
- else
53
- raise_parse_error(value)
54
- end
55
- end
56
-
57
- def url?(image_path)
58
- uri = URI(add_https_if_needed(image_path))
59
- uri.host.present? && uri.host =~ /(localhost(:\d+)?|\w+\.(\w+\.)*\w+)/ && uri.path.present?
60
- rescue URI::InvalidURIError
61
- false
62
- end
63
-
64
- def add_https_if_needed(image_path)
65
- image_path.start_with?('https://') ? image_path : "https://#{image_path}"
66
- end
67
-
68
- def parse_image_url(image_path)
69
- uri = URI(add_https_if_needed(image_path))
70
- host = "#{uri.host}:#{uri.port}"
71
- path = uri.path.delete_prefix('/')
72
- namespace, name = get_namespace_and_name(path)
73
- [host, namespace, name]
74
- end
75
-
76
- def get_namespace_and_name(path)
77
- path_parts = path.rpartition('/')
78
-
79
- if path_parts.first.empty?
80
- [nil, path_parts.last]
81
- else
82
- [path_parts.first, path_parts.last]
83
- end
84
- end
85
-
86
- def parse_docker_hub_image(image_name)
87
- if contains_account_name?(image_name)
88
- namespace = image_name.split('/').first
89
- name = image_name.split('/', 2).last.delete_suffix('/')
90
- else
91
- namespace = Settings.docker_hub.public_namespace
92
- name = image_name
93
- end
94
-
95
- [namespace, name]
31
+ def raise_parse_error(message)
32
+ raise UffizziCore::ComposeFile::ParseError, message
96
33
  end
97
34
 
98
- def contains_account_name?(image_name)
99
- image_name_parts = image_name.split('/')
35
+ def get_namespace_and_name(image_path)
36
+ return [nil, image_path] unless image_path.index('/').present?
100
37
 
101
- image_name_parts.count > 1
38
+ image_path.split('/')
102
39
  end
103
40
  end
104
41
  end
@@ -190,7 +190,7 @@ class UffizziCore::ComposeFileService
190
190
  err = [e.problem, e.context].compact.join(' ')
191
191
  raise UffizziCore::ComposeFile::ParseError, I18n.t('compose.invalid_file', err: err, line: e.line, column: e.column)
192
192
  end
193
- raise UffizziCore::ComposeFile::ParseError, I18n.t('compose.unsupported_file') if compose_data.nil?
193
+ raise UffizziCore::ComposeFile::ParseError, I18n.t('compose.unsupported_file') if compose_data.nil? || compose_data.is_a?(String)
194
194
 
195
195
  compose_data
196
196
  end
@@ -11,9 +11,8 @@ class UffizziCore::ContainerRegistryService
11
11
 
12
12
  def init_by_container(container)
13
13
  registry_url = container.dig(:image, :registry_url)
14
- repository_url = container.dig(:build, :repository_url)
15
14
 
16
- return new(:docker_hub, container) if registry_url.blank? && repository_url.blank?
15
+ return new(:docker_hub, container) if registry_url.include?('docker.io')
17
16
  return new(:azure, container) if registry_url.include?('azurecr.io')
18
17
  return new(:google, container) if registry_url.include?('gcr.io')
19
18
  return new(:amazon, container) if registry_url.include?('amazonaws.com')
@@ -71,7 +70,7 @@ class UffizziCore::ContainerRegistryService
71
70
  end
72
71
 
73
72
  def image_name(credentials)
74
- if image_data[:registry_url].present? && [:google, :github_container_registry, :docker_registry].exclude?(type)
73
+ if image_data[:registry_url].present? && [:google, :github_container_registry, :docker_registry, :docker_hub].exclude?(type)
75
74
  return image_data[:name]
76
75
  end
77
76
 
@@ -19,7 +19,7 @@ class UffizziCore::DeploymentService
19
19
  deployment_form = UffizziCore::Api::Cli::V1::Deployment::CreateForm.new(deployment_attributes)
20
20
  deployment_form.assign_dependences!(project, user)
21
21
  deployment_form.compose_file = compose_file
22
- deployment_form.creation_source = params[:creation_source] || UffizziCore::Deployment.creation_source.compose_file_manual
22
+ deployment_form.creation_source = params[:creation_source] || UffizziCore::Deployment::COMPOSE_FILE_MANUAL
23
23
  deployment_form.metadata = params[:metadata] || {}
24
24
 
25
25
  run_deployment_creation_tasks(deployment_form) if deployment_form.save
@@ -19,6 +19,7 @@ en:
19
19
  invalid_service_name: "Invalid service name '%{value}': a service name must consist of lower case alphanumeric characters, ''-'', and must start and end with an alphanumeric character"
20
20
  no_ingress: Service ingress has not been defined.
21
21
  invalid_image_value: Invalid image value '%{value}'
22
+ image_name_contains_uppercase_value: Image name '%{value}' contains uppercase characters
22
23
  unprocessable_image: Invalid credential '%{value} or image does not exist'
23
24
  invalid_repo_type: Unsupported repo type
24
25
  repo_not_found: The specified repository doesn't exist '%{name}'
@@ -0,0 +1,7 @@
1
+ # frozen_string_literal: true
2
+
3
+ class AddFullImageNameToContainer < ActiveRecord::Migration[6.1]
4
+ def change
5
+ add_column(:uffizzi_core_containers, :full_image_name, :string)
6
+ end
7
+ end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module UffizziCore
4
- VERSION = '2.1.17'
4
+ VERSION = '2.1.19'
5
5
  end
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: 2.1.17
4
+ version: 2.1.19
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: 2023-04-05 00:00:00.000000000 Z
12
+ date: 2023-04-13 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: aasm
@@ -137,6 +137,20 @@ dependencies:
137
137
  - - "~>"
138
138
  - !ruby/object:Gem::Version
139
139
  version: '1.61'
140
+ - !ruby/object:Gem::Dependency
141
+ name: docker_distribution
142
+ requirement: !ruby/object:Gem::Requirement
143
+ requirements:
144
+ - - ">="
145
+ - !ruby/object:Gem::Version
146
+ version: '0'
147
+ type: :runtime
148
+ prerelease: false
149
+ version_requirements: !ruby/object:Gem::Requirement
150
+ requirements:
151
+ - - ">="
152
+ - !ruby/object:Gem::Version
153
+ version: '0'
140
154
  - !ruby/object:Gem::Dependency
141
155
  name: dotenv
142
156
  requirement: !ruby/object:Gem::Requirement
@@ -1029,6 +1043,7 @@ files:
1029
1043
  - db/migrate/20220927113647_add_additional_subdomains_to_containers.rb
1030
1044
  - db/migrate/20230111000000_add_state_to_memberships.rb
1031
1045
  - db/migrate/20230306142513_add_last_deploy_at_to_deployments.rb
1046
+ - db/migrate/20230406154451_add_full_image_name_to_container.rb
1032
1047
  - db/seeds.rb
1033
1048
  - lib/tasks/uffizzi_core_tasks.rake
1034
1049
  - lib/uffizzi_core.rb