uffizzi_core 2.2.23 → 2.2.25

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: 173a91720da5a1063dd5db63c18c0232a5621dd68b77a120b81341aafba4c2a8
4
- data.tar.gz: 03f50a4669fe8688f0e3d280b0589c5123f39ad710cf24d09bdaea19235cc9d3
3
+ metadata.gz: 70847fae8bc28249be5879f8496e7436e05079077dc23ad53394d08676158be6
4
+ data.tar.gz: 2ac3e45d651e069f5e11b69b022efa285c5f0c0f176fb5a17c0bc58c3d4dad88
5
5
  SHA512:
6
- metadata.gz: 75934782b7e324fa161b9968efe45454e3483f791980ba85b8342a8c93ce49951483d06250154fdba2bf212aa8ea5794531d90afcf1039825f4d4ddfc8917c82
7
- data.tar.gz: a5c73682a9152c98c1801379c91c72fbf66212b429d9412d240731f80181d21b91349cdda6e02d51e5616a1968ebb5ea5c99baec830aa1e3fd7cd3e441078b15
6
+ metadata.gz: c128f0afe2384d0763597a9bbc3977748282a454a7d6396680b6f6642f00aa3b6ea32ee0d6c1125846338fec29e8ec02a0bf135d16943a3a2f3ff1f7caf5e797
7
+ data.tar.gz: 8a0877404587daa608bb636f6500c03578d711ab7cb8e58db97ed9cb663114374cef6f8a619f6dbc9a5c0c0ac3fe4478bf559f53df1c3b6f266d3820f7661f3c
@@ -78,6 +78,10 @@ class UffizziCore::ControllerClient
78
78
  get("/namespaces/#{namespace}/cluster/#{name}")
79
79
  end
80
80
 
81
+ def patch_cluster(name:, namespace:, body:)
82
+ patch("/namespaces/#{namespace}/cluster/#{name}", body)
83
+ end
84
+
81
85
  private
82
86
 
83
87
  def get(url, params = {})
@@ -88,6 +92,10 @@ class UffizziCore::ControllerClient
88
92
  make_request(:post, url, params)
89
93
  end
90
94
 
95
+ def patch(url, params = {})
96
+ make_request(:patch, url, params)
97
+ end
98
+
91
99
  def make_request(method, url, params)
92
100
  response = connection.send(method, url, params)
93
101
  body = response.body
@@ -11,13 +11,18 @@ class UffizziCore::Api::Cli::V1::Projects::ClustersController < UffizziCore::Api
11
11
  clusters = resource_project.clusters.enabled
12
12
  return respond_with clusters if request_by_admin? || valid_request_from_ci_workflow?
13
13
 
14
- respond_with clusters.deployed_by_user(current_user)
14
+ respond_with clusters.deployed_by_user(current_user), each_serializer: UffizziCore::Api::Cli::V1::Projects::ShortClusterSerializer
15
15
  end
16
16
 
17
17
  def create
18
+ version = cluster_params[:k8s_version]
19
+ kubernetes_distribution = find_kubernetes_distribution(version)
20
+ return render_distribution_version_error(version) if kubernetes_distribution.blank?
21
+
18
22
  cluster_form = UffizziCore::Api::Cli::V1::Cluster::CreateForm.new(cluster_params)
19
23
  cluster_form.project = resource_project
20
24
  cluster_form.deployed_by = current_user
25
+ cluster_form.kubernetes_distribution = kubernetes_distribution
21
26
  return respond_with cluster_form unless cluster_form.save
22
27
 
23
28
  UffizziCore::ClusterService.start_deploy(cluster_form)
@@ -25,6 +30,32 @@ class UffizziCore::Api::Cli::V1::Projects::ClustersController < UffizziCore::Api
25
30
  respond_with cluster_form
26
31
  end
27
32
 
33
+ def scale_down
34
+ if resource_cluster.deployed?
35
+ UffizziCore::ClusterService.scale_down!(resource_cluster)
36
+ return respond_with resource_cluster
37
+ end
38
+
39
+ return render_scale_error(I18n.t('cluster.already_asleep', name: resource_cluster.name)) if resource_cluster.scaled_down?
40
+
41
+ if resource_cluster.deploying_namespace? || resource_cluster.deploying?
42
+ render_scale_error(I18n.t('cluster.deploy_in_process', name: resource_cluster.name))
43
+ end
44
+ rescue AASM::InvalidTransition, UffizziCore::ClusterScaleError => e
45
+ render_scale_error(e.message)
46
+ end
47
+
48
+ def scale_up
49
+ if resource_cluster.scaled_down?
50
+ UffizziCore::ClusterService.scale_up!(resource_cluster)
51
+ return respond_with resource_cluster
52
+ end
53
+
54
+ return render_scale_error(I18n.t('cluster.already_awake', name: resource_cluster.name)) if resource_cluster.deployed?
55
+ rescue AASM::InvalidTransition, UffizziCore::ClusterScaleError => e
56
+ render_scale_error(e.message)
57
+ end
58
+
28
59
  def show
29
60
  respond_with resource_cluster
30
61
  end
@@ -57,4 +88,20 @@ class UffizziCore::Api::Cli::V1::Projects::ClustersController < UffizziCore::Api
57
88
  def cluster_params
58
89
  params.require(:cluster)
59
90
  end
91
+
92
+ def render_scale_error(message)
93
+ render json: { errors: { state: [message] } }, status: :unprocessable_entity
94
+ end
95
+
96
+ def find_kubernetes_distribution(version)
97
+ return UffizziCore::KubernetesDistribution.default if version.blank?
98
+
99
+ UffizziCore::KubernetesDistribution.find_by(version: version)
100
+ end
101
+
102
+ def render_distribution_version_error(version)
103
+ available_versions = UffizziCore::KubernetesDistribution.pluck(:version).join(', ')
104
+ message = I18n.t('kubernetes_distribution.not_available', version: version, available_versions: available_versions)
105
+ render json: { errors: { kubernetes_distribution: [message] } }, status: :unprocessable_entity
106
+ end
60
107
  end
@@ -0,0 +1,9 @@
1
+ # frozen_string_literal: true
2
+
3
+ class UffizziCore::ClusterScaleError < StandardError
4
+ def initialize(action)
5
+ message = I18n.t('cluster.scaling_failed', action: action)
6
+
7
+ super(message)
8
+ end
9
+ end
@@ -0,0 +1,11 @@
1
+ # frozen_string_literal: true
2
+
3
+ class UffizziCore::Cluster::ManageScalingDownJob < UffizziCore::ApplicationJob
4
+ sidekiq_options queue: :clusters, retry: Settings.default_job_retry_count
5
+
6
+ def perform(id)
7
+ cluster = UffizziCore::Cluster.find(id)
8
+
9
+ UffizziCore::ClusterService.manage_scale_down(cluster)
10
+ end
11
+ end
@@ -0,0 +1,11 @@
1
+ # frozen_string_literal: true
2
+
3
+ class UffizziCore::Cluster::ManageScalingUpJob < UffizziCore::ApplicationJob
4
+ sidekiq_options queue: :clusters, retry: Settings.default_job_retry_count
5
+
6
+ def perform(id, try = 1)
7
+ cluster = UffizziCore::Cluster.find(id)
8
+
9
+ UffizziCore::ClusterService.manage_scale_up(cluster, try)
10
+ end
11
+ end
@@ -6,6 +6,7 @@ module UffizziCore::Concerns::Models::Cluster
6
6
 
7
7
  NAMESPACE_PREFIX = 'c'
8
8
 
9
+ # rubocop:disable Metrics/BlockLength
9
10
  included do
10
11
  include AASM
11
12
  extend Enumerize
@@ -20,12 +21,17 @@ module UffizziCore::Concerns::Models::Cluster
20
21
  enumerize :creation_source, in: UffizziCore.cluster_creation_sources, scope: true, predicates: true
21
22
  attribute :creation_source, :string, default: :manual
22
23
  validates :creation_source, presence: true
24
+ belongs_to :kubernetes_distribution, optional: true
23
25
 
24
26
  aasm(:state) do
25
27
  state :deploying_namespace, initial: true
26
28
  state :failed_deploy_namespace
27
29
  state :deploying
28
30
  state :deployed
31
+ state :scaling_down
32
+ state :scaled_down
33
+ state :scaling_up
34
+ state :failed_scale_up
29
35
  state :failed
30
36
  state :disabled
31
37
 
@@ -41,12 +47,40 @@ module UffizziCore::Concerns::Models::Cluster
41
47
  transitions from: [:deploying], to: :deployed
42
48
  end
43
49
 
50
+ event :start_scaling_down do
51
+ transitions from: [:deployed], to: :scaling_down
52
+ end
53
+
54
+ event :scale_down do
55
+ transitions from: [:scaling_down], to: :scaled_down
56
+ end
57
+
58
+ event :start_scaling_up do
59
+ transitions from: [:scaled_down, :failed_scale_up], to: :scaling_up
60
+ end
61
+
62
+ event :scale_up do
63
+ transitions from: [:scaling_up], to: :deployed
64
+ end
65
+
66
+ event :fail_scale_up do
67
+ transitions from: [:scaling_up], to: :failed_scale_up
68
+ end
69
+
44
70
  event :fail do
45
71
  transitions from: [:deploying], to: :failed
46
72
  end
47
73
 
48
74
  event :disable, after: :after_disable do
49
- transitions from: [:deploying_namespace, :failed_deploy_namespace, :deploying, :deployed, :failed], to: :disabled
75
+ transitions from: [
76
+ :deploying_namespace,
77
+ :failed_deploy_namespace,
78
+ :deploying,
79
+ :deployed,
80
+ :scaling_down,
81
+ :scaled_down,
82
+ :failed,
83
+ ], to: :disabled
50
84
  end
51
85
  end
52
86
 
@@ -58,4 +92,5 @@ module UffizziCore::Concerns::Models::Cluster
58
92
  [NAMESPACE_PREFIX, id].join
59
93
  end
60
94
  end
95
+ # rubocop:enable Metrics/BlockLength
61
96
  end
@@ -0,0 +1,15 @@
1
+ # frozen_string_literal: true
2
+
3
+ module UffizziCore::Concerns::Models::KubernetesDistribution
4
+ extend ActiveSupport::Concern
5
+
6
+ included do
7
+ self.table_name = UffizziCore.table_names[:kubernetes_distributions]
8
+
9
+ has_many :clusters
10
+
11
+ def self.default
12
+ find_by(default: true)
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,5 @@
1
+ # frozen_string_literal: true
2
+
3
+ class UffizziCore::KubernetesDistribution < UffizziCore::ApplicationRecord
4
+ include UffizziCore::Concerns::Models::KubernetesDistribution
5
+ end
@@ -13,6 +13,14 @@ class UffizziCore::Api::Cli::V1::Projects::ClustersPolicy < UffizziCore::Applica
13
13
  context.user_access_module.admin_or_developer_access_to_project?(context.user, context.project)
14
14
  end
15
15
 
16
+ def scale_down?
17
+ context.user_access_module.admin_or_developer_access_to_project?(context.user, context.project)
18
+ end
19
+
20
+ def scale_up?
21
+ context.user_access_module.admin_or_developer_access_to_project?(context.user, context.project)
22
+ end
23
+
16
24
  def destroy?
17
25
  context.user_access_module.admin_or_developer_access_to_project?(context.user, context.project)
18
26
  end
@@ -3,5 +3,9 @@
3
3
  class UffizziCore::Api::Cli::V1::Projects::ClusterSerializer < UffizziCore::BaseSerializer
4
4
  type :cluster
5
5
 
6
- attributes :id, :name, :state, :kubeconfig, :created_at, :host
6
+ attributes :id, :name, :state, :kubeconfig, :created_at, :host, :k8s_version
7
+
8
+ def k8s_version
9
+ object.kubernetes_distribution&.version || UffizziCore::KubernetesDistribution.default.version
10
+ end
7
11
  end
@@ -0,0 +1,7 @@
1
+ # frozen_string_literal: true
2
+
3
+ class UffizziCore::Api::Cli::V1::Projects::ShortClusterSerializer < UffizziCore::BaseSerializer
4
+ type :cluster
5
+
6
+ attributes :id, :name
7
+ end
@@ -4,11 +4,25 @@ class UffizziCore::Controller::CreateCluster::ClusterSerializer < UffizziCore::B
4
4
  include UffizziCore::DependencyInjectionConcern
5
5
  include_module_if_exists('UffizziCore::Controller::CreateCluster::ClusterSerializerModule')
6
6
 
7
- attributes :name, :manifest, :base_ingress_host
7
+ attributes :name, :manifest, :base_ingress_host, :distro, :image
8
8
 
9
9
  def base_ingress_host
10
10
  managed_dns_zone = controller_settings_service.vcluster(object).managed_dns_zone
11
11
 
12
12
  [object.namespace, managed_dns_zone].join('.')
13
13
  end
14
+
15
+ def image
16
+ kubernetes_distribution.image
17
+ end
18
+
19
+ def distro
20
+ kubernetes_distribution.distro
21
+ end
22
+
23
+ private
24
+
25
+ def kubernetes_distribution
26
+ @kubernetes_distribution ||= object.kubernetes_distribution
27
+ end
14
28
  end
@@ -0,0 +1,14 @@
1
+ # frozen_string_literal: true
2
+
3
+ class UffizziCore::Controller::UpdateCluster::ClusterSerializer < UffizziCore::BaseSerializer
4
+ include UffizziCore::DependencyInjectionConcern
5
+ include_module_if_exists('UffizziCore::Controller::UpdateCluster::ClusterSerializerModule')
6
+
7
+ attributes :name, :manifest, :base_ingress_host
8
+
9
+ def base_ingress_host
10
+ managed_dns_zone = controller_settings_service.vcluster(object).managed_dns_zone
11
+
12
+ [object.namespace, managed_dns_zone].join('.')
13
+ end
14
+ end
@@ -24,6 +24,32 @@ class UffizziCore::ClusterService
24
24
  UffizziCore::Cluster::ManageDeployingJob.perform_in(5.seconds, cluster.id)
25
25
  end
26
26
 
27
+ def scale_up!(cluster)
28
+ cluster.start_scaling_up!
29
+ UffizziCore::ControllerService.patch_cluster(cluster, sleep: false)
30
+ UffizziCore::Cluster::ManageScalingUpJob.perform_in(5.seconds, cluster.id)
31
+ end
32
+
33
+ def manage_scale_up(cluster, try)
34
+ return cluster.fail_scale_up! if try > Settings.vcluster.max_scale_up_retry_count
35
+ return cluster.scale_up! if ready?(cluster)
36
+
37
+ UffizziCore::Cluster::ManageScalingUpJob.perform_in(5.seconds, cluster.id, ++try)
38
+ end
39
+
40
+ def scale_down!(cluster)
41
+ cluster.start_scaling_down!
42
+ UffizziCore::ControllerService.patch_cluster(cluster, sleep: true)
43
+
44
+ UffizziCore::Cluster::ManageScalingDownJob.perform_in(5.seconds, cluster.id)
45
+ end
46
+
47
+ def manage_scale_down(cluster)
48
+ return cluster.scale_down! unless awake?(cluster)
49
+
50
+ UffizziCore::Cluster::ManageScalingDownJob.perform_in(5.seconds, cluster.id)
51
+ end
52
+
27
53
  def manage_deploying(cluster, try)
28
54
  return if cluster.disabled?
29
55
  return cluster.fail! if try > Settings.vcluster.max_creation_retry_count
@@ -41,5 +67,19 @@ class UffizziCore::ClusterService
41
67
 
42
68
  UffizziCore::Cluster::ManageDeployingJob.perform_in(5.seconds, cluster.id, ++try)
43
69
  end
70
+
71
+ private
72
+
73
+ def awake?(cluster)
74
+ data = UffizziCore::ControllerService.show_cluster(cluster)
75
+
76
+ !data.status.sleep
77
+ end
78
+
79
+ def ready?(cluster)
80
+ data = UffizziCore::ControllerService.show_cluster(cluster)
81
+
82
+ data.status.ready
83
+ end
44
84
  end
45
85
  end
@@ -110,6 +110,13 @@ class UffizziCore::ControllerService
110
110
  controller_client(cluster).delete_cluster(namespace: cluster.namespace)
111
111
  end
112
112
 
113
+ def patch_cluster(cluster, sleep:)
114
+ body = UffizziCore::Controller::UpdateCluster::ClusterSerializer.new(cluster).as_json
115
+ body[:sleep] = sleep
116
+
117
+ controller_client(cluster).patch_cluster(name: cluster.name, namespace: cluster.namespace, body: body)
118
+ end
119
+
113
120
  private
114
121
 
115
122
  def check_any_container_has_public_port(containers)
@@ -83,11 +83,20 @@ en:
83
83
  deployment:
84
84
  invalid_state: Preview with ID deployment-%{id} %{state}
85
85
  already_exists: An active deployment already exists
86
+
87
+ cluster:
88
+ already_asleep: The cluster %{name} is already asleep.
89
+ already_awake: The cluster %{name} is already awake.
90
+ scaling_failed: Failed to %{action} cluster.
91
+ deploy_in_process: Please wait until the cluster %{name} is deployed.
86
92
 
87
93
  session:
88
94
  unsupported_login_type: This type of login is not supported
89
95
  unauthorized: Unauthorized
90
96
 
97
+ kubernetes_distribution:
98
+ not_available: "The k8s version %{version} is not supported. Available version are: %{available_versions}."
99
+
91
100
  enumerize:
92
101
  credential:
93
102
  type:
data/config/routes.rb CHANGED
@@ -10,7 +10,12 @@ UffizziCore::Engine.routes.draw do
10
10
  resources :projects, only: ['index', 'show', 'destroy'], param: :slug do
11
11
  scope module: :projects do
12
12
  resource :compose_file, only: ['show', 'create', 'destroy']
13
- resources :clusters, only: [:index, :create, :show, :destroy], param: :name
13
+ resources :clusters, only: [:index, :create, :show, :destroy], param: :name do
14
+ member do
15
+ put :scale_down
16
+ put :scale_up
17
+ end
18
+ end
14
19
  resources :deployments, only: ['index', 'show', 'create', 'destroy', 'update'] do
15
20
  post :deploy_containers, on: :member
16
21
  scope module: :deployments do
@@ -0,0 +1,13 @@
1
+ # frozen_string_literal: true
2
+
3
+ class CreateUffizziCoreKubernetesDistributions < ActiveRecord::Migration[6.1]
4
+ def change
5
+ create_table :uffizzi_core_kubernetes_distributions do |t|
6
+ t.string :version
7
+ t.string :distro
8
+ t.string :image
9
+ t.boolean :default, default: false
10
+ t.timestamps
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,7 @@
1
+ # frozen_string_literal: true
2
+
3
+ class AddKubernetesDistributionIdToUffizziCoreClusters < ActiveRecord::Migration[6.1]
4
+ def change
5
+ add_column(:uffizzi_core_clusters, :kubernetes_distribution_id, :integer, foreign_key: true)
6
+ end
7
+ end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module UffizziCore
4
- VERSION = '2.2.23'
4
+ VERSION = '2.2.25'
5
5
  end
data/lib/uffizzi_core.rb CHANGED
@@ -66,6 +66,7 @@ module UffizziCore
66
66
  host_volume_files: :uffizzi_core_host_volume_files,
67
67
  container_host_volume_files: :uffizzi_core_container_host_volume_files,
68
68
  deployment_events: :uffizzi_core_deployment_events,
69
+ kubernetes_distributions: :uffizzi_core_kubernetes_distributions,
69
70
  }
70
71
  mattr_accessor :user_creation_sources, default: [:system, :online_registration, :google, :sso]
71
72
  mattr_accessor :user_project_roles, default: [:admin, :developer, :viewer]
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.2.23
4
+ version: 2.2.25
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-10-06 00:00:00.000000000 Z
12
+ date: 2023-10-19 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: aasm
@@ -804,6 +804,7 @@ files:
804
804
  - app/controllers/uffizzi_core/api/cli/v1/projects_controller.rb
805
805
  - app/controllers/uffizzi_core/api/cli/v1/sessions_controller.rb
806
806
  - app/controllers/uffizzi_core/application_controller.rb
807
+ - app/errors/uffizzi_core/cluster_scale_error.rb
807
808
  - app/errors/uffizzi_core/compose_file/build_error.rb
808
809
  - app/errors/uffizzi_core/compose_file/credential_error.rb
809
810
  - app/errors/uffizzi_core/compose_file/parse_error.rb
@@ -841,6 +842,8 @@ files:
841
842
  - app/jobs/uffizzi_core/cluster/delete_job.rb
842
843
  - app/jobs/uffizzi_core/cluster/deploy_job.rb
843
844
  - app/jobs/uffizzi_core/cluster/manage_deploying_job.rb
845
+ - app/jobs/uffizzi_core/cluster/manage_scaling_down_job.rb
846
+ - app/jobs/uffizzi_core/cluster/manage_scaling_up_job.rb
844
847
  - app/jobs/uffizzi_core/config_file/apply_job.rb
845
848
  - app/jobs/uffizzi_core/deployment/create_credential_job.rb
846
849
  - app/jobs/uffizzi_core/deployment/create_credentials_job.rb
@@ -865,6 +868,7 @@ files:
865
868
  - app/lib/uffizzi_core/concerns/models/deployment_event.rb
866
869
  - app/lib/uffizzi_core/concerns/models/event.rb
867
870
  - app/lib/uffizzi_core/concerns/models/host_volume_file.rb
871
+ - app/lib/uffizzi_core/concerns/models/kubernetes_distribution.rb
868
872
  - app/lib/uffizzi_core/concerns/models/membership.rb
869
873
  - app/lib/uffizzi_core/concerns/models/payment.rb
870
874
  - app/lib/uffizzi_core/concerns/models/price.rb
@@ -909,6 +913,7 @@ files:
909
913
  - app/models/uffizzi_core/deployment_event.rb
910
914
  - app/models/uffizzi_core/event.rb
911
915
  - app/models/uffizzi_core/host_volume_file.rb
916
+ - app/models/uffizzi_core/kubernetes_distribution.rb
912
917
  - app/models/uffizzi_core/membership.rb
913
918
  - app/models/uffizzi_core/payment.rb
914
919
  - app/models/uffizzi_core/price.rb
@@ -982,6 +987,7 @@ files:
982
987
  - app/serializers/uffizzi_core/api/cli/v1/projects/deployments_serializer.rb
983
988
  - app/serializers/uffizzi_core/api/cli/v1/projects/deployments_serializer/user_serializer.rb
984
989
  - app/serializers/uffizzi_core/api/cli/v1/projects/secret_serializer.rb
990
+ - app/serializers/uffizzi_core/api/cli/v1/projects/short_cluster_serializer.rb
985
991
  - app/serializers/uffizzi_core/api/cli/v1/short_project_serializer.rb
986
992
  - app/serializers/uffizzi_core/api/cli/v1/user_serializer.rb
987
993
  - app/serializers/uffizzi_core/api/cli/v1/user_serializer/account_serializer.rb
@@ -997,6 +1003,7 @@ files:
997
1003
  - app/serializers/uffizzi_core/controller/deploy_containers/container_serializer/container_host_volume_file_serializer.rb
998
1004
  - app/serializers/uffizzi_core/controller/deploy_containers/credential_serializer.rb
999
1005
  - app/serializers/uffizzi_core/controller/deploy_containers/host_volume_file_serializer.rb
1006
+ - app/serializers/uffizzi_core/controller/update_cluster/cluster_serializer.rb
1000
1007
  - app/services/uffizzi_core/account_service.rb
1001
1008
  - app/services/uffizzi_core/activity_item_service.rb
1002
1009
  - app/services/uffizzi_core/ci_service.rb
@@ -1088,6 +1095,8 @@ files:
1088
1095
  - db/migrate/20230711101901_add_host_to_clusters.rb
1089
1096
  - db/migrate/20230810140316_add_source_to_uffizzi_core_clusters.rb
1090
1097
  - db/migrate/20230824150022_update_name_constraint_to_projects.rb
1098
+ - db/migrate/20231009162719_create_uffizzi_core_kubernetes_distributions.rb
1099
+ - db/migrate/20231009182412_add_kubernetes_distribution_id_to_uffizzi_core_clusters.rb
1091
1100
  - db/seeds.rb
1092
1101
  - lib/tasks/uffizzi_core_tasks.rake
1093
1102
  - lib/uffizzi_core.rb