uffizzi_core 0.6.1 → 0.8.0

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 5db1e654767dd515b19f3848fe63f6f0c194ac998f705bc78327b10ccf0cb401
4
- data.tar.gz: 1743714525d2fd0e149bd16c4c7f6ec8a08c56d51cbec9df7ff559491c0712e5
3
+ metadata.gz: 8dea69b2a59531600dfb66428f656f48199aca57b46090feb7908c4c2649d6a0
4
+ data.tar.gz: '0049394671ce7727844814ebe46a671a9a1d420063546d5d12faf1d61748f5bb'
5
5
  SHA512:
6
- metadata.gz: 1df17b138ba1bfca50b4b30d68012c80d2d38cf1a4ff0374d3a10ebd711eb6aa8e2aa0d62dc5652c9178ea83b7543981332d023a22e45aa409b3dbeed40c7314
7
- data.tar.gz: 36da046695524c28f9f8d9c101d906ef32018f79f9240ce2ee10c71a7d12a7b19dbe7d182a0a867ce47d27119074a665dbb5cefd9259092325dbd1b5a323e7e2
6
+ metadata.gz: 278c7ce3923efa9d4db4476eb3ddad88c28b664af7fbf75a0c7547921d478ad6860fd7ea5987932bbcdcf1d01a418c55bac388a864e1f186468d3ec163f911cf
7
+ data.tar.gz: 83927e7d75d0e926cc1d42f16f31c9e086de1daedd33cb1315b60e118896f9d90b3ee102893ef7e9716e7e354c793610e609ae64aaf7be1657694fe166a62480
@@ -14,7 +14,10 @@ class UffizziCore::Api::Cli::V1::Projects::DeploymentsController < UffizziCore::
14
14
  # @response [Array<Deployment>] 200 OK
15
15
  # @response 401 Not authorized
16
16
  def index
17
- respond_with deployments
17
+ search_labels = JSON.parse(q_param)
18
+ filtered_deployments = deployments.with_labels(search_labels)
19
+
20
+ respond_with filtered_deployments, each_serializer: UffizziCore::Api::Cli::V1::Projects::DeploymentsSerializer
18
21
  end
19
22
 
20
23
  # Get deployment information by id
@@ -51,7 +54,7 @@ class UffizziCore::Api::Cli::V1::Projects::DeploymentsController < UffizziCore::
51
54
  errors = check_credentials(compose_file)
52
55
  return render_errors(errors) if errors.present?
53
56
 
54
- deployment = UffizziCore::DeploymentService.create_from_compose(compose_file, resource_project, current_user)
57
+ deployment = UffizziCore::DeploymentService.create_from_compose(compose_file, resource_project, current_user, metadata_params)
55
58
 
56
59
  respond_with deployment
57
60
  end
@@ -82,8 +85,9 @@ class UffizziCore::Api::Cli::V1::Projects::DeploymentsController < UffizziCore::
82
85
  errors = check_credentials(compose_file)
83
86
  return render_errors(errors) if errors.present?
84
87
 
85
- deployment = UffizziCore::Deployment.find(params[:id])
86
- updated_deployment = UffizziCore::DeploymentService.update_from_compose(compose_file, resource_project, current_user, deployment)
88
+ deployment = deployments.find(params[:id])
89
+ updated_deployment = UffizziCore::DeploymentService.update_from_compose(compose_file, resource_project, current_user, deployment,
90
+ metadata_params)
87
91
 
88
92
  respond_with updated_deployment
89
93
  end
@@ -171,6 +175,10 @@ class UffizziCore::Api::Cli::V1::Projects::DeploymentsController < UffizziCore::
171
175
  params.permit(dependencies: [:name, :path, :source, :content])
172
176
  end
173
177
 
178
+ def metadata_params
179
+ params[:metadata]
180
+ end
181
+
174
182
  def render_invalid_file
175
183
  render json: { errors: { state: ['Invalid compose file'] } }, status: :unprocessable_entity
176
184
  end
@@ -4,6 +4,7 @@ class UffizziCore::Api::Cli::V1::Deployment::CreateForm < UffizziCore::Deploymen
4
4
  include UffizziCore::ApplicationForm
5
5
 
6
6
  permit :creation_source,
7
+ :metadata,
7
8
  containers_attributes: [
8
9
  :image,
9
10
  :service_name,
@@ -50,6 +51,7 @@ class UffizziCore::Api::Cli::V1::Deployment::CreateForm < UffizziCore::Deploymen
50
51
  validate :check_exists_ingress_container
51
52
  validate :check_max_memory_limit
52
53
  validate :check_max_memory_request
54
+ validate :check_secrets_exist_in_database
53
55
 
54
56
  def assign_dependences!(project, user)
55
57
  self.project = project
@@ -90,4 +92,17 @@ class UffizziCore::Api::Cli::V1::Deployment::CreateForm < UffizziCore::Deploymen
90
92
 
91
93
  errors.add(:containers, :max_memory_request_error, max: project.account.container_memory_limit)
92
94
  end
95
+
96
+ def check_secrets_exist_in_database
97
+ return if compose_file.nil?
98
+
99
+ existing_secrets = project.secrets.pluck('name')
100
+ compose_file.template.payload['containers_attributes']
101
+ .map { |container| container['secret_variables'].map { |secret| secret['name'] } }.flatten.uniq
102
+ .select { |secret| existing_secrets.exclude?(secret) }
103
+ .each do |secret|
104
+ error_message = I18n.t('compose.project_secret_not_found', secret: secret)
105
+ errors.add(:secret_variables, error_message)
106
+ end
107
+ end
93
108
  end
@@ -3,46 +3,47 @@
3
3
  class UffizziCore::Api::Cli::V1::Deployment::UpdateForm < UffizziCore::Deployment
4
4
  include UffizziCore::ApplicationForm
5
5
 
6
- permit containers_attributes: [
7
- :image,
8
- :service_name,
9
- :tag,
10
- :port,
11
- :public,
12
- :memory_limit,
13
- :memory_request,
14
- :entrypoint,
15
- :command,
16
- :receive_incoming_requests,
17
- :continuously_deploy,
18
- { variables: [:name, :value],
19
- secret_variables: [:name, :value],
20
- volumes: [:source, :target, :type, :read_only],
21
- repo_attributes: [
22
- :namespace,
23
- :name,
24
- :slug,
25
- :type,
26
- :description,
27
- :is_private,
28
- :repository_id,
29
- :branch,
30
- :kind,
31
- :dockerfile_path,
32
- :dockerfile_context_path,
33
- :deploy_preview_when_pull_request_is_opened,
34
- :delete_preview_when_pull_request_is_closed,
35
- :deploy_preview_when_image_tag_is_created,
36
- :delete_preview_when_image_tag_is_updated,
37
- :share_to_github,
38
- :delete_preview_after,
39
- { args: [:name, :value] },
40
- ],
41
- container_config_files_attributes: [
42
- :config_file_id,
43
- :mount_path,
44
- ] },
45
- ]
6
+ permit :metadata,
7
+ containers_attributes: [
8
+ :image,
9
+ :service_name,
10
+ :tag,
11
+ :port,
12
+ :public,
13
+ :memory_limit,
14
+ :memory_request,
15
+ :entrypoint,
16
+ :command,
17
+ :receive_incoming_requests,
18
+ :continuously_deploy,
19
+ { variables: [:name, :value],
20
+ secret_variables: [:name, :value],
21
+ volumes: [:source, :target, :type, :read_only],
22
+ repo_attributes: [
23
+ :namespace,
24
+ :name,
25
+ :slug,
26
+ :type,
27
+ :description,
28
+ :is_private,
29
+ :repository_id,
30
+ :branch,
31
+ :kind,
32
+ :dockerfile_path,
33
+ :dockerfile_context_path,
34
+ :deploy_preview_when_pull_request_is_opened,
35
+ :delete_preview_when_pull_request_is_closed,
36
+ :deploy_preview_when_image_tag_is_created,
37
+ :delete_preview_when_image_tag_is_updated,
38
+ :share_to_github,
39
+ :delete_preview_after,
40
+ { args: [:name, :value] },
41
+ ],
42
+ container_config_files_attributes: [
43
+ :config_file_id,
44
+ :mount_path,
45
+ ] },
46
+ ]
46
47
 
47
48
  validate :check_all_containers_have_unique_ports
48
49
  validate :check_exists_ingress_container
@@ -45,7 +45,7 @@ module UffizziCore::Concerns::Models::Container
45
45
  validates :command, 'uffizzi_core/image_command_args': true, allow_nil: true
46
46
  validates :tag, presence: true
47
47
 
48
- aasm :continuously_deploy, column: :continuously_deploy do
48
+ aasm :continuously_deploy, column: :continuously_deploy, namespace: :cd do
49
49
  state :disabled, initial: true
50
50
  state :enabled
51
51
  end
@@ -27,6 +27,10 @@ module UffizziCore::Concerns::Models::Credential
27
27
  event :unauthorize do
28
28
  transitions from: [:not_connected, :active], to: :unauthorized
29
29
  end
30
+
31
+ event :disconnect do
32
+ transitions from: [:active, :unauthorized], to: :not_connected
33
+ end
30
34
  end
31
35
 
32
36
  def github_container_registry?
@@ -59,7 +63,7 @@ module UffizziCore::Concerns::Models::Credential
59
63
  account.projects.find_each do |project|
60
64
  project.deployments.find_each do |deployment|
61
65
  containers = deployment.containers
62
- attributes = { continuously_deploy: UffizziCore::Container::STATE_DISABLED }
66
+ attributes = { continuously_deploy: UffizziCore::Container::STATE_CD_DISABLED }
63
67
 
64
68
  containers.with_docker_hub_repo.update_all(attributes) if docker_hub?
65
69
  end
@@ -12,5 +12,9 @@ module UffizziCore::DeploymentRepo
12
12
  scope :active_for_credential_id, ->(credential_id) {
13
13
  active.joins(project: :credentials).merge(UffizziCore::Project.active).where(credentials: { id: credential_id })
14
14
  }
15
+
16
+ scope :with_labels, ->(labels) {
17
+ where("#{UffizziCore::Deployment.table_name}.metadata @> ?", labels.to_json)
18
+ }
15
19
  end
16
20
  end
@@ -16,16 +16,13 @@ class UffizziCore::Api::Cli::V1::Projects::DeploymentSerializer < UffizziCore::B
16
16
  :image_id,
17
17
  :ingress_container_ready,
18
18
  :ingress_container_state,
19
- :creation_source
19
+ :creation_source,
20
+ :metadata
20
21
 
21
22
  has_many :containers
22
23
 
23
24
  belongs_to :deployed_by
24
25
 
25
- def deployed_by
26
- object.deployed_by
27
- end
28
-
29
26
  def containers
30
27
  object.containers.active
31
28
  end
@@ -0,0 +1,7 @@
1
+ # frozen_string_literal: true
2
+
3
+ class UffizziCore::Api::Cli::V1::Projects::DeploymentsSerializer::UserSerializer < UffizziCore::BaseSerializer
4
+ type :user
5
+
6
+ attributes :email
7
+ end
@@ -0,0 +1,14 @@
1
+ # frozen_string_literal: true
2
+
3
+ class UffizziCore::Api::Cli::V1::Projects::DeploymentsSerializer < UffizziCore::BaseSerializer
4
+ type :deployment
5
+
6
+ attributes :id,
7
+ :created_at,
8
+ :updated_at,
9
+ :state,
10
+ :preview_url,
11
+ :metadata
12
+
13
+ belongs_to :deployed_by
14
+ end
@@ -41,12 +41,7 @@ class UffizziCore::Controller::DeployContainers::ContainerSerializer < UffizziCo
41
41
  end
42
42
 
43
43
  def tag
44
- case object.repo.type
45
- when UffizziCore::Repo::Github.name
46
- UffizziCore::RepoService.tag(object.repo)
47
- else
48
- object.tag
49
- end
44
+ object.tag
50
45
  end
51
46
 
52
47
  def entrypoint
@@ -20,7 +20,7 @@ class UffizziCore::ContainerService
20
20
  end
21
21
 
22
22
  def continuously_deploy_enabled?(container)
23
- container.aasm(:continuously_deploy).current_state == UffizziCore::Container::STATE_ENABLED
23
+ container.aasm(:continuously_deploy).current_state == UffizziCore::Container::STATE_CD_ENABLED
24
24
  end
25
25
 
26
26
  def valid_memory_limit?(container)
@@ -12,38 +12,37 @@ class UffizziCore::DeploymentService
12
12
  }.freeze
13
13
 
14
14
  class << self
15
- def create_from_compose(compose_file, project, user)
15
+ def create_from_compose(compose_file, project, user, metadata)
16
16
  deployment_attributes = ActionController::Parameters.new(compose_file.template.payload)
17
17
  deployment_form = UffizziCore::Api::Cli::V1::Deployment::CreateForm.new(deployment_attributes)
18
18
  deployment_form.assign_dependences!(project, user)
19
19
  deployment_form.compose_file = compose_file
20
20
  deployment_form.creation_source = UffizziCore::Deployment.creation_source.compose_file_manual
21
+ deployment_form.metadata = metadata || {}
21
22
 
22
- if deployment_form.save
23
- update_subdomain!(deployment_form)
24
-
25
- UffizziCore::Deployment::CreateJob.perform_async(deployment_form.id)
26
- end
23
+ run_deployment_creation_tasks(deployment_form) if deployment_form.save
27
24
 
28
25
  deployment_form
29
26
  end
30
27
 
31
- def update_from_compose(compose_file, project, user, deployment)
28
+ def update_from_compose(compose_file, project, user, deployment, metadata)
32
29
  deployment_attributes = ActionController::Parameters.new(compose_file.template.payload)
33
30
 
34
31
  deployment_form = UffizziCore::Api::Cli::V1::Deployment::UpdateForm.new(deployment_attributes)
35
32
  deployment_form.assign_dependences!(project, user)
36
33
  deployment_form.compose_file = compose_file
34
+ deployment_form.metadata = metadata || {}
37
35
 
38
36
  ActiveRecord::Base.transaction do
39
37
  deployment.containers.destroy_all
40
38
  deployment.compose_file.destroy! if deployment.compose_file&.kind&.temporary?
41
-
42
- deployment.update!(
39
+ params = {
43
40
  containers: deployment_form.containers,
44
41
  compose_file_id: compose_file.id,
45
42
  creation_source: UffizziCore::Deployment.creation_source.compose_file_manual,
46
- )
43
+ metadata: deployment_form.metadata,
44
+ }
45
+ deployment.update!(params)
47
46
  end
48
47
 
49
48
  deployment
@@ -88,27 +87,28 @@ class UffizziCore::DeploymentService
88
87
  end
89
88
 
90
89
  def build_subdomain(deployment)
91
- if deployment.continuous_preview_payload.present?
92
- continuous_preview_payload = deployment.continuous_preview_payload
90
+ return build_docker_continuous_preview_subdomain(deployment) if deployment&.continuous_preview_payload&.fetch('docker', nil).present?
93
91
 
94
- return build_pull_request_subdomain(deployment) if continuous_preview_payload['pull_request'].present?
95
- return build_docker_continuous_preview_subdomain(deployment) if continuous_preview_payload['docker'].present?
96
- end
92
+ github_metadata = deployment.metadata.dig('labels', 'github')
93
+ return build_pull_request_subdomain(deployment) if
94
+ github_metadata&.dig('pull_request', 'number').present? && github_metadata&.dig('repository').present?
97
95
 
98
96
  build_default_subdomain(deployment)
99
97
  end
100
98
 
101
99
  def build_pull_request_subdomain(deployment)
102
- project = deployment.project
103
- continuous_preview_payload = deployment.continuous_preview_payload
104
- pull_request_payload = continuous_preview_payload['pull_request']
105
- repo_name = pull_request_payload['repository_full_name'].split('/').last
106
- deployment_name = name(deployment)
107
- subdomain = "pr#{pull_request_payload['id']}-#{deployment_name}-#{repo_name}-#{project.slug}"
108
-
100
+ github_payload = deployment.metadata.dig('labels', 'github')
101
+ repo_name = github_payload['repository'].split('/').last
102
+ pull_request_number = github_payload['pull_request']['number']
103
+ subdomain = "pr-#{pull_request_number}-#{name(deployment)}-#{repo_name}-#{deployment.project.slug}"
109
104
  format_subdomain(subdomain)
110
105
  end
111
106
 
107
+ def update_subdomain!(deployment)
108
+ deployment.subdomain = build_subdomain(deployment)
109
+ deployment.save!
110
+ end
111
+
112
112
  def build_docker_continuous_preview_subdomain(deployment)
113
113
  project = deployment.project
114
114
  continuous_preview_payload = deployment.continuous_preview_payload
@@ -201,12 +201,6 @@ class UffizziCore::DeploymentService
201
201
  "deployment-#{deployment.id}"
202
202
  end
203
203
 
204
- def update_subdomain!(deployment)
205
- deployment.subdomain = build_subdomain(deployment)
206
-
207
- deployment.save!
208
- end
209
-
210
204
  def pull_request_payload_present?(deployment)
211
205
  deployment.continuous_preview_payload.present? && deployment.continuous_preview_payload['pull_request'].present?
212
206
  end
@@ -219,6 +213,12 @@ class UffizziCore::DeploymentService
219
213
 
220
214
  private
221
215
 
216
+ def run_deployment_creation_tasks(deployment)
217
+ update_subdomain!(deployment)
218
+
219
+ UffizziCore::Deployment::CreateJob.perform_async(deployment.id)
220
+ end
221
+
222
222
  def deployment_process_status(deployment)
223
223
  containers = deployment.active_containers
224
224
  activity_items = containers.map { |container| container.activity_items.order_by_id.last }.compact
@@ -0,0 +1,7 @@
1
+ # frozen_string_literal: true
2
+
3
+ class AddMetadataToDeployment < ActiveRecord::Migration[6.1]
4
+ def change
5
+ add_column(:uffizzi_core_deployments, :metadata, :jsonb, default: {})
6
+ end
7
+ end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module UffizziCore
4
- VERSION = '0.6.1'
4
+ VERSION = '0.8.0'
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: 0.6.1
4
+ version: 0.8.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-17 00:00:00.000000000 Z
12
+ date: 2022-08-25 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: aasm
@@ -829,7 +829,6 @@ files:
829
829
  - app/models/uffizzi_core/repo/azure.rb
830
830
  - app/models/uffizzi_core/repo/docker_hub.rb
831
831
  - app/models/uffizzi_core/repo/docker_registry.rb
832
- - app/models/uffizzi_core/repo/github.rb
833
832
  - app/models/uffizzi_core/repo/github_container_registry.rb
834
833
  - app/models/uffizzi_core/repo/google.rb
835
834
  - app/models/uffizzi_core/role.rb
@@ -877,6 +876,8 @@ files:
877
876
  - app/serializers/uffizzi_core/api/cli/v1/projects/deployments/container_serializer.rb
878
877
  - app/serializers/uffizzi_core/api/cli/v1/projects/deployments/container_serializer/container_config_file_serializer.rb
879
878
  - app/serializers/uffizzi_core/api/cli/v1/projects/deployments/container_serializer/container_config_file_serializer/config_file_serializer.rb
879
+ - app/serializers/uffizzi_core/api/cli/v1/projects/deployments_serializer.rb
880
+ - app/serializers/uffizzi_core/api/cli/v1/projects/deployments_serializer/user_serializer.rb
880
881
  - app/serializers/uffizzi_core/api/cli/v1/projects/secret_serializer.rb
881
882
  - app/serializers/uffizzi_core/api/cli/v1/short_project_serializer.rb
882
883
  - app/serializers/uffizzi_core/api/cli/v1/user_serializer.rb
@@ -964,6 +965,7 @@ files:
964
965
  - db/migrate/20220422151523_add_volumes_to_uffizzi_core_containers.rb
965
966
  - db/migrate/20220525113412_rename_name_to_uffizzi_containers.rb
966
967
  - db/migrate/20220704135629_add_disabled_at_to_deployments.rb
968
+ - db/migrate/20220805164628_add_metadata_to_deployment.rb
967
969
  - db/seeds.rb
968
970
  - lib/tasks/uffizzi_core_tasks.rake
969
971
  - lib/uffizzi_core.rb
@@ -1,4 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- class UffizziCore::Repo::Github < UffizziCore::Repo
4
- end