Hi David,
When I run this patch on mock, system templates display fine, even with
machineTemplates inline volumeTemplates and networkTemplates.
However, when I run on fgcp, I get the following error:
E, [2013-03-16T00:36:11.714489 #13212] ERROR -- 500: [NoMethodError]
undefined method `[]' for nil:NilClass
d:/sources/OSS/cloud/deltacloud/server/lib/cimi/models/schema.rb:273:in
`to_xml'
d:/sources/OSS/cloud/deltacloud/server/lib/cimi/models/schema.rb:381:in
`block in to_xml'
d:/sources/OSS/cloud/deltacloud/server/lib/cimi/models/schema.rb:381:in
`each'
d:/sources/OSS/cloud/deltacloud/server/lib/cimi/models/schema.rb:381:in
`to_xml'
d:/sources/OSS/cloud/deltacloud/server/lib/cimi/models/schema.rb:150:in
`convert_to_xml'
d:/sources/OSS/cloud/deltacloud/server/lib/cimi/models/schema.rb:127:in
`to_xml'
d:/sources/OSS/cloud/deltacloud/server/lib/cimi/models/schema.rb:381:in
`block in to_xml'
d:/sources/OSS/cloud/deltacloud/server/lib/cimi/models/schema.rb:381:in
`each'
d:/sources/OSS/cloud/deltacloud/server/lib/cimi/models/schema.rb:381:in
`to_xml'
d:/sources/OSS/cloud/deltacloud/server/lib/cimi/models/schema.rb:150:in
`convert_to_xml'
d:/sources/OSS/cloud/deltacloud/server/lib/cimi/models/schema.rb:242:in
`block in to_xml'
d:/sources/OSS/cloud/deltacloud/server/lib/cimi/models/schema.rb:242:in
`map'
d:/sources/OSS/cloud/deltacloud/server/lib/cimi/models/schema.rb:242:in
`to_xml'
d:/sources/OSS/cloud/deltacloud/server/lib/cimi/models/schema.rb:381:in
`block in to_xml'
d:/sources/OSS/cloud/deltacloud/server/lib/cimi/models/schema.rb:381:in
`each'
d:/sources/OSS/cloud/deltacloud/server/lib/cimi/models/schema.rb:381:in
`to_xml'
d:/sources/OSS/cloud/deltacloud/server/lib/cimi/models/schema.rb:150:in
`convert_to_xml'
d:/sources/OSS/cloud/deltacloud/server/lib/cimi/models/schema.rb:242:in
`block in to_xml'
d:/sources/OSS/cloud/deltacloud/server/lib/cimi/models/schema.rb:242:in
`map'
d:/sources/OSS/cloud/deltacloud/server/lib/cimi/models/schema.rb:242:in
`to_xml'
d:/sources/OSS/cloud/deltacloud/server/lib/cimi/models/schema.rb:381:in
`block in to_xml'
I've printed module and name in schema.rb:273:
model: #<CIMI::Model::SystemTemplate:0x40d8de8>
name: property
model: {:name=>"Secure1", :description=>"Network tier 1",
:type=>"http://schemas.dmtf.org/cimi/1/Network",
:network_template=>#<CIMI::Model::NetworkTemplate:0x4
0da540 @select_attrs=[], @base_id=nil, @attribute_values={:id=>nil,
:name=>"Private network", :description=>"", :created=>nil,
:updated=>nil, :property=>nil, :n
etwork_config=>#<CIMI::Model::NetworkConfigurationRef:0x40da138
@select_attrs=[], @base_id=nil, @attribute_values={:id=>nil, :name=>nil,
:description=>nil, :cre
ated=>nil, :updated=>nil, :property=>nil, :network_type=>"PRIVATE",
:mtu=>nil, :class_of_service=>"BRONZE", :operations=>nil, :href=>nil}>,
:forwarding_group=>#
<CIMI::Model::ForwardingGroupRef:0x40d9880 @select_attrs=[],
@base_id=nil, @attribute_values={:id=>nil, :name=>nil,
:description=>nil, :created=>nil, :updated=>
nil, :property=>nil, :networks=>nil, :operations=>nil, :href=>nil}>,
:operations=>nil}>}
name: properties
model:
name: property
Do you understand what's wrong?
Regards,
Dies Koper
> -----Original Message-----
> From: [email protected] [mailto:[email protected]]
> Sent: Saturday, 16 March 2013 12:42 AM
> To: [email protected]
> Subject: [PATCH] added Template subcollections to SystemTemplate
>
> From: Dies Koper <[email protected]>
>
> ---
> server/lib/cimi/models.rb | 4 +-
> server/lib/cimi/models/machine_template.rb | 6 +-
> server/lib/cimi/models/network_template.rb | 4 +-
> server/lib/cimi/models/system.rb | 4 +-
> server/lib/cimi/models/system_template.rb | 20 +++--
> server/lib/cimi/models/volume_template.rb | 4 +-
> server/lib/deltacloud/drivers/fgcp/fgcp_client.rb | 4 +
> .../drivers/fgcp/fgcp_driver_cimi_methods.rb | 94
> +++++++++++++++++-----
> .../mock/data/cimi/system_template/template1.json | 31 ++++++-
> .../drivers/mock/mock_driver_cimi_methods.rb | 32 ++++++++
> .../cimi/collections/system_templates_test.rb | 47 +++++++++++
> 11 files changed, 207 insertions(+), 43 deletions(-)
>
> diff --git a/server/lib/cimi/models.rb b/server/lib/cimi/models.rb
> index 8eeb96c..e605b42 100644
> --- a/server/lib/cimi/models.rb
> +++ b/server/lib/cimi/models.rb
> @@ -79,7 +79,7 @@ require_relative './models/address_template_create'
> require_relative './models/address_create'
> require_relative './models/forwarding_group'
> require_relative './models/forwarding_group_template'
> -require_relative './models/system_template'
> -require_relative './models/system'
> require_relative './models/network_template'
> require_relative './models/network_create'
> +require_relative './models/system_template'
> +require_relative './models/system'
> diff --git a/server/lib/cimi/models/machine_template.rb
> b/server/lib/cimi/models/machine_template.rb
> index 68e865b..c167555 100644
> --- a/server/lib/cimi/models/machine_template.rb
> +++ b/server/lib/cimi/models/machine_template.rb
> @@ -28,10 +28,12 @@ class CIMI::Model::MachineTemplate <
> CIMI::Model::Base
> scalar :href, :initial_location
> end
>
> - array :volume_templates do
> - scalar :href, :initial_location
> + class CIMI::Model::VolumeTemplateWithLocation <
> CIMI::Model::VolumeTemplate
> + text :initial_location
> end
>
> + array :volume_templates, :ref =>
> CIMI::Model::VolumeTemplateWithLocation
> +
> array :network_interfaces do
> href :vsp
> text :hostname, :mac_address, :state, :protocol, :allocation
> diff --git a/server/lib/cimi/models/network_template.rb
> b/server/lib/cimi/models/network_template.rb
> index 4f69f52..301d56a 100644
> --- a/server/lib/cimi/models/network_template.rb
> +++ b/server/lib/cimi/models/network_template.rb
> @@ -17,8 +17,8 @@ class CIMI::Model::NetworkTemplate <
CIMI::Model::Base
>
> acts_as_root_entity
>
> - ref :network_config, :required => true
> - ref :forwarding_group, :required => true
> + ref :network_config, :class => CIMI::Model::NetworkConfiguration
> + ref :forwarding_group
>
> array :operations do
> scalar :rel, :href
> diff --git a/server/lib/cimi/models/system.rb
> b/server/lib/cimi/models/system.rb
> index 118f9f5..e8a9ad8 100644
> --- a/server/lib/cimi/models/system.rb
> +++ b/server/lib/cimi/models/system.rb
> @@ -17,7 +17,9 @@ class CIMI::Model::System < CIMI::Model::Base
>
> acts_as_root_entity
>
> - text :state
> + href :system_template, :required => false
> +
> + text :state, :required => true
>
> # FIXME: Any reason for these comments?
>
> diff --git a/server/lib/cimi/models/system_template.rb
> b/server/lib/cimi/models/system_template.rb
> index 82e418b..c60f759 100644
> --- a/server/lib/cimi/models/system_template.rb
> +++ b/server/lib/cimi/models/system_template.rb
> @@ -20,19 +20,17 @@ class CIMI::Model::SystemTemplate <
> CIMI::Model::Base
> array :component_descriptors do
> text :name, :description
> hash_map :properties
> - text :type
> -
> - # FIXME: Any reasons for these comments?
> + text :type, :required => true
>
> #component_template, comprises:
> - # struct :machine_template, :class =>
> CIMI::Model::MachineTemplate
> - # struct :system_template, :class =>
> CIMI::Model::SystemTemplate
> - # struct :credential_template, :class =>
> CIMI::Model::CredentialTemplate
> - # struct :volume_template, :class =>
> CIMI::Model::VolumeTemplate
> - # struct :network_template, :class =>
> CIMI::Model::NetworkTemplate
> - # struct :network_port_template, :class =>
> CIMI::Model::NetworkPortTemplate
> - # struct :forwarding_group_template, :class =>
> CIMI::Model::ForwardingGroupTemplate
> - # struct :address_template, :class =>
> CIMI::Model::AddressTemplate
> + ref :machine_template, :class => CIMI::Model::MachineTemplate
> + ref :system_template, :class => CIMI::Model::SystemTemplate
> + ref :credential_template, :class =>
> CIMI::Model::CredentialTemplate
> + ref :volume_template, :class => CIMI::Model::VolumeTemplate
> + ref :network_template, :class => CIMI::Model::NetworkTemplate
> + ref :network_port_template, :class =>
> CIMI::Model::NetworkPortTemplate
> + ref :forwarding_group_template, :class =>
> CIMI::Model::ForwardingGroupTemplate
> + ref :address_template, :class => CIMI::Model::AddressTemplate
> text :quantity
> end
>
> diff --git a/server/lib/cimi/models/volume_template.rb
> b/server/lib/cimi/models/volume_template.rb
> index bda4657..43e9c86 100644
> --- a/server/lib/cimi/models/volume_template.rb
> +++ b/server/lib/cimi/models/volume_template.rb
> @@ -17,8 +17,8 @@ class CIMI::Model::VolumeTemplate <
CIMI::Model::Base
>
> acts_as_root_entity
>
> - ref :volume_config, :required => true
> - ref :volume_image, :required => true
> + ref :volume_config, :required => true, :class =>
> CIMI::Model::VolumeConfiguration
> + ref :volume_image
>
> array :meter_templates do
> end
> diff --git a/server/lib/deltacloud/drivers/fgcp/fgcp_client.rb
> b/server/lib/deltacloud/drivers/fgcp/fgcp_client.rb
> index fed3b70..9597c13 100644
> --- a/server/lib/deltacloud/drivers/fgcp/fgcp_client.rb
> +++ b/server/lib/deltacloud/drivers/fgcp/fgcp_client.rb
> @@ -94,6 +94,10 @@ class FgcpClient
> request('ListVSYSDescriptor')
> end
>
> + def get_vsys_descriptor_configuration(vsys_descriptor_id)
> + request('GetVSYSDescriptorConfiguration', {'vsysDescriptorId' =>
> vsys_descriptor_id})
> + end
> +
> def list_vservers(vsys_id)
> request('ListVServer', {'vsysId' => vsys_id})
> end
> diff --git
> a/server/lib/deltacloud/drivers/fgcp/fgcp_driver_cimi_methods.rb
> b/server/lib/deltacloud/drivers/fgcp/fgcp_driver_cimi_methods.rb
> index b4d31f6..60f5e84 100644
> --- a/server/lib/deltacloud/drivers/fgcp/fgcp_driver_cimi_methods.rb
> +++ b/server/lib/deltacloud/drivers/fgcp/fgcp_driver_cimi_methods.rb
> @@ -29,39 +29,95 @@ module Deltacloud::Drivers::Fgcp
> def systems(credentials, opts={})
> safely do
> client = new_client(credentials)
> + xml = client.list_vsys['vsyss']
> + return [] if xml.nil?
> + context = opts[:env]
>
> - if opts and opts[:id]
> - vsys_ids = [opts[:id]]
> - else
> - xml = client.list_vsys['vsyss']
> - return [] if xml.nil?
> - vsys_ids = xml[0]['vsys'].collect { |vsys|
> vsys['vsysId'][0] }
> - end
> -
> - vsys_ids.collect do |vsys_id|
> - vsys = client.get_vsys_configuration(vsys_id)['vsys'][0]
> + systems = xml[0]['vsys'].collect do |vsys|
> + vsys_id = vsys['vsysId'][0]
> vsys_description_el = vsys['description']
> CIMI::Model::System.new(
> - :id => vsys['vsysId'][0],
> + :id => vsys_id,
> :name => vsys['vsysName'][0],
> -# :machines =>
> "http://cimi.example.org/systems/#{vsys['vsysId'][0]}/machines?realm
> _id=#{vsys['vsysId'][0]}",
> -# :volumes =>
> "http://cimi.example.org/systems/#{vsys['vsysId'][0]}/volumes?realm_
> id=#{vsys['vsysId'][0]}",
> -# :networks =>
> "http://cimi.example.org/systems/#{vsys['vsysId'][0]}/networks?realm
> _id=#{vsys['vsysId'][0]}",
> -# :addresses =>
> "http://cimi.example.org/systems/#{vsys['vsysId'][0]}/addresses?real
> m_id=#{vsys['vsysId'][0]}",
> - :description => vsys_description_el ?
> vsys_description_el[0] : nil
> + :description => vsys_description_el ?
> vsys_description_el[0] : nil,
> + :machines => { :href =>
> context.system_url("#{vsys_id}/machines") },
> + :volumes => { :href =>
> context.system_url("#{vsys_id}/volumes") },
> + :networks => { :href =>
> context.system_url("#{vsys_id}/networks") },
> + :addresses => { :href =>
> context.system_url("#{vsys_id}/addresses") }
> )
> end
> + systems = systems.select { |s| opts[:id] == s[:id] } if
opts[:id]
> + # now add system state
> + systems.each do |system|
> + xml = client.list_vservers(system[:id])['vservers']
> + if xml.nil?
> + system[:state] = 'MIXED'
> + else
> + xml[0]['vserver'].each do |vserver|
> + state =
> @@INSTANCE_STATE_MAP[client.get_vserver_status(vserver['vserverId'][
> 0])['vserverStatus'][0]]
> + state = 'STARTED' if state == 'RUNNING'
> + system[:state] ||= state
> + if system[:state] != state
> + system[:state] = 'MIXED'
> + break
> + end
> + end
> + end
> + end
> + systems
> end
> end
>
> def system_templates(credentials, opts={})
> safely do
> client = new_client(credentials)
> + context = opts[:env]
> templates =
> client.list_vsys_descriptor['vsysdescriptors'][0]['vsysdescriptor'].
> collect do |desc|
> + conf =
> client.get_vsys_descriptor_configuration(desc['vsysdescriptorId'][0]
> )['vsysdescriptor'][0]
> + components = conf['vservers'][0]['vserver'].collect do
> |vserver|
> + next if vserver['vserverType'][0] == 'firewall'
> + volume_templates = vserver['vdisks'][0]['vdisk'].collect
> do |vdisk|
> + CIMI::Model::VolumeTemplateWithLocation.new(
> +# :volume_config => {:capacity =>
> "#{vdisk['size'][0].to_i * 1024 * 1024}"}
> + :volume_config =>
> CIMI::Model::VolumeConfiguration.new(:capacity =>
> vdisk['size'][0].to_i * 1024 * 1024)
> + )
> + end if vserver['vdisks']
> + {
> + :name => desc['vsysdescriptorName'][0],
> + :description => '',
> + :type =>
> "http://schemas.dmtf.org/cimi/1/Machine",
> + :machine_template => CIMI::Model::MachineTemplate.new(
> + :name => vserver['vserverName'][0],
> + :description => '',
> + :machine_config =>
> CIMI::Service::MachineConfiguration.find(vserver['vserverType'][0],
> context),
> + :machine_image => { :href =>
> context.machine_image_url(vserver['diskimageId'][0]) },
> + :volume_templates => volume_templates
> + )
> + }
> + end
> + if conf['vsysdescriptorId'][0] =~ /(1|2|3)-tier Skeleton/
> + tiers = ['DMZ', 'Secure1', 'Secure2']
> + components += 1.upto($1.to_i).collect do |n|
> + {
> + :name => tiers[n],
> + :description => "Network tier #{n}",
> + :type =>
> "http://schemas.dmtf.org/cimi/1/Network",
> + :network_template =>
> CIMI::Model::NetworkTemplate.new(
> + :name => 'Private network',
> + :description => '',
> + :network_config =>
> CIMI::Model::NetworkConfiguration.new(
> + :network_type => 'PRIVATE',
> + :class_of_service => 'BRONZE'
> + )
> + )
> + }
> + end
> + end
> CIMI::Model::SystemTemplate.new(
> - :id => desc['vsysdescriptorId'][0],
> - :name => desc['vsysdescriptorName'][0],
> - :description => desc['description'][0]
> + :id => desc['vsysdescriptorId'][0],
> + :name => desc['vsysdescriptorName'][0],
> + :description => desc['description'][0],
> + :component_descriptors => components.compact
> )
> end
> templates = templates.select { |t| opts[:id] == t[:id] } if
> opts[:id]
> diff --git
> a/server/lib/deltacloud/drivers/mock/data/cimi/system_template/templ
> ate1.json
> b/server/lib/deltacloud/drivers/mock/data/cimi/system_template/templ
> ate1.json
> index 495fc24..913252b 100644
> ---
> a/server/lib/deltacloud/drivers/mock/data/cimi/system_template/templ
> ate1.json
> +++
> b/server/lib/deltacloud/drivers/mock/data/cimi/system_template/templ
> ate1.json
> @@ -4,20 +4,43 @@
> "created": "Fri Feb 08 12:15:15 EET 2013",
> "componentDescriptors": [
> { "name": "my machine",
> - "type": "http://schemas.dmtf.org/cimi/1/Machine",
> "description": "an inline mock machine template",
> + "type": "http://schemas.dmtf.org/cimi/1/Machine",
> "machineTemplate": {
> "name": "machine in mock system",
> "description": "machine in system",
> "machineConfig": { "href":
> "http://example.com/configs/m1-small" },
> - "machineImage": { "href": "http://example.com/images/img1" }
> + "machineImage": { "href": "http://example.com/images/img1" },
> + "volumeTemplates": [
> + { "href": "http://example.com/volumes/sysvol1" }
> + ]
> }
> },
> + { "name": "my second machine",
> + "description": "another inline mock machine template",
> + "type": "http://schemas.dmtf.org/cimi/1/Machine",
> + "machineTemplate": {
> + "name": "machine in mock system",
> + "description": "machine in system",
> + "machineConfig": { "href":
> "http://example.com/configs/m1-small" },
> + "machineImage": { "href": "http://example.com/images/img1" },
> + "volumeTemplates": [
> + { "volumeConfig": {"capacity": 10485760} }
> + ]
> + }
> + },
> + { "name": "my third machine",
> + "description": "a reference to a mock machine template",
> + "type": "http://schemas.dmtf.org/cimi/1/Machine",
> + "machineTemplate": { "href" :
> "http://example.com/machine_templates/template1" }
> + },
> { "name": "my network",
> + "description": "an inline network template",
> "type": "http://schemas.dmtf.org/cimi/1/Network",
> - "description": "a reference to an existing mock network
template",
> "networkTemplate": {
> - "href":
> "http://cimi.example.org/network_templates/template1"
> + "name": "network in mock system",
> + "description": "network in system",
> + "networkConfig": { "networkType": "PRIVATE",
> "classOfService": "GOLD" }
> }
> }
> ],
> diff --git
> a/server/lib/deltacloud/drivers/mock/mock_driver_cimi_methods.rb
> b/server/lib/deltacloud/drivers/mock/mock_driver_cimi_methods.rb
> index b1c57c8..13987f2 100644
> --- a/server/lib/deltacloud/drivers/mock/mock_driver_cimi_methods.rb
> +++ b/server/lib/deltacloud/drivers/mock/mock_driver_cimi_methods.rb
> @@ -35,6 +35,38 @@ module Deltacloud::Drivers::Mock
> systems.map{|sys|convert_cimi_mock_urls(:system,
> sys ,opts[:env])}.flatten
> end
>
> + def create_system(credentials, opts={})
> + check_credentials(credentials)
> + id = "#{opts[:env].send("systems_url")}/#{opts[:name]}"
> + sys_hsh = { "id"=> id,
> + "name" => opts[:name],
> + "description" => opts[:description],
> + "created" => Time.now,
> + "state" => "STOPPED",
> + "systemTemplate"=> { "href" =>
> opts[:system_template].id },
> + "operations" => [{"rel"=>"edit", "href"=> id},
> + {"rel"=>"delete", "href"=>
> id}] }
> + system = CIMI::Model::System.from_json(JSON.generate(sys_hsh))
> +
> + @client.store_cimi(:system, system)
> + system
> + end
> +
> + def delete_system(credentials, id)
> + check_credentials(credentials)
> + @client.destroy_cimi(:system, id)
> + end
> +
> + def start_system(credentials, id)
> + check_credentials(credentials)
> + update_object_state(id, "System", "STARTED")
> + end
> +
> + def stop_system(credentials, id)
> + check_credentials(credentials)
> + update_object_state(id, "System", "STOPPED")
> + end
> +
> def system_templates(credentials, opts={})
> check_credentials(credentials)
> if opts[:id].nil?
> diff --git a/server/tests/cimi/collections/system_templates_test.rb
> b/server/tests/cimi/collections/system_templates_test.rb
> index 8c4f1a7..87488b4 100644
> --- a/server/tests/cimi/collections/system_templates_test.rb
> +++ b/server/tests/cimi/collections/system_templates_test.rb
> @@ -38,4 +38,51 @@ describe CIMI::Collections::SystemTemplates do
> status.must_equal 404
> end
>
> + it 'should allow to retrieve system template\'s machine template\'s
> ref details' do
> + get root_url '/system_templates/template1'
> + (xml/'SystemTemplate/componentDescriptor').each do |c|
> + if (c/'name').inner_text == 'my third machine'
> + (c/'machineTemplate').wont_be_empty
> + (c/'machineTemplate').to_s.must_equal '<machineTemplate
> href="http://example.com/machine_templates/template1"/>'
> + end
> + end
> + end
> +
> + it 'should allow to retrieve system template\'s machine template\'s
> inline details' do
> + get root_url '/system_templates/template1'
> + (xml/'SystemTemplate/componentDescriptor').each do |c|
> + if (c/'name').inner_text == 'my machine'
> + (c/'machineTemplate').wont_be_empty
> + (c/'machineTemplate/name').inner_text.must_equal 'machine in
> mock system'
> + (c/'machineTemplate/description').inner_text.must_equal
> 'machine in system'
> + (c/'machineTemplate/machineConfig').to_s.must_equal
> '<machineConfig href="http://example.com/configs/m1-small"/>'
> + (c/'machineTemplate/machineImage').to_s.must_equal
> '<machineImage href="http://example.com/images/img1"/>'
> + (c/'machineTemplate/volumeTemplate').to_s.must_equal
> '<volumeTemplate href="http://example.com/volumes/sysvol1"/>'
> + end
> + end
> + end
> +
> + it 'should allow to retrieve system template\'s machine template\'s
> inline volume template' do
> + get root_url '/system_templates/template1'
> + (xml/'SystemTemplate/componentDescriptor').each do |c|
> + if (c/'name').inner_text == 'my second machine'
> + (c/'machineTemplate').wont_be_empty
> + (c/'machineTemplate/description').inner_text.must_equal
> 'another inline mock machine template'
> + (c/'machineTemplate/volumeTemplate').wont_be_empty
> +
> (c/'machineTemplate/volumeTemplate/volumeConfig').wont_be_empty
> +
> (c/'machineTemplate/volumeTemplate/volumeConfig/capacity').inner_tex
> t.must_equal '10485760'
> + end
> + end
> + end
> +
> + it 'should allow to retrieve system template\'s network' do
> + get root_url '/system_templates/template1'
> + (xml/'SystemTemplate/componentDescriptor').each do |c|
> + if (c/'name').inner_text == 'network in mock system'
> + (c/'networkTemplate').inner_text.must_equal 'my network'
> +
> (c/'networkTemplate/networkConfig/networkType').inner_text.must_equa
> l 'GOLD'
> + end
> + end
> + end
> +
> end
> --
> 1.8.0.msysgit.0
>
>