From: Michal Fojtik <[email protected]> - Added MachineTemplateCreate action
Signed-off-by: Michal fojtik <[email protected]> --- server/lib/cimi/collections/base.rb | 2 +- server/lib/cimi/models.rb | 3 +- server/lib/cimi/models/base.rb | 14 ++-- server/lib/cimi/models/machine.rb | 1 - server/lib/cimi/models/machine_configuration.rb | 4 +- server/lib/cimi/models/machine_template.rb | 25 ------- server/lib/cimi/models/machine_template_create.rb | 12 ++++ server/lib/cimi/models/resource.rb | 14 +++- server/lib/cimi/models/schema.rb | 82 ++++++++++++++--------- 9 files changed, 86 insertions(+), 71 deletions(-) diff --git a/server/lib/cimi/collections/base.rb b/server/lib/cimi/collections/base.rb index b63fc4d..fa611e8 100644 --- a/server/lib/cimi/collections/base.rb +++ b/server/lib/cimi/collections/base.rb @@ -57,7 +57,7 @@ module CIMI::Collections end error JSON::ParserError do - report_error(400) + report_error(400, "Bad request (#{request.env['sinatra.error'].message})") end error REXML::ParseException do diff --git a/server/lib/cimi/models.rb b/server/lib/cimi/models.rb index 892637d..4863534 100644 --- a/server/lib/cimi/models.rb +++ b/server/lib/cimi/models.rb @@ -71,6 +71,7 @@ require_relative './models/machine' require_relative './models/machine_configuration' require_relative './models/machine_image' require_relative './models/machine_template' +require_relative './models/machine_template_create' require_relative './models/machine_create' require_relative './models/network_port' require_relative './models/network' @@ -82,5 +83,3 @@ require_relative './models/address' require_relative './models/address_template' require_relative './models/forwarding_group' require_relative './models/forwarding_group_template' - -require_relative './models/actions/machine_template_create' diff --git a/server/lib/cimi/models/base.rb b/server/lib/cimi/models/base.rb index 1f519dc..34ccb3f 100644 --- a/server/lib/cimi/models/base.rb +++ b/server/lib/cimi/models/base.rb @@ -80,9 +80,9 @@ module CIMI::Model class ValidationError < StandardError - def initialize(attribute) - @attr_name = attribute - super("Required attribute '#{@attr_name}' must be set.") + def initialize(attr_list, format) + @lst = attr_list.map { |a| a.send("#{format}_name") } + super("Required attributes not set: #{name}") end # Report the ValidationError as HTTP 400 - Bad Request @@ -91,7 +91,7 @@ module CIMI::Model end def name - @attr_name + @lst.join(',') end end @@ -142,11 +142,15 @@ module CIMI::Model end def validate!(format=:xml) + failed_attrs = [] self.class.required_attributes.each do |attr| unless attr.valid?(send(attr.name)) - raise CIMI::Model::ValidationError.new(attr.send("#{format}_name")) + failed_attrs << attr end end + unless failed_attrs.empty? + raise CIMI::Model::ValidationError.new(failed_attrs, format) + end end # FIXME: Kludge around the fact that we do not have proper *Create diff --git a/server/lib/cimi/models/machine.rb b/server/lib/cimi/models/machine.rb index 4010aa0..1b98d00 100644 --- a/server/lib/cimi/models/machine.rb +++ b/server/lib/cimi/models/machine.rb @@ -81,7 +81,6 @@ class CIMI::Model::Machine < CIMI::Model::Base CIMI::Model::MachineVolume.collection_for_instance(context.params[:id], context) end - private def self.from_instance(instance, context) cpu = memory = (instance.instance_profile.id == "opaque")? "n/a" : nil machine_conf = CIMI::Model::MachineConfiguration.find(instance.instance_profile.name, context) diff --git a/server/lib/cimi/models/machine_configuration.rb b/server/lib/cimi/models/machine_configuration.rb index 5926915..c580195 100644 --- a/server/lib/cimi/models/machine_configuration.rb +++ b/server/lib/cimi/models/machine_configuration.rb @@ -17,8 +17,8 @@ class CIMI::Model::MachineConfiguration < CIMI::Model::Base acts_as_root_entity :as => "machineConfigs" - text :cpu - text :memory + text :cpu, :required => true + text :memory, :required => true array :disks do text :capacity diff --git a/server/lib/cimi/models/machine_template.rb b/server/lib/cimi/models/machine_template.rb index 5967250..ddb0c7e 100644 --- a/server/lib/cimi/models/machine_template.rb +++ b/server/lib/cimi/models/machine_template.rb @@ -52,35 +52,10 @@ class CIMI::Model::MachineTemplate < CIMI::Model::Base end end - def create(template, context) - new_template = current_db.add_machine_template( - :name => template.name, - :description => template.description, - :machine_config => template.machine_config.href, - :machine_image => template.machine_image.href, - :ent_properties => template.property.to_json - ) - from_db(new_template, context) - end - - def create_from_json(body, context) - template = CIMI::Model::MachineTemplateCreate.from_json(body) - template.validate!(:json) - create(template, context) - end - - def create_from_xml(body, context) - template = CIMI::Model::MachineTemplateCreate.from_xml(body) - template.validate!(:xml) - create(template, context) - end - def delete!(id, context) current_db.machine_templates.first(:id => id).destroy end - private - def from_db(model, context) self.new( :id => context.machine_template_url(model.id), diff --git a/server/lib/cimi/models/machine_template_create.rb b/server/lib/cimi/models/machine_template_create.rb index 4d46b79..5e5e411 100644 --- a/server/lib/cimi/models/machine_template_create.rb +++ b/server/lib/cimi/models/machine_template_create.rb @@ -18,4 +18,16 @@ class CIMI::Model::MachineTemplateCreate < CIMI::Model::Base href :machine_config, :required => true href :machine_image, :required => true + def create(context) + validate! + new_template = self.class.current_db.add_machine_template( + :name => name, + :description => description, + :machine_config => machine_config.href, + :machine_image => machine_image.href, + :ent_properties => property.to_json + ) + CIMI::Model::MachineTemplate.from_db(new_template, context) + end + end diff --git a/server/lib/cimi/models/resource.rb b/server/lib/cimi/models/resource.rb index d7eceec..ad62e49 100644 --- a/server/lib/cimi/models/resource.rb +++ b/server/lib/cimi/models/resource.rb @@ -112,10 +112,18 @@ module CIMI end def parse(text, content_type) - if content_type == "application/xml" - from_xml(text) + if ["application/xml", "text/xml"].include? content_type + entity = from_xml(text) + entity.validate!(:xml) + entity elsif content_type == "application/json" - from_json(text) + if text.kind_of? StringIO + entity = from_json(text.read) + else + entity = from_json(text) + end + entity.validate!(:json) + entity else raise "Can not parse content type #{content_type}" end diff --git a/server/lib/cimi/models/schema.rb b/server/lib/cimi/models/schema.rb index 7260b81..39f4a13 100644 --- a/server/lib/cimi/models/schema.rb +++ b/server/lib/cimi/models/schema.rb @@ -98,32 +98,9 @@ class CIMI::Model::Schema attr_accessor :schema - def initialize(name, opts, &block) + def initialize(name, opts={}, &block) content = opts[:content] super(name, opts) - if opts[:class] - raise "Cannot use both :class and :schema" if opts[:schema] - refname = "#{opts[:class].name.split("::").last}Ref" - if CIMI::Model::const_defined?(refname) - @klass = CIMI::Model::const_get(refname) - else - @klass = Class.new(opts[:class]) do - scalar :href - - def ref_id(ctx) - # FIXME: We should use ctx's routes to split - # out the :id - href.split('/').last - end - - def find(ctx) - opts[:class].find(ref_id(ctx), ctx) - end - end - CIMI::Model::const_set(refname, @klass) - end - opts[:schema] = @klass.schema - end if opts[:schema] if block_given? raise "Cannot provide :schema option and a block" @@ -180,6 +157,12 @@ class CIMI::Model::Schema json end + def valid?(value) + @schema.required_attributes.all? { |a| + a.valid?(value.send(a.name)) + } + end + def convert(value) if @klass @klass.new(value || {}) @@ -188,10 +171,6 @@ class CIMI::Model::Schema end end - def valid?(value) - @schema.required_attributes.any? { |a| a.valid?(value.send(a.name) )} - end - private def struct if @klass @@ -202,6 +181,45 @@ class CIMI::Model::Schema end end + class Ref < CIMI::Model::Schema::Struct + + def initialize(name, opts={}, &block) + raise 'The :class attribute must be set' unless opts[:class] + refname = "#{opts[:class].name.split("::").last}Ref" + if CIMI::Model::const_defined?(refname) + @klass = CIMI::Model::const_get(refname) + else + @klass = Class.new(opts[:class]) do + scalar :href + + def ref_id(ctx) + # FIXME: We should use ctx's routes to split + # out the :id + href.split('/').last + end + + def find(ctx) + opts[:class].find(ref_id(ctx), ctx) + end + end + CIMI::Model::const_set(refname, @klass) + end + @klass.class_eval { def href?; !href.nil?; end } + opts[:schema] = @klass.schema + super(name, opts, &block) + end + + # The 'ref' could be the reference to a CIMI entity or the full CIMI + # entity representation. + # + def valid?(value) + !value.href.nil? || @klass.schema.required_attributes.all? { |a| + a.valid?(value.send(a.name)) + } + end + + end + class Array < Attribute attr_accessor :struct @@ -425,12 +443,12 @@ class CIMI::Model::Schema add_attributes!([name, opts], Struct, &block) end - def ref(name, klass = nil) - unless klass + def ref(name, opts={}) + unless opts[:class] s = name.to_s.camelize.gsub(/Config$/, "Configuration") - klass = CIMI::Model::const_get(s) + opts[:class] = CIMI::Model::const_get(s) end - struct(name, :class => klass) + add_attributes!([name, opts], Ref) end def hash(name) -- 1.8.1.2
