cluster.rb 2.77 KB
Newer Older
1
module Gcp
2
  class Cluster < ActiveRecord::Base
3
    extend Gitlab::Gcp::Model
4

5
    belongs_to :project, inverse_of: :cluster
6
    belongs_to :user
Shinya Maeda's avatar
Shinya Maeda committed
7
    belongs_to :service
8

9 10 11 12
    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'

13
    attr_encrypted :password,
14
      mode: :per_attribute_iv,
15 16 17 18
      key: Gitlab::Application.secrets.db_key_base,
      algorithm: 'aes-256-cbc'

    attr_encrypted :kubernetes_token,
19
      mode: :per_attribute_iv,
20 21 22 23
      key: Gitlab::Application.secrets.db_key_base,
      algorithm: 'aes-256-cbc'

    attr_encrypted :gcp_token,
24
      mode: :per_attribute_iv,
25 26 27 28 29 30 31 32 33 34
      key: Gitlab::Application.secrets.db_key_base,
      algorithm: 'aes-256-cbc'

    enum status: {
      scheduled: 1,
      creating: 2,
      created: 3,
      errored: 4
    }

35 36 37 38 39 40 41 42 43 44 45 46 47 48 49
    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
50 51 52

    validates :gcp_cluster_size,
      presence: true,
53 54 55 56
      numericality: {
        only_integer: true,
        greater_than: 0
      }
57 58 59 60 61 62 63 64 65 66 67 68

    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?

69
    state_machine :status, initial: :scheduled do
70
      event :make_creating do
71 72 73
        transition any - [:creating] => :creating
      end

74
      event :make_created do
75 76 77
        transition any - [:created] => :created
      end

78
      event :make_errored do
79 80 81 82 83 84 85 86
        transition any - [:errored] => :errored
      end

      before_transition any => [:errored, :created] do |cluster|
        cluster.gcp_token = nil
        cluster.gcp_operation_id = nil
      end

87
      before_transition any => [:errored] do |cluster, transition|
88 89 90 91 92
        status_reason = transition.args.first
        cluster.status_reason = status_reason
      end
    end

93 94 95
    def project_namespace_placeholder
      "#{project.path}-#{project.id}"
    end
96

97 98
    def on_creation?
      scheduled? || creating?
99
    end
100 101 102 103

    def api_url
      'https://' + endpoint
    end
104 105 106 107 108 109 110 111 112

    def restrict_modification
      if on_creation?
        errors.add(:base, "cannot modify during creation")
        return false
      end

      true
    end
113 114
  end
end