require "db/mongo/models/model_with_provider" require "db/mongo/models/stack_template/stack_template_factory" require "providers/exceptions/name_conflict" require "db/validators/run_list_array" module Devops module Model class StackBase include ::Mongoid::Document include ::Mongoid::Timestamps::Created include ::ActiveModel::Validations store_in collection: "stacks" include ModelWithProviderAccount field :_id, as: :id, overwrite: true, type: String field :name, type: String field :project, type: String field :environment, type: String field :category, type: String field :stack_template, type: String field :parameters, type: Hash, default: {} field :owner, type: String field :run_list, type: Array, default: [] field :stack_status, type: String field :persisting_is_locked, type: Boolean field :tags, type: Hash, default: {} attr_accessor :events validates :id, :project, :environment, :category, :stack_template, :owner, presence: true validates :id, uniqueness: true, on: :create validates :name, presence: true, allow_nil: true validates :run_list, runListArray: {allow_nil: true} def to_hash attributes.tap { |hash| hash['id'] = hash.delete('_id') } end def create_stack_in_cloud! out begin provider_instance.create_stack(self, out) rescue ProviderErrors::NameConflict raise InvalidRecord.new "Duplicate key error: stack with name '#{id}' already exists in cloud" end end def delete_stack_in_cloud! provider_instance.delete_stack(self) end def sync_status_and_events! self.stack_status = provider_instance.stack_details(self)[:stack_status] self.events = provider_instance.stack_events(self) rescue Fog::AWS::CloudFormation::NotFound self.stack_status = 'NOT_FOUND' end def resources provider_instance.stack_resources(self) end # resource_id is logical def resource(resource_id) provider_instance.stack_resource(self, resource_id) end def stack_template_model Devops::Model::StackTemplateFactory.get_class(provider).find(stack_template) end def lock_persisting! update_attribute :persisting_is_locked, true end def unlock_persisting! update_attribute :persisting_is_locked, false end def account_instance @account_instance ||= Devops::Model::AwsProviderAccount.find(provider_account) end class << self # attrs should include: # - id (String) # - environment (String) # - stack_template (String) # - provider (String) # - provider_account (String) def create(attrs, out) model = new(attrs) model.create_stack_in_cloud!(out) model.sync_status_and_events! model end end end end end