You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@deltacloud.apache.org by mf...@apache.org on 2013/03/26 18:57:48 UTC
[02/30] Client: Complete rewrite of deltacloud-client
http://git-wip-us.apache.org/repos/asf/deltacloud/blob/b6d3365c/client/lib/deltacloud/client/methods/driver.rb
----------------------------------------------------------------------
diff --git a/client/lib/deltacloud/client/methods/driver.rb b/client/lib/deltacloud/client/methods/driver.rb
new file mode 100644
index 0000000..107bcc3
--- /dev/null
+++ b/client/lib/deltacloud/client/methods/driver.rb
@@ -0,0 +1,54 @@
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements. See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership. The
+# ASF licenses this file to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance with the
+# License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+# License for the specific language governing permissions and limitations
+# under the License.
+
+module Deltacloud::Client
+ module Methods
+ module Driver
+
+ # Retrieve list of all drivers
+ #
+ # Filter options:
+ #
+ # - :id -> Filter drivers using their 'id'
+ # - :state -> Filter drivers by their 'state'
+ #
+ def drivers(filter_opts={})
+ from_collection(
+ :drivers,
+ connection.get(api_uri('drivers'), filter_opts)
+ )
+ end
+
+ # Retrieve the given driver
+ #
+ # - driver_id -> Driver to retrieve
+ #
+ def driver(driver_id)
+ from_resource(
+ :driver,
+ connection.get(api_uri("drivers/#{driver_id}"))
+ )
+ end
+
+ # List of the current driver providers
+ #
+ def providers
+ driver(current_driver).providers
+ end
+
+ end
+
+ end
+end
http://git-wip-us.apache.org/repos/asf/deltacloud/blob/b6d3365c/client/lib/deltacloud/client/methods/firewall.rb
----------------------------------------------------------------------
diff --git a/client/lib/deltacloud/client/methods/firewall.rb b/client/lib/deltacloud/client/methods/firewall.rb
new file mode 100644
index 0000000..547dfc5
--- /dev/null
+++ b/client/lib/deltacloud/client/methods/firewall.rb
@@ -0,0 +1,66 @@
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements. See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership. The
+# ASF licenses this file to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance with the
+# License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+# License for the specific language governing permissions and limitations
+# under the License.
+
+module Deltacloud::Client
+ module Methods
+ module Firewall
+
+ # Retrieve list of all firewall entities
+ #
+ # Filter options:
+ #
+ # - :id -> Filter entities using 'id' attribute
+ #
+ def firewalls(filter_opts={})
+ from_collection :firewalls,
+ connection.get(api_uri('firewalls'), filter_opts)
+ end
+
+ # Retrieve the single firewall entity
+ #
+ # - firewall_id -> Firewall entity to retrieve
+ #
+ def firewall(firewall_id)
+ from_resource :firewall,
+ connection.get(api_uri("firewalls/#{firewall_id}"))
+ end
+
+ # Create a new firewall
+ #
+ # - create_opts
+ #
+ def create_firewall(name, create_opts={})
+ create_resource :firewall, { :name => name }.merge(create_opts)
+ end
+
+ def destroy_firewall(firewall_id)
+ destroy_resource :firewall, firewall_id
+ end
+
+ def add_firewall_rule(firewall_id, protocol, port_from, port_to, opts={})
+ r = connection.post(api_uri("firewalls/#{firewall_id}/rules")) do |request|
+ request.params = {
+ :protocol => protocol,
+ :port_from => port_from,
+ :port_to => port_to
+ }
+ # TODO: Add support for sources
+ end
+ model(:firewall).convert(self, r.body)
+ end
+
+ end
+ end
+end
http://git-wip-us.apache.org/repos/asf/deltacloud/blob/b6d3365c/client/lib/deltacloud/client/methods/hardware_profile.rb
----------------------------------------------------------------------
diff --git a/client/lib/deltacloud/client/methods/hardware_profile.rb b/client/lib/deltacloud/client/methods/hardware_profile.rb
new file mode 100644
index 0000000..0cf744c
--- /dev/null
+++ b/client/lib/deltacloud/client/methods/hardware_profile.rb
@@ -0,0 +1,42 @@
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements. See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership. The
+# ASF licenses this file to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance with the
+# License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+# License for the specific language governing permissions and limitations
+# under the License.
+
+module Deltacloud::Client
+ module Methods
+ module HardwareProfile
+
+ # Retrieve list of all hardware_profiles
+ #
+ # Filter options:
+ #
+ # - :id -> Filter hardware_profiles using their 'id'
+ #
+ def hardware_profiles(filter_opts={})
+ from_collection :hardware_profiles,
+ connection.get(api_uri('hardware_profiles'), filter_opts)
+ end
+
+ # Retrieve the given hardware_profile
+ #
+ # - hardware_profile_id -> hardware_profile to retrieve
+ #
+ def hardware_profile(hwp_id)
+ from_resource :hardware_profile,
+ connection.get(api_uri("hardware_profiles/#{hwp_id}"))
+ end
+
+ end
+ end
+end
http://git-wip-us.apache.org/repos/asf/deltacloud/blob/b6d3365c/client/lib/deltacloud/client/methods/image.rb
----------------------------------------------------------------------
diff --git a/client/lib/deltacloud/client/methods/image.rb b/client/lib/deltacloud/client/methods/image.rb
new file mode 100644
index 0000000..8e3765b
--- /dev/null
+++ b/client/lib/deltacloud/client/methods/image.rb
@@ -0,0 +1,62 @@
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements. See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership. The
+# ASF licenses this file to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance with the
+# License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+# License for the specific language governing permissions and limitations
+# under the License.
+
+module Deltacloud::Client
+ module Methods
+ module Image
+
+ # Retrieve list of all images
+ #
+ # Filter options:
+ #
+ # - :id -> Filter images using their 'id'
+ # - :state -> Filter images by their 'state'
+ # - :architecture -> Filter images by their 'architecture'
+ #
+ def images(filter_opts={})
+ from_collection :images,
+ connection.get(api_uri('images'), filter_opts)
+ end
+
+ # Retrieve the given image
+ #
+ # - image_id -> Image to retrieve
+ #
+ def image(image_id)
+ from_resource :image,
+ connection.get(api_uri("images/#{image_id}"))
+ end
+
+ # Create a new image from instance
+ #
+ # - instance_id -> The stopped instance used for creation
+ # - create_opts
+ # - :name -> Name of the new image
+ # - :description -> Description of the new image
+ #
+ def create_image(instance_id, create_opts={})
+ create_resource :image, { :instance_id => instance_id }.merge(create_opts)
+ end
+
+ # Destroy given image
+ # NOTE: This operation might not be supported for all drivers.
+ #
+ def destroy_image(image_id)
+ destroy_resource :image, image_id
+ end
+
+ end
+ end
+end
http://git-wip-us.apache.org/repos/asf/deltacloud/blob/b6d3365c/client/lib/deltacloud/client/methods/instance.rb
----------------------------------------------------------------------
diff --git a/client/lib/deltacloud/client/methods/instance.rb b/client/lib/deltacloud/client/methods/instance.rb
new file mode 100644
index 0000000..4749d82
--- /dev/null
+++ b/client/lib/deltacloud/client/methods/instance.rb
@@ -0,0 +1,140 @@
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements. See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership. The
+# ASF licenses this file to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance with the
+# License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+# License for the specific language governing permissions and limitations
+# under the License.
+
+module Deltacloud::Client
+ module Methods
+ module Instance
+
+ # Retrieve list of all instances
+ #
+ # Filter options:
+ #
+ # - :id -> Filter instances using their 'id'
+ # - :state -> Filter instances by their 'state'
+ # - :realm_id -> Filter instances based on their 'realm_id'
+ #
+ def instances(filter_opts={})
+ from_collection(
+ :instances,
+ connection.get(api_uri('/instances'), filter_opts)
+ )
+ end
+
+ # Retrieve the given instance
+ #
+ # - instance_id -> Instance to retrieve
+ #
+ def instance(instance_id)
+ from_resource(
+ :instance,
+ connection.get(api_uri("instances/#{instance_id}"))
+ )
+ end
+
+ # Create a new instance
+ #
+ # - image_id -> Image to use for instance creation (img1, ami-12345, etc...)
+ # - create_opts -> Various options that DC support for the current
+ # provider.
+ #
+ # Returns created instance, or list of created instances or all instances.
+ #
+ def create_instance(image_id, create_opts={})
+ r = create_resource :instance, create_opts.merge(
+ :image_id => image_id,
+ :no_convert_model => true
+ )
+ parse_create_instance(r)
+ end
+
+ # Destroy the current +Instance+
+ # Returns 'true' if the response was 204 No Content
+ #
+ # - instance_id -> The 'id' of the Instance to destroy
+ #
+ def destroy_instance(instance_id)
+ destroy_resource :instance, instance_id
+ end
+
+ # Attempt to change the +Instance+ state to STOPPED
+ #
+ # - instance_id -> The 'id' of the Instance to stop
+ #
+ def stop_instance(instance_id)
+ instance_action :stop, instance_id
+ end
+
+ # Attempt to change the +Instance+ state to STARTED
+ #
+ # - instance_id -> The 'id' of the Instance to start
+ #
+ def start_instance(instance_id)
+ instance_action :start, instance_id
+ end
+
+ # Attempt to reboot the +Instance+
+ #
+ # - instance_id -> The 'id' of the Instance to reboot
+ #
+ def reboot_instance(instance_id)
+ instance_action :reboot, instance_id
+ end
+
+ private
+
+ # Avoid codu duplication ;-)
+ #
+ def instance_action(action, instance_id)
+ result = connection.post(
+ api_uri("/instances/#{instance_id}/#{action}")
+ )
+ if result.status.is_ok?
+ from_resource(:instance, result)
+ else
+ instance(instance_id)
+ end
+ end
+
+ # Handles parsing of +create_instance+ method
+ #
+ # - response -> +create_instance+ HTTP response body
+ #
+ def parse_create_instance(response)
+ # If Deltacloud API return only Location (30x), follow it and
+ # retrieve created instance from there.
+ #
+ if response.status.is_redirect?
+ # If Deltacloud API redirect to list of instances
+ # then return list of **all** instances, otherwise
+ # grab the instance_id from Location header
+ #
+ redirect_instance = response.headers['Location'].split('/').last
+ if redirect_instance == 'instances'
+ instances
+ else
+ instance(redirect_instance)
+ end
+ elsif response.body.to_xml.root.name == 'instances'
+ # If more than 1 instance was created, return list
+ #
+ from_collection(:instances, response.body)
+ else
+ from_resource(:instance, response)
+ end
+ end
+
+ end
+ end
+end
http://git-wip-us.apache.org/repos/asf/deltacloud/blob/b6d3365c/client/lib/deltacloud/client/methods/instance_state.rb
----------------------------------------------------------------------
diff --git a/client/lib/deltacloud/client/methods/instance_state.rb b/client/lib/deltacloud/client/methods/instance_state.rb
new file mode 100644
index 0000000..3c853d0
--- /dev/null
+++ b/client/lib/deltacloud/client/methods/instance_state.rb
@@ -0,0 +1,41 @@
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements. See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership. The
+# ASF licenses this file to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance with the
+# License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+# License for the specific language governing permissions and limitations
+# under the License.
+
+module Deltacloud::Client
+ module Methods
+ module InstanceState
+
+ # Representation of the current driver state machine
+ #
+ def instance_states
+ r = connection.get(api_uri("instance_states"))
+ r.body.to_xml.root.xpath('state').map do |se|
+ state = model(:instance_state).new_state(se['name'])
+ se.xpath('transition').each do |te|
+ state.transitions << model(:instance_state).new_transition(
+ te['to'], te['action']
+ )
+ end
+ state
+ end
+ end
+
+ def instance_state(name)
+ instance_states.find { |s| s.name.to_s.eql?(name.to_s) }
+ end
+
+ end
+ end
+end
http://git-wip-us.apache.org/repos/asf/deltacloud/blob/b6d3365c/client/lib/deltacloud/client/methods/key.rb
----------------------------------------------------------------------
diff --git a/client/lib/deltacloud/client/methods/key.rb b/client/lib/deltacloud/client/methods/key.rb
new file mode 100644
index 0000000..8984f23
--- /dev/null
+++ b/client/lib/deltacloud/client/methods/key.rb
@@ -0,0 +1,59 @@
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements. See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership. The
+# ASF licenses this file to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance with the
+# License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+# License for the specific language governing permissions and limitations
+# under the License.
+
+module Deltacloud::Client
+ module Methods
+ module Key
+
+ # Retrieve list of all key entities
+ #
+ # Filter options:
+ #
+ # - :id -> Filter entities using 'id' attribute
+ #
+ def keys(filter_opts={})
+ from_collection :keys,
+ connection.get(api_uri('keys'), filter_opts)
+ end
+
+ # Retrieve the single key entity
+ #
+ # - key_id -> Key entity to retrieve
+ #
+ def key(key_id)
+ from_resource :key,
+ connection.get(api_uri("keys/#{key_id}"))
+ end
+
+ # Create a new credentials to use with authentication
+ # to an +Instance+
+ #
+ # - key_name -> The name of the key
+ # - create_opts
+ # : public_key -> Your SSH public key (eg. ~/.ssh/id_rsa.pub)
+ #
+ def create_key(key_name, create_opts={})
+ create_resource :key, create_opts.merge(:name => key_name)
+ end
+
+ # Destroy the SSH key
+ #
+ def destroy_key(key_id)
+ destroy_resource :key, key_id
+ end
+
+ end
+ end
+end
http://git-wip-us.apache.org/repos/asf/deltacloud/blob/b6d3365c/client/lib/deltacloud/client/methods/realm.rb
----------------------------------------------------------------------
diff --git a/client/lib/deltacloud/client/methods/realm.rb b/client/lib/deltacloud/client/methods/realm.rb
new file mode 100644
index 0000000..41807f0
--- /dev/null
+++ b/client/lib/deltacloud/client/methods/realm.rb
@@ -0,0 +1,43 @@
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements. See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership. The
+# ASF licenses this file to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance with the
+# License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+# License for the specific language governing permissions and limitations
+# under the License.
+
+module Deltacloud::Client
+ module Methods
+ module Realm
+
+ # Retrieve list of all realms
+ #
+ # Filter options:
+ #
+ # - :id -> Filter realms using their 'id'
+ # - :state -> Filter realms by their 'state'
+ #
+ def realms(filter_opts={})
+ from_collection :realms,
+ connection.get(api_uri("realms"), filter_opts)
+ end
+
+ # Retrieve the given realm
+ #
+ # - realm_id -> Instance to retrieve
+ #
+ def realm(realm_id)
+ from_resource :realm,
+ connection.get(api_uri("realms/#{realm_id}"))
+ end
+
+ end
+ end
+end
http://git-wip-us.apache.org/repos/asf/deltacloud/blob/b6d3365c/client/lib/deltacloud/client/methods/storage_snapshot.rb
----------------------------------------------------------------------
diff --git a/client/lib/deltacloud/client/methods/storage_snapshot.rb b/client/lib/deltacloud/client/methods/storage_snapshot.rb
new file mode 100644
index 0000000..33c1696
--- /dev/null
+++ b/client/lib/deltacloud/client/methods/storage_snapshot.rb
@@ -0,0 +1,62 @@
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements. See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership. The
+# ASF licenses this file to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance with the
+# License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+# License for the specific language governing permissions and limitations
+# under the License.
+
+module Deltacloud::Client
+ module Methods
+ module StorageSnapshot
+
+ # Retrieve list of all storage_snapshot entities
+ #
+ # Filter options:
+ #
+ # - :id -> Filter entities using 'id' attribute
+ #
+ def storage_snapshots(filter_opts={})
+ from_collection :storage_snapshots,
+ connection.get(api_uri('storage_snapshots'), filter_opts)
+ end
+
+ # Retrieve the single storage_snapshot entity
+ #
+ # - storage_snapshot_id -> StorageSnapshot entity to retrieve
+ #
+ def storage_snapshot(storage_snapshot_id)
+ from_resource :storage_snapshot,
+ connection.get(api_uri("storage_snapshots/#{storage_snapshot_id}"))
+ end
+
+ # Create a new StorageSnapshot based on +volume_id+
+ #
+ # - volume_id -> ID of the +StorageVolume+ to create snapshot from
+ # - create_opts ->
+ # :name -> Name of the StorageSnapshot
+ # :description -> Description of the StorageSnapshot
+ #
+ def create_storage_snapshot(volume_id, create_opts={})
+ create_resource :storage_snapshot, create_opts.merge(:volume_id => volume_id)
+ end
+
+ # Destroy the current +StorageSnapshot+
+ # Returns 'true' if the response was 204 No Content
+ #
+ # - snapshot_id -> The 'id' of the snapshot to destroy
+ #
+ def destroy_storage_snapshot(snapshot_id)
+ destroy_resource :storage_snapshot, snapshot_id
+ end
+
+ end
+ end
+end
http://git-wip-us.apache.org/repos/asf/deltacloud/blob/b6d3365c/client/lib/deltacloud/client/methods/storage_volume.rb
----------------------------------------------------------------------
diff --git a/client/lib/deltacloud/client/methods/storage_volume.rb b/client/lib/deltacloud/client/methods/storage_volume.rb
new file mode 100644
index 0000000..be6c4ca
--- /dev/null
+++ b/client/lib/deltacloud/client/methods/storage_volume.rb
@@ -0,0 +1,95 @@
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements. See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership. The
+# ASF licenses this file to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance with the
+# License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+# License for the specific language governing permissions and limitations
+# under the License.
+
+module Deltacloud::Client
+ module Methods
+ module StorageVolume
+
+ # Retrieve list of all storage_volumes
+ #
+ # Filter options:
+ #
+ # - :id -> Filter storage_volumes using their 'id'
+ # - :state -> Filter storage_volumes by their 'state'
+ #
+ def storage_volumes(filter_opts={})
+ from_collection :storage_volumes,
+ connection.get(api_uri("storage_volumes"), filter_opts)
+ end
+
+ # Retrieve the given storage_volume
+ #
+ # - storage_volume_id -> Instance to retrieve
+ #
+ def storage_volume(storage_volume_id)
+ from_resource :storage_volume,
+ connection.get(api_uri("storage_volumes/#{storage_volume_id}"))
+ end
+
+ # Create new storage volume
+ #
+ # - :snapshot_id -> Snapshot to use for creating a new volume
+ # - :capacity -> Initial Volume capacity
+ # - :realm_id -> Create volume in this realm
+ # - :name -> Volume name
+ # - :description -> Volume description
+ #
+ # NOTE: Some create options might not be supported by backend cloud
+ #
+ def create_storage_volume(create_opts={})
+ create_resource :storage_volume, create_opts
+ end
+
+ # Destroy the current +StorageVolume+
+ # Returns 'true' if the response was 204 No Content
+ #
+ # - volume_id -> The 'id' of the volume to destroy
+ #
+ def destroy_storage_volume(volume_id)
+ destroy_resource :storage_volume, volume_id
+ end
+
+ # Attach the Storage Volume to the Instance
+ # The +device+ parameter could be used if supported.
+ #
+ # - volume_id -> Volume ID (eg. 'vol1')
+ # - instance_id -> Target Instance ID (eg. 'inst1')
+ # - device -> Target device in Instance (eg. '/dev/sda2')
+ #
+ def attach_storage_volume(volume_id, instance_id, device=nil)
+ must_support! :storage_volumes
+ result = connection.post(api_uri("/storage_volumes/#{volume_id}/attach")) do |r|
+ r.params = { :instance_id => instance_id, :device => device }
+ end
+ if result.status.is_ok?
+ from_resource(:storage_volume, result)
+ end
+ end
+
+ # Detach the Storage Volume from the Instance
+ #
+ # -volume_id -> Volume to detach
+ #
+ def detach_storage_volume(volume_id)
+ must_support! :storage_volumes
+ result = connection.post(api_uri("/storage_volumes/#{volume_id}/detach"))
+ if result.status.is_ok?
+ from_resource(:storage_volume, result)
+ end
+ end
+
+ end
+ end
+end
http://git-wip-us.apache.org/repos/asf/deltacloud/blob/b6d3365c/client/lib/deltacloud/client/models.rb
----------------------------------------------------------------------
diff --git a/client/lib/deltacloud/client/models.rb b/client/lib/deltacloud/client/models.rb
new file mode 100644
index 0000000..63b5a24
--- /dev/null
+++ b/client/lib/deltacloud/client/models.rb
@@ -0,0 +1,30 @@
+# 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.
+
+require_relative './models/base'
+require_relative './models/driver'
+require_relative './models/realm'
+require_relative './models/hardware_profile'
+require_relative './models/image'
+require_relative './models/instance_address'
+require_relative './models/instance'
+require_relative './models/instance_state'
+require_relative './models/storage_volume'
+require_relative './models/storage_snapshot'
+require_relative './models/key'
+require_relative './models/address'
+require_relative './models/bucket'
+require_relative './models/blob'
+require_relative './models/firewall'
http://git-wip-us.apache.org/repos/asf/deltacloud/blob/b6d3365c/client/lib/deltacloud/client/models/address.rb
----------------------------------------------------------------------
diff --git a/client/lib/deltacloud/client/models/address.rb b/client/lib/deltacloud/client/models/address.rb
new file mode 100644
index 0000000..d39d80b
--- /dev/null
+++ b/client/lib/deltacloud/client/models/address.rb
@@ -0,0 +1,57 @@
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements. See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership. The
+# ASF licenses this file to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance with the
+# License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+# License for the specific language governing permissions and limitations
+# under the License.
+
+module Deltacloud::Client
+ class Address < Base
+ include Deltacloud::Client::Methods::Address
+
+ # Inherited attributes: :_id, :name, :description
+
+ # Custom attributes:
+ #
+ attr_reader :ip
+ attr_reader :instance_id
+
+ # Address model methods
+ #
+
+ # Associate the IP address to the +Instance+
+ #
+ def associate(instance_id)
+ associate_address(_id, instance_id)
+ end
+
+ # Disassociate the IP address from +Instance+
+ #
+ def disassociate
+ disassociate_address(_id)
+ end
+
+ def destroy!
+ destroy_address(_id)
+ end
+
+ # Parse the Address entity from XML body
+ #
+ # - xml_body -> Deltacloud API XML representation of the address
+ #
+ def self.parse(xml_body)
+ {
+ :ip => xml_body.text_at(:ip),
+ :instance_id => xml_body.attr_at('instance', :id)
+ }
+ end
+ end
+end
http://git-wip-us.apache.org/repos/asf/deltacloud/blob/b6d3365c/client/lib/deltacloud/client/models/base.rb
----------------------------------------------------------------------
diff --git a/client/lib/deltacloud/client/models/base.rb b/client/lib/deltacloud/client/models/base.rb
new file mode 100644
index 0000000..9f51fb0
--- /dev/null
+++ b/client/lib/deltacloud/client/models/base.rb
@@ -0,0 +1,151 @@
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements. See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership. The
+# ASF licenses this file to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance with the
+# License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+# License for the specific language governing permissions and limitations
+# under the License.
+
+module Deltacloud::Client
+
+ class Base
+
+ extend Helpers::XmlHelper
+
+ include Deltacloud::Client::Helpers::Model
+ include Deltacloud::Client::Methods::Api
+
+ # These attributes are common for all models
+ #
+ # - obj_id -> The :id of Deltacloud API model (eg. instance ID)
+ #
+ attr_reader :obj_id
+ attr_reader :name
+ attr_reader :description
+
+ # The Base class that other models should inherit from
+ # To initialize, you need to suply these mandatory params:
+ #
+ # - :_client -> Reference to Client instance
+ # - :_id -> The 'id' of resource. The '_' is there to avoid conflicts
+ #
+ def initialize(opts={})
+ @options = opts
+ @obj_id = @options.delete(:_id)
+ # Do not allow to modify the object#base_id
+ @obj_id.freeze
+ @client = @options.delete(:_client)
+ @original_body = @options.delete(:original_body)
+ update_instance_variables!(@options)
+ end
+
+ alias_method :_id, :obj_id
+
+ # Populate instance variables in model
+ # This method could be also used to update the variables for already
+ # initialized models. Look at +Instance#reload!+ method.
+ #
+ def update_instance_variables!(opts={})
+ @options.merge!(opts)
+ @options.each { |key, val| self.instance_variable_set("@#{key}", val) unless val.nil? }
+ self
+ end
+
+ # Eye-candy representation of model, without ugly @client representation
+ #
+ def to_s
+ "#<#{self.class.name}> #{@options.merge(:_id => @obj_id).inspect}"
+ end
+
+ # An internal reference to the current Deltacloud::Client::Connection
+ # instance. Used for implementing the model methods
+ #
+ def client
+ @client
+ end
+
+ # Shorthand for +client+.connection
+ #
+ # Return Faraday connection object.
+ #
+ def connection
+ client.connection
+ end
+
+ # Return the cached version of Deltacloud API entrypoint
+ #
+ def entrypoint
+ client.entrypoint
+ end
+
+ # Return the original XML body model was constructed from
+ # This might help debugging broken XML
+ #
+ def original_body
+ @original_body
+ end
+
+ # The model#id is the old way how to get the Deltacloud API resource
+ # 'id'. However this collide with the Ruby Object#id.
+ #
+ def id
+ warn '[DEPRECATION] `id` is deprecated because of possible conflict with Object#id. Use `_id` instead.'
+ _id
+ end
+
+ class << self
+
+ # Parse the XML response body from Deltacloud API
+ # to +Hash+. Result is then used to create an instance of Deltacloud model
+ #
+ # NOTE: Children classes **must** implement this class method
+ #
+ def parse(client_ref, inst)
+ warn "The self#parse method **must** be defined in #{self.class.name}"
+ {}
+ end
+
+ # Convert the parsed +Hash+ from +parse+ method to instance of Deltacloud model
+ #
+ # - client_ref -> Reference to the Client instance
+ # - obj -> Might be a Nokogiri::Element or Response
+ #
+ def convert(client_ref, obj)
+ body = extract_xml_body(obj).to_xml.root
+ attrs = parse(body)
+ attrs.merge!({
+ :_id => body['id'],
+ :_client => client_ref,
+ :name => body.text_at(:name),
+ :description => body.text_at(:description)
+ })
+ validate_attrs!(attrs)
+ new(attrs.merge(:original_body => obj))
+ end
+
+ # Convert response for the collection responses.
+ #
+ def from_collection(client_ref, response)
+ response.body.to_xml.xpath('/*/*').map do |entity|
+ convert(client_ref, entity)
+ end
+ end
+
+ # The :_id and :_client attributes are mandotory
+ # to construct a Base model object.
+ #
+ def validate_attrs!(attrs)
+ raise error.new('The :_id must not be nil.') if attrs[:_id].nil?
+ raise error.new('The :_client reference is missing.') if attrs[:_client].nil?
+ end
+
+ end
+ end
+end
http://git-wip-us.apache.org/repos/asf/deltacloud/blob/b6d3365c/client/lib/deltacloud/client/models/blob.rb
----------------------------------------------------------------------
diff --git a/client/lib/deltacloud/client/models/blob.rb b/client/lib/deltacloud/client/models/blob.rb
new file mode 100644
index 0000000..569c187
--- /dev/null
+++ b/client/lib/deltacloud/client/models/blob.rb
@@ -0,0 +1,56 @@
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements. See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership. The
+# ASF licenses this file to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance with the
+# License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+# License for the specific language governing permissions and limitations
+# under the License.
+
+module Deltacloud::Client
+ class Blob < Base
+
+ include Deltacloud::Client::Methods::Blob
+ include Deltacloud::Client::Methods::Bucket
+
+ # Inherited attributes: :_id, :name, :description
+
+ # Custom attributes:
+ #
+ attr_reader :bucket_id
+ attr_reader :content_length
+ attr_reader :content_type
+ attr_reader :last_modified
+ attr_reader :user_metadata
+
+ # Blob model methods
+ #
+
+ def bucket
+ super(bucket_id)
+ end
+
+ # Parse the Blob entity from XML body
+ #
+ # - xml_body -> Deltacloud API XML representation of the blob
+ #
+ def self.parse(xml_body)
+ {
+ :bucket_id => xml_body.text_at(:bucket_id) || xml_body.text_at(:bucket), # FIXME: DC bug
+ :content_length => xml_body.text_at(:content_length),
+ :content_type => xml_body.text_at(:content_type),
+ :last_modified => xml_body.text_at(:last_modified),
+ :user_metadata => xml_body.xpath('user_metadata/entry').inject({}) { |r,e|
+ r[e['key']] = e.text.strip
+ r
+ }
+ }
+ end
+ end
+end
http://git-wip-us.apache.org/repos/asf/deltacloud/blob/b6d3365c/client/lib/deltacloud/client/models/bucket.rb
----------------------------------------------------------------------
diff --git a/client/lib/deltacloud/client/models/bucket.rb b/client/lib/deltacloud/client/models/bucket.rb
new file mode 100644
index 0000000..9a8a856
--- /dev/null
+++ b/client/lib/deltacloud/client/models/bucket.rb
@@ -0,0 +1,65 @@
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements. See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership. The
+# ASF licenses this file to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance with the
+# License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+# License for the specific language governing permissions and limitations
+# under the License.
+
+module Deltacloud::Client
+ class Bucket < Base
+
+ include Deltacloud::Client::Methods::Bucket
+ include Deltacloud::Client::Methods::Blob
+
+ # Inherited attributes: :_id, :name, :description
+
+ # Custom attributes:
+ #
+ attr_reader :size
+ attr_reader :blob_ids
+
+ # Bucket model methods
+ #
+ #
+
+ # All blobs associated with the current bucket
+ # The 'bucket_id' should not be set in this case.
+ #
+ def blobs(bucket_id=nil)
+ super(_id)
+ end
+
+ # Add a new blob to the bucket.
+ # See: +create_blob+
+ #
+ def add_blob(blob_name, blob_data, blob_create_opts={})
+ create_blob(_id, blob_name, blob_data, create_opts)
+ end
+
+ # Remove a blob from the bucket
+ # See: +destroy_blob+
+ #
+ def remove_blob(blob_id)
+ destroy_blob(_id, blob_id)
+ end
+
+ # Parse the Bucket entity from XML body
+ #
+ # - xml_body -> Deltacloud API XML representation of the bucket
+ #
+ def self.parse(xml_body)
+ {
+ :size => xml_body.text_at(:size),
+ :blob_ids => xml_body.xpath('blob').map { |b| b['id'] }
+ }
+ end
+ end
+end
http://git-wip-us.apache.org/repos/asf/deltacloud/blob/b6d3365c/client/lib/deltacloud/client/models/driver.rb
----------------------------------------------------------------------
diff --git a/client/lib/deltacloud/client/models/driver.rb b/client/lib/deltacloud/client/models/driver.rb
new file mode 100644
index 0000000..538d463
--- /dev/null
+++ b/client/lib/deltacloud/client/models/driver.rb
@@ -0,0 +1,87 @@
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements. See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership. The
+# ASF licenses this file to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance with the
+# License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+# License for the specific language governing permissions and limitations
+# under the License.
+
+module Deltacloud::Client
+
+ class Driver < Base
+
+ attr_reader :providers
+
+ # Syntax sugar for returning provider from Driver
+ # instance:
+ #
+ # client.driver(:ec2)['us-west-1'] # => List of endpoints
+ #
+ # - provider_id -> Provider ID, like 'us-west-1'
+ #
+ def [](provider_id)
+ @providers ||= []
+ prov = @providers.find { |p| p.name == provider_id }
+ prov.instance_variable_set('@client', @client)
+ prov
+ end
+
+ def self.parse(xml_body)
+ {
+ :providers => xml_body.xpath('provider').map { |p| Provider.parse(p) }
+ }
+ end
+
+ class Provider
+
+ attr_reader :name
+ attr_reader :entrypoints
+
+ def initialize(name, entrypoints=[])
+ @name = name
+ @entrypoints = entrypoints
+ end
+
+ # Syntax sugar for retrieving list of endpoints available for the
+ # provider
+ #
+ # - entrypoint_id -> Entrypoint ID, like 's3'
+ #
+ def [](entrypoint_id)
+ @entrypoints ||= []
+ ent_point = @entrypoints.find { |name, _| name == entrypoint_id }
+ ent_point ? ent_point.last : nil
+ end
+
+ # Method to check if given credentials can be used to authorize
+ # connection to current provider:
+ #
+ # client.driver(:ec2)['us-west-1'].valid_credentials? 'user', 'password'
+ #
+ # - api_user -> API key
+ # - api_password -> API secret
+ #
+ def valid_credentials?(api_user, api_password)
+ unless @client
+ raise error.new('Please use driver("ec2")[API_PROVIDER].valid_credentials?')
+ end
+ @client.use(@client.current_driver, api_user, api_password, @name).valid_credentials?
+ end
+
+ def self.parse(p)
+ new(
+ p['id'],
+ p.xpath('entrypoint').inject({}) { |r, e| r[e['kind']] = e.text.strip; r }
+ )
+ end
+ end
+
+ end
+end
http://git-wip-us.apache.org/repos/asf/deltacloud/blob/b6d3365c/client/lib/deltacloud/client/models/firewall.rb
----------------------------------------------------------------------
diff --git a/client/lib/deltacloud/client/models/firewall.rb b/client/lib/deltacloud/client/models/firewall.rb
new file mode 100644
index 0000000..9bbe0f2
--- /dev/null
+++ b/client/lib/deltacloud/client/models/firewall.rb
@@ -0,0 +1,70 @@
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements. See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership. The
+# ASF licenses this file to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance with the
+# License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+# License for the specific language governing permissions and limitations
+# under the License.
+
+module Deltacloud::Client
+ class Firewall < Base
+
+ include Deltacloud::Client::Methods::Common
+ include Deltacloud::Client::Methods::Firewall
+
+ # Inherited attributes: :_id, :name, :description
+
+ # Custom attributes:
+ #
+ attr_reader :owner_id
+ attr_reader :rules
+
+ # Firewall model methods
+ #
+ # def reboot!
+ # firewall_reboot(_id)
+ # end
+
+ # Parse the Firewall entity from XML body
+ #
+ # - xml_body -> Deltacloud API XML representation of the firewall
+ #
+ def self.parse(xml_body)
+ {
+ :owner_id => xml_body.text_at(:owner_id),
+ :rules => xml_body.xpath('rules/rule').map { |rule|
+ Rule.convert(self, rule)
+ }
+ }
+ end
+
+ class Rule < Deltacloud::Client::Base
+
+ attr_reader :allow_protocol
+ attr_reader :port_from
+ attr_reader :port_to
+ attr_reader :direction
+ attr_reader :sources
+
+ def self.parse(xml_body)
+ {
+ :allow_protocol => xml_body.text_at(:allow_protocol),
+ :port_from => xml_body.text_at(:port_from),
+ :port_to => xml_body.text_at(:port_to),
+ :direction => xml_body.text_at(:direction),
+ :sources => xml_body.xpath('sources/source').map { |s|
+ { :name => s['name'], :owner => s['owner'], :type => s['type'] }
+ }
+ }
+ end
+
+ end
+ end
+end
http://git-wip-us.apache.org/repos/asf/deltacloud/blob/b6d3365c/client/lib/deltacloud/client/models/hardware_profile.rb
----------------------------------------------------------------------
diff --git a/client/lib/deltacloud/client/models/hardware_profile.rb b/client/lib/deltacloud/client/models/hardware_profile.rb
new file mode 100644
index 0000000..83432b8
--- /dev/null
+++ b/client/lib/deltacloud/client/models/hardware_profile.rb
@@ -0,0 +1,68 @@
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements. See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership. The
+# ASF licenses this file to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance with the
+# License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+# License for the specific language governing permissions and limitations
+# under the License.
+
+module Deltacloud::Client
+ class HardwareProfile < Base
+
+ include Deltacloud::Client::Helpers
+
+ attr_reader :properties
+
+ def self.parse(hwp)
+ {
+ :properties => hwp.xpath('property').map { |p|
+ property_klass(p['kind']).parse(p)
+ }
+ }
+ end
+
+ def cpu
+ property :cpu
+ end
+
+ def memory
+ property :memory
+ end
+
+ def architecture
+ property :architecture
+ end
+
+ def storage
+ property :storage
+ end
+
+ def opaque?
+ @properties.empty? && @name == 'opaque'
+ end
+
+ private
+
+ def property(name)
+ @properties.find { |p| p.name == name.to_s }
+ end
+
+ def self.property_klass(kind)
+ case kind
+ when 'enum' then Property::Enum
+ when 'range' then Property::Range
+ when 'fixed' then Property::Fixed
+ when 'opaque' then Property::Property
+ else raise error.new("Unknown HWP property: #{kind}")
+ end
+ end
+
+ end
+end
http://git-wip-us.apache.org/repos/asf/deltacloud/blob/b6d3365c/client/lib/deltacloud/client/models/image.rb
----------------------------------------------------------------------
diff --git a/client/lib/deltacloud/client/models/image.rb b/client/lib/deltacloud/client/models/image.rb
new file mode 100644
index 0000000..8599f41
--- /dev/null
+++ b/client/lib/deltacloud/client/models/image.rb
@@ -0,0 +1,60 @@
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements. See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership. The
+# ASF licenses this file to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance with the
+# License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+# License for the specific language governing permissions and limitations
+# under the License.
+
+module Deltacloud::Client
+ class Image < Base
+
+ attr_reader :owner_id, :architecture, :state
+ attr_reader :creation_time, :root_type, :hardware_profile_ids
+
+ def hardware_profiles
+ @client.hardware_profiles.select { |hwp| @hardware_profile_ids.include?(hwp._id) }
+ end
+
+ def is_compatible?(hardware_profile_id)
+ hardware_profile_ids.include? hardware_profile_id
+ end
+
+ # Launch the image using +Instance+#+create_instance+ method.
+ # This method is more strict in checking +HardwareProfile+
+ # and in case you use incompatible HWP it raise an error.
+ #
+ # - create_instance_opts -> +create_instance+ options
+ #
+ def launch(create_instance_opts={})
+
+ if hwp_id = create_instance_opts[:hwp_id]
+ raise error(:incompatible_hardware_profile).new(
+ "Profile '#{hwp_id}' is not compatible with this image."
+ ) unless is_compatible?(hwp_id)
+ end
+
+ @client.create_instance(self._id, create_instance_opts)
+ end
+
+ def self.parse(xml_body)
+ {
+ :owner_id => xml_body.text_at(:owner_id),
+ :architecture => xml_body.text_at(:architecture),
+ :state => xml_body.text_at(:state),
+ :creation_time => xml_body.text_at('creation_time'),
+ :root_type => xml_body.text_at('root_type'),
+ :hardware_profile_ids => xml_body.xpath('hardware_profiles/hardware_profile').map { |h|
+ h['id']
+ }
+ }
+ end
+ end
+end
http://git-wip-us.apache.org/repos/asf/deltacloud/blob/b6d3365c/client/lib/deltacloud/client/models/instance.rb
----------------------------------------------------------------------
diff --git a/client/lib/deltacloud/client/models/instance.rb b/client/lib/deltacloud/client/models/instance.rb
new file mode 100644
index 0000000..01e1882
--- /dev/null
+++ b/client/lib/deltacloud/client/models/instance.rb
@@ -0,0 +1,122 @@
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements. See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership. The
+# ASF licenses this file to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance with the
+# License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+# License for the specific language governing permissions and limitations
+# under the License.
+
+module Deltacloud::Client
+ class Instance < Base
+
+ include Deltacloud::Client::Methods::Common
+ include Deltacloud::Client::Methods::Instance
+ include Deltacloud::Client::Methods::Realm
+ include Deltacloud::Client::Methods::HardwareProfile
+ include Deltacloud::Client::Methods::Image
+
+ attr_reader :realm_id
+ attr_reader :owner_id
+ attr_reader :image_id
+ attr_reader :hardware_profile_id
+
+ attr_accessor :state
+ attr_accessor :public_addresses
+ attr_accessor :private_addresses
+
+ # Destroy the current Instance
+ #
+ def destroy!
+ destroy_instance(_id)
+ end
+
+ # Execute +stop_instance+ method on current Instance
+ #
+ def stop!
+ stop_instance(_id) && reload!
+ end
+
+ # Execute +start_instance+ method on current Instance
+ #
+ def start!
+ start_instance(_id) && reload!
+ end
+
+ # Execute +reboot_instance+ method on current Instance
+ #
+ def reboot!
+ reboot_instance(_id) && reload!
+ end
+
+ # Retrieve the +Realm+ associated with Instance
+ #
+ def realm
+ super(realm_id)
+ end
+
+ def hardware_profile
+ super(hardware_profile_id)
+ end
+
+ def image
+ super(image_id)
+ end
+
+ def method_missing(name, *args)
+ return self.state.downcase == $1 if name.to_s =~ /^is_(\w+)\?$/
+ super
+ end
+
+ # Helper for is_STATE?
+ #
+ # is_running?
+ # is_stopped?
+ #
+ def method_missing(name, *args)
+ if name =~ /^is_(\w+)\?$/
+ return state == $1.upcase
+ end
+ super
+ end
+
+ class << self
+
+ def parse(xml_body)
+ {
+ :state => xml_body.text_at('state'),
+ :owner_id => xml_body.text_at('owner_id'),
+ :realm_id => xml_body.attr_at('realm', :id),
+ :image_id => xml_body.attr_at('image', :id),
+ :hardware_profile_id => xml_body.attr_at('hardware_profile', :id),
+ :public_addresses => InstanceAddress.convert(
+ xml_body.xpath('public_addresses/address')
+ ),
+ :private_addresses => InstanceAddress.convert(
+ xml_body.xpath('private_addresses/address')
+ )
+ }
+ end
+
+ end
+
+ # Attempt to reload :public_addresses, :private_addresses and :state
+ # of the instance, after the instance is modified by calling method
+ #
+ def reload!
+ new_instance = instance(_id)
+ update_instance_variables!(
+ :public_addresses => new_instance.public_addresses,
+ :private_addresses => new_instance.private_addresses,
+ :state => new_instance.state
+ )
+ end
+
+ end
+end
http://git-wip-us.apache.org/repos/asf/deltacloud/blob/b6d3365c/client/lib/deltacloud/client/models/instance_address.rb
----------------------------------------------------------------------
diff --git a/client/lib/deltacloud/client/models/instance_address.rb b/client/lib/deltacloud/client/models/instance_address.rb
new file mode 100644
index 0000000..f40c264
--- /dev/null
+++ b/client/lib/deltacloud/client/models/instance_address.rb
@@ -0,0 +1,35 @@
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements. See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership. The
+# ASF licenses this file to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance with the
+# License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+# License for the specific language governing permissions and limitations
+# under the License.
+
+module Deltacloud::Client
+ class InstanceAddress < OpenStruct
+
+ attr_reader :type
+ attr_reader :value
+
+ def to_s
+ @value
+ end
+
+ def self.convert(address_xml_block)
+ address_xml_block.map do |addr|
+ new(
+ :type => addr['type'],
+ :value => addr.text
+ )
+ end
+ end
+ end
+end
http://git-wip-us.apache.org/repos/asf/deltacloud/blob/b6d3365c/client/lib/deltacloud/client/models/instance_state.rb
----------------------------------------------------------------------
diff --git a/client/lib/deltacloud/client/models/instance_state.rb b/client/lib/deltacloud/client/models/instance_state.rb
new file mode 100644
index 0000000..79dddad
--- /dev/null
+++ b/client/lib/deltacloud/client/models/instance_state.rb
@@ -0,0 +1,52 @@
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements. See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership. The
+# ASF licenses this file to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance with the
+# License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+# License for the specific language governing permissions and limitations
+# under the License.
+
+module Deltacloud::Client
+
+ class InstanceState
+
+ def self.new_state(name)
+ State.new(name)
+ end
+
+ def self.new_transition(to, action)
+ Transition.new(to, action)
+ end
+
+ class State
+ attr_reader :name
+ attr_reader :transitions
+
+ def initialize(name)
+ @name, @transitions = name, []
+ end
+ end
+
+ class Transition
+ attr_reader :to
+ attr_reader :action
+
+ def initialize(to, action)
+ @to = to
+ @action = action
+ end
+
+ def auto?
+ @action.nil?
+ end
+ end
+
+ end
+end
http://git-wip-us.apache.org/repos/asf/deltacloud/blob/b6d3365c/client/lib/deltacloud/client/models/key.rb
----------------------------------------------------------------------
diff --git a/client/lib/deltacloud/client/models/key.rb b/client/lib/deltacloud/client/models/key.rb
new file mode 100644
index 0000000..da38ee5
--- /dev/null
+++ b/client/lib/deltacloud/client/models/key.rb
@@ -0,0 +1,52 @@
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements. See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership. The
+# ASF licenses this file to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance with the
+# License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+# License for the specific language governing permissions and limitations
+# under the License.
+
+module Deltacloud::Client
+ class Key < Base
+
+ # Inherited attributes: :_id, :name, :description
+
+ # Custom attributes:
+ #
+ attr_reader :state
+ attr_reader :username
+ attr_reader :password
+ attr_reader :public_key
+ attr_reader :fingerprint
+
+ # Key model methods
+ def pem
+ @public_key
+ end
+
+ def destroy!
+ destroy_key(_id)
+ end
+
+ # Parse the Key entity from XML body
+ #
+ # - xml_body -> Deltacloud API XML representation of the key
+ #
+ def self.parse(xml_body)
+ {
+ :state => xml_body.text_at(:state),
+ :username => xml_body.text_at(:username),
+ :password => xml_body.text_at(:password),
+ :fingerprint => xml_body.text_at(:fingerprint),
+ :public_key => xml_body.text_at(:pem)
+ }
+ end
+ end
+end
http://git-wip-us.apache.org/repos/asf/deltacloud/blob/b6d3365c/client/lib/deltacloud/client/models/realm.rb
----------------------------------------------------------------------
diff --git a/client/lib/deltacloud/client/models/realm.rb b/client/lib/deltacloud/client/models/realm.rb
new file mode 100644
index 0000000..d01739c
--- /dev/null
+++ b/client/lib/deltacloud/client/models/realm.rb
@@ -0,0 +1,29 @@
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements. See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership. The
+# ASF licenses this file to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance with the
+# License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+# License for the specific language governing permissions and limitations
+# under the License.
+
+module Deltacloud::Client
+ class Realm < Base
+
+ attr_reader :limit
+ attr_reader :state
+
+ def self.parse(xml_body)
+ {
+ :state => xml_body.text_at('state'),
+ :limit => xml_body.text_at('limit')
+ }
+ end
+ end
+end
http://git-wip-us.apache.org/repos/asf/deltacloud/blob/b6d3365c/client/lib/deltacloud/client/models/storage_snapshot.rb
----------------------------------------------------------------------
diff --git a/client/lib/deltacloud/client/models/storage_snapshot.rb b/client/lib/deltacloud/client/models/storage_snapshot.rb
new file mode 100644
index 0000000..f844e9f
--- /dev/null
+++ b/client/lib/deltacloud/client/models/storage_snapshot.rb
@@ -0,0 +1,54 @@
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements. See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership. The
+# ASF licenses this file to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance with the
+# License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+# License for the specific language governing permissions and limitations
+# under the License.
+
+module Deltacloud::Client
+ class StorageSnapshot < Base
+
+ include Deltacloud::Client::Methods::StorageSnapshot
+ include Deltacloud::Client::Methods::StorageVolume
+
+ # Inherited attributes: :_id, :name, :description
+
+ # Custom attributes:
+ #
+ attr_reader :created
+ attr_reader :storage_volume_id
+
+ # StorageSnapshot model methods
+ #
+ def storage_volume
+ super(storage_volume_id)
+ end
+
+ # Syntax sugar for destroying the current instance
+ # of StorageSnapshot
+ #
+ def destroy!
+ destroy_storage_snapshot(_id)
+ end
+
+
+ # Parse the StorageSnapshot entity from XML body
+ #
+ # - xml_body -> Deltacloud API XML representation of the storage_snapshot
+ #
+ def self.parse(xml_body)
+ {
+ :created => xml_body.text_at(:created),
+ :storage_volume_id => xml_body.attr_at('storage_volume', :id)
+ }
+ end
+ end
+end
http://git-wip-us.apache.org/repos/asf/deltacloud/blob/b6d3365c/client/lib/deltacloud/client/models/storage_volume.rb
----------------------------------------------------------------------
diff --git a/client/lib/deltacloud/client/models/storage_volume.rb b/client/lib/deltacloud/client/models/storage_volume.rb
new file mode 100644
index 0000000..26e1e80
--- /dev/null
+++ b/client/lib/deltacloud/client/models/storage_volume.rb
@@ -0,0 +1,96 @@
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements. See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership. The
+# ASF licenses this file to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance with the
+# License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+# License for the specific language governing permissions and limitations
+# under the License.
+
+module Deltacloud::Client
+ class StorageVolume < Base
+
+ include Deltacloud::Client::Methods::Common
+ include Deltacloud::Client::Methods::Instance
+ include Deltacloud::Client::Methods::StorageVolume
+ include Deltacloud::Client::Methods::StorageSnapshot
+
+ attr_accessor :created
+ attr_accessor :state
+ attr_accessor :capacity
+ attr_accessor :capacity_unit
+ attr_accessor :device
+ attr_accessor :realm_id
+ attr_accessor :kind
+ attr_accessor :mount
+
+ # Check if the current volume is attached to an Instance
+ #
+ def attached?
+ !mount[:instance].nil?
+ end
+
+ # Attach this volume to the instance
+ #
+ def attach(instance_id, device=nil)
+ attach_storage_volume(_id, instance_id, device) && reload!
+ end
+
+ # Detach this volume from the currently attached instance
+ #
+ def detach!
+ detach_storage_volume(_id) && reload!
+ end
+
+ # Destroy the storage volume
+ #
+ def destroy!
+ destroy_storage_volume(_id)
+ end
+
+ # Syntax sugar for creating a snapshot from volume
+ # See: +create_storage_snapshot+
+ #
+ def snapshot!(snapshot_opts={})
+ snap = create_storage_snapshot(_id, snapshot_opts)
+ reload! && snap
+ end
+
+ def instance
+ super(mount[:instance])
+ end
+
+ def self.parse(xml_body)
+ {
+ :created => xml_body.text_at('created'),
+ :state => xml_body.text_at('state'),
+ :device => xml_body.text_at('device'),
+ :capacity => xml_body.text_at('capacity'),
+ :capacity_unit => xml_body.attr_at('capacity', :unit),
+ :state => xml_body.text_at('state'),
+ :realm_id => xml_body.attr_at('realm', :id),
+ :kind => xml_body.text_at('kind'),
+ :mount => {
+ :instance => xml_body.attr_at('mount/instance', :id),
+ :device => xml_body.attr_at('mount/device', :name)
+ }
+ }
+ end
+
+ private
+
+ def reload!
+ new_volume = storage_volume(_id)
+ update_instance_variables!(
+ :state => new_volume.state,
+ :mount => new_volume.mount
+ )
+ end
+ end
+end
http://git-wip-us.apache.org/repos/asf/deltacloud/blob/b6d3365c/client/lib/deltacloud/core_ext.rb
----------------------------------------------------------------------
diff --git a/client/lib/deltacloud/core_ext.rb b/client/lib/deltacloud/core_ext.rb
new file mode 100644
index 0000000..e85cdba
--- /dev/null
+++ b/client/lib/deltacloud/core_ext.rb
@@ -0,0 +1,19 @@
+# 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.
+
+require_relative './core_ext/element'
+require_relative './core_ext/string'
+require_relative './core_ext/fixnum'
+require_relative './core_ext/string'
http://git-wip-us.apache.org/repos/asf/deltacloud/blob/b6d3365c/client/lib/deltacloud/core_ext/element.rb
----------------------------------------------------------------------
diff --git a/client/lib/deltacloud/core_ext/element.rb b/client/lib/deltacloud/core_ext/element.rb
new file mode 100644
index 0000000..43b3c61
--- /dev/null
+++ b/client/lib/deltacloud/core_ext/element.rb
@@ -0,0 +1,32 @@
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements. See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership. The
+# ASF licenses this file to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance with the
+# License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+# License for the specific language governing permissions and limitations
+# under the License.
+
+module Nokogiri
+ module XML
+
+ class Element
+
+ def text_at(xpath)
+ (val = self.at(xpath)) ? val.text.strip : nil
+ end
+
+ def attr_at(xpath, attr_name)
+ (val = self.at(xpath)) ? val[attr_name.to_s.strip] : nil
+ end
+
+ end
+
+ end
+end
http://git-wip-us.apache.org/repos/asf/deltacloud/blob/b6d3365c/client/lib/deltacloud/core_ext/fixnum.rb
----------------------------------------------------------------------
diff --git a/client/lib/deltacloud/core_ext/fixnum.rb b/client/lib/deltacloud/core_ext/fixnum.rb
new file mode 100644
index 0000000..5eb6e1b
--- /dev/null
+++ b/client/lib/deltacloud/core_ext/fixnum.rb
@@ -0,0 +1,30 @@
+# 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 Fixnum
+
+ def is_redirect?
+ (self.to_s =~ /^3(\d+)$/) ? true : false
+ end
+
+ def is_ok?
+ (self.to_s =~ /^2(\d+)$/) ? true : false
+ end
+
+ def is_no_content?
+ self == 204
+ end
+
+end
http://git-wip-us.apache.org/repos/asf/deltacloud/blob/b6d3365c/client/lib/deltacloud/core_ext/nil.rb
----------------------------------------------------------------------
diff --git a/client/lib/deltacloud/core_ext/nil.rb b/client/lib/deltacloud/core_ext/nil.rb
new file mode 100644
index 0000000..6612326
--- /dev/null
+++ b/client/lib/deltacloud/core_ext/nil.rb
@@ -0,0 +1,22 @@
+# 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 NilClass
+
+ def to_xml
+ raise Deltacloud::Client::InvalidXMLError.new('Server returned empty body')
+ end
+
+end
http://git-wip-us.apache.org/repos/asf/deltacloud/blob/b6d3365c/client/lib/deltacloud/core_ext/string.rb
----------------------------------------------------------------------
diff --git a/client/lib/deltacloud/core_ext/string.rb b/client/lib/deltacloud/core_ext/string.rb
new file mode 100644
index 0000000..e02aacf
--- /dev/null
+++ b/client/lib/deltacloud/core_ext/string.rb
@@ -0,0 +1,49 @@
+# 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 String
+
+ # Used to automagically convert any XML in String
+ # (like HTTP response body) to Nokogiri::XML object
+ #
+ # If Nokogiri::XML fails, InvalidXMLError is returned.
+ #
+ def to_xml
+ Nokogiri::XML(self)
+ end
+
+ unless method_defined? :camelize
+ def camelize
+ split('_').map { |w| w.capitalize }.join
+ end
+ end
+
+ unless method_defined? :pluralize
+ def pluralize
+ return self + 'es' if self =~ /ess$/
+ return self[0, self.length-1] + "ies" if self =~ /ty$/
+ return self if self =~ /data$/
+ self + "s"
+ end
+ end
+
+ unless method_defined? :singularize
+ def singularize
+ return self.gsub(/ies$/, 'y') if self =~ /ies$/
+ return self.gsub(/es$/, '') if self =~ /sses$/
+ self.gsub(/s$/, '')
+ end
+ end
+end
http://git-wip-us.apache.org/repos/asf/deltacloud/blob/b6d3365c/client/lib/deltacloud/error_response.rb
----------------------------------------------------------------------
diff --git a/client/lib/deltacloud/error_response.rb b/client/lib/deltacloud/error_response.rb
new file mode 100644
index 0000000..428b5ec
--- /dev/null
+++ b/client/lib/deltacloud/error_response.rb
@@ -0,0 +1,92 @@
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements. See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership. The
+# ASF licenses this file to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance with the
+# License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+# License for the specific language governing permissions and limitations
+# under the License.
+
+module Deltacloud
+ class ErrorResponse < Faraday::Response::Middleware
+
+ include Deltacloud::Client::Helpers::Model
+
+ # This method tries to parse the error XML from Deltacloud API
+ # In case there is no error returned in body, it will try to use
+ # the generic error reporting.
+ #
+ # - klass -> Deltacloud::Client::+Class+
+ # - message -> Exception message (overiden by error body message if
+ # present)
+ # - error -> Deltacloud XML error representation
+ #
+ def client_error(name, error, message=nil)
+ args = {
+ :message => message,
+ :status => error ? error[:status] : '500'
+ }
+ # If Deltacloud API send error in response body, parse it.
+ # Otherwise, when DC API send just plain text error, use
+ # it as exception message.
+ # If DC API does not send anything back, then fallback to
+ # the 'message' attribute.
+ #
+ if error and !error[:body].empty?
+ if xml_error?(error)
+ args.merge! parse_error(error[:body].to_xml.root)
+ else
+ args[:message] = error[:body]
+ end
+ end
+ error(name).new(args)
+ end
+
+ def call(env)
+ @app.call(env).on_complete do |e|
+ case e[:status].to_s
+ when '401'
+ raise client_error(:authentication_error, e, 'Invalid :api_user or :api_password')
+ when '405'
+ raise client_error(
+ :invalid_state, e, 'Resource state does not permit this action'
+ )
+ when '404'
+ raise client_error(:not_found, e, 'Object not found')
+ when /40\d/
+ raise client_error(:client_failure, e)
+ when '500'
+ raise client_error(:server_error, e)
+ when '502'
+ raise client_error(:backend_error, e)
+ when '501'
+ raise client_error(:not_supported, e)
+ end
+ end
+ end
+
+ private
+
+ def xml_error?(error)
+ error[:body].to_xml.root && error[:body].to_xml.root.name == 'error'
+ end
+
+ # Parse the Deltacloud API error body to Hash
+ #
+ def parse_error(body)
+ args = {}
+ args[:original_error] = body.to_s
+ args[:server_backtrace] = body.text_at('backtrace')
+ args[:message] ||= body.text_at('message')
+ args[:driver] = body.attr_at('backend', 'driver')
+ args[:provider] = body.attr_at('backend', 'provider')
+ args
+ end
+ end
+end
http://git-wip-us.apache.org/repos/asf/deltacloud/blob/b6d3365c/client/lib/documentation.rb
----------------------------------------------------------------------
diff --git a/client/lib/documentation.rb b/client/lib/documentation.rb
deleted file mode 100644
index 88f0861..0000000
--- a/client/lib/documentation.rb
+++ /dev/null
@@ -1,59 +0,0 @@
-# Licensed to the Apache Software Foundation (ASF) under one or more
-# contributor license agreements. See the NOTICE file distributed with
-# this work for additional information regarding copyright ownership. The
-# ASF licenses this file to you under the Apache License, Version 2.0 (the
-# "License"); you may not use this file except in compliance with the
-# License. You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-# License for the specific language governing permissions and limitations
-# under the License.
-
-module DeltaCloud
- class Documentation
-
- attr_reader :api, :description, :params, :collection_operations
- attr_reader :collection, :operation
-
- def initialize(api, opts={})
- @description, @api = opts[:description], api
- @params = parse_parameters(opts[:params]) if opts[:params]
- @collection_operations = opts[:operations] if opts[:operations]
- @collection = opts[:collection]
- @operation = opts[:operation]
- self
- end
-
- def operations
- @collection_operations.collect { |o| api.documentation(@collection, o) }
- end
-
- class OperationParameter
- attr_reader :name
- attr_reader :type
- attr_reader :required
- attr_reader :description
-
- def initialize(data)
- @name, @type, @required, @description = data[:name], data[:type], data[:required], data[:description]
- end
-
- def to_comment
- " # @param [#{@type}, #{@name}] #{@description}"
- end
-
- end
-
- private
-
- def parse_parameters(params)
- params.collect { |p| OperationParameter.new(p) }
- end
-
- end
-
-end
http://git-wip-us.apache.org/repos/asf/deltacloud/blob/b6d3365c/client/lib/errors.rb
----------------------------------------------------------------------
diff --git a/client/lib/errors.rb b/client/lib/errors.rb
deleted file mode 100644
index d0eff44..0000000
--- a/client/lib/errors.rb
+++ /dev/null
@@ -1,140 +0,0 @@
-# Licensed to the Apache Software Foundation (ASF) under one or more
-# contributor license agreements. See the NOTICE file distributed with
-# this work for additional information regarding copyright ownership. The
-# ASF licenses this file to you under the Apache License, Version 2.0 (the
-# "License"); you may not use this file except in compliance with the
-# License. You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-# License for the specific language governing permissions and limitations
-# under the License.
-
-module DeltaCloud
- module HTTPError
-
- class ClientError < StandardError
-
- attr_reader :params, :driver, :provider
-
- def initialize(code, message, opts={}, backtrace=nil)
- @params, @driver, @provider = opts[:params], opts[:driver], opts[:provider]
- if code.to_s =~ /^5(\d{2})/
- message += "\nParameters: #{@params.inspect}\n"
- message += "Driver: #{@driver}@#{@provider}"
- end
- super("#{code}\n\n#{self.class.superclass}: #{message}\n\n")
- # If server provided us the backtrace, then replace client backtrace
- # with the server one.
- set_backtrace(backtrace) unless backtrace.nil?
- end
- end
-
- class ServerError < ClientError; end
- class UknownError < ClientError; end
-
- # For sake of consistent documentation we need to create
- # this exceptions manually, instead of using some meta-programming.
- # Client will really appreciate this it will try to catch some
- # specific exception.
-
- # Client errors (4xx)
- class BadRequest < ClientError; end
- class Unauthorized < ClientError; end
- class Forbidden < ClientError; end
- class NotFound < ClientError; end
- class MethodNotAllowed < ClientError; end
- class NotAcceptable < ClientError; end
- class RequestTimeout < ClientError; end
- class Gone < ClientError; end
- class ExpectationFailed < ClientError; end
- class UnsupportedMediaType < ClientError; end
-
- # Server errors (5xx)
- class DeltacloudError < ServerError; end
- class ProviderError < ServerError; end
- class ProviderTimeout < ServerError; end
- class ServiceUnavailable < ServerError; end
- class NotImplemented < ServerError; end
-
- class ExceptionHandler
-
- attr_reader :http_status_code, :message, :trace
-
- def initialize(status_code, message=nil, opts={}, backtrace=nil, &block)
- @http_status_code = status_code.to_i
- @trace = backtrace
- @message = message || client_error_messages[status_code] || 'No error message received'
- @options = opts
- instance_eval(&block) if block_given?
- end
-
- def on(code, exception_class)
- if code == @http_status_code
- raise exception_class.new(code, @message, @options, @trace)
- end
- end
-
- private
-
- def client_error_messages
- {
- 400 => 'The request could not be understood by the server due to malformed syntax.',
- 401 => 'Authentication required for this request or invalid credentials provided.',
- 403 => 'Requested operation is not allowed for this resource.',
- 404 => 'Not Found',
- 405 => 'Method not allowed for this resource.',
- 406 => 'Requested media type is not supported by server.',
- 408 => 'The client did not produce a request within the time that the server was prepared to wait.',
- 410 => 'The resource is no longer available'
- }
- end
-
- end
-
- def self.parse_response_error(response)
-
- end
-
- def self.client_error(code)
- ExceptionHandler.new(code) do
- # Client errors
- on 400, BadRequest
- on 401, Unauthorized
- on 403, Forbidden
- on 404, NotFound
- on 405, MethodNotAllowed
- on 406, NotAcceptable
- on 408, RequestTimeout
- on 410, Gone
- end
- end
-
- def self.server_error(code, message, opts={}, backtrace=nil)
- ExceptionHandler.new(code, message, opts, backtrace) do
- # Client errors
- on 400, BadRequest
- on 401, Unauthorized
- on 403, Forbidden
- on 404, NotFound
- on 405, MethodNotAllowed
- on 406, NotAcceptable
- on 408, RequestTimeout
- on 410, Gone
- on 415, UnsupportedMediaType
- on 417, ExpectationFailed
- # Server errors
- on 500, DeltacloudError
- on 501, NotImplemented
- on 502, ProviderError
- on 503, ServiceUnavailable
- on 504, ProviderTimeout
- end
- raise Deltacloud::HTTPError::UnknownError.new(code, message, opts, backtrace)
- end
-
- end
-end
http://git-wip-us.apache.org/repos/asf/deltacloud/blob/b6d3365c/client/lib/hwp_properties.rb
----------------------------------------------------------------------
diff --git a/client/lib/hwp_properties.rb b/client/lib/hwp_properties.rb
deleted file mode 100644
index 686deaa..0000000
--- a/client/lib/hwp_properties.rb
+++ /dev/null
@@ -1,61 +0,0 @@
-# Licensed to the Apache Software Foundation (ASF) under one or more
-# contributor license agreements. See the NOTICE file distributed with
-# this work for additional information regarding copyright ownership. The
-# ASF licenses this file to you under the Apache License, Version 2.0 (the
-# "License"); you may not use this file except in compliance with the
-# License. You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-# License for the specific language governing permissions and limitations
-# under the License.
-
-module DeltaCloud
-
- module HWP
-
- class Property
- attr_reader :name, :unit, :value, :kind
-
- def initialize(xml, name)
- @name, @kind, @value, @unit = xml['name'], xml['kind'].to_sym, xml['value'], xml['unit']
- declare_ranges(xml)
- self
- end
-
- def present?
- ! @value.nil?
- end
-
- private
-
- def declare_ranges(xml)
- case xml['kind']
- when 'range' then
- self.class.instance_eval do
- attr_reader :range
- end
- @range = { :from => xml.xpath('range').first['first'], :to => xml.xpath('range').first['last'] }
- when 'enum' then
- self.class.instance_eval do
- attr_reader :options
- end
- @options = xml.xpath('enum/entry').collect { |e| e['value'] }
- end
- end
-
- end
-
- # FloatProperty is like Property but return value is Float instead of String.
- class FloatProperty < Property
- def initialize(xml, name)
- super(xml, name)
- @value = @value.to_f if @value
- end
- end
- end
-
-end