require 'tempfile' require 'securerandom' class StackTemplateBase < MongoModel attr_accessor :id, :template_url, :template_json, :provider # Few words about template_url: # In Amazon Cloudformation the template file must be stored on an Amazon S3 bucket, # but for Openstack stacks it isn't neccessary (your may use local file). # I decided to enforce template_url strategy using in openstack to reach more common # interface between different providers' stack templates. types id: {type: String, empty: false}, provider: {type: String, empty: false}, template_json: {type: String, empty: false}, template_url: {type: String, empty: false} def initialize(attrs) self.id = attrs['id'] self.template_json = attrs['template_json'].to_s self.template_url = attrs['template_url'] self.provider = attrs['provider'] self end def to_hash_without_id { provider: provider, template_json: template_json, template_url: template_url } end # do not forget to destroy template files on template destroying def delete_template_file_from_storage raise 'Override me' end # attrs should include: # - id (String) # - provider (String) # - template_json (String) def self.create(attrs) json = attrs['template_json'] attrs['template_url'] = generate_template_file_and_upload_to_storage(attrs['id'], json) new(attrs) end def self.build_from_bson(attrs) attrs['id'] = attrs["_id"] self.new(attrs) end class << self private def generate_template_file_and_upload_to_storage(id, json) tempfile = Tempfile.new('foo') tempfile.write(json) secure_filename = "#{id}-#{SecureRandom.hex}.template" upload_file_to_storage(secure_filename, tempfile.path) ensure tempfile.close tempfile.unlink end def upload_file_to_storage(filename, file_path) raise 'Override me' end end end