You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@deltacloud.apache.org by di...@fast.au.fujitsu.com on 2013/03/28 12:11:19 UTC

[PATCH] CIMI: added subcollections to System and SystemTemplate added create and delete system support for mock and fgcp.

From: Dies Koper <di...@fast.au.fujitsu.com>

---
 server/lib/cimi/collections/systems.rb             |  95 +++++----
 server/lib/cimi/helpers/cimi_rabbit_helper.rb      |  54 ++++++
 server/lib/cimi/models.rb                          |  13 +-
 server/lib/cimi/models/machine_template.rb         |   6 +-
 server/lib/cimi/models/network_template.rb         |   4 +-
 server/lib/cimi/models/system.rb                   |  24 +--
 server/lib/cimi/models/system_address.rb           |  26 +++
 server/lib/cimi/models/system_create.rb            |  20 ++
 server/lib/cimi/models/system_credential.rb        |  26 +++
 server/lib/cimi/models/system_forwarding_group.rb  |  26 +++
 server/lib/cimi/models/system_machine.rb           |  26 +++
 server/lib/cimi/models/system_network.rb           |  26 +++
 server/lib/cimi/models/system_network_port.rb      |  26 +++
 server/lib/cimi/models/system_system.rb            |  26 +++
 server/lib/cimi/models/system_template.rb          |  20 +-
 server/lib/cimi/models/system_volume.rb            |  26 +++
 server/lib/cimi/models/volume_template.rb          |   4 +-
 server/lib/cimi/service.rb                         |   6 +
 server/lib/cimi/service/system.rb                  |   2 +-
 server/lib/cimi/service/system_address.rb          |  34 ++++
 server/lib/cimi/service/system_create.rb           |  39 ++++
 server/lib/cimi/service/system_forwarding_group.rb |  34 ++++
 server/lib/cimi/service/system_machine.rb          |  34 ++++
 server/lib/cimi/service/system_network.rb          |  34 ++++
 server/lib/cimi/service/system_volume.rb           |  34 ++++
 server/lib/deltacloud/drivers/fgcp/fgcp_client.rb  |   4 +
 .../drivers/fgcp/fgcp_driver_cimi_methods.rb       | 215 +++++++++++++++++++--
 .../mock/data/cimi/system_address/sysaddress1.json |   8 +
 .../sysforwardinggroup1.json                       |   8 +
 .../mock/data/cimi/system_machine/sysmach1.json    |   8 +
 .../mock/data/cimi/system_network/sysnet1.json     |   8 +
 .../mock/data/cimi/system_template/template1.json  |  31 ++-
 .../mock/data/cimi/system_volume/sysvol1.json      |   8 +
 .../drivers/mock/mock_driver_cimi_methods.rb       | 109 +++++++++++
 .../cimi/collections/system_templates_test.rb      |  47 +++++
 35 files changed, 1021 insertions(+), 90 deletions(-)
 create mode 100644 server/lib/cimi/models/system_address.rb
 create mode 100644 server/lib/cimi/models/system_create.rb
 create mode 100644 server/lib/cimi/models/system_credential.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_network_port.rb
 create mode 100644 server/lib/cimi/models/system_system.rb
 create mode 100644 server/lib/cimi/models/system_volume.rb
 create mode 100644 server/lib/cimi/service/system_address.rb
 create mode 100644 server/lib/cimi/service/system_create.rb
 create mode 100644 server/lib/cimi/service/system_forwarding_group.rb
 create mode 100644 server/lib/cimi/service/system_machine.rb
 create mode 100644 server/lib/cimi/service/system_network.rb
 create mode 100644 server/lib/cimi/service/system_volume.rb
 create mode 100644 server/lib/deltacloud/drivers/mock/data/cimi/system_address/sysaddress1.json
 create mode 100644 server/lib/deltacloud/drivers/mock/data/cimi/system_forwarding_group/sysforwardinggroup1.json
 create mode 100644 server/lib/deltacloud/drivers/mock/data/cimi/system_machine/sysmach1.json
 create mode 100644 server/lib/deltacloud/drivers/mock/data/cimi/system_network/sysnet1.json
 create mode 100644 server/lib/deltacloud/drivers/mock/data/cimi/system_volume/sysvol1.json

diff --git a/server/lib/cimi/collections/systems.rb b/server/lib/cimi/collections/systems.rb
index 5c3903e..179daea 100644
--- a/server/lib/cimi/collections/systems.rb
+++ b/server/lib/cimi/collections/systems.rb
@@ -107,45 +107,70 @@ module CIMI::Collections
         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 = SystemVolume.collection_for_system(params[:id], self)
-            respond_to do |format|
-              format.json {volumes.to_json}
-              format.xml  {volumes.to_xml}
-            end
-          end
-        end
+      collection :systems, :with_id => :ent_id do
+        description 'List system\'s systems'
+        generate_system_subcollection_index_operation :with_capability => :system_systems
+        generate_system_subcollection_show_operation :with_capability => :system_systems
+        generate_add_to_system_operation :with_capability => :add_system_to_system
+        generate_remove_from_system_operation :with_capability => :remove_system_from_system
+      end
 
-        operation :show, :with_capability => :storage_volumes do
-          description "Retrieve a System's specific SystemVolume"
-          control do
-            volume = 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
+      collection :machines, :with_id => :ent_id do
+        description 'List system\'s machines'
+        generate_system_subcollection_index_operation :with_capability => :system_machines
+        generate_system_subcollection_show_operation :with_capability => :system_machines
+        generate_add_to_system_operation :with_capability => :add_machine_to_system
+        generate_remove_from_system_operation :with_capability => :remove_machine_from_system
+      end
 
-        operation :destroy, :with_capability => :detach_storage_volume do
-          description "Remove/detach a volume from the System's SystemVolumeCollection"
-          control do
-            system_volume = 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
+      collection :credentials, :with_id => :ent_id do
+        description 'List system\'s credentials'
+        generate_system_subcollection_index_operation :with_capability => :system_credentials
+        generate_system_subcollection_show_operation :with_capability => :system_credentials
+        generate_add_to_system_operation :with_capability => :add_credential_to_system
+        generate_remove_from_system_operation :with_capability => :remove_credential_from_system
+      end
 
+      collection :volumes, :with_id => :ent_id do
+        description 'List system\'s volumes'
+        generate_system_subcollection_index_operation :with_capability => :system_volumes
+        generate_system_subcollection_show_operation :with_capability => :system_volumes
+        generate_add_to_system_operation :with_capability => :add_volume_to_system
+        generate_remove_from_system_operation :with_capability => :remove_volume_from_system
       end
+
+      collection :networks, :with_id => :ent_id do
+        description 'List system\'s networks'
+        generate_system_subcollection_index_operation :with_capability => :system_networks
+        generate_system_subcollection_show_operation :with_capability => :system_networks
+        generate_add_to_system_operation :with_capability => :add_network_to_system
+        generate_remove_from_system_operation :with_capability => :remove_network_from_system
+      end
+
+      collection :network_ports, :with_id => :ent_id do
+        description 'List system\'s network ports'
+        generate_system_subcollection_index_operation :with_capability => :system_network_ports
+        generate_system_subcollection_show_operation :with_capability => :system_network_ports
+        generate_add_to_system_operation :with_capability => :add_network_port_to_system
+        generate_remove_from_system_operation :with_capability => :remove_network_port_from_system
+      end
+
+      collection :addresses, :with_id => :ent_id do
+        description 'List system\'s addresses'
+        generate_system_subcollection_index_operation :with_capability => :system_addresses
+        generate_system_subcollection_show_operation :with_capability => :system_addresses
+        generate_add_to_system_operation :with_capability => :add_addresses_to_system
+        generate_remove_from_system_operation :with_capability => :remove_addresses_from_system
+      end
+
+      collection :forwarding_groups, :with_id => :ent_id do
+        description 'List system\'s forwarding groups'
+        generate_system_subcollection_index_operation :with_capability => :system_forwarding_groups
+        generate_system_subcollection_show_operation :with_capability => :system_forwarding_groups
+        generate_add_to_system_operation :with_capability => :add_forwarding_groups_to_system
+        generate_remove_from_system_operation :with_capability => :remove_forwarding_groups_from_system
+      end
+
     end
 
   end
diff --git a/server/lib/cimi/helpers/cimi_rabbit_helper.rb b/server/lib/cimi/helpers/cimi_rabbit_helper.rb
index 548262a..0661bf6 100644
--- a/server/lib/cimi/helpers/cimi_rabbit_helper.rb
+++ b/server/lib/cimi/helpers/cimi_rabbit_helper.rb
@@ -55,5 +55,59 @@ module CIMI
       end
     end
 
+    def generate_remove_from_system_operation(opts={})
+      collection_name = "System#{@collection_name.to_s.singularize.camelize}"
+      operation :destroy, :with_capability => opts[:with_capability] do
+        description "Remove specified #{collection_name} entity from System"
+        control do
+          CIMI::Service.const_get(collection_name).delete!(params[:id], self, params[:ent_id])
+          no_content_with_status(200)
+        end
+      end
+    end
+
+    def generate_add_to_system_operation(opts={})
+      collection_name = "System#{@collection_name.to_s.singularize.camelize}"
+      operation :create, :with_capability => opts[:with_capability] do
+        description "Add specified #{collection_name} entity to System"
+        control do
+          ent = CIMI::Service.const_get("#{collection_name}Create").parse(params[:id], self).create
+          headers_for_create ent
+          respond_to do |format|
+            format.json { ent.to_json }
+            format.xml { ent.to_xml }
+          end
+        end
+      end
+    end
+
+    def generate_system_subcollection_index_operation(opts={})
+      collection_name = "System#{@collection_name.to_s.singularize.camelize}"
+      operation :index, :with_capability => opts[:with_capability] do
+        description "List all entities in System's #{collection_name} collection"
+        control do
+          ent = CIMI::Service.const_get(collection_name).collection_for_system(params[:id], self)
+          respond_to do |format|
+            format.xml { ent.to_xml }
+            format.json { ent.to_json }
+          end
+        end
+      end
+    end
+
+    def generate_system_subcollection_show_operation(opts={})
+      collection_name = "System#{@collection_name.to_s.singularize.camelize}"
+      operation :show, :with_capability => opts[:with_capability] do
+        description "Show details of System's #{collection_name} entity"
+        control do
+          ent = CIMI::Service.const_get(collection_name).find(params[:id], self, params[:ent_id])
+          respond_to do |format|
+            format.xml { ent.to_xml }
+            format.json { ent.to_json }
+          end
+        end
+      end
+    end
+
   end
 end
diff --git a/server/lib/cimi/models.rb b/server/lib/cimi/models.rb
index 8eeb96c..9a86990 100644
--- a/server/lib/cimi/models.rb
+++ b/server/lib/cimi/models.rb
@@ -79,7 +79,16 @@ 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_network_port'
+require_relative './models/system_network'
+require_relative './models/system_address'
+require_relative './models/system_forwarding_group'
+require_relative './models/system_machine'
+require_relative './models/system_volume'
+require_relative './models/system_credential'
+require_relative './models/system_system'
+require_relative './models/system'
+require_relative './models/system_create'
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..4515351 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, :class => CIMI::Model::ForwardingGroup
 
   array :operations do
     scalar :rel, :href
diff --git a/server/lib/cimi/models/system.rb b/server/lib/cimi/models/system.rb
index 118f9f5..dbab95b 100644
--- a/server/lib/cimi/models/system.rb
+++ b/server/lib/cimi/models/system.rb
@@ -17,18 +17,18 @@ class CIMI::Model::System < CIMI::Model::Base
 
   acts_as_root_entity
 
-  text :state
-
-  # FIXME: Any reason for these comments?
-
-  #  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
+  text :state, :required => true
+
+  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
+
+  #TODO: implement the attributes commented out
 
   #  array :meters do
   #    scalar :href
diff --git a/server/lib/cimi/models/system_address.rb b/server/lib/cimi/models/system_address.rb
new file mode 100644
index 0000000..0709ff8
--- /dev/null
+++ b/server/lib/cimi/models/system_address.rb
@@ -0,0 +1,26 @@
+# 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
+
+  acts_as_root_entity
+
+  href :address
+
+  array :operations do
+    scalar :rel, :href
+  end
+
+end
diff --git a/server/lib/cimi/models/system_create.rb b/server/lib/cimi/models/system_create.rb
new file mode 100644
index 0000000..cf9d412
--- /dev/null
+++ b/server/lib/cimi/models/system_create.rb
@@ -0,0 +1,20 @@
+# 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::SystemCreate < CIMI::Model::Base
+
+  ref :system_template, :required => true
+
+end
diff --git a/server/lib/cimi/models/system_credential.rb b/server/lib/cimi/models/system_credential.rb
new file mode 100644
index 0000000..8967867
--- /dev/null
+++ b/server/lib/cimi/models/system_credential.rb
@@ -0,0 +1,26 @@
+# 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::SystemCredential < CIMI::Model::Base
+
+  acts_as_root_entity
+
+  href :credential
+
+  array :operations do
+    scalar :rel, :href
+  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..f9e5225
--- /dev/null
+++ b/server/lib/cimi/models/system_forwarding_group.rb
@@ -0,0 +1,26 @@
+# 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
+
+  acts_as_root_entity
+
+  href :forwarding_group
+
+  array :operations do
+    scalar :rel, :href
+  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..54097c7
--- /dev/null
+++ b/server/lib/cimi/models/system_machine.rb
@@ -0,0 +1,26 @@
+# 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
+
+  acts_as_root_entity
+
+  href :machine
+
+  array :operations do
+    scalar :rel, :href
+  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..1bf10d5
--- /dev/null
+++ b/server/lib/cimi/models/system_network.rb
@@ -0,0 +1,26 @@
+# 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
+
+  acts_as_root_entity
+
+  href :network
+
+  array :operations do
+    scalar :rel, :href
+  end
+
+end
diff --git a/server/lib/cimi/models/system_network_port.rb b/server/lib/cimi/models/system_network_port.rb
new file mode 100644
index 0000000..3a0c812
--- /dev/null
+++ b/server/lib/cimi/models/system_network_port.rb
@@ -0,0 +1,26 @@
+# 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::SystemNetworkPort < CIMI::Model::Base
+
+  acts_as_root_entity
+
+  href :network_port
+
+  array :operations do
+    scalar :rel, :href
+  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..b94ec18
--- /dev/null
+++ b/server/lib/cimi/models/system_system.rb
@@ -0,0 +1,26 @@
+# 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
+
+  acts_as_root_entity
+
+  href :system
+
+  array :operations do
+    scalar :rel, :href
+  end
+
+end
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/system_volume.rb b/server/lib/cimi/models/system_volume.rb
new file mode 100644
index 0000000..be31846
--- /dev/null
+++ b/server/lib/cimi/models/system_volume.rb
@@ -0,0 +1,26 @@
+# 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
+
+  acts_as_root_entity
+
+  href :volume
+
+  array :operations do
+    scalar :rel, :href
+  end
+
+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/cimi/service.rb b/server/lib/cimi/service.rb
index 8176532..892f6ad 100644
--- a/server/lib/cimi/service.rb
+++ b/server/lib/cimi/service.rb
@@ -45,7 +45,13 @@ require_relative './service/network_create'
 require_relative './service/network'
 require_relative './service/forwarding_group'
 require_relative './service/volume_template_create'
+require_relative './service/system_machine'
+require_relative './service/system_volume'
+require_relative './service/system_network'
+require_relative './service/system_forwarding_group'
+require_relative './service/system_address'
 require_relative './service/system'
+require_relative './service/system_create'
 require_relative './service/address_template_create'
 require_relative './service/volume'
 require_relative './service/volume_image_create'
diff --git a/server/lib/cimi/service/system.rb b/server/lib/cimi/service/system.rb
index daad428..bb28e82 100644
--- a/server/lib/cimi/service/system.rb
+++ b/server/lib/cimi/service/system.rb
@@ -38,7 +38,7 @@ class CIMI::Service::System < CIMI::Service::Base
   end
 
   def self.delete!(id, context)
-    context.driver.destroy_system(context.credentials, id)
+    context.driver.destroy_system(context.credentials, {:id=>id})
   end
 
 
diff --git a/server/lib/cimi/service/system_address.rb b/server/lib/cimi/service/system_address.rb
new file mode 100644
index 0000000..2afaf4f
--- /dev/null
+++ b/server/lib/cimi/service/system_address.rb
@@ -0,0 +1,34 @@
+# 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::Service::SystemAddress < CIMI::Service::Base
+
+  def self.find(system_id, context, id=:all)
+    if id == :all
+      addresses = context.driver.system_addresses(context.credentials, {:env=>context, :system_id=>system_id})
+    else
+      addresses = context.driver.system_addresses(context.credentials, {:env=>context, :system_id=>system_id, :id=>id})
+      raise CIMI::Model::NotFound if addresses.empty?
+      addresses.first
+    end
+  end
+
+  def self.collection_for_system(system_id, context)
+    system_addresses = self.find(system_id, context)
+    addresses_url = context.url("/system/#{system_id}/addresses") if context.driver.has_capability? :add_addresses_to_system
+    CIMI::Model::SystemAddress.list(addresses_url, system_addresses, :add_url => addresses_url)
+  end
+
+end
diff --git a/server/lib/cimi/service/system_create.rb b/server/lib/cimi/service/system_create.rb
new file mode 100644
index 0000000..5e58445
--- /dev/null
+++ b/server/lib/cimi/service/system_create.rb
@@ -0,0 +1,39 @@
+# 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::Service::SystemCreate < CIMI::Service::Base
+
+  def create
+    if system_template.href?
+      template = resolve(system_template)
+    else
+      # FIXME: What if this href isn't there ? What if the user
+      # tries to override some aspect of the system template ?
+    end
+    params = {
+      :system_template => system_template,
+      :name => name,
+      :description => description,
+      :env => context
+    }
+    result = context.driver.create_system(context.credentials, params)
+    result.name = name if name
+    result.description = description if description
+    result.property = property if property
+#    result.save
+    result
+  end
+
+end
diff --git a/server/lib/cimi/service/system_forwarding_group.rb b/server/lib/cimi/service/system_forwarding_group.rb
new file mode 100644
index 0000000..e7c269c
--- /dev/null
+++ b/server/lib/cimi/service/system_forwarding_group.rb
@@ -0,0 +1,34 @@
+# 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::Service::SystemForwardingGroup < CIMI::Service::Base
+
+  def self.find(system_id, context, id=:all)
+    if id == :all
+      groups = context.driver.system_forwarding_groups(context.credentials, {:env=>context, :system_id=>system_id})
+    else
+      groups = context.driver.system_forwarding_groups(context.credentials, {:env=>context, :system_id=>system_id, :id=>id})
+      raise CIMI::Model::NotFound if groups.empty?
+      groups.first
+    end
+  end
+
+  def self.collection_for_system(system_id, context)
+    system_forwarding_groups = self.find(system_id, context)
+    forwarding_groups_url = context.url("/system/#{system_id}/forwarding_groups") if context.driver.has_capability? :add_forwarding_groups_to_system
+    CIMI::Model::SystemForwardingGroup.list(forwarding_groups_url, system_forwarding_groups, :add_url => forwarding_groups_url)
+  end
+
+end
diff --git a/server/lib/cimi/service/system_machine.rb b/server/lib/cimi/service/system_machine.rb
new file mode 100644
index 0000000..d19026a
--- /dev/null
+++ b/server/lib/cimi/service/system_machine.rb
@@ -0,0 +1,34 @@
+# 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::Service::SystemMachine < CIMI::Service::Base
+
+  def self.find(system_id, context, id=:all)
+    if id == :all
+      machines = context.driver.system_machines(context.credentials, {:env=>context, :system_id=>system_id})
+    else
+      machines = context.driver.system_machines(context.credentials, {:env=>context, :system_id=>system_id, :id=>id})
+      raise CIMI::Model::NotFound if machines.empty?
+      machines.first
+    end
+  end
+
+  def self.collection_for_system(system_id, context)
+    system_machines = self.find(system_id, context)
+    machines_url = context.url("/system/#{system_id}/machines") if context.driver.has_capability? :add_machines_to_system
+    CIMI::Model::SystemMachine.list(machines_url, system_machines, :add_url => machines_url)
+  end
+
+end
diff --git a/server/lib/cimi/service/system_network.rb b/server/lib/cimi/service/system_network.rb
new file mode 100644
index 0000000..5ff9323
--- /dev/null
+++ b/server/lib/cimi/service/system_network.rb
@@ -0,0 +1,34 @@
+# 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::Service::SystemNetwork < CIMI::Service::Base
+
+  def self.find(system_id, context, id=:all)
+    if id == :all
+      networks = context.driver.system_networks(context.credentials, {:env=>context, :system_id=>system_id})
+    else
+      networks = context.driver.system_networks(context.credentials, {:env=>context, :system_id=>system_id, :id=>id})
+      raise CIMI::Model::NotFound if networks.empty?
+      networks.first
+    end
+  end
+
+  def self.collection_for_system(system_id, context)
+    system_networks = self.find(system_id, context)
+    networks_url = context.url("/system/#{system_id}/networks") if context.driver.has_capability? :add_networks_to_system
+    CIMI::Model::SystemNetwork.list(networks_url, system_networks, :add_url => networks_url)
+  end
+
+end
diff --git a/server/lib/cimi/service/system_volume.rb b/server/lib/cimi/service/system_volume.rb
new file mode 100644
index 0000000..7f4306b
--- /dev/null
+++ b/server/lib/cimi/service/system_volume.rb
@@ -0,0 +1,34 @@
+# 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::Service::SystemVolume < CIMI::Service::Base
+
+  def self.find(system_id, context, id=:all)
+    if id == :all
+      vols = context.driver.system_volumes(context.credentials, {:env=>context, :system_id=>system_id})
+    else
+      vols = context.driver.system_volumes(context.credentials, {:env=>context, :system_id=>system_id, :id=>id})
+      raise CIMI::Model::NotFound if vols.empty?
+      vols.first
+    end
+  end
+
+  def self.collection_for_system(system_id, context)
+    system_volumes = self.find(system_id, context)
+    volumes_url = context.url("/system/#{system_id}/volumes") if context.driver.has_capability? :add_volumes_to_system
+    CIMI::Model::SystemVolume.list(volumes_url, system_volumes, :add_url => volumes_url)
+  end
+
+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..6e08de9 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,216 @@ 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?realm_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|
+          vservers = client.list_vservers(system[:id])['vservers'][0]['vserver']
+          if vservers.nil?
+            system[:state] = 'MIXED'
+          else
+            vservers.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 create_system(credentials, opts={})
+      safely do
+        client = new_client(credentials)
+        name = opts[:name] || "system_#{Time.now.to_s}"
+        template = opts[:system_template]
+        template_id = template.id || template.href.to_s.gsub(/.*\/([^\/]+)$/, '\1')
+        vsys_id = client.create_vsys(template_id, name)['vsysId'][0]
+        opts[:id] = vsys_id
+        systems(credentials, opts).first
+      end
+    end
+
+    def destroy_system(credentials, opts={})
+      delete_firewall(credentials, {:id=>"#{opts[:id]}-S-0001"})
+    end
+
+    def system_machines(credentials, opts={})
+      safely do
+        client = new_client(credentials)
+        #if :expand not specified, list of hrefs only, else convert from :instances?
+        context = opts[:env]
+        vsys_id = opts[:system_id]
+        xml = client.list_vservers(vsys_id)['vservers']
+        return [] if xml.nil?
+
+        machines = xml[0]['vserver'].collect do |vserver|
+          vserver_id = vserver['vserverId'][0]
+          CIMI::Model::SystemMachine.new(
+            :id      => context.system_url("#{vsys_id}/machines/#{vserver_id}"),
+            :name    => vserver['vserverName'][0],
+            :machine => { :href => context.machine_url(vserver_id)}
+          ) unless opts[:id] and opts[:id] != vserver_id
+        end
+        machines.compact
+      end
+    end
+
+    def system_volumes(credentials, opts={})
+      safely do
+        client = new_client(credentials)
+        context = opts[:env]
+        vsys_id = opts[:system_id]
+        #if :expand not specified, list of hrefs only, else convert from :storage_volumes?
+        xml = client.list_vdisk(vsys_id)['vdisks']
+        return [] if xml.nil?
+
+        volumes = xml[0]['vdisk'].collect do |vdisk|
+          vdisk_id = vdisk['vdiskId'][0]
+          CIMI::Model::SystemVolume.new(
+            :id      => context.system_url("#{vsys_id}/volumes/#{vdisk_id}"),
+            :name    => vdisk['vdiskName'][0],
+            :volume  => { :href => context.volume_url(vdisk_id)}
+          ) unless opts[:id] and opts[:id] != vdisk_id
+        end
+        volumes.compact
+      end
+    end
+
+    def system_networks(credentials, opts={})
+      safely do
+        client = new_client(credentials)
+        context = opts[:env]
+        vsys_id = opts[:system_id]
+        #if :expand not specified, list of hrefs only, else ??
+        vsys = client.get_vsys_configuration(vsys_id)['vsys'][0]
+
+        # retrieve network segment (subnet) info
+        networks = vsys['vnets'][0]['vnet'].collect do |vnet|
+          network_id = vnet['networkId'][0]
+          network_id =~ /.*-(\w)$/
+          CIMI::Model::SystemNetwork.new(
+            :id      => context.system_url("#{vsys_id}/networks/#{network_id}"),
+            :name    => "#{$1} for system #{vsys['vsysName'][0]}",
+            :network => { :href => context.network_url(network_id)}
+          ) unless opts[:id] and opts[:id] != network_id
+        end
+        networks.compact
+      end
+    end
+
+    def system_addresses(credentials, opts={})
+      safely do
+        client = new_client(credentials)
+        context = opts[:env]
+        vsys_id = opts[:system_id]
+        #if :expand not specified, list of hrefs only, else ??
+        xml = client.list_public_ips(vsys_id)['publicips']
+        return [] if xml.nil?
+
+        # retrieve network segment (subnet) info
+        addresses = xml[0]['publicip'].collect do |ip|
+          address = ip['address'][0]
+          CIMI::Model::SystemAddress.new(
+            :id      => context.system_url("#{vsys_id}/addresses/#{address}"),
+            :name    => "Public IP address allocated to system #{ip['vsysId'][0]}",
+            :address => { :href => context.address_url(address)}
+          ) unless opts[:id] and opts[:id] != address
+        end
+        addresses.compact
+      end
+    end
+
+    def system_forwarding_groups(credentials, opts={})
+      safely do
+        client = new_client(credentials)
+        context = opts[:env]
+        vsys_id = opts[:system_id]
+        #if :expand not specified, list of hrefs only, else ??
+        vsys = client.get_vsys_configuration(vsys_id)['vsys'][0]
+
+        group_id = "#{vsys_id}-N"
+        groups = []
+        groups << CIMI::Model::SystemForwardingGroup.new(
+          :id               => context.system_url("#{vsys_id}/forwarding_groups/#{group_id}"),
+          :name             => "Routing group of system #{vsys['vsysName'][0]}",
+          :forwarding_group => { :href => context.forwarding_group_url(group_id)}
+        ) unless vsys['vnets'][0]['vnet'].size <= 1 or (opts[:id] and opts[:id] != group_id)
+        groups
       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 => 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
+          # add network templates
+          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_address/sysaddress1.json b/server/lib/deltacloud/drivers/mock/data/cimi/system_address/sysaddress1.json
new file mode 100644
index 0000000..af16b70
--- /dev/null
+++ b/server/lib/deltacloud/drivers/mock/data/cimi/system_address/sysaddress1.json
@@ -0,0 +1,8 @@
+{ "id": "http://cimi.example.org/systems/system1/addresses/address1",
+  "name": "sysaddress1",
+  "created": "Fri Feb 08 12:15:15 EET 2013",
+  "address": { "href": "http://cimi.example.org/addresses/address1" },
+  "operations": [
+    { "rel": "delete", "href": "http://cimi.example.org/systems/system1/addresses/address1" }
+  ]
+}
diff --git a/server/lib/deltacloud/drivers/mock/data/cimi/system_forwarding_group/sysforwardinggroup1.json b/server/lib/deltacloud/drivers/mock/data/cimi/system_forwarding_group/sysforwardinggroup1.json
new file mode 100644
index 0000000..db23214
--- /dev/null
+++ b/server/lib/deltacloud/drivers/mock/data/cimi/system_forwarding_group/sysforwardinggroup1.json
@@ -0,0 +1,8 @@
+{ "id": "http://cimi.example.org/systems/system1/forwarding_groups/group1",
+  "name": "sysforwardinggroup1",
+  "created": "Fri Feb 08 12:15:15 EET 2013",
+  "forwarding_group": { "href": "http://cimi.example.org/forwarding_groups/group1" },
+  "operations": [
+    { "rel": "delete", "href": "http://cimi.example.org/systems/system1/forwarding_groups/group1" }
+  ]
+}
diff --git a/server/lib/deltacloud/drivers/mock/data/cimi/system_machine/sysmach1.json b/server/lib/deltacloud/drivers/mock/data/cimi/system_machine/sysmach1.json
new file mode 100644
index 0000000..8fe2a92
--- /dev/null
+++ b/server/lib/deltacloud/drivers/mock/data/cimi/system_machine/sysmach1.json
@@ -0,0 +1,8 @@
+{ "id": "http://cimi.example.org/systems/system1/machines/inst0",
+  "name": "sysmach1",
+  "created": "Fri Feb 08 12:15:15 EET 2013",
+  "machine": { "href": "http://cimi.example.org/machines/inst0" },
+  "operations": [
+    { "rel": "delete", "href": "http://cimi.example.org/systems/system1/machines/inst0" }
+  ]
+}
diff --git a/server/lib/deltacloud/drivers/mock/data/cimi/system_network/sysnet1.json b/server/lib/deltacloud/drivers/mock/data/cimi/system_network/sysnet1.json
new file mode 100644
index 0000000..09002ed
--- /dev/null
+++ b/server/lib/deltacloud/drivers/mock/data/cimi/system_network/sysnet1.json
@@ -0,0 +1,8 @@
+{ "id": "http://cimi.example.org/systems/system1/networks/network1",
+  "name": "sysnetwork1",
+  "created": "Fri Feb 08 12:15:15 EET 2013",
+  "network": { "href": "http://cimi.example.org/networks/network1" },
+  "operations": [
+    { "rel": "delete", "href": "http://cimi.example.org/systems/system1/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
index 495fc24..913252b 100644
--- a/server/lib/deltacloud/drivers/mock/data/cimi/system_template/template1.json
+++ b/server/lib/deltacloud/drivers/mock/data/cimi/system_template/template1.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/data/cimi/system_volume/sysvol1.json b/server/lib/deltacloud/drivers/mock/data/cimi/system_volume/sysvol1.json
new file mode 100644
index 0000000..12e3554
--- /dev/null
+++ b/server/lib/deltacloud/drivers/mock/data/cimi/system_volume/sysvol1.json
@@ -0,0 +1,8 @@
+{ "id": "http://cimi.example.org/systems/system1/volumes/vol1",
+  "name": "sysvol1",
+  "created": "Fri Feb 08 12:15:15 EET 2013",
+  "volume": { "href": "http://cimi.example.org/volumes/vol1" },
+  "operations": [
+    { "rel": "delete", "href": "http://cimi.example.org/systems/system1/volumes/vol1" }
+  ]
+}
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..9a6daa2 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,115 @@ 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 destroy_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_machines(credentials, opts={})
+      check_credentials(credentials)
+      if opts[:id].nil?
+        machines = @client.load_all_cimi(:system_machine).map{|mach| CIMI::Model::SystemMachine.from_json(mach)}
+      else
+        begin
+          machines = [CIMI::Model::SystemMachine.from_json(@client.load_cimi(:system_machine, opts[:id]))]
+        rescue Errno::ENOENT
+          return []
+        end
+      end
+      #FIXME: with ":machines", delete url becomes 'http://localhost:3001/cimi/machines?id=sysmach1'
+      #with ":system_machine"/":system_machines", undefined method `system_machine_url' for #<CIMI::Collections::Systems:0x44fe338> in mock_driver_cimi_methods.rb:261
+      machines.map{|mach|convert_cimi_mock_urls(:machines, mach, opts[:env])}.flatten
+    end
+
+    def system_volumes(credentials, opts={})
+      check_credentials(credentials)
+      if opts[:id].nil?
+        volumes = @client.load_all_cimi(:system_volume).map{|vol| CIMI::Model::SystemVolume.from_json(vol)}
+      else
+        begin
+          volumes = [CIMI::Model::SystemVolume.from_json(@client.load_cimi(:system_volume, opts[:id]))]
+        rescue Errno::ENOENT
+          return []
+        end
+      end
+      #FIXME: with ":volumes", delete url becomes 'http://localhost:3001/cimi/volumes?id=sysvol1'
+      #with ":system_volume"/":system_volumes", undefined method `system_volume_url' for #<CIMI::Collections::Systems:0x44fe338> in mock_driver_cimi_methods.rb:261
+      volumes.map{|vol|convert_cimi_mock_urls(:volumes, vol, opts[:env])}.flatten
+    end
+
+    def system_networks(credentials, opts={})
+      check_credentials(credentials)
+      if opts[:id].nil?
+        networks = @client.load_all_cimi(:system_network).map{|net| CIMI::Model::SystemNetwork.from_json(net)}
+      else
+        begin
+          networks = [CIMI::Model::SystemNetwork.from_json(@client.load_cimi(:system_network, opts[:id]))]
+        rescue Errno::ENOENT
+          return []
+        end
+      end
+      #FIXME
+      networks.map{|vol|convert_cimi_mock_urls(:networks, vol, opts[:env])}.flatten
+    end
+
+    def system_addresses(credentials, opts={})
+      check_credentials(credentials)
+      if opts[:id].nil?
+        addresses = @client.load_all_cimi(:system_address).map{|a| CIMI::Model::SystemAddress.from_json(a)}
+      else
+        begin
+          addresses = [CIMI::Model::SystemVolume.from_json(@client.load_cimi(:system_address, opts[:id]))]
+        rescue Errno::ENOENT
+          return []
+        end
+      end
+      #FIXME
+      addresses.map{|a|convert_cimi_mock_urls(:addresses, a, opts[:env])}.flatten
+    end
+
+    def system_forwarding_groups(credentials, opts={})
+      check_credentials(credentials)
+      if opts[:id].nil?
+        groups = @client.load_all_cimi(:system_forwarding_group).map{|group| CIMI::Model::SystemForwardingGroup.from_json(group)}
+      else
+        begin
+          groups = [CIMI::Model::SystemForwardingGroup.from_json(@client.load_cimi(:system_forwarding_group, opts[:id]))]
+        rescue Errno::ENOENT
+          return []
+        end
+      end
+      #FIXME
+      groups.map{|group|convert_cimi_mock_urls(:forwarding_groups, group, opts[:env])}.flatten
+    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_text.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_equal 'GOLD'
+      end
+    end
+  end
+
 end
-- 
1.8.0.msysgit.0



Re: [PATCH] CIMI: added subcollections to System and SystemTemplate added create and delete system support for mock and fgcp.

Posted by Michal Fojtik <mf...@redhat.com>.
On 03/28/2013 12:11 PM, diesk@fast.au.fujitsu.com wrote:

ACK. Nice work Dies!

   -- Michal


> From: Dies Koper <di...@fast.au.fujitsu.com>
>
> ---
>   server/lib/cimi/collections/systems.rb             |  95 +++++----
>   server/lib/cimi/helpers/cimi_rabbit_helper.rb      |  54 ++++++
>   server/lib/cimi/models.rb                          |  13 +-
>   server/lib/cimi/models/machine_template.rb         |   6 +-
>   server/lib/cimi/models/network_template.rb         |   4 +-
>   server/lib/cimi/models/system.rb                   |  24 +--
>   server/lib/cimi/models/system_address.rb           |  26 +++
>   server/lib/cimi/models/system_create.rb            |  20 ++
>   server/lib/cimi/models/system_credential.rb        |  26 +++
>   server/lib/cimi/models/system_forwarding_group.rb  |  26 +++
>   server/lib/cimi/models/system_machine.rb           |  26 +++
>   server/lib/cimi/models/system_network.rb           |  26 +++
>   server/lib/cimi/models/system_network_port.rb      |  26 +++
>   server/lib/cimi/models/system_system.rb            |  26 +++
>   server/lib/cimi/models/system_template.rb          |  20 +-
>   server/lib/cimi/models/system_volume.rb            |  26 +++
>   server/lib/cimi/models/volume_template.rb          |   4 +-
>   server/lib/cimi/service.rb                         |   6 +
>   server/lib/cimi/service/system.rb                  |   2 +-
>   server/lib/cimi/service/system_address.rb          |  34 ++++
>   server/lib/cimi/service/system_create.rb           |  39 ++++
>   server/lib/cimi/service/system_forwarding_group.rb |  34 ++++
>   server/lib/cimi/service/system_machine.rb          |  34 ++++
>   server/lib/cimi/service/system_network.rb          |  34 ++++
>   server/lib/cimi/service/system_volume.rb           |  34 ++++
>   server/lib/deltacloud/drivers/fgcp/fgcp_client.rb  |   4 +
>   .../drivers/fgcp/fgcp_driver_cimi_methods.rb       | 215 +++++++++++++++++++--
>   .../mock/data/cimi/system_address/sysaddress1.json |   8 +
>   .../sysforwardinggroup1.json                       |   8 +
>   .../mock/data/cimi/system_machine/sysmach1.json    |   8 +
>   .../mock/data/cimi/system_network/sysnet1.json     |   8 +
>   .../mock/data/cimi/system_template/template1.json  |  31 ++-
>   .../mock/data/cimi/system_volume/sysvol1.json      |   8 +
>   .../drivers/mock/mock_driver_cimi_methods.rb       | 109 +++++++++++
>   .../cimi/collections/system_templates_test.rb      |  47 +++++
>   35 files changed, 1021 insertions(+), 90 deletions(-)
>   create mode 100644 server/lib/cimi/models/system_address.rb
>   create mode 100644 server/lib/cimi/models/system_create.rb
>   create mode 100644 server/lib/cimi/models/system_credential.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_network_port.rb
>   create mode 100644 server/lib/cimi/models/system_system.rb
>   create mode 100644 server/lib/cimi/models/system_volume.rb
>   create mode 100644 server/lib/cimi/service/system_address.rb
>   create mode 100644 server/lib/cimi/service/system_create.rb
>   create mode 100644 server/lib/cimi/service/system_forwarding_group.rb
>   create mode 100644 server/lib/cimi/service/system_machine.rb
>   create mode 100644 server/lib/cimi/service/system_network.rb
>   create mode 100644 server/lib/cimi/service/system_volume.rb
>   create mode 100644 server/lib/deltacloud/drivers/mock/data/cimi/system_address/sysaddress1.json
>   create mode 100644 server/lib/deltacloud/drivers/mock/data/cimi/system_forwarding_group/sysforwardinggroup1.json
>   create mode 100644 server/lib/deltacloud/drivers/mock/data/cimi/system_machine/sysmach1.json
>   create mode 100644 server/lib/deltacloud/drivers/mock/data/cimi/system_network/sysnet1.json
>   create mode 100644 server/lib/deltacloud/drivers/mock/data/cimi/system_volume/sysvol1.json
>
> diff --git a/server/lib/cimi/collections/systems.rb b/server/lib/cimi/collections/systems.rb
> index 5c3903e..179daea 100644
> --- a/server/lib/cimi/collections/systems.rb
> +++ b/server/lib/cimi/collections/systems.rb
> @@ -107,45 +107,70 @@ module CIMI::Collections
>           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 = SystemVolume.collection_for_system(params[:id], self)
> -            respond_to do |format|
> -              format.json {volumes.to_json}
> -              format.xml  {volumes.to_xml}
> -            end
> -          end
> -        end
> +      collection :systems, :with_id => :ent_id do
> +        description 'List system\'s systems'
> +        generate_system_subcollection_index_operation :with_capability => :system_systems
> +        generate_system_subcollection_show_operation :with_capability => :system_systems
> +        generate_add_to_system_operation :with_capability => :add_system_to_system
> +        generate_remove_from_system_operation :with_capability => :remove_system_from_system
> +      end
>
> -        operation :show, :with_capability => :storage_volumes do
> -          description "Retrieve a System's specific SystemVolume"
> -          control do
> -            volume = 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
> +      collection :machines, :with_id => :ent_id do
> +        description 'List system\'s machines'
> +        generate_system_subcollection_index_operation :with_capability => :system_machines
> +        generate_system_subcollection_show_operation :with_capability => :system_machines
> +        generate_add_to_system_operation :with_capability => :add_machine_to_system
> +        generate_remove_from_system_operation :with_capability => :remove_machine_from_system
> +      end
>
> -        operation :destroy, :with_capability => :detach_storage_volume do
> -          description "Remove/detach a volume from the System's SystemVolumeCollection"
> -          control do
> -            system_volume = 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
> +      collection :credentials, :with_id => :ent_id do
> +        description 'List system\'s credentials'
> +        generate_system_subcollection_index_operation :with_capability => :system_credentials
> +        generate_system_subcollection_show_operation :with_capability => :system_credentials
> +        generate_add_to_system_operation :with_capability => :add_credential_to_system
> +        generate_remove_from_system_operation :with_capability => :remove_credential_from_system
> +      end
>
> +      collection :volumes, :with_id => :ent_id do
> +        description 'List system\'s volumes'
> +        generate_system_subcollection_index_operation :with_capability => :system_volumes
> +        generate_system_subcollection_show_operation :with_capability => :system_volumes
> +        generate_add_to_system_operation :with_capability => :add_volume_to_system
> +        generate_remove_from_system_operation :with_capability => :remove_volume_from_system
>         end
> +
> +      collection :networks, :with_id => :ent_id do
> +        description 'List system\'s networks'
> +        generate_system_subcollection_index_operation :with_capability => :system_networks
> +        generate_system_subcollection_show_operation :with_capability => :system_networks
> +        generate_add_to_system_operation :with_capability => :add_network_to_system
> +        generate_remove_from_system_operation :with_capability => :remove_network_from_system
> +      end
> +
> +      collection :network_ports, :with_id => :ent_id do
> +        description 'List system\'s network ports'
> +        generate_system_subcollection_index_operation :with_capability => :system_network_ports
> +        generate_system_subcollection_show_operation :with_capability => :system_network_ports
> +        generate_add_to_system_operation :with_capability => :add_network_port_to_system
> +        generate_remove_from_system_operation :with_capability => :remove_network_port_from_system
> +      end
> +
> +      collection :addresses, :with_id => :ent_id do
> +        description 'List system\'s addresses'
> +        generate_system_subcollection_index_operation :with_capability => :system_addresses
> +        generate_system_subcollection_show_operation :with_capability => :system_addresses
> +        generate_add_to_system_operation :with_capability => :add_addresses_to_system
> +        generate_remove_from_system_operation :with_capability => :remove_addresses_from_system
> +      end
> +
> +      collection :forwarding_groups, :with_id => :ent_id do
> +        description 'List system\'s forwarding groups'
> +        generate_system_subcollection_index_operation :with_capability => :system_forwarding_groups
> +        generate_system_subcollection_show_operation :with_capability => :system_forwarding_groups
> +        generate_add_to_system_operation :with_capability => :add_forwarding_groups_to_system
> +        generate_remove_from_system_operation :with_capability => :remove_forwarding_groups_from_system
> +      end
> +
>       end
>
>     end
> diff --git a/server/lib/cimi/helpers/cimi_rabbit_helper.rb b/server/lib/cimi/helpers/cimi_rabbit_helper.rb
> index 548262a..0661bf6 100644
> --- a/server/lib/cimi/helpers/cimi_rabbit_helper.rb
> +++ b/server/lib/cimi/helpers/cimi_rabbit_helper.rb
> @@ -55,5 +55,59 @@ module CIMI
>         end
>       end
>
> +    def generate_remove_from_system_operation(opts={})
> +      collection_name = "System#{@collection_name.to_s.singularize.camelize}"
> +      operation :destroy, :with_capability => opts[:with_capability] do
> +        description "Remove specified #{collection_name} entity from System"
> +        control do
> +          CIMI::Service.const_get(collection_name).delete!(params[:id], self, params[:ent_id])
> +          no_content_with_status(200)
> +        end
> +      end
> +    end
> +
> +    def generate_add_to_system_operation(opts={})
> +      collection_name = "System#{@collection_name.to_s.singularize.camelize}"
> +      operation :create, :with_capability => opts[:with_capability] do
> +        description "Add specified #{collection_name} entity to System"
> +        control do
> +          ent = CIMI::Service.const_get("#{collection_name}Create").parse(params[:id], self).create
> +          headers_for_create ent
> +          respond_to do |format|
> +            format.json { ent.to_json }
> +            format.xml { ent.to_xml }
> +          end
> +        end
> +      end
> +    end
> +
> +    def generate_system_subcollection_index_operation(opts={})
> +      collection_name = "System#{@collection_name.to_s.singularize.camelize}"
> +      operation :index, :with_capability => opts[:with_capability] do
> +        description "List all entities in System's #{collection_name} collection"
> +        control do
> +          ent = CIMI::Service.const_get(collection_name).collection_for_system(params[:id], self)
> +          respond_to do |format|
> +            format.xml { ent.to_xml }
> +            format.json { ent.to_json }
> +          end
> +        end
> +      end
> +    end
> +
> +    def generate_system_subcollection_show_operation(opts={})
> +      collection_name = "System#{@collection_name.to_s.singularize.camelize}"
> +      operation :show, :with_capability => opts[:with_capability] do
> +        description "Show details of System's #{collection_name} entity"
> +        control do
> +          ent = CIMI::Service.const_get(collection_name).find(params[:id], self, params[:ent_id])
> +          respond_to do |format|
> +            format.xml { ent.to_xml }
> +            format.json { ent.to_json }
> +          end
> +        end
> +      end
> +    end
> +
>     end
>   end
> diff --git a/server/lib/cimi/models.rb b/server/lib/cimi/models.rb
> index 8eeb96c..9a86990 100644
> --- a/server/lib/cimi/models.rb
> +++ b/server/lib/cimi/models.rb
> @@ -79,7 +79,16 @@ 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_network_port'
> +require_relative './models/system_network'
> +require_relative './models/system_address'
> +require_relative './models/system_forwarding_group'
> +require_relative './models/system_machine'
> +require_relative './models/system_volume'
> +require_relative './models/system_credential'
> +require_relative './models/system_system'
> +require_relative './models/system'
> +require_relative './models/system_create'
> 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..4515351 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, :class => CIMI::Model::ForwardingGroup
>
>     array :operations do
>       scalar :rel, :href
> diff --git a/server/lib/cimi/models/system.rb b/server/lib/cimi/models/system.rb
> index 118f9f5..dbab95b 100644
> --- a/server/lib/cimi/models/system.rb
> +++ b/server/lib/cimi/models/system.rb
> @@ -17,18 +17,18 @@ class CIMI::Model::System < CIMI::Model::Base
>
>     acts_as_root_entity
>
> -  text :state
> -
> -  # FIXME: Any reason for these comments?
> -
> -  #  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
> +  text :state, :required => true
> +
> +  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
> +
> +  #TODO: implement the attributes commented out
>
>     #  array :meters do
>     #    scalar :href
> diff --git a/server/lib/cimi/models/system_address.rb b/server/lib/cimi/models/system_address.rb
> new file mode 100644
> index 0000000..0709ff8
> --- /dev/null
> +++ b/server/lib/cimi/models/system_address.rb
> @@ -0,0 +1,26 @@
> +# 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
> +
> +  acts_as_root_entity
> +
> +  href :address
> +
> +  array :operations do
> +    scalar :rel, :href
> +  end
> +
> +end
> diff --git a/server/lib/cimi/models/system_create.rb b/server/lib/cimi/models/system_create.rb
> new file mode 100644
> index 0000000..cf9d412
> --- /dev/null
> +++ b/server/lib/cimi/models/system_create.rb
> @@ -0,0 +1,20 @@
> +# 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::SystemCreate < CIMI::Model::Base
> +
> +  ref :system_template, :required => true
> +
> +end
> diff --git a/server/lib/cimi/models/system_credential.rb b/server/lib/cimi/models/system_credential.rb
> new file mode 100644
> index 0000000..8967867
> --- /dev/null
> +++ b/server/lib/cimi/models/system_credential.rb
> @@ -0,0 +1,26 @@
> +# 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::SystemCredential < CIMI::Model::Base
> +
> +  acts_as_root_entity
> +
> +  href :credential
> +
> +  array :operations do
> +    scalar :rel, :href
> +  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..f9e5225
> --- /dev/null
> +++ b/server/lib/cimi/models/system_forwarding_group.rb
> @@ -0,0 +1,26 @@
> +# 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
> +
> +  acts_as_root_entity
> +
> +  href :forwarding_group
> +
> +  array :operations do
> +    scalar :rel, :href
> +  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..54097c7
> --- /dev/null
> +++ b/server/lib/cimi/models/system_machine.rb
> @@ -0,0 +1,26 @@
> +# 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
> +
> +  acts_as_root_entity
> +
> +  href :machine
> +
> +  array :operations do
> +    scalar :rel, :href
> +  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..1bf10d5
> --- /dev/null
> +++ b/server/lib/cimi/models/system_network.rb
> @@ -0,0 +1,26 @@
> +# 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
> +
> +  acts_as_root_entity
> +
> +  href :network
> +
> +  array :operations do
> +    scalar :rel, :href
> +  end
> +
> +end
> diff --git a/server/lib/cimi/models/system_network_port.rb b/server/lib/cimi/models/system_network_port.rb
> new file mode 100644
> index 0000000..3a0c812
> --- /dev/null
> +++ b/server/lib/cimi/models/system_network_port.rb
> @@ -0,0 +1,26 @@
> +# 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::SystemNetworkPort < CIMI::Model::Base
> +
> +  acts_as_root_entity
> +
> +  href :network_port
> +
> +  array :operations do
> +    scalar :rel, :href
> +  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..b94ec18
> --- /dev/null
> +++ b/server/lib/cimi/models/system_system.rb
> @@ -0,0 +1,26 @@
> +# 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
> +
> +  acts_as_root_entity
> +
> +  href :system
> +
> +  array :operations do
> +    scalar :rel, :href
> +  end
> +
> +end
> 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/system_volume.rb b/server/lib/cimi/models/system_volume.rb
> new file mode 100644
> index 0000000..be31846
> --- /dev/null
> +++ b/server/lib/cimi/models/system_volume.rb
> @@ -0,0 +1,26 @@
> +# 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
> +
> +  acts_as_root_entity
> +
> +  href :volume
> +
> +  array :operations do
> +    scalar :rel, :href
> +  end
> +
> +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/cimi/service.rb b/server/lib/cimi/service.rb
> index 8176532..892f6ad 100644
> --- a/server/lib/cimi/service.rb
> +++ b/server/lib/cimi/service.rb
> @@ -45,7 +45,13 @@ require_relative './service/network_create'
>   require_relative './service/network'
>   require_relative './service/forwarding_group'
>   require_relative './service/volume_template_create'
> +require_relative './service/system_machine'
> +require_relative './service/system_volume'
> +require_relative './service/system_network'
> +require_relative './service/system_forwarding_group'
> +require_relative './service/system_address'
>   require_relative './service/system'
> +require_relative './service/system_create'
>   require_relative './service/address_template_create'
>   require_relative './service/volume'
>   require_relative './service/volume_image_create'
> diff --git a/server/lib/cimi/service/system.rb b/server/lib/cimi/service/system.rb
> index daad428..bb28e82 100644
> --- a/server/lib/cimi/service/system.rb
> +++ b/server/lib/cimi/service/system.rb
> @@ -38,7 +38,7 @@ class CIMI::Service::System < CIMI::Service::Base
>     end
>
>     def self.delete!(id, context)
> -    context.driver.destroy_system(context.credentials, id)
> +    context.driver.destroy_system(context.credentials, {:id=>id})
>     end
>
>
> diff --git a/server/lib/cimi/service/system_address.rb b/server/lib/cimi/service/system_address.rb
> new file mode 100644
> index 0000000..2afaf4f
> --- /dev/null
> +++ b/server/lib/cimi/service/system_address.rb
> @@ -0,0 +1,34 @@
> +# 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::Service::SystemAddress < CIMI::Service::Base
> +
> +  def self.find(system_id, context, id=:all)
> +    if id == :all
> +      addresses = context.driver.system_addresses(context.credentials, {:env=>context, :system_id=>system_id})
> +    else
> +      addresses = context.driver.system_addresses(context.credentials, {:env=>context, :system_id=>system_id, :id=>id})
> +      raise CIMI::Model::NotFound if addresses.empty?
> +      addresses.first
> +    end
> +  end
> +
> +  def self.collection_for_system(system_id, context)
> +    system_addresses = self.find(system_id, context)
> +    addresses_url = context.url("/system/#{system_id}/addresses") if context.driver.has_capability? :add_addresses_to_system
> +    CIMI::Model::SystemAddress.list(addresses_url, system_addresses, :add_url => addresses_url)
> +  end
> +
> +end
> diff --git a/server/lib/cimi/service/system_create.rb b/server/lib/cimi/service/system_create.rb
> new file mode 100644
> index 0000000..5e58445
> --- /dev/null
> +++ b/server/lib/cimi/service/system_create.rb
> @@ -0,0 +1,39 @@
> +# 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::Service::SystemCreate < CIMI::Service::Base
> +
> +  def create
> +    if system_template.href?
> +      template = resolve(system_template)
> +    else
> +      # FIXME: What if this href isn't there ? What if the user
> +      # tries to override some aspect of the system template ?
> +    end
> +    params = {
> +      :system_template => system_template,
> +      :name => name,
> +      :description => description,
> +      :env => context
> +    }
> +    result = context.driver.create_system(context.credentials, params)
> +    result.name = name if name
> +    result.description = description if description
> +    result.property = property if property
> +#    result.save
> +    result
> +  end
> +
> +end
> diff --git a/server/lib/cimi/service/system_forwarding_group.rb b/server/lib/cimi/service/system_forwarding_group.rb
> new file mode 100644
> index 0000000..e7c269c
> --- /dev/null
> +++ b/server/lib/cimi/service/system_forwarding_group.rb
> @@ -0,0 +1,34 @@
> +# 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::Service::SystemForwardingGroup < CIMI::Service::Base
> +
> +  def self.find(system_id, context, id=:all)
> +    if id == :all
> +      groups = context.driver.system_forwarding_groups(context.credentials, {:env=>context, :system_id=>system_id})
> +    else
> +      groups = context.driver.system_forwarding_groups(context.credentials, {:env=>context, :system_id=>system_id, :id=>id})
> +      raise CIMI::Model::NotFound if groups.empty?
> +      groups.first
> +    end
> +  end
> +
> +  def self.collection_for_system(system_id, context)
> +    system_forwarding_groups = self.find(system_id, context)
> +    forwarding_groups_url = context.url("/system/#{system_id}/forwarding_groups") if context.driver.has_capability? :add_forwarding_groups_to_system
> +    CIMI::Model::SystemForwardingGroup.list(forwarding_groups_url, system_forwarding_groups, :add_url => forwarding_groups_url)
> +  end
> +
> +end
> diff --git a/server/lib/cimi/service/system_machine.rb b/server/lib/cimi/service/system_machine.rb
> new file mode 100644
> index 0000000..d19026a
> --- /dev/null
> +++ b/server/lib/cimi/service/system_machine.rb
> @@ -0,0 +1,34 @@
> +# 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::Service::SystemMachine < CIMI::Service::Base
> +
> +  def self.find(system_id, context, id=:all)
> +    if id == :all
> +      machines = context.driver.system_machines(context.credentials, {:env=>context, :system_id=>system_id})
> +    else
> +      machines = context.driver.system_machines(context.credentials, {:env=>context, :system_id=>system_id, :id=>id})
> +      raise CIMI::Model::NotFound if machines.empty?
> +      machines.first
> +    end
> +  end
> +
> +  def self.collection_for_system(system_id, context)
> +    system_machines = self.find(system_id, context)
> +    machines_url = context.url("/system/#{system_id}/machines") if context.driver.has_capability? :add_machines_to_system
> +    CIMI::Model::SystemMachine.list(machines_url, system_machines, :add_url => machines_url)
> +  end
> +
> +end
> diff --git a/server/lib/cimi/service/system_network.rb b/server/lib/cimi/service/system_network.rb
> new file mode 100644
> index 0000000..5ff9323
> --- /dev/null
> +++ b/server/lib/cimi/service/system_network.rb
> @@ -0,0 +1,34 @@
> +# 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::Service::SystemNetwork < CIMI::Service::Base
> +
> +  def self.find(system_id, context, id=:all)
> +    if id == :all
> +      networks = context.driver.system_networks(context.credentials, {:env=>context, :system_id=>system_id})
> +    else
> +      networks = context.driver.system_networks(context.credentials, {:env=>context, :system_id=>system_id, :id=>id})
> +      raise CIMI::Model::NotFound if networks.empty?
> +      networks.first
> +    end
> +  end
> +
> +  def self.collection_for_system(system_id, context)
> +    system_networks = self.find(system_id, context)
> +    networks_url = context.url("/system/#{system_id}/networks") if context.driver.has_capability? :add_networks_to_system
> +    CIMI::Model::SystemNetwork.list(networks_url, system_networks, :add_url => networks_url)
> +  end
> +
> +end
> diff --git a/server/lib/cimi/service/system_volume.rb b/server/lib/cimi/service/system_volume.rb
> new file mode 100644
> index 0000000..7f4306b
> --- /dev/null
> +++ b/server/lib/cimi/service/system_volume.rb
> @@ -0,0 +1,34 @@
> +# 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::Service::SystemVolume < CIMI::Service::Base
> +
> +  def self.find(system_id, context, id=:all)
> +    if id == :all
> +      vols = context.driver.system_volumes(context.credentials, {:env=>context, :system_id=>system_id})
> +    else
> +      vols = context.driver.system_volumes(context.credentials, {:env=>context, :system_id=>system_id, :id=>id})
> +      raise CIMI::Model::NotFound if vols.empty?
> +      vols.first
> +    end
> +  end
> +
> +  def self.collection_for_system(system_id, context)
> +    system_volumes = self.find(system_id, context)
> +    volumes_url = context.url("/system/#{system_id}/volumes") if context.driver.has_capability? :add_volumes_to_system
> +    CIMI::Model::SystemVolume.list(volumes_url, system_volumes, :add_url => volumes_url)
> +  end
> +
> +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..6e08de9 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,216 @@ 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?realm_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|
> +          vservers = client.list_vservers(system[:id])['vservers'][0]['vserver']
> +          if vservers.nil?
> +            system[:state] = 'MIXED'
> +          else
> +            vservers.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 create_system(credentials, opts={})
> +      safely do
> +        client = new_client(credentials)
> +        name = opts[:name] || "system_#{Time.now.to_s}"
> +        template = opts[:system_template]
> +        template_id = template.id || template.href.to_s.gsub(/.*\/([^\/]+)$/, '\1')
> +        vsys_id = client.create_vsys(template_id, name)['vsysId'][0]
> +        opts[:id] = vsys_id
> +        systems(credentials, opts).first
> +      end
> +    end
> +
> +    def destroy_system(credentials, opts={})
> +      delete_firewall(credentials, {:id=>"#{opts[:id]}-S-0001"})
> +    end
> +
> +    def system_machines(credentials, opts={})
> +      safely do
> +        client = new_client(credentials)
> +        #if :expand not specified, list of hrefs only, else convert from :instances?
> +        context = opts[:env]
> +        vsys_id = opts[:system_id]
> +        xml = client.list_vservers(vsys_id)['vservers']
> +        return [] if xml.nil?
> +
> +        machines = xml[0]['vserver'].collect do |vserver|
> +          vserver_id = vserver['vserverId'][0]
> +          CIMI::Model::SystemMachine.new(
> +            :id      => context.system_url("#{vsys_id}/machines/#{vserver_id}"),
> +            :name    => vserver['vserverName'][0],
> +            :machine => { :href => context.machine_url(vserver_id)}
> +          ) unless opts[:id] and opts[:id] != vserver_id
> +        end
> +        machines.compact
> +      end
> +    end
> +
> +    def system_volumes(credentials, opts={})
> +      safely do
> +        client = new_client(credentials)
> +        context = opts[:env]
> +        vsys_id = opts[:system_id]
> +        #if :expand not specified, list of hrefs only, else convert from :storage_volumes?
> +        xml = client.list_vdisk(vsys_id)['vdisks']
> +        return [] if xml.nil?
> +
> +        volumes = xml[0]['vdisk'].collect do |vdisk|
> +          vdisk_id = vdisk['vdiskId'][0]
> +          CIMI::Model::SystemVolume.new(
> +            :id      => context.system_url("#{vsys_id}/volumes/#{vdisk_id}"),
> +            :name    => vdisk['vdiskName'][0],
> +            :volume  => { :href => context.volume_url(vdisk_id)}
> +          ) unless opts[:id] and opts[:id] != vdisk_id
> +        end
> +        volumes.compact
> +      end
> +    end
> +
> +    def system_networks(credentials, opts={})
> +      safely do
> +        client = new_client(credentials)
> +        context = opts[:env]
> +        vsys_id = opts[:system_id]
> +        #if :expand not specified, list of hrefs only, else ??
> +        vsys = client.get_vsys_configuration(vsys_id)['vsys'][0]
> +
> +        # retrieve network segment (subnet) info
> +        networks = vsys['vnets'][0]['vnet'].collect do |vnet|
> +          network_id = vnet['networkId'][0]
> +          network_id =~ /.*-(\w)$/
> +          CIMI::Model::SystemNetwork.new(
> +            :id      => context.system_url("#{vsys_id}/networks/#{network_id}"),
> +            :name    => "#{$1} for system #{vsys['vsysName'][0]}",
> +            :network => { :href => context.network_url(network_id)}
> +          ) unless opts[:id] and opts[:id] != network_id
> +        end
> +        networks.compact
> +      end
> +    end
> +
> +    def system_addresses(credentials, opts={})
> +      safely do
> +        client = new_client(credentials)
> +        context = opts[:env]
> +        vsys_id = opts[:system_id]
> +        #if :expand not specified, list of hrefs only, else ??
> +        xml = client.list_public_ips(vsys_id)['publicips']
> +        return [] if xml.nil?
> +
> +        # retrieve network segment (subnet) info
> +        addresses = xml[0]['publicip'].collect do |ip|
> +          address = ip['address'][0]
> +          CIMI::Model::SystemAddress.new(
> +            :id      => context.system_url("#{vsys_id}/addresses/#{address}"),
> +            :name    => "Public IP address allocated to system #{ip['vsysId'][0]}",
> +            :address => { :href => context.address_url(address)}
> +          ) unless opts[:id] and opts[:id] != address
> +        end
> +        addresses.compact
> +      end
> +    end
> +
> +    def system_forwarding_groups(credentials, opts={})
> +      safely do
> +        client = new_client(credentials)
> +        context = opts[:env]
> +        vsys_id = opts[:system_id]
> +        #if :expand not specified, list of hrefs only, else ??
> +        vsys = client.get_vsys_configuration(vsys_id)['vsys'][0]
> +
> +        group_id = "#{vsys_id}-N"
> +        groups = []
> +        groups << CIMI::Model::SystemForwardingGroup.new(
> +          :id               => context.system_url("#{vsys_id}/forwarding_groups/#{group_id}"),
> +          :name             => "Routing group of system #{vsys['vsysName'][0]}",
> +          :forwarding_group => { :href => context.forwarding_group_url(group_id)}
> +        ) unless vsys['vnets'][0]['vnet'].size <= 1 or (opts[:id] and opts[:id] != group_id)
> +        groups
>         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 => 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
> +          # add network templates
> +          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_address/sysaddress1.json b/server/lib/deltacloud/drivers/mock/data/cimi/system_address/sysaddress1.json
> new file mode 100644
> index 0000000..af16b70
> --- /dev/null
> +++ b/server/lib/deltacloud/drivers/mock/data/cimi/system_address/sysaddress1.json
> @@ -0,0 +1,8 @@
> +{ "id": "http://cimi.example.org/systems/system1/addresses/address1",
> +  "name": "sysaddress1",
> +  "created": "Fri Feb 08 12:15:15 EET 2013",
> +  "address": { "href": "http://cimi.example.org/addresses/address1" },
> +  "operations": [
> +    { "rel": "delete", "href": "http://cimi.example.org/systems/system1/addresses/address1" }
> +  ]
> +}
> diff --git a/server/lib/deltacloud/drivers/mock/data/cimi/system_forwarding_group/sysforwardinggroup1.json b/server/lib/deltacloud/drivers/mock/data/cimi/system_forwarding_group/sysforwardinggroup1.json
> new file mode 100644
> index 0000000..db23214
> --- /dev/null
> +++ b/server/lib/deltacloud/drivers/mock/data/cimi/system_forwarding_group/sysforwardinggroup1.json
> @@ -0,0 +1,8 @@
> +{ "id": "http://cimi.example.org/systems/system1/forwarding_groups/group1",
> +  "name": "sysforwardinggroup1",
> +  "created": "Fri Feb 08 12:15:15 EET 2013",
> +  "forwarding_group": { "href": "http://cimi.example.org/forwarding_groups/group1" },
> +  "operations": [
> +    { "rel": "delete", "href": "http://cimi.example.org/systems/system1/forwarding_groups/group1" }
> +  ]
> +}
> diff --git a/server/lib/deltacloud/drivers/mock/data/cimi/system_machine/sysmach1.json b/server/lib/deltacloud/drivers/mock/data/cimi/system_machine/sysmach1.json
> new file mode 100644
> index 0000000..8fe2a92
> --- /dev/null
> +++ b/server/lib/deltacloud/drivers/mock/data/cimi/system_machine/sysmach1.json
> @@ -0,0 +1,8 @@
> +{ "id": "http://cimi.example.org/systems/system1/machines/inst0",
> +  "name": "sysmach1",
> +  "created": "Fri Feb 08 12:15:15 EET 2013",
> +  "machine": { "href": "http://cimi.example.org/machines/inst0" },
> +  "operations": [
> +    { "rel": "delete", "href": "http://cimi.example.org/systems/system1/machines/inst0" }
> +  ]
> +}
> diff --git a/server/lib/deltacloud/drivers/mock/data/cimi/system_network/sysnet1.json b/server/lib/deltacloud/drivers/mock/data/cimi/system_network/sysnet1.json
> new file mode 100644
> index 0000000..09002ed
> --- /dev/null
> +++ b/server/lib/deltacloud/drivers/mock/data/cimi/system_network/sysnet1.json
> @@ -0,0 +1,8 @@
> +{ "id": "http://cimi.example.org/systems/system1/networks/network1",
> +  "name": "sysnetwork1",
> +  "created": "Fri Feb 08 12:15:15 EET 2013",
> +  "network": { "href": "http://cimi.example.org/networks/network1" },
> +  "operations": [
> +    { "rel": "delete", "href": "http://cimi.example.org/systems/system1/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
> index 495fc24..913252b 100644
> --- a/server/lib/deltacloud/drivers/mock/data/cimi/system_template/template1.json
> +++ b/server/lib/deltacloud/drivers/mock/data/cimi/system_template/template1.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/data/cimi/system_volume/sysvol1.json b/server/lib/deltacloud/drivers/mock/data/cimi/system_volume/sysvol1.json
> new file mode 100644
> index 0000000..12e3554
> --- /dev/null
> +++ b/server/lib/deltacloud/drivers/mock/data/cimi/system_volume/sysvol1.json
> @@ -0,0 +1,8 @@
> +{ "id": "http://cimi.example.org/systems/system1/volumes/vol1",
> +  "name": "sysvol1",
> +  "created": "Fri Feb 08 12:15:15 EET 2013",
> +  "volume": { "href": "http://cimi.example.org/volumes/vol1" },
> +  "operations": [
> +    { "rel": "delete", "href": "http://cimi.example.org/systems/system1/volumes/vol1" }
> +  ]
> +}
> 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..9a6daa2 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,115 @@ 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 destroy_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_machines(credentials, opts={})
> +      check_credentials(credentials)
> +      if opts[:id].nil?
> +        machines = @client.load_all_cimi(:system_machine).map{|mach| CIMI::Model::SystemMachine.from_json(mach)}
> +      else
> +        begin
> +          machines = [CIMI::Model::SystemMachine.from_json(@client.load_cimi(:system_machine, opts[:id]))]
> +        rescue Errno::ENOENT
> +          return []
> +        end
> +      end
> +      #FIXME: with ":machines", delete url becomes 'http://localhost:3001/cimi/machines?id=sysmach1'
> +      #with ":system_machine"/":system_machines", undefined method `system_machine_url' for #<CIMI::Collections::Systems:0x44fe338> in mock_driver_cimi_methods.rb:261
> +      machines.map{|mach|convert_cimi_mock_urls(:machines, mach, opts[:env])}.flatten
> +    end
> +
> +    def system_volumes(credentials, opts={})
> +      check_credentials(credentials)
> +      if opts[:id].nil?
> +        volumes = @client.load_all_cimi(:system_volume).map{|vol| CIMI::Model::SystemVolume.from_json(vol)}
> +      else
> +        begin
> +          volumes = [CIMI::Model::SystemVolume.from_json(@client.load_cimi(:system_volume, opts[:id]))]
> +        rescue Errno::ENOENT
> +          return []
> +        end
> +      end
> +      #FIXME: with ":volumes", delete url becomes 'http://localhost:3001/cimi/volumes?id=sysvol1'
> +      #with ":system_volume"/":system_volumes", undefined method `system_volume_url' for #<CIMI::Collections::Systems:0x44fe338> in mock_driver_cimi_methods.rb:261
> +      volumes.map{|vol|convert_cimi_mock_urls(:volumes, vol, opts[:env])}.flatten
> +    end
> +
> +    def system_networks(credentials, opts={})
> +      check_credentials(credentials)
> +      if opts[:id].nil?
> +        networks = @client.load_all_cimi(:system_network).map{|net| CIMI::Model::SystemNetwork.from_json(net)}
> +      else
> +        begin
> +          networks = [CIMI::Model::SystemNetwork.from_json(@client.load_cimi(:system_network, opts[:id]))]
> +        rescue Errno::ENOENT
> +          return []
> +        end
> +      end
> +      #FIXME
> +      networks.map{|vol|convert_cimi_mock_urls(:networks, vol, opts[:env])}.flatten
> +    end
> +
> +    def system_addresses(credentials, opts={})
> +      check_credentials(credentials)
> +      if opts[:id].nil?
> +        addresses = @client.load_all_cimi(:system_address).map{|a| CIMI::Model::SystemAddress.from_json(a)}
> +      else
> +        begin
> +          addresses = [CIMI::Model::SystemVolume.from_json(@client.load_cimi(:system_address, opts[:id]))]
> +        rescue Errno::ENOENT
> +          return []
> +        end
> +      end
> +      #FIXME
> +      addresses.map{|a|convert_cimi_mock_urls(:addresses, a, opts[:env])}.flatten
> +    end
> +
> +    def system_forwarding_groups(credentials, opts={})
> +      check_credentials(credentials)
> +      if opts[:id].nil?
> +        groups = @client.load_all_cimi(:system_forwarding_group).map{|group| CIMI::Model::SystemForwardingGroup.from_json(group)}
> +      else
> +        begin
> +          groups = [CIMI::Model::SystemForwardingGroup.from_json(@client.load_cimi(:system_forwarding_group, opts[:id]))]
> +        rescue Errno::ENOENT
> +          return []
> +        end
> +      end
> +      #FIXME
> +      groups.map{|group|convert_cimi_mock_urls(:forwarding_groups, group, opts[:env])}.flatten
> +    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_text.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_equal 'GOLD'
> +      end
> +    end
> +  end
> +
>   end
>


-- 

Michal Fojtik <mf...@redhat.com>
Deltacloud API, CloudForms