165 lines
		
	
	
		
			5.6 KiB
		
	
	
	
		
			Ruby
		
	
	
	
	
	
			
		
		
	
	
			165 lines
		
	
	
		
			5.6 KiB
		
	
	
	
		
			Ruby
		
	
	
	
	
	
| require "db/mongo/models/model_with_provider"
 | |
| require "providers/exceptions/name_conflict"
 | |
| 
 | |
| module Devops
 | |
|   module Model
 | |
|     class StackBase < MongoModel
 | |
| 
 | |
|       include ModelWithProvider
 | |
| 
 | |
|       attr_accessor :id, :name, :project, :deploy_env, :stack_template, :parameters, :details, :events, :owner, :run_list
 | |
| 
 | |
|       types id: {type: String, empty: false},
 | |
|             provider: {type: String, empty: false},
 | |
|             project: {type: String},
 | |
|             deploy_env: {type: String},
 | |
|             stack_template: {type: String, empty: false},
 | |
|             name: {type: String, nil: true},
 | |
|             owner: {type: String},
 | |
|             run_list: {type: Array, value_type: String, empty: true, nil: true}
 | |
|             # details: {type: Hash, nil: true} # Hash type isn't supported yet
 | |
| 
 | |
|       set_field_validators :id, [::Validators::FieldValidator::NotNil,
 | |
|                                       ::Validators::FieldValidator::FieldType::String,
 | |
|                                       ::Validators::FieldValidator::NotEmpty]
 | |
| 
 | |
|       set_field_validators :provider, [::Validators::FieldValidator::NotNil,
 | |
|                                       ::Validators::FieldValidator::FieldType::String,
 | |
|                                       ::Validators::FieldValidator::NotEmpty]
 | |
| 
 | |
|       set_field_validators :project, [::Validators::FieldValidator::NotNil,
 | |
|                                       ::Validators::FieldValidator::FieldType::String,
 | |
|                                       ::Validators::FieldValidator::NotEmpty]
 | |
| 
 | |
|       set_field_validators :deploy_env, [::Validators::FieldValidator::NotNil,
 | |
|                                       ::Validators::FieldValidator::FieldType::String,
 | |
|                                       ::Validators::FieldValidator::NotEmpty]
 | |
| 
 | |
|       set_field_validators :stack_template, [::Validators::FieldValidator::NotNil,
 | |
|                                       ::Validators::FieldValidator::FieldType::String,
 | |
|                                       ::Validators::FieldValidator::NotEmpty]
 | |
| 
 | |
|       set_field_validators :name, [::Validators::FieldValidator::Nil,
 | |
|                                       ::Validators::FieldValidator::FieldType::String,
 | |
|                                       ::Validators::FieldValidator::NotEmpty]
 | |
| 
 | |
|       set_field_validators :owner, [::Validators::FieldValidator::NotNil,
 | |
|                                       ::Validators::FieldValidator::FieldType::String,
 | |
|                                       ::Validators::FieldValidator::NotEmpty]
 | |
| 
 | |
|       set_field_validators :run_list, [::Validators::FieldValidator::NotNil,
 | |
|                                       ::Validators::FieldValidator::FieldType::Array,
 | |
|                                       ::Validators::FieldValidator::RunList]
 | |
| 
 | |
|       def initialize attrs={}
 | |
| #        self.provider = self.class.provider
 | |
|         self.set_provider(attrs)
 | |
|         self.id = attrs['id']
 | |
|         self.project = attrs['project']
 | |
|         self.deploy_env = attrs['deploy_env']
 | |
|         self.stack_template = attrs['stack_template']
 | |
|         self.name = attrs['name']
 | |
|         self.parameters = attrs['parameters']
 | |
|         self.details = attrs['details']
 | |
|         self.owner = attrs['owner']
 | |
|         self.run_list = attrs['run_list'] || []
 | |
|         self
 | |
|       end
 | |
| 
 | |
|       # TODO: use string keys
 | |
|       def to_hash_without_id
 | |
|         {
 | |
|           project: project,
 | |
|           deploy_env: deploy_env,
 | |
|           stack_template: stack_template,
 | |
|           name: name,
 | |
|           parameters: parameters,
 | |
|           # details are required to proper status handling
 | |
|           details: bson_safe_details,
 | |
|           stack_status: stack_status,
 | |
|           owner: owner,
 | |
|           run_list: run_list
 | |
|         }.merge(provider_hash)
 | |
|       end
 | |
| 
 | |
|       # overrided in ec2
 | |
|       def bson_safe_details
 | |
|         details
 | |
|       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_details!
 | |
|         self.details = provider_instance.stack_details(self)
 | |
|         self.events = provider_instance.stack_events(self)
 | |
|       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
 | |
| 
 | |
|       # there is only one way to update stack status right now:
 | |
|       #     stack.sync_details!
 | |
|       #     mongo.stack_update(stack)
 | |
|       # It's because syncing updates @details instance variable, but doesn'not persist it.
 | |
|       # Also that's why we need to have "details" key in #to_mongo_hash
 | |
|       def stack_status
 | |
|         raise 'override me'
 | |
|       end
 | |
| 
 | |
|       def stack_statuses
 | |
|         # maybe they differ in different providers, so use method instead of hardcoding
 | |
|         {
 | |
|           in_progress: 'CREATE_IN_PROGRESS',
 | |
|           complete: 'CREATE_COMPLETE'
 | |
|         }
 | |
|       end
 | |
| 
 | |
|       def template_body
 | |
|         stack_template_model.template_body
 | |
|       end
 | |
| 
 | |
|       def stack_template_model
 | |
|         Devops::Db.connector.stack_template(stack_template)
 | |
|       end
 | |
| 
 | |
|       class << self
 | |
| 
 | |
|         # attrs should include:
 | |
|         # - id (String)
 | |
|         # - deploy_env (String)
 | |
|         # - stack_template (String)
 | |
|         # - provider (String)
 | |
|         # - provider_account (String)
 | |
|         def create(attrs, out)
 | |
|           model = new(attrs)
 | |
|           model.create_stack_in_cloud!(out)
 | |
|           model.sync_details!
 | |
|           model
 | |
|         end
 | |
| 
 | |
|         def build_from_bson(attrs)
 | |
|           attrs['id'] = attrs["_id"]
 | |
|           self.new(attrs)
 | |
|         end
 | |
|       end
 | |
| 
 | |
|     end
 | |
|   end
 | |
| end
 | 
