diff --git a/app/models/gcp/cluster.rb b/app/models/gcp/cluster.rb index 543505c24c29fba0e58c5117c5ebeb51e6513d3b..74644207afdf84dcf30ed64415b6b70d7ae88da6 100644 --- a/app/models/gcp/cluster.rb +++ b/app/models/gcp/cluster.rb @@ -6,6 +6,10 @@ module Gcp belongs_to :user belongs_to :service + default_value_for :gcp_cluster_zone, 'us-central1-a' + default_value_for :gcp_cluster_size, 3 + default_value_for :gcp_machine_type, 'n1-standard-4' + attr_encrypted :password, mode: :per_attribute_iv, key: Gitlab::Application.secrets.db_key_base, @@ -28,6 +32,35 @@ module Gcp errored: 4 } + validates :gcp_project_id, + length: 1..63, + format: { + with: Gitlab::Regex.kubernetes_namespace_regex, + message: Gitlab::Regex.kubernetes_namespace_regex_message + } + + validates :gcp_cluster_name, + length: 1..63, + format: { + with: Gitlab::Regex.kubernetes_namespace_regex, + message: Gitlab::Regex.kubernetes_namespace_regex_message + } + + validates :gcp_cluster_zone, presence: true + validates :gcp_cluster_size, presence: true, + numericality: { only_integer: true, greater_than: 0 } + + validates :project_namespace, + allow_blank: true, + length: 1..63, + format: { + with: Gitlab::Regex.kubernetes_namespace_regex, + message: Gitlab::Regex.kubernetes_namespace_regex_message + } + + # if we do not do status transition we prevent change + validate :restrict_modification, on: :update, unless: :status_changed? + state_machine :status, initial: :scheduled do event :creating do transition any - [:creating] => :creating @@ -52,22 +85,9 @@ module Gcp end end - validates :gcp_project_id, presence: true - validates :gcp_cluster_zone, presence: true - validates :gcp_cluster_name, presence: true - validates :gcp_cluster_size, presence: true, - numericality: { only_integer: true, greater_than: 0 } - - validates :project_namespace, - allow_blank: true, - length: 1..63, - format: { - with: Gitlab::Regex.kubernetes_namespace_regex, - message: Gitlab::Regex.kubernetes_namespace_regex_message - } - - # if we do not do status transition we prevent change - validate :restrict_modification, on: :update, unless: :status_changed? + def project_namespace_placeholder + "#{project.path}-#{project.id}" + end def on_creation? scheduled? || creating? diff --git a/app/policies/gcp/cluster_policy.rb b/app/policies/gcp/cluster_policy.rb index dd0a5bff146df736801ddf0ccd0e49a7a0691569..e77173ea6e15b8094c380fca958b55d4fe7ee582 100644 --- a/app/policies/gcp/cluster_policy.rb +++ b/app/policies/gcp/cluster_policy.rb @@ -4,11 +4,7 @@ module Gcp delegate { @subject.project } - condition(:safe_to_change) do - can?(:master_access) && !cluster.on_creation? - end - - rule { safe_to_change }.policy do + rule { can?(:master_access) }.policy do enable :update_cluster enable :admin_cluster end diff --git a/app/services/ci/integrate_cluster_service.rb b/app/services/ci/integrate_cluster_service.rb index 959c425fe74736161edd71eb0ca817eb916cbb15..ae7dccb0f42398a83bc244eacf2d01d3fa2d0850 100644 --- a/app/services/ci/integrate_cluster_service.rb +++ b/app/services/ci/integrate_cluster_service.rb @@ -9,7 +9,7 @@ module Ci kubernetes_token: token, username: username, password: password, - service: project.find_or_initialize_service('kubernetes'), + service: cluster.project.find_or_initialize_service('kubernetes'), status_event: :created) cluster.service.update!( diff --git a/app/views/projects/clusters/_form.html.haml b/app/views/projects/clusters/_form.html.haml index a59c48b2c6872bc81380cbd5aef53445b471cd83..c9ec25d2072cba9885173c5d7483c95f723d3fdd 100644 --- a/app/views/projects/clusters/_form.html.haml +++ b/app/views/projects/clusters/_form.html.haml @@ -26,7 +26,7 @@ .form-group = field.label :project_namespace - = field.text_field :project_namespace, class: 'form-control' + = field.text_field :project_namespace, class: 'form-control', placeholder: @cluster.project_namespace_placeholder .form-group = field.label :gcp_machine_type diff --git a/app/views/projects/clusters/show.html.haml b/app/views/projects/clusters/show.html.haml index 3643ba40ee79c0984b1cee0ed9f56e6475574a81..d7839504f32e859c3067d386b7085211ce92136a 100644 --- a/app/views/projects/clusters/show.html.haml +++ b/app/views/projects/clusters/show.html.haml @@ -29,7 +29,7 @@ = s_('ClusterIntegration|Save changes') - - if can?(current_user, :update_cluster, @cluster) && @cluster.on_creation? + - if can?(current_user, :admin_cluster, @cluster) .form_group %label = s_('ClusterIntegration|Google container engine') @@ -37,15 +37,18 @@ - link_gke = link_to(s_('ClusterIntegration|Google Container Engine'), '', target: '_blank', rel: 'noopener noreferrer') = s_('ClusterIntegration|Manage your cluster by visiting %{link_gke}').html_safe % { link_gke: link_gke } - .hidden.js-cluster-error.alert.alert-danger{ role: 'alert' } - = s_('ClusterIntegration|Something went wrong while creating your cluster on Google Container Engine.') - %code.js-error-reason + - if @cluster.errored? + .js-cluster-error.alert.alert-danger{ role: 'alert' } + = s_('ClusterIntegration|Something went wrong while creating your cluster on Google Container Engine.') + %code.js-error-reason - .hidden.js-cluster-success.alert.alert-info{ role: 'alert' } - = s_('ClusterIntegration|Cluster was successfully created on Google Container Engine.') + - if @cluster.on_creation? + .js-cluster-creating.alert.alert-info{ role: 'alert' } + = s_('ClusterIntegration|Cluster is being created on Google Container Engine...') - .hidden.js-cluster-creating.alert.alert-info{ role: 'alert' } - = s_('ClusterIntegration|Cluster is being created on Google Container Engine...') + - if @cluster.created? + .js-cluster-success.alert.alert-info{ role: 'alert' } + = s_('ClusterIntegration|Cluster was successfully created on Google Container Engine.') .form_group %label diff --git a/app/workers/concerns/cluster_queue.rb b/app/workers/concerns/cluster_queue.rb index 736ae90303c391ed3d980084df1c5e6ec234ff48..a5074d13220ab403b17b8b9af608f5287961fab3 100644 --- a/app/workers/concerns/cluster_queue.rb +++ b/app/workers/concerns/cluster_queue.rb @@ -5,6 +5,6 @@ module ClusterQueue extend ActiveSupport::Concern included do - sidekiq_options queue: :manage_cluster + sidekiq_options queue: :gcp_cluster end end diff --git a/config/sidekiq_queues.yml b/config/sidekiq_queues.yml index 74a08b3f086a9bd3c7c90e8321fb7ba1f91d9a22..e2bb766ee47e2f30d8538090e3a4381db525d4a5 100644 --- a/config/sidekiq_queues.yml +++ b/config/sidekiq_queues.yml @@ -62,6 +62,6 @@ - [update_user_activity, 1] - [propagate_service_template, 1] - [background_migration, 1] - - [manage_cluster, 1] + - [gcp_cluster, 1] - [project_migrate_hashed_storage, 1] - [storage_migrator, 1] diff --git a/db/migrate/20170924094327_create_gcp_clusters.rb b/db/migrate/20170924094327_create_gcp_clusters.rb index 032db09e748ea689db942adfb11a785069532585..42171be7fc4b939d8d5d2960aaeb4890fa8bec1d 100644 --- a/db/migrate/20170924094327_create_gcp_clusters.rb +++ b/db/migrate/20170924094327_create_gcp_clusters.rb @@ -4,13 +4,13 @@ class CreateGcpClusters < ActiveRecord::Migration def change create_table :gcp_clusters do |t| t.references :project, null: false, index: { unique: true }, foreign_key: { on_delete: :cascade } - t.references :user, null: false, foreign_key: true - t.references :service, foreign_key: true + t.references :user, foreign_key: { on_delete: :nullify } + t.references :service, foreign_key: { on_delete: :nullify } # General t.boolean :enabled, default: true t.integer :status - t.string :status_reason + t.text :status_reason # k8s integration specific t.string :project_namespace @@ -18,10 +18,10 @@ class CreateGcpClusters < ActiveRecord::Migration # Cluster details t.string :endpoint t.text :ca_cert - t.string :encrypted_kubernetes_token + t.text :encrypted_kubernetes_token t.string :encrypted_kubernetes_token_iv t.string :username - t.string :encrypted_password + t.text :encrypted_password t.string :encrypted_password_iv # GKE @@ -31,7 +31,7 @@ class CreateGcpClusters < ActiveRecord::Migration t.integer :gcp_cluster_size, null: false t.string :gcp_machine_type t.string :gcp_operation_id - t.string :encrypted_gcp_token + t.text :encrypted_gcp_token t.string :encrypted_gcp_token_iv t.datetime_with_timezone :created_at, null: false diff --git a/db/schema.rb b/db/schema.rb index 9fc8191751ced0a79caa2168c156011e5ddc0cee..0056fe7a09f3b717973ac24d3d27c432cdf40fc3 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -577,18 +577,18 @@ ActiveRecord::Schema.define(version: 20170928100231) do create_table "gcp_clusters", force: :cascade do |t| t.integer "project_id", null: false - t.integer "user_id", null: false + t.integer "user_id" t.integer "service_id" t.boolean "enabled", default: true t.integer "status" - t.string "status_reason" + t.text "status_reason" t.string "project_namespace" t.string "endpoint" t.text "ca_cert" - t.string "encrypted_kubernetes_token" + t.text "encrypted_kubernetes_token" t.string "encrypted_kubernetes_token_iv" t.string "username" - t.string "encrypted_password" + t.text "encrypted_password" t.string "encrypted_password_iv" t.string "gcp_project_id", null: false t.string "gcp_cluster_zone", null: false @@ -596,10 +596,10 @@ ActiveRecord::Schema.define(version: 20170928100231) do t.integer "gcp_cluster_size", null: false t.string "gcp_machine_type" t.string "gcp_operation_id" - t.string "encrypted_gcp_token" + t.text "encrypted_gcp_token" t.string "encrypted_gcp_token_iv" - t.datetime "created_at", null: false - t.datetime "updated_at", null: false + t.datetime_with_timezone "created_at", null: false + t.datetime_with_timezone "updated_at", null: false end add_index "gcp_clusters", ["project_id"], name: "index_gcp_clusters_on_project_id", unique: true, using: :btree @@ -1752,8 +1752,8 @@ ActiveRecord::Schema.define(version: 20170928100231) do add_foreign_key "events", "users", column: "author_id", name: "fk_edfd187b6f", on_delete: :cascade add_foreign_key "forked_project_links", "projects", column: "forked_to_project_id", name: "fk_434510edb0", on_delete: :cascade add_foreign_key "gcp_clusters", "projects", on_delete: :cascade - add_foreign_key "gcp_clusters", "services" - add_foreign_key "gcp_clusters", "users" + add_foreign_key "gcp_clusters", "services", on_delete: :nullify + add_foreign_key "gcp_clusters", "users", on_delete: :nullify add_foreign_key "gpg_keys", "users", on_delete: :cascade add_foreign_key "gpg_signatures", "gpg_keys", on_delete: :nullify add_foreign_key "gpg_signatures", "projects", on_delete: :cascade