From: Dies Koper <di...@fast.au.fujitsu.com> --- server/lib/cimi/collections/addresses.rb | 2 +- server/lib/cimi/collections/machines.rb | 2 +- server/lib/cimi/collections/system_templates.rb | 72 ++++++++ server/lib/cimi/collections/systems.rb | 198 +++++++++++++++++++++ server/lib/cimi/models.rb | 10 ++ server/lib/cimi/models/base.rb | 4 +- server/lib/cimi/models/collection.rb | 3 + server/lib/cimi/models/system.rb | 78 ++++++++ server/lib/cimi/models/system_address.rb | 90 ++++++++++ server/lib/cimi/models/system_forwarding_group.rb | 90 ++++++++++ server/lib/cimi/models/system_machine.rb | 90 ++++++++++ server/lib/cimi/models/system_network.rb | 90 ++++++++++ server/lib/cimi/models/system_system.rb | 32 ++++ server/lib/cimi/models/system_template.rb | 66 +++++++ server/lib/cimi/models/system_volume.rb | 90 ++++++++++ .../drivers/mock/data/cimi/system/system1.json | 12 ++ .../mock/data/cimi/system_template/template1.json | 27 +++ server/lib/deltacloud/drivers/mock/mock_client.rb | 2 + .../drivers/mock/mock_driver_cimi_methods.rb | 27 +++ 19 files changed, 981 insertions(+), 4 deletions(-) create mode 100644 server/lib/cimi/collections/system_templates.rb create mode 100644 server/lib/cimi/collections/systems.rb create mode 100644 server/lib/cimi/models/system.rb create mode 100644 server/lib/cimi/models/system_address.rb create mode 100644 server/lib/cimi/models/system_forwarding_group.rb create mode 100644 server/lib/cimi/models/system_machine.rb create mode 100644 server/lib/cimi/models/system_network.rb create mode 100644 server/lib/cimi/models/system_system.rb create mode 100644 server/lib/cimi/models/system_template.rb create mode 100644 server/lib/cimi/models/system_volume.rb create mode 100644 server/lib/deltacloud/drivers/mock/data/cimi/system/system1.json create mode 100644 server/lib/deltacloud/drivers/mock/data/cimi/system_template/template1.json
diff --git a/server/lib/cimi/collections/addresses.rb b/server/lib/cimi/collections/addresses.rb index 9ea1764..a51e658 100644 --- a/server/lib/cimi/collections/addresses.rb +++ b/server/lib/cimi/collections/addresses.rb @@ -20,7 +20,7 @@ module CIMI::Collections collection :addresses do - description 'An Address represents an IP address, and its associated metdata, for a particular Network.' + description 'An Address represents an IP address, and its associated metadata, for a particular Network.' operation :index, :with_capability => :addresses do description 'List all Addresses in the AddressCollection' diff --git a/server/lib/cimi/collections/machines.rb b/server/lib/cimi/collections/machines.rb index 5718f46..9a71bb1 100644 --- a/server/lib/cimi/collections/machines.rb +++ b/server/lib/cimi/collections/machines.rb @@ -85,7 +85,7 @@ module CIMI::Collections end action :restart, :with_capability => :reboot_instance do - description "Start specific machine." + description "Restart specific machine." param :id, :string, :required control do machine = Machine.find(params[:id], self) diff --git a/server/lib/cimi/collections/system_templates.rb b/server/lib/cimi/collections/system_templates.rb new file mode 100644 index 0000000..88fbe30 --- /dev/null +++ b/server/lib/cimi/collections/system_templates.rb @@ -0,0 +1,72 @@ +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. The +# ASF licenses this file to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance with the +# License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. + +module CIMI::Collections + class SystemTemplates < Base + + set :capability, lambda { |t| true } + + collection :system_templates do + + operation :index do + description "List all system templates" + control do + system_templates = CIMI::Model::SystemTemplate.list(self).select_by(params['$select']) + respond_to do |format| + format.xml { system_templates.to_xml } + format.json { system_templates.to_json } + end + end + end + + operation :show do + description "Show specific system template" + control do + system_template = CIMI::Model::SystemTemplate.find(params[:id], self) + respond_to do |format| + format.xml { system_template.to_xml } + format.json { system_template.to_json } + end + end + end + + operation :create do + description "Create new system template" + control do + if grab_content_type(request.content_type, request.body) == :json + new_system_template = CIMI::Model::SystemTemplate.create_from_json(request.body.read, self) + else + new_system_template = CIMI::Model::SystemTemplate.create_from_xml(request.body.read, self) + end + headers_for_create new_system_template + respond_to do |format| + format.json { new_system_template.to_json } + format.xml { new_system_template.to_xml } + end + end + end + + operation :destroy do + description "Delete a specified system template" + control do + CIMI::Model::SystemTemplate.delete!(params[:id], self) + no_content_with_status(200) + end + end + + end + + end +end diff --git a/server/lib/cimi/collections/systems.rb b/server/lib/cimi/collections/systems.rb new file mode 100644 index 0000000..250b1d2 --- /dev/null +++ b/server/lib/cimi/collections/systems.rb @@ -0,0 +1,198 @@ +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. The +# ASF licenses this file to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance with the +# License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. + +module CIMI::Collections + class Systems < Base + + set :capability, lambda { |m| driver.respond_to? m } + + collection :systems do + description 'List all systems' + + operation :index, :with_capability => :systems do + description "List all systems" + control do + systems = System.list(self).select_by(params['$select']).filter_by(params['$filter']) + respond_to do |format| + format.xml { systems.to_xml } + format.json { systems.to_json } + end + end + end + + operation :show, :with_capability => :system do + description "Show specific system." + control do + system = System.find(params[:id], self) + respond_to do |format| + format.xml { system.to_xml } + format.json { system.to_json } + end + end + end + + operation :create, :with_capability => :create_system do + description "Create a new System entity." + control do + if grab_content_type(request.content_type, request.body) == :json + new_system = System.create_from_json(request.body.read, self) + else + new_system = System.create_from_xml(request.body.read, self) + end + headers_for_create new_system + respond_to do |format| + format.json { new_system.to_json } + format.xml { new_system.to_xml } + end + end + end + + operation :destroy, :with_capability => :destroy_system do + description "Delete a specified system." + control do + System.delete!(params[:id], self) + no_content_with_status(200) + end + end + + action :stop, :with_capability => :stop_system do + description "Stop specific system." + param :id, :string, :required + control do + system = System.find(params[:id], self) + if grab_content_type(request.content_type, request.body) == :json + action = Action.from_json(request.body.read) + else + action = Action.from_xml(request.body.read) + end + system.perform(action, self) do |operation| + no_content_with_status(202) if operation.success? + # Handle errors using operation.failure? + end + end + end + + action :restart, :with_capability => :reboot_system do + description "Restart specific system." + param :id, :string, :required + control do + system = System.find(params[:id], self) + if grab_content_type(request.content_type, request.body) == :json + action = Action.from_json(request.body.read.gsub("restart", "reboot")) + else + action = Action.from_xml(request.body.read.gsub("restart", "reboot")) + end + system.perform(action, self) do |operation| + no_content_with_status(202) if operation.success? + # Handle errors using operation.failure? + end + end + end + + action :start, :with_capability => :start_system do + description "Start specific system." + param :id, :string, :required + control do + system = System.find(params[:id], self) + if grab_content_type(request.content_type, request.body) == :json + action = Action.from_json(request.body.read) + else + action = Action.from_xml(request.body.read) + end + system.perform(action, self) do |operation| + no_content_with_status(202) if operation.success? + # Handle errors using operation.failure? + end + end + end + + action :pause, :with_capability => :pause_system do + description "Pause specific system." + param :id, :string, :required + control do + system = System.find(params[:id], self) + if grab_content_type(request.content_type, request.body) == :json + action = Action.from_json(request.body.read) + else + action = Action.from_xml(request.body.read) + end + system.perform(action, self) do |operation| + no_content_with_status(202) if operation.success? + # Handle errors using operation.failure? + end + end + end + + action :suspend, :with_capability => :suspend_system do + description "Suspend specific system." + param :id, :string, :required + control do + system = System.find(params[:id], self) + if grab_content_type(request.content_type, request.body) == :json + action = Action.from_json(request.body.read) + else + action = Action.from_xml(request.body.read) + end + system.perform(action, self) do |operation| + no_content_with_status(202) if operation.success? + # Handle errors using operation.failure? + end + end + end + + #use rabbit subcollections for volumes index/show: + collection :volumes, :with_id => :vol_id do + + operation :index, :with_capability => :storage_volumes do + description "Retrieve the System's SystemVolumeCollection" + control do + volumes = CIMI::Model::SystemVolume.collection_for_instance(params[:id], self) + respond_to do |format| + format.json {volumes.to_json} + format.xml {volumes.to_xml} + end + end + end + + operation :show, :with_capability => :storage_volumes do + description "Retrieve a System's specific SystemVolume" + control do + volume = CIMI::Model::SystemVolume.find(params[:id], self, params[:vol_id]) + respond_to do |format| + format.json {volume.to_json} + format.xml {volume.to_xml} + end + end + end + + operation :destroy, :with_capability => :detach_storage_volume do + description "Remove/detach a volume from the System's SystemVolumeCollection" + control do + system_volume = CIMI::Model::SystemVolume.find(params[:id], self, params[:vol_id]) + location = system_volume.initial_location + system_volumes = System.detach_volume(params[:vol_id], location, self) + respond_to do |format| + format.json{ system_volumes.to_json} + format.xml{ system_volumes.to_xml} + end + end + end + + end + + end + + end +end diff --git a/server/lib/cimi/models.rb b/server/lib/cimi/models.rb index 20c0ef1..ec1a1c9 100644 --- a/server/lib/cimi/models.rb +++ b/server/lib/cimi/models.rb @@ -81,3 +81,13 @@ require_relative './models/address' require_relative './models/address_template' require_relative './models/forwarding_group' require_relative './models/forwarding_group_template' +require_relative './models/system_system' +require_relative './models/system_volume' +require_relative './models/system_machine' +require_relative './models/system_template' +#require_relative './models/system_credential' +#require_relative './models/system_network_port' +require_relative './models/system_network' +require_relative './models/system_address' +require_relative './models/system_forwarding_group' +require_relative './models/system' diff --git a/server/lib/cimi/models/base.rb b/server/lib/cimi/models/base.rb index c74b8c3..2c49c75 100644 --- a/server/lib/cimi/models/base.rb +++ b/server/lib/cimi/models/base.rb @@ -63,7 +63,7 @@ require_relative '../helpers/database_helper' # [struct(name, opts, &block)] # A structured subobject; the block defines the schema of the # subobject. The +:content+ option can be used to specify the attribute -# that should receive the content of hte corresponding XML element +# that should receive the content of the corresponding XML element # [array(name, opts, &block)] # An array of structured subobjects; the block defines the schema of # the subobjects. @@ -86,7 +86,7 @@ module CIMI::Model # # Common attributes for all resources # - text :id, :name, :description, :created + text :id, :name, :description, :created, :updated hash :property end diff --git a/server/lib/cimi/models/collection.rb b/server/lib/cimi/models/collection.rb index f36c081..17ad95b 100644 --- a/server/lib/cimi/models/collection.rb +++ b/server/lib/cimi/models/collection.rb @@ -121,7 +121,9 @@ module CIMI::Model # Return a collection of entities def list(context) + puts "list(#{context}) called." entries = find(:all, context) + puts "entries: #{entries}" desc = "#{self.name.split("::").last} Collection for the #{context.driver.name.capitalize} driver" acts_as_root_entity unless collection_class id = context.send("#{collection_class.entry_name}_url") @@ -135,6 +137,7 @@ module CIMI::Model url = context.send(cimi_create) ops << { :rel => "add", :href => url } end + puts "entries: #{entries}" collection_class.new(:id => id, :count => entries.size, :entries => entries, diff --git a/server/lib/cimi/models/system.rb b/server/lib/cimi/models/system.rb new file mode 100644 index 0000000..619e7a9 --- /dev/null +++ b/server/lib/cimi/models/system.rb @@ -0,0 +1,78 @@ +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. The +# ASF licenses this file to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance with the +# License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. + +class CIMI::Model::System < CIMI::Model::Base + + acts_as_root_entity + + text :state + + collection :systems, :class => CIMI::Model::SystemSystem + collection :machines, :class => CIMI::Model::SystemMachine +# collection :credentials, :class => CIMI::Model::SystemCredential + collection :volumes, :class => CIMI::Model::SystemVolume + collection :networks, :class => CIMI::Model::SystemNetwork +# collection :network_ports, :class => CIMI::Model::SystemNetworkPort + collection :addresses, :class => CIMI::Model::SystemAddress + collection :forwarding_groups, :class => CIMI::Model::SystemForwardingGroup + + array :meters do + scalar :href + end + + href :event_log + + array :operations do + scalar :rel, :href + end + + def self.find(id, context) + puts "system#self.find called" + systems = [] + if id == :all + systems = context.driver.systems(context.credentials, {:env=>context}) +puts "systems from driver #{systems.size}" + else + system = context.driver.system(context.credentials, {:env=>context, :id=>id}) + raise CIMI::Model::NotFound unless system + system + end + end + + def self.create_from_json(body, context) + #todo: mfojtik and lutter are refactoring this mechanism + end + + def self.create_from_xml(body, context) + #todo: mfojtik and lutter are refactoring this mechanism + end + + def perform(action, context, &block) + begin + if context.driver.send(:"#{action.name}_system", context.credentials, self.id.split("/").last) + block.callback :success + else + raise "Operation failed to execute on given System" + end + rescue => e + block.callback :failure, e.message + end + end + + def self.delete!(id, context) + context.driver.destroy_system(context.credentials, id) + end + +end diff --git a/server/lib/cimi/models/system_address.rb b/server/lib/cimi/models/system_address.rb new file mode 100644 index 0000000..a4c88bf --- /dev/null +++ b/server/lib/cimi/models/system_address.rb @@ -0,0 +1,90 @@ +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. The +# ASF licenses this file to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance with the +# License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. + +class CIMI::Model::SystemAddress < CIMI::Model::Base + + href :address + + array :operations do + scalar :rel, :href + end + + def self.find(instance_id, context, id=:all) + puts "system_address#self.find called" + if id == :all + addresses = context.driver.storage_addresses(context.credentials) + addresses.inject([]) do |attached, vol| + id = context.system_url(instance_id)+"/addresses/#{vol.id}" + attached << self.new( + :id => id, + :name => vol.id, + :description => "SystemAddress #{vol.id} for System #{instance_id}", + :created => vol.created.nil? ? nil : Time.parse(vol.created).xmlschema, + :initial_location => vol.device, + :address => {:href=>context.address_url(vol.id)}, + :operations => [{:href=>id, :rel => "delete" }] + ) if vol.instance_id == instance_id + attached + end + else + vol = context.driver.storage_address(context.credentials, {:id=>id}) + id = context.system_url(instance_id)+"/addresses/#{vol.id}" + raise CIMI::Model::NotFound unless vol.instance_id == instance_id + self.new( + :id => id, + :name => vol.id, + :description => "SystemAddress #{vol.id} for System #{instance_id}", + :created => vol.created.nil? ? nil : Time.parse(vol.created).xmlschema, + :initial_location => vol.device, + :address => {:href=>context.address_url(vol.id)}, + :operations => [{:href=>id, :rel => "delete" }] + ) + end + end + + def self.find_to_attach_from_xml(xml_in, context) + xml = XmlSimple.xml_in(xml_in) + vol_id = xml["address"].first["href"].split("/").last + location = xml["initialLocation"].first.strip + [vol_id, location] + end + + def self.find_to_attach_from_json(json_in, context) + json = JSON.parse(json_in) + vol_id = json["address"]["href"].split("/").last + location = json["initialLocation"] + [vol_id, location] + end + + + def self.collection_for_instance(instance_id, context) + system_addresses = self.find(instance_id, context) + addresses_url = context.url("/systems/#{instance_id}/addresses") + unless CIMI::Model.const_defined?('SystemAddressCollection') + collection_class = CIMI::Model::Collection.generate(self) + else + collection_class = CIMI::Model::SystemAddressCollection + end + collection_class.new( + :id => addresses_url, + :name => 'default', + :count => system_addresses.size, + :description => "Address collection for System #{instance_id}", + :entries => system_addresses, + :operations => [{ :href => addresses_url.singularize+"_attach", :rel => "add" }] + ) + end + +end diff --git a/server/lib/cimi/models/system_forwarding_group.rb b/server/lib/cimi/models/system_forwarding_group.rb new file mode 100644 index 0000000..95c148c --- /dev/null +++ b/server/lib/cimi/models/system_forwarding_group.rb @@ -0,0 +1,90 @@ +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. The +# ASF licenses this file to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance with the +# License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. + +class CIMI::Model::SystemForwardingGroup < CIMI::Model::Base + + href :forwarding_group + + array :operations do + scalar :rel, :href + end + + def self.find(instance_id, context, id=:all) + puts "system_machine#self.find called" + if id == :all + forwarding_groups = context.driver.storage_forwarding_groups(context.credentials) + forwarding_groups.inject([]) do |attached, vol| + id = context.system_url(instance_id)+"/forwarding_groups/#{vol.id}" + attached << self.new( + :id => id, + :name => vol.id, + :description => "SystemForwardingGroup #{vol.id} for System #{instance_id}", + :created => vol.created.nil? ? nil : Time.parse(vol.created).xmlschema, + :initial_location => vol.device, + :forwarding_group => {:href=>context.forwarding_group_url(vol.id)}, + :operations => [{:href=>id, :rel => "delete" }] + ) if vol.instance_id == instance_id + attached + end + else + vol = context.driver.storage_forwarding_group(context.credentials, {:id=>id}) + id = context.system_url(instance_id)+"/forwarding_groups/#{vol.id}" + raise CIMI::Model::NotFound unless vol.instance_id == instance_id + self.new( + :id => id, + :name => vol.id, + :description => "SystemForwardingGroup #{vol.id} for System #{instance_id}", + :created => vol.created.nil? ? nil : Time.parse(vol.created).xmlschema, + :initial_location => vol.device, + :forwarding_group => {:href=>context.forwarding_group_url(vol.id)}, + :operations => [{:href=>id, :rel => "delete" }] + ) + end + end + + def self.find_to_attach_from_xml(xml_in, context) + xml = XmlSimple.xml_in(xml_in) + vol_id = xml["forwarding_group"].first["href"].split("/").last + location = xml["initialLocation"].first.strip + [vol_id, location] + end + + def self.find_to_attach_from_json(json_in, context) + json = JSON.parse(json_in) + vol_id = json["forwarding_group"]["href"].split("/").last + location = json["initialLocation"] + [vol_id, location] + end + + + def self.collection_for_instance(instance_id, context) + system_forwarding_groups = self.find(instance_id, context) + forwarding_groups_url = context.url("/systems/#{instance_id}/forwarding_groups") + unless CIMI::Model.const_defined?('SystemForwardingGroupCollection') + collection_class = CIMI::Model::Collection.generate(self) + else + collection_class = CIMI::Model::SystemForwardingGroupCollection + end + collection_class.new( + :id => forwarding_groups_url, + :name => 'default', + :count => system_forwarding_groups.size, + :description => "ForwardingGroup collection for System #{instance_id}", + :entries => system_forwarding_groups, + :operations => [{ :href => forwarding_groups_url.singularize+"_attach", :rel => "add" }] + ) + end + +end diff --git a/server/lib/cimi/models/system_machine.rb b/server/lib/cimi/models/system_machine.rb new file mode 100644 index 0000000..5c96ded --- /dev/null +++ b/server/lib/cimi/models/system_machine.rb @@ -0,0 +1,90 @@ +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. The +# ASF licenses this file to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance with the +# License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. + +class CIMI::Model::SystemMachine < CIMI::Model::Base + + href :machine + + array :operations do + scalar :rel, :href + end + + def self.find(instance_id, context, id=:all) + puts "system_machine#self.find called" + if id == :all + machines = context.driver.storage_machines(context.credentials) + machines.inject([]) do |attached, vol| + id = context.system_url(instance_id)+"/machines/#{vol.id}" + attached << self.new( + :id => id, + :name => vol.id, + :description => "SystemMachine #{vol.id} for System #{instance_id}", + :created => vol.created.nil? ? nil : Time.parse(vol.created).xmlschema, + :initial_location => vol.device, + :machine => {:href=>context.machine_url(vol.id)}, + :operations => [{:href=>id, :rel => "delete" }] + ) if vol.instance_id == instance_id + attached + end + else + vol = context.driver.storage_machine(context.credentials, {:id=>id}) + id = context.system_url(instance_id)+"/machines/#{vol.id}" + raise CIMI::Model::NotFound unless vol.instance_id == instance_id + self.new( + :id => id, + :name => vol.id, + :description => "SystemMachine #{vol.id} for System #{instance_id}", + :created => vol.created.nil? ? nil : Time.parse(vol.created).xmlschema, + :initial_location => vol.device, + :machine => {:href=>context.machine_url(vol.id)}, + :operations => [{:href=>id, :rel => "delete" }] + ) + end + end + + def self.find_to_attach_from_xml(xml_in, context) + xml = XmlSimple.xml_in(xml_in) + vol_id = xml["machine"].first["href"].split("/").last + location = xml["initialLocation"].first.strip + [vol_id, location] + end + + def self.find_to_attach_from_json(json_in, context) + json = JSON.parse(json_in) + vol_id = json["machine"]["href"].split("/").last + location = json["initialLocation"] + [vol_id, location] + end + + + def self.collection_for_instance(instance_id, context) + system_machines = self.find(instance_id, context) + machines_url = context.url("/systems/#{instance_id}/machines") + unless CIMI::Model.const_defined?('SystemMachineCollection') + collection_class = CIMI::Model::Collection.generate(self) + else + collection_class = CIMI::Model::SystemMachineCollection + end + collection_class.new( + :id => machines_url, + :name => 'default', + :count => system_machines.size, + :description => "Machine collection for System #{instance_id}", + :entries => system_machines, + :operations => [{ :href => machines_url.singularize+"_attach", :rel => "add" }] + ) + end + +end diff --git a/server/lib/cimi/models/system_network.rb b/server/lib/cimi/models/system_network.rb new file mode 100644 index 0000000..df3f831 --- /dev/null +++ b/server/lib/cimi/models/system_network.rb @@ -0,0 +1,90 @@ +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. The +# ASF licenses this file to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance with the +# License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. + +class CIMI::Model::SystemNetwork < CIMI::Model::Base + + href :network + + array :operations do + scalar :rel, :href + end + + def self.find(instance_id, context, id=:all) + puts "SystemNetwork#self.find called" + if id == :all + networks = context.driver.storage_networks(context.credentials) + networks.inject([]) do |attached, vol| + id = context.system_url(instance_id)+"/networks/#{vol.id}" + attached << self.new( + :id => id, + :name => vol.id, + :description => "SystemNetwork #{vol.id} for System #{instance_id}", + :created => vol.created.nil? ? nil : Time.parse(vol.created).xmlschema, + :initial_location => vol.device, + :network => {:href=>context.network_url(vol.id)}, + :operations => [{:href=>id, :rel => "delete" }] + ) if vol.instance_id == instance_id + attached + end + else + vol = context.driver.storage_network(context.credentials, {:id=>id}) + id = context.system_url(instance_id)+"/networks/#{vol.id}" + raise CIMI::Model::NotFound unless vol.instance_id == instance_id + self.new( + :id => id, + :name => vol.id, + :description => "SystemNetwork #{vol.id} for System #{instance_id}", + :created => vol.created.nil? ? nil : Time.parse(vol.created).xmlschema, + :initial_location => vol.device, + :network => {:href=>context.network_url(vol.id)}, + :operations => [{:href=>id, :rel => "delete" }] + ) + end + end + + def self.find_to_attach_from_xml(xml_in, context) + xml = XmlSimple.xml_in(xml_in) + vol_id = xml["network"].first["href"].split("/").last + location = xml["initialLocation"].first.strip + [vol_id, location] + end + + def self.find_to_attach_from_json(json_in, context) + json = JSON.parse(json_in) + vol_id = json["network"]["href"].split("/").last + location = json["initialLocation"] + [vol_id, location] + end + + + def self.collection_for_instance(instance_id, context) + system_networks = self.find(instance_id, context) + networks_url = context.url("/systems/#{instance_id}/networks") + unless CIMI::Model.const_defined?('SystemNetworkCollection') + collection_class = CIMI::Model::Collection.generate(self) + else + collection_class = CIMI::Model::SystemNetworkCollection + end + collection_class.new( + :id => networks_url, + :name => 'default', + :count => system_networks.size, + :description => "Network collection for System #{instance_id}", + :entries => system_networks, + :operations => [{ :href => networks_url.singularize+"_attach", :rel => "add" }] + ) + end + +end diff --git a/server/lib/cimi/models/system_system.rb b/server/lib/cimi/models/system_system.rb new file mode 100644 index 0000000..41f9ae7 --- /dev/null +++ b/server/lib/cimi/models/system_system.rb @@ -0,0 +1,32 @@ +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. The +# ASF licenses this file to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance with the +# License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. + +class CIMI::Model::SystemSystem < CIMI::Model::Base + + href :system + + array :operations do + scalar :rel, :href + end + + def self.find(instance_id, context, id=:all) + puts "SystemSystem#self.find called" + end + + + def self.collection_for_instance(instance_id, context) + end + +end diff --git a/server/lib/cimi/models/system_template.rb b/server/lib/cimi/models/system_template.rb new file mode 100644 index 0000000..9cfc64c --- /dev/null +++ b/server/lib/cimi/models/system_template.rb @@ -0,0 +1,66 @@ +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. The +# ASF licenses this file to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance with the +# License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. + +class CIMI::Model::SystemTemplate < CIMI::Model::Base + + acts_as_root_entity + + array :component_descriptors do + text :name, :description + hash :properties + text :type + scalar :component_template #or :class => CIMI::Model::Base ? + text :quantity + end + + array :meter_templates do + scalar :href + end + + href :event_log_template + + array :operations do + scalar :rel, :href + end + + class << self + def find(id, context) + puts "system_template#self.find called" + templates = [] + if id == :all + templates = context.driver.system_templates(context.credentials, {:env=>context}) +puts "Templates from driver #{templates.size}" + else + template = context.driver.system_templates(context.credentials, {:env=>context, :id=>id}) + raise CIMI::Model::NotFound unless template + template + end + end + + def create_from_json(body, context) + #todo: mfojtik and lutter are refactoring this mechanism + end + + def create_from_xml(body, context) + #todo: mfojtik and lutter are refactoring this mechanism + end + + def delete!(id, context) + context.driver.destroy_system_template(context.credentials, id) + end + + end + +end diff --git a/server/lib/cimi/models/system_volume.rb b/server/lib/cimi/models/system_volume.rb new file mode 100644 index 0000000..3433402 --- /dev/null +++ b/server/lib/cimi/models/system_volume.rb @@ -0,0 +1,90 @@ +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. The +# ASF licenses this file to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance with the +# License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. + +class CIMI::Model::SystemVolume < CIMI::Model::Base + + href :volume + + array :operations do + scalar :rel, :href + end + + def self.find(instance_id, context, id=:all) + puts "system_volume#self.find called" + if id == :all + volumes = context.driver.storage_volumes(context.credentials) + volumes.inject([]) do |attached, vol| + id = context.system_url(instance_id)+"/volumes/#{vol.id}" + attached << self.new( + :id => id, + :name => vol.id, + :description => "SystemVolume #{vol.id} for System #{instance_id}", + :created => vol.created.nil? ? nil : Time.parse(vol.created).xmlschema, + :initial_location => vol.device, + :volume => {:href=>context.volume_url(vol.id)}, + :operations => [{:href=>id, :rel => "delete" }] + ) if vol.instance_id == instance_id + attached + end + else + vol = context.driver.storage_volume(context.credentials, {:id=>id}) + id = context.system_url(instance_id)+"/volumes/#{vol.id}" + raise CIMI::Model::NotFound unless vol.instance_id == instance_id + self.new( + :id => id, + :name => vol.id, + :description => "SystemVolume #{vol.id} for System #{instance_id}", + :created => vol.created.nil? ? nil : Time.parse(vol.created).xmlschema, + :initial_location => vol.device, + :volume => {:href=>context.volume_url(vol.id)}, + :operations => [{:href=>id, :rel => "delete" }] + ) + end + end + + def self.find_to_attach_from_xml(xml_in, context) + xml = XmlSimple.xml_in(xml_in) + vol_id = xml["volume"].first["href"].split("/").last + location = xml["initialLocation"].first.strip + [vol_id, location] + end + + def self.find_to_attach_from_json(json_in, context) + json = JSON.parse(json_in) + vol_id = json["volume"]["href"].split("/").last + location = json["initialLocation"] + [vol_id, location] + end + + + def self.collection_for_instance(instance_id, context) + system_volumes = self.find(instance_id, context) + volumes_url = context.url("/systems/#{instance_id}/volumes") + unless CIMI::Model.const_defined?('SystemVolumeCollection') + collection_class = CIMI::Model::Collection.generate(self) + else + collection_class = CIMI::Model::SystemVolumeCollection + end + collection_class.new( + :id => volumes_url, + :name => 'default', + :count => system_volumes.size, + :description => "Volume collection for System #{instance_id}", + :entries => system_volumes, + :operations => [{ :href => volumes_url.singularize+"_attach", :rel => "add" }] + ) + end + +end diff --git a/server/lib/deltacloud/drivers/mock/data/cimi/system/system1.json b/server/lib/deltacloud/drivers/mock/data/cimi/system/system1.json new file mode 100644 index 0000000..450233d --- /dev/null +++ b/server/lib/deltacloud/drivers/mock/data/cimi/system/system1.json @@ -0,0 +1,12 @@ +{ "id": "http://cimi.example.org/systems/template1", + "name": "system1", + "description": "the first system", + "created": "Fri Feb 08 15:25:41 EET 2013", + "state": "STOPPED", + "machines": { "href": "http://cimi.example.org/systems/87654/machines"}, + "networks": { "href": "http://cimi.example.org/systems/87654/networks"}, + "operations": [ + { "rel": "edit", "href": "http://cimi.example.org/networks/network1" }, + { "rel": "delete", "href": "http://cimi.example.org/networks/network1" } + ] +} diff --git a/server/lib/deltacloud/drivers/mock/data/cimi/system_template/template1.json b/server/lib/deltacloud/drivers/mock/data/cimi/system_template/template1.json new file mode 100644 index 0000000..0672df1 --- /dev/null +++ b/server/lib/deltacloud/drivers/mock/data/cimi/system_template/template1.json @@ -0,0 +1,27 @@ +{ "id": "http://cimi.example.org/system_templates/template1", + "name": "system template 1", + "description": "A mock system template", + "created": "Fri Feb 08 12:15:15 EET 2013", + "componentDescriptors": [ + { "name": "my machine", + "description": "an inline mock machine template", + "type": "http://schemas.dmtf.org/cimi/1/Machine", + "machineTemplate": { + "name": "machine in mock system", + "description": "machine in ststem", + "machineConfig": "http://example.com/configs/m1-small", + "machineImage": "http://example.com/images/img1" + } + }, + { "name": "my network", + "description": "a reference to an existing mock network template", + "type": "http://schemas.dmtf.org/cimi/1/Network", + "networkTemplate": { + "href": "http://cimi.example.org/network_templates/template1" + } + } + ], + "operations": [ + { "rel": "edit", "href": "http://cimi.example.org/network_templates/template1" }, + { "rel": "delete", "href": "http://cimi.example.org/network_templates/template1" }] +} diff --git a/server/lib/deltacloud/drivers/mock/mock_client.rb b/server/lib/deltacloud/drivers/mock/mock_client.rb index 449b6a8..d7796a2 100644 --- a/server/lib/deltacloud/drivers/mock/mock_client.rb +++ b/server/lib/deltacloud/drivers/mock/mock_client.rb @@ -92,7 +92,9 @@ module Deltacloud::Drivers::Mock end def load_all_cimi(model_name) + puts "dir: #{File::join(cimi_dir(model_name), "*.json")}" model_files = Dir[File::join(cimi_dir(model_name), "*.json")] + puts "model_files: #{model_files}" model_files.map{|f| File.read(f)} end 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 336f77b..57ea5ef 100644 --- a/server/lib/deltacloud/drivers/mock/mock_driver_cimi_methods.rb +++ b/server/lib/deltacloud/drivers/mock/mock_driver_cimi_methods.rb @@ -20,6 +20,31 @@ module Deltacloud::Drivers::Mock class MockDriver < Deltacloud::BaseDriver + + def systems(credentials, opts={}) + check_credentials(credentials) + if opts[:id].nil? + systems = @client.load_all_cimi(:system).map{|sys| CIMI::Model::System.from_json(sys)} + systems.map{|sys|convert_cimi_mock_urls(:system, sys ,opts[:env])}.flatten + else + system = CIMI::Model::System.from_json(@client.load_cimi(:system, opts[:id])) + convert_cimi_mock_urls(:system, system, opts[:env]) + end + end + + def system_templates(credentials, opts={}) + check_credentials(credentials) + puts "reached mock's system_templates with opts: #{opts}" + if opts[:id].nil? + system_templates = @client.load_all_cimi(:system_template).map{|sys_templ| CIMI::Model::SystemTemplate.from_json(sys_templ)} + puts "raw templates from files: #{system_templates}" + system_templates.map{|sys_templ|convert_cimi_mock_urls(:system_template, sys_templ, opts[:env])}.flatten + else + system_template = CIMI::Model::SystemTemplate.from_json(@client.load_cimi(:system_template, opts[:id])) + convert_cimi_mock_urls(:system_template, system_template, opts[:env]) + end + end + def networks(credentials, opts={}) check_credentials(credentials) if opts[:id].nil? @@ -138,6 +163,8 @@ module Deltacloud::Drivers::Mock end end end + puts "cimi_object.name = #{cimi_object.name}" + puts "context = #{context}" object_url = context.send(:"#{model_name}_url", cimi_object.name) cimi_object.id=object_url cimi_object.operations.each{|op| op.href=object_url } -- 1.8.0.msysgit.0