<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0">
<channel>
<title>marios log - Deltacloud</title>
<description>Posts categorized as 'Deltacloud'</description>
<link>http://mariosandreou.com</link>

<item>
<title>Deltacloud Networks API - a work in progress</title>
<description>&lt;p&gt;&lt;br /&gt;&lt;/p&gt;

&lt;div class=&quot;blog_title&quot;&gt;

Deltacloud Networks API - a work in progress

&lt;/div&gt;

&lt;p&gt;The Deltacloud API is missing the management of network resources. Many IaaS APIs still don’t have a notion of ‘network’ resource management whilst for others the Network API is relatively new. However, the Deltacoud project has received requests for the addition of network management related functionality and we’ve been discussing this on and off for the past year or so. Towards the end of 2012 we made a first attempt with some network models to fuel discussion and this blog post introduces the second iteration of the code for further comments.&lt;/p&gt;

&lt;p&gt;Each member of the ‘networks team’ took ‘ownership’ of a particular cloud provider to discuss how the initial model would ‘fit’ against that provider’s network API. This &lt;a href=&quot;http://etherpad.deltacloud.org/p/DeltacloudNetworks&quot;&gt;etherpad&lt;/a&gt; has some of our preliminary notes; Jan Provaznik looked at RHEV-M, Michal Fojtik looked at vSphere, Dies Koper looked at FGCP, Francesco Vollero looked at EC2 and I looked at OpenStack and CIMI. Tomas Sedovic acted as UN weapons inspector and sanity checker.&lt;/p&gt;

&lt;p&gt;Angus Thomas developed the use cases to guide development. For this first iteration I focused on the simplest use case: “Place an Instance into a particular Network”. Furthermore, I decided to focus on putting down some fully working code for EC2 and OpenStack to explore the feasibility of the Networks abstractions and guide further development for the other drivers.&lt;/p&gt;

&lt;hr /&gt;

&lt;p&gt;&lt;a id=&quot;index&quot;&gt; &lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;#network_models&quot;&gt;The Network Models&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;#driver_patterns&quot;&gt;Common Operations and Driver Patterns&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;#patches&quot;&gt;Patches&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;#issues&quot;&gt;Open Issues/Questions&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;hr /&gt;

&lt;h3 id=&quot;the-network-models&quot;&gt;The Network Models&lt;/h3&gt;
&lt;p&gt;&lt;a id=&quot;network_models&quot;&gt; &lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The original model had three entities - Network, Subnet and Port. The ‘Port’ entity proved to be problematic, because for some cloud providers this represented a ‘switch port’ whereas for others it represented a ‘network interface’. In Deltacloud we just want to model the connection of an Instance to a Network. So I decided to remove the Port model altogether and replace it with an ‘instance_bindings’ attribute on the Instance resource. This attempts to abstract away or reconcile the differences between the two ‘types’ of Port resource found in the various cloud provider APIs.&lt;/p&gt;

&lt;div class=&quot;img&quot;&gt;

&lt;img src=&quot;/images/Mar2013/Network_Bindings.jpg&quot; alt=&quot;network models proposal&quot; /&gt;

&lt;/div&gt;

&lt;p&gt;As I attempt to illustrate above, Network and Subnet remain as stand alone resources implying full CRUD operations for these where supported. The Network and Subnet models are pretty similar with respect to their attributes. One not so obvious distinction worth noting is that Network has an ‘address_blocks’ attribute whereas Subnet has an ‘address_block’ attribute. This is because for Openstack Quantum, the Subnets that are associated with a given Network do not have to utilise/occupy contiguous CIDR address blocks - that is it is perfectly legal for one subnet to use “10.0.0.0/8” and the other to use “192.168.0.0/16”. These two address blocks cannot be described using a single CIDR string. Hence, for Network, address_blocks is an array of CIDR address strings to accommodate for this difference.&lt;/p&gt;

&lt;p&gt;The Instance model is extended with the network_bindings attribute - an array - because an Instance can be associated with more than one Network (in some providers). Each network_binding contains a reference to the network and subnet as well as the IP address resulting from this association. Moving forward we can either extend this abstraction to contain more attributes or if necessary and feasible, extract it back into a stand-alone entity.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;#index&quot;&gt;back to top&lt;/a&gt;
&lt;br /&gt;&lt;/p&gt;
&lt;hr /&gt;

&lt;h3 id=&quot;common-operations-and-driver-patterns&quot;&gt;Common Operations and Driver Patterns&lt;/h3&gt;
&lt;p&gt;&lt;a id=&quot;driver_patterns&quot;&gt; &lt;/a&gt;&lt;/p&gt;

&lt;h4 id=&quot;networks&quot;&gt;Networks&lt;/h4&gt;

&lt;p&gt;For EC2 the Network resource is mapped to the EC2 VPC, whilst for Openstack it is mapped to the Quantum Network. In EC2, each Netowrk (VPC) has a ‘cidr’ attribute whereas for Openstack a Quantum network does not (cidr is present on the Quantum Subnet resource). For Openstack, each Network ‘knows’ which subnets belong to it, whereas for EC2 this information must be deduced by filtering the Subnets.&lt;/p&gt;

&lt;p&gt;Populating the list of Network resources in the case of EC2:&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;    def networks(credentials, opts={})
      ec2 = new_client(credentials)
      networks = []
      safely do
        subnets = subnets(credentials) #get all subnets once
        ec2.describe_vpcs.each do |vpc|
          vpc_subnets = subnets.inject([]){|res,cur| res&amp;lt;&amp;lt;cur if cur.network==vpc[:vpc_id]  ;res} #collect subnets for this.network
          networks &amp;lt;&amp;lt; convert_vpc(vpc, vpc_subnets)
        end
      end
      networks = filter_on(networks, :id, opts)
    end

    def convert_vpc(vpc, subnets=[])
      addr_blocks = subnets.inject([]){|res,cur| res &amp;lt;&amp;lt; cur.address_block  ; res}
      Network.new({ :id =&amp;gt; vpc[:vpc_id],
                    :name =&amp;gt; vpc[:vpc_id],
                    :state=&amp;gt; vpc[:state],
                    :subnets =&amp;gt; subnets.inject([]){|res,cur| res &amp;lt;&amp;lt; cur.id  ;res},
                    :address_blocks=&amp;gt; (addr_blocks.empty? ? [vpc[:cidr_block]] : addr_blocks)  })
    end
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;In other words, you retrieve the list of subnets, then for each VPC returned create a Deltacloud::Network resource using the VPC and the subset of the Subnets that are associated with that. One distinction/point of discussion here is that for the ‘addr_blocks’ attribute (cidr), when there are subnets in the given VPC, I only report the CIDR addresses of those subnets in address_blocks. The alternative is to simply use the :cidr_block of the entire VPC, but it made more sense to me to report only the addresses that an Instance can actually use at a given time.&lt;/p&gt;

&lt;p&gt;For Openstack however, each Network resource ‘knows’ which subnets belong to it. However, a Network does not ‘know’ about the CIDR address blocks in use on those subnets. Hence:&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;    def networks(credentials, opts={})
      os = new_client(credentials, &quot;network&quot;)
      networks = []
      safely do
        subnets = os.subnets
        os.networks.each do |net|
          addr_blocks = get_address_blocks_for(net.id, subnets)
          networks &amp;lt;&amp;lt; convert_network(net, addr_blocks)
        end
      end

    def get_address_blocks_for(network_id, subnets)
      return [] if subnets.empty?
      addr_blocks = []
      subnets.each do |sn|
        if sn.network_id == network_id
          addr_blocks &amp;lt;&amp;lt; sn.cidr
        end
      end
      addr_blocks
    end

    def convert_network(net, addr_blocks)
      Network.new({ :id =&amp;gt; net.id,
                    :name =&amp;gt; net.name,
                    :subnets =&amp;gt; net.subnets,
                    :state =&amp;gt; (net.admin_state_up ? &quot;UP&quot; : &quot;DOWN&quot;),
                    :address_blocks =&amp;gt; addr_blocks
      })
    end
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;In other words, you must retrieve the list of subnets to determine the CIDR address blocks for those subnets belonging to the given Network, before converting the result into a Deltacloud::Network.&lt;/p&gt;

&lt;p&gt;One final implication of the difference between EC2 VPC ‘knowing’ about CIDR and Openstack Network not knowing, is that creation of a Network in EC2 demands a cidr block. This difference will have to be somehow reconciled - either by making ‘cidr’ a compulsory parameter that is ignored for Openstack, or making it optional and choosing a default for EC2 when it isn’t supplied. We could also advertise the difference using a driver ‘feature’.&lt;/p&gt;

&lt;h4 id=&quot;subnets&quot;&gt;Subnets&lt;/h4&gt;

&lt;p&gt;Listing of subnets is thankfully more straightforward without any big differences between the two providers. Each returned subnet resource contains all the attributes required to build the Deltacloud::Subnet. In both cases, a subnet ‘knows’ about the Network it belongs to as well as the CIDR block it occupies/uses. For the create operation in both cases you must supply network_id and address_block parameters:&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;    def create_subnet(credentials, opts={})
      ec2 = new_client(credentials)
      safely do
        subnet = ec2.create_subnet(opts[:network_id], opts[:address_block])
        convert_subnet(subnet)
      end
    end

    def convert_subnet(subnet)
      Subnet.new({  :id =&amp;gt; subnet[:subnet_id],
                    :name =&amp;gt; subnet[:subnet_id],
                    :network =&amp;gt;subnet[:vpc_id],
                    :address_block =&amp;gt; subnet[:cidr_block],
                    :state =&amp;gt; subnet[:state] })
    end
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h4 id=&quot;instances&quot;&gt;Instances&lt;/h4&gt;

&lt;p&gt;The Instance operations impacted for this initial use case are creation, listing (retrieval) as well as deletion. When creating an Instance a client must provide the network_id and subnet_id parameters.&lt;/p&gt;

&lt;p&gt;For EC2, placing an Instance into a particular Network during Instance creation is very straightforward, because the EC2 compute and network APIs are exposed via the same interface (the EC2 API). You simply pass the ‘subnet_id’ parameter to the EC2 instance creation operation and extract the required ‘network_bindings’ from the response:&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;    def convert_instance(instance)
    ...
      if instance[:vpc_id]
        inst_params.merge!(:network_bindings =&amp;gt; [{:network=&amp;gt;instance[:vpc_id], :subnet=&amp;gt;instance[:subnet_id], :ip_address=&amp;gt; instance[:aws_private_ip_address]}])
      end
      Instance.new(inst_params)
    end
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;However, in the case of Openstack, the Quantum and Nova APIs do not have such a straightforward interface. To place an Instance into a particular Network, you must first create the Instance, then create a Quantum Port on the required Network and Subnet and then set the Port to refer to the created Instance:&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;    def create_instance(credentials, image_id, opts)
      (...)
      safely do
        server = os.create_server(params)
        net_bind = []
        if opts[:network_id] &amp;amp;&amp;amp; opts[:subnet_id] &amp;amp;&amp;amp; (quantum=have_quantum?(credentials)) #place instance into a network
          port = quantum.create_port(opts[:network_id], {&quot;fixed_ips&quot;=&amp;gt;[{&quot;subnet_id&quot;=&amp;gt;opts[:subnet_id]}], &quot;device_id&quot;=&amp;gt;server.id})
          net_bind = [{:network=&amp;gt;opts[:network], :subnet=&amp;gt;opts[:subnet_id], :ip_address=&amp;gt;port.fixed_ips.first[&quot;ip_address&quot;]}]
          server.refresh
        end
        result = convert_from_server(server, os.connection.authuser, get_attachments(server.id, os), net_bind)
      end
      result
    end
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;For the same reasons (interplay between compute and network APIs), creation of the network_bindings attribute when listing Instance(s) is much simpler for EC2 - you simply extract the required information from the EC2 response. For Openstack however you must deduce the network bindings by retrieving a list of Quantum Ports and discovering which of those refers to the given Instance:&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;    def instances(credentials, opts={})
      (...)
      insts = attachments = ports = []
      safely do
        if quantum = have_quantum?(credentials)
          ports = quantum.ports
        end
        (...)
          insts = os.list_servers_detail.collect do |s|
            net_bind = get_net_bindings_for(s[:id], ports)
            convert_from_server(s, os.connection.authuser,get_attachments(s[:id], os), net_bind)
          end
        end
      end
      insts = filter_on( insts, :state, opts )
      insts
    end

    def get_net_bindings_for(server_id, ports)
      return [] if ports.empty?
      net_bind = []
      ports.each do |port|
        if port.device_id == server_id
          port.fixed_ips.each do |fix_ip|
            net_bind &amp;lt;&amp;lt; {:network=&amp;gt; port.network_id, :subnet=&amp;gt;fix_ip[&quot;subnet_id&quot;] , :ip_address=&amp;gt;fix_ip[&quot;ip_address&quot;]}
          end
        end
      end
      net_bind
    end
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;A final note is that for the destroy_instance operation in the Openstack driver I added an extra ‘cleanup’ step to destroy any ports associated with the given Instance:&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;    def destroy_instance(credentials, instance_id)
      os = new_client(credentials)
      server = instance = nil
      safely do
        server = os.get_server(instance_id)
        server.delete!
        if quantum = have_quantum?(credentials) #destroy ports if any
          quantum.ports.each do |port|
            if port.device_id == server.id
              quantum.delete_port(port.id)
            end
          end
        end
      (...)
    end
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;&lt;a href=&quot;#index&quot;&gt;back top&lt;/a&gt;
&lt;br /&gt;&lt;/p&gt;
&lt;hr /&gt;

&lt;h3 id=&quot;patches&quot;&gt;Patches&lt;/h3&gt;
&lt;p&gt;&lt;a id=&quot;patches&quot;&gt; &lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The patches implementing this functionality have been sent to the &lt;a href=&quot;http://deltacloud.apache.org/contact.html&quot;&gt;dev@deltacloud.apache.org&lt;/a&gt; mailing list. They are also available from tracker as set &lt;a href=&quot;http://tracker.deltacloud.org/set/395&quot;&gt;395&lt;/a&gt;. One note is that in order to use the Openstack Quantum code you need to build from my fork of &lt;a href=&quot;https://github.com/marios/ruby-openstack&quot;&gt;ruby-openstack&lt;/a&gt;; I’ll be releasing a newer version of the gem (1.10) that includes this functionality in the next few days.&lt;/p&gt;

&lt;p&gt;Note that the current patches have incomplete ‘views’ - in particular the XML/JSON views are not fully implemented. I mainly used the HTML interface for testing and so the HTML UI should be used to review this set for now.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;#index&quot;&gt;back to top&lt;/a&gt;
&lt;br /&gt;&lt;/p&gt;
&lt;hr /&gt;

&lt;h3 id=&quot;open-issuesquestions&quot;&gt;Open Issues/Questions&lt;/h3&gt;
&lt;p&gt;&lt;a id=&quot;issues&quot;&gt; &lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;How do these revised models and operations fit for your IaaS API (RHEV-M, vSphere, FGCP, CIMI).&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;For example, for RHEV-M we know that there is no separation of Network and Subnet. Furthermore, creation of Networks is an admin-level task and so the create_network method likely wouldn’t be exposed for the RHEV-M driver. With respect to placing an Instance into a particular Network I understand the procedure is similar to Openstack Quantum: create an instance and then create a network interface on that instance which is associated with a particular Network. I will likely be targetting the RHEV-M driver next to explore these issues further.&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;How do we reconcile the fact that in some clouds, there is no ‘subnet’ entity (e.g. RHEV-M).&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;One implication is that for operations such as ‘create_instance’ where we may mandate that a user must supply both a network_id as well as a subnet_id. We &lt;em&gt;could&lt;/em&gt; only require the subnet_id (with the network_id being deduced from that). However, this brings us back to the ‘what if there is no subnet’? Do we then map given IaaS provider’s ‘Network’ resource to the Deltacloud ‘Subnet’ (and only expose ‘Subnet’ but not ‘Network’ at the top-level /api entry point?)?&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Do we want to merge the Network and Subnet models?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The logic here is that for all the operations regarding an Instance and indeed the network_binding association of Instance &amp;lt;–&amp;gt; Network+Subnet involves both network_id and subnet_id. In a given IaaS provider that supports both Network and Subnet models, you associate your Instances with a Subnet, not a Network. So if you have 2 networks each containing 3 subnets, in effect you have a choice of 6 subnets to which an Instance can be associated - each Network+Subnet combination becomes one target for the association. This idea needs further exploration/discussion, though it may solve the issue with those providers that don’t support a 2 tier Networking model (like RHEV-M, CIMI).&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;#index&quot;&gt;back to top&lt;/a&gt;&lt;/p&gt;
</description>
<published>2013-03-20 00:00:00 +0200</published>
<link>http://mariosandreou.com/deltacloud/cloud_api/2013/03/20/deltacloud-networks-api-rfc.html</link>
</item>

<item>
<title>Deltacloud CIMI API - CIMI Volumes, Machines and the MachineVolume collection</title>
<description>&lt;p&gt;&lt;br /&gt;&lt;/p&gt;

&lt;div class=&quot;blog_title&quot;&gt;

Deltacloud CIMI API - CIMI Volumes, Machines and the MachineVolume collection

&lt;/div&gt;

&lt;p&gt;In case you didnt know, Deltacloud implements the DMTF &lt;a href=&quot;http://dmtf.org/standards/cloud&quot;&gt;Cloud Infrastructure Management Interface&lt;/a&gt; API (CIMI). This means that you can ‘talk’ CIMI to any of the cloud providers &lt;a href=&quot;http://deltacloud.apache.org/drivers.html&quot;&gt;supported&lt;/a&gt; by Deltacloud, including Amazon EC2, Openstack, RHEV-M and vSphere. The documentation on the Deltacloud &lt;a href=&quot;http://deltacloud.apache.org/&quot;&gt;website&lt;/a&gt; is in dire need of update to include CIMI-specific information; this should be addressed soon but until then here are some notes showing how to work with CIMI Volumes and Machines in Deltacloud.&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Starting Deltacloud with the &lt;a href=&quot;#cimi_frontend&quot;&gt;CIMI frontend enabled&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;Listing &lt;a href=&quot;#machines&quot;&gt;Machines&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;Listing &lt;a href=&quot;#volumes&quot;&gt;Volumes&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;Working with the &lt;a href=&quot;#machine_volumes&quot;&gt;MachineVolume&lt;/a&gt; collection&lt;/li&gt;
&lt;/ul&gt;

&lt;hr /&gt;

&lt;h3 id=&quot;starting-deltacloud-with-the-cimi-frontend-enabled&quot;&gt;Starting Deltacloud with the CIMI frontend enabled&lt;/h3&gt;
&lt;p&gt;&lt;a id=&quot;cimi_frontend&quot;&gt; &lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The ‘-f’ flag is used to tell deltacloud which ‘frontend’ to enable. By default, only the ‘classic’ &lt;a href=&quot;http://deltacloud.apache.org/rest-api.html&quot;&gt;Deltacloud API&lt;/a&gt; is exposed. Right now you can enable ‘cimi’, ‘ec2’ or ‘deltacloud’; in fact you can expose all three with a single instance of the Deltacloud server:&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;deltacloudd -i mock -f cimi,ec2,deltacloud
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;The deltacloud API is exposed at /api, the CIMI API is exposed at /cimi and the EC2 API is exposed at /ec2. You can get the these locations by requesting the deltacloud URI in a web browser (by default the server is started at localhost:3001).&lt;/p&gt;

&lt;p&gt;So we can request the CIMI CloudEntryPoint:&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;[marios@name server]$ curl -H &quot;Accept: application/xml&quot;
            http://localhost:3001/cimi/cloudEntryPoint

&amp;lt;CloudEntryPoint xmlns=&quot;http://schemas.dmtf.org/cimi/1&quot;&amp;gt;
  &amp;lt;id&amp;gt;http://localhost:3001/cimi/cloudEntryPoint&amp;lt;/id&amp;gt;
  &amp;lt;name&amp;gt;mock&amp;lt;/name&amp;gt;
  &amp;lt;description&amp;gt;Cloud Entry Point for the Deltacloud mock driver&amp;lt;/description&amp;gt;
  &amp;lt;created&amp;gt;2012-11-28 12:48:40 +0200&amp;lt;/created&amp;gt;
  &amp;lt;baseURI&amp;gt;http://localhost:3001/cimi&amp;lt;/baseURI&amp;gt;
  &amp;lt;resourceMetadata href=&quot;http://localhost:3001/cimi/resource_metadata&quot; /&amp;gt;
  &amp;lt;machines href=&quot;http://localhost:3001/cimi/machines&quot; /&amp;gt;
  &amp;lt;machineConfigs href=&quot;http://localhost:3001/cimi/machine_configurations&quot; /&amp;gt;
  &amp;lt;machineImages href=&quot;http://localhost:3001/cimi/machine_images&quot; /&amp;gt;
  &amp;lt;credentials href=&quot;http://localhost:3001/cimi/credentials&quot; /&amp;gt;
  &amp;lt;volumes href=&quot;http://localhost:3001/cimi/volumes&quot; /&amp;gt;
  &amp;lt;volumeConfigs href=&quot;http://localhost:3001/cimi/volume_configurations&quot; /&amp;gt;
  &amp;lt;volumeImages href=&quot;http://localhost:3001/cimi/volume_images&quot; /&amp;gt;
  &amp;lt;networks href=&quot;http://localhost:3001/cimi/networks&quot; /&amp;gt;
  &amp;lt;networkTemplates href=&quot;http://localhost:3001/cimi/network_templates&quot; /&amp;gt;
  &amp;lt;networkConfigs href=&quot;http://localhost:3001/cimi/network_configurations&quot; /&amp;gt;
  &amp;lt;networkPorts href=&quot;http://localhost:3001/cimi/network_ports&quot; /&amp;gt;
  &amp;lt;networkPortTemplates href=&quot;http://localhost:3001/cimi/network_port_templates&quot; /&amp;gt;
  &amp;lt;networkPortConfigs href=&quot;http://localhost:3001/cimi/network_port_configurations&quot; /&amp;gt;
  &amp;lt;addresses href=&quot;http://localhost:3001/cimi/addresses&quot; /&amp;gt;
  &amp;lt;addressTemplates href=&quot;http://localhost:3001/cimi/address_templates&quot; /&amp;gt;
  &amp;lt;forwardingGroups href=&quot;http://localhost:3001/cimi/forwarding_groups&quot; /&amp;gt;
  &amp;lt;forwardingGroupTemplates href=&quot;http://localhost:3001/cimi/forwarding_group_templates&quot; /&amp;gt;
&amp;lt;/CloudEntryPoint&amp;gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;&lt;br /&gt;&lt;/p&gt;
&lt;hr /&gt;

&lt;h3 id=&quot;listing-machines&quot;&gt;Listing Machines&lt;/h3&gt;
&lt;p&gt;&lt;a id=&quot;machines&quot;&gt; &lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Following the link obtained from the cloudEntryPoint:&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;[marios@name server]$ curl --user &quot;mockuser:mockpassword&quot;
    -H &quot;Accept: application/xml&quot;
    http://localhost:3001/cimi/machines

&amp;lt;Collection xmlns=&quot;http://schemas.dmtf.org/cimi/1&quot;&amp;gt;
  &amp;lt;id&amp;gt;http://localhost:3001/cimi/machines&amp;lt;/id&amp;gt;
  &amp;lt;name&amp;gt;default&amp;lt;/name&amp;gt;
  &amp;lt;description&amp;gt;Machine Collection for the Mock driver&amp;lt;/description&amp;gt;
  &amp;lt;count&amp;gt;2&amp;lt;/count&amp;gt;
  &amp;lt;Machine&amp;gt;
    &amp;lt;id&amp;gt;http://localhost:3001/cimi/machines/inst0&amp;lt;/id&amp;gt;
    &amp;lt;name&amp;gt;inst0&amp;lt;/name&amp;gt;
    &amp;lt;description&amp;gt;Mock Instance With Profile Change&amp;lt;/description&amp;gt;
    &amp;lt;property name=&quot;machine_image&quot;&amp;gt;http://localhost:3001/cimi/machine_images/img1&amp;lt;/property&amp;gt;
    &amp;lt;property name=&quot;credential&quot;&amp;gt;http://localhost:3001/cimi/credentials&amp;lt;/property&amp;gt;
    &amp;lt;state&amp;gt;STARTED&amp;lt;/state&amp;gt;
    &amp;lt;cpu&amp;gt;1&amp;lt;/cpu&amp;gt;
    &amp;lt;memory&amp;gt;12582912&amp;lt;/memory&amp;gt;
    &amp;lt;disks href=&quot;http://localhost:3001/cimi/machines/inst0/disks&quot;&amp;gt;
      &amp;lt;id&amp;gt;http://localhost:3001/cimi/machines/inst0/disks&amp;lt;/id&amp;gt;
      &amp;lt;count&amp;gt;1&amp;lt;/count&amp;gt;
      &amp;lt;Disk&amp;gt;
        &amp;lt;id&amp;gt;http://localhost:3001/cimi/machines/inst0/disks/inst0_disk_891289600&amp;lt;/id&amp;gt;
        &amp;lt;name&amp;gt;inst0_disk_891289600&amp;lt;/name&amp;gt;
        &amp;lt;description&amp;gt;DiskCollection for Machine inst0&amp;lt;/description&amp;gt;
        &amp;lt;capacity&amp;gt;891289600&amp;lt;/capacity&amp;gt;
      &amp;lt;/Disk&amp;gt;
    &amp;lt;/disks&amp;gt;
    &amp;lt;volumes href=&quot;http://localhost:3001/cimi/machines/inst0/volumes&quot; /&amp;gt;
    &amp;lt;operation rel=&quot;http://schemas.dmtf.org/cimi/1/action/restart&quot;
          href=&quot;http://localhost:3001/cimi/machines/inst0/restart&quot; /&amp;gt;
    &amp;lt;operation rel=&quot;http://schemas.dmtf.org/cimi/1/action/stop&quot;
          href=&quot;http://localhost:3001/cimi/machines/inst0/stop&quot; /&amp;gt;
  &amp;lt;/Machine&amp;gt;

  (...)
&amp;lt;/Collection&amp;gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Again, following the URI we can obtain the MachineVolume collection for a specific Machine:&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;[marios@name server]$ curl --user &quot;mockuser:mockpassword&quot;
        -H &quot;Accept: application/xml&quot;
         http://localhost:3001/cimi/machines/inst1/volumes

&amp;lt;Collection xmlns=&quot;http://schemas.dmtf.org/cimi/1&quot;
      resourceURI=&quot;http://schemas.dmtf.org/cimi/1/MachineVolumeCollection&quot;&amp;gt;
  &amp;lt;id&amp;gt;http://localhost:3001/cimi/machines/inst1/volumes&amp;lt;/id&amp;gt;
  &amp;lt;count&amp;gt;1&amp;lt;/count&amp;gt;
  &amp;lt;MachineVolume&amp;gt;
    &amp;lt;id&amp;gt;http://localhost:3001/cimi/machines/inst1/volumes/vol3&amp;lt;/id&amp;gt;
    &amp;lt;name&amp;gt;vol3&amp;lt;/name&amp;gt;
    &amp;lt;description&amp;gt;MachineVolume vol3 for Machine inst1&amp;lt;/description&amp;gt;
    &amp;lt;created&amp;gt;2009-07-30T14:35:11Z&amp;lt;/created&amp;gt;
    &amp;lt;initialLocation&amp;gt;/dev/sda1&amp;lt;/initialLocation&amp;gt;
    &amp;lt;volume href=&quot;http://localhost:3001/cimi/volumes/vol3&quot; /&amp;gt;
    &amp;lt;operation rel=&quot;delete&quot;
      href=&quot;http://localhost:3001/cimi/machines/inst1/volumes/vol3&quot; /&amp;gt;
  &amp;lt;/MachineVolume&amp;gt;
  &amp;lt;operation rel=&quot;add&quot;
      href=&quot;http://localhost:3001/cimi/machines/inst1/volume_attach&quot; /&amp;gt;
&amp;lt;/Collection&amp;gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;&lt;a id=&quot;notice_add_uri&quot;&gt; &lt;/a&gt;
Notice the ‘addURI’ of the MachineVolume collection (/inst1/volume_attach) which we will use &lt;a href=&quot;#machine_volumes&quot;&gt;later&lt;/a&gt; to attach a new Volume to this instance. Also, notice the ‘deleteURI’ of the MachineVolume, which is used to detach the particular Volume from this Machine.&lt;/p&gt;

&lt;p&gt;&lt;br /&gt;&lt;/p&gt;
&lt;hr /&gt;

&lt;h3 id=&quot;listing-volumes&quot;&gt;Listing Volumes&lt;/h3&gt;
&lt;p&gt;&lt;a id=&quot;volumes&quot;&gt; &lt;/a&gt;&lt;/p&gt;

&lt;p&gt;You can retrieve the Volume collection in order to select the volume you would like to attach to a Machine:&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;curl --user &quot;mockuser:mockpassword&quot; -H &quot;Accept: application/xml&quot;
    http://localhost:3001/cimi/volumes

&amp;lt;Collection xmlns=&quot;http://schemas.dmtf.org/cimi/1&quot;
     resourceURI=&quot;http://schemas.dmtf.org/cimi/1/VolumeCollection&quot;&amp;gt;
  &amp;lt;id&amp;gt;http://localhost:3001/cimi/volumes&amp;lt;/id&amp;gt;
  &amp;lt;count&amp;gt;3&amp;lt;/count&amp;gt;
  &amp;lt;Volume&amp;gt;
    &amp;lt;id&amp;gt;http://localhost:3001/cimi/volumes/vol2&amp;lt;/id&amp;gt;
    &amp;lt;name&amp;gt;vol2&amp;lt;/name&amp;gt;
    &amp;lt;description&amp;gt;vol2&amp;lt;/description&amp;gt;
    &amp;lt;created&amp;gt;2009-07-30T14:35:11Z&amp;lt;/created&amp;gt;
    &amp;lt;state&amp;gt;AVAILABLE&amp;lt;/state&amp;gt;
    &amp;lt;type&amp;gt;http://schemas.dmtf.org/cimi/1/mapped&amp;lt;/type&amp;gt;
    &amp;lt;capacity&amp;gt;1048576&amp;lt;/capacity&amp;gt;
    &amp;lt;bootable&amp;gt;false&amp;lt;/bootable&amp;gt;
  &amp;lt;/Volume&amp;gt;
(...)
&amp;lt;/Collection&amp;gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;&lt;br /&gt;&lt;/p&gt;
&lt;hr /&gt;

&lt;h3 id=&quot;working-with-the-machinevolume-collection&quot;&gt;Working with the MachineVolume collection&lt;/h3&gt;
&lt;p&gt;&lt;a id=&quot;machine_volumes&quot;&gt; &lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Once you’ve selected a Volume, you can attach it to a Machine with:&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;curl -v --user &quot;mockuser:mockpassword&quot; -H &quot;Content-Type: application/xml&quot;
    -H &quot;Accept: application/xml&quot; -X PUT -d
    '&amp;lt;MachineVolume xmlns=&quot;http://schemas.dmtf.org/cimi/1/MachineVolume&quot;&amp;gt;
      &amp;lt;initialLocation&amp;gt; /dev/sdf &amp;lt;/initialLocation&amp;gt;
      &amp;lt;volume href=&quot;http://localhost:3001/cimi/volumes/vol2&quot;/&amp;gt;
    &amp;lt;/MachineVolume&amp;gt;'  http://localhost:3001/cimi/machines/inst1/volume_attach
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;The URI for the attach operation is obtained from the MachineVolume collection - the “&lt;a href=&quot;#notice_add_uri&quot;&gt;addURI&lt;/a&gt;”. In JSON format the same request looks like:&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;curl -v --user &quot;mockuser:mockpassword&quot; -H &quot;Content-Type: application/json&quot;
    -H &quot;Accept: application/xml&quot; -X PUT -d
    '{&quot;resourceURI&quot;:&quot;http://schemas.dmtf.org/cimi/1/MachineVolume&quot;,
    &quot;initialLocation&quot;: &quot;/dev/sdf&quot;,
    &quot;volume&quot;: {&quot;href&quot;:&quot;http://localhost:3001/cimi/volumes/vol2&quot;}}'
    http://localhost:3001/cimi/machines/inst1/volume_attach
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;The response in the newly created MachineVolume entity:&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&amp;lt; HTTP/1.1 201 Created
&amp;lt; Content-Type: application/xml
&amp;lt; CIMI-Specification-Version: 1.0.1
&amp;lt; Content-Length: 522
&amp;lt; ETag: 8379f00a2f8d73091758a62591874082
&amp;lt; Cache-Control: max-age=0, private, must-revalidate
&amp;lt; Date: Wed, 28 Nov 2012 11:12:49 GMT
&amp;lt; Connection: keep-alive
&amp;lt;
&amp;lt;MachineVolume xmlns=&quot;http://schemas.dmtf.org/cimi/1&quot;
    resourceURI=&quot;http://schemas.dmtf.org/cimi/1/MachineVolume&quot;&amp;gt;
  &amp;lt;id&amp;gt;http://localhost:3001/cimi/machines/inst1/volumes/vol2&amp;lt;/id&amp;gt;
  &amp;lt;name&amp;gt;vol2&amp;lt;/name&amp;gt;
  &amp;lt;description&amp;gt;MachineVolume vol2 for Machine inst1&amp;lt;/description&amp;gt;
  &amp;lt;created&amp;gt;2009-07-30T14:35:11Z&amp;lt;/created&amp;gt;
  &amp;lt;initialLocation&amp;gt;/dev/sdf&amp;lt;/initialLocation&amp;gt;
  &amp;lt;volume href=&quot;http://localhost:3001/cimi/volumes/vol2&quot; /&amp;gt;
  &amp;lt;operation rel=&quot;delete&quot;
    href=&quot;http://localhost:3001/cimi/machines/inst1/volumes/vol2&quot; /&amp;gt;
&amp;lt;/MachineVolume&amp;gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;To detach a Volume from a Machine we use the ‘delete’ URI given in the serialization of the MachineVolume:&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;curl -v --user &quot;mockuser:mockpassword&quot; -H &quot;Accept: application/xml&quot;
    -X DELETE http://localhost:3001/cimi/machines/inst1/volumes/vol2

&amp;lt; HTTP/1.1 200 OK
&amp;lt; Content-Type: application/xml
&amp;lt; CIMI-Specification-Version: 1.0.1
&amp;lt; Content-Length: 747
&amp;lt; ETag: 8e2d333a3747634c04942b7d219a8d59
&amp;lt; Cache-Control: max-age=0, private, must-revalidate
&amp;lt; Date: Wed, 28 Nov 2012 11:15:53 GMT
&amp;lt; Connection: keep-alive
&amp;lt;
&amp;lt;Collection xmlns=&quot;http://schemas.dmtf.org/cimi/1&quot;
    resourceURI=&quot;http://schemas.dmtf.org/cimi/1/MachineVolumeCollection&quot;&amp;gt;
  &amp;lt;id&amp;gt;http://localhost:3001/cimi/machines/inst1/volumes&amp;lt;/id&amp;gt;
  &amp;lt;count&amp;gt;1&amp;lt;/count&amp;gt;
  &amp;lt;MachineVolume&amp;gt;
    &amp;lt;id&amp;gt;http://localhost:3001/cimi/machines/inst1/volumes/vol3&amp;lt;/id&amp;gt;
    &amp;lt;name&amp;gt;vol3&amp;lt;/name&amp;gt;
    &amp;lt;description&amp;gt;MachineVolume vol3 for Machine inst1&amp;lt;/description&amp;gt;
    &amp;lt;created&amp;gt;2009-07-30T14:35:11Z&amp;lt;/created&amp;gt;
    &amp;lt;initialLocation&amp;gt;/dev/sda1&amp;lt;/initialLocation&amp;gt;
    &amp;lt;volume href=&quot;http://localhost:3001/cimi/volumes/vol3&quot; /&amp;gt;
    &amp;lt;operation rel=&quot;delete&quot; href=&quot;http://localhost:3001/cimi/machines/inst1/volumes/vol3&quot; /&amp;gt;
  &amp;lt;/MachineVolume&amp;gt;
  &amp;lt;operation rel=&quot;add&quot; href=&quot;http://localhost:3001/cimi/machines/inst1/volume_attach&quot; /&amp;gt;
&amp;lt;/Collection&amp;gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;The response shows the updated MachineVolume collection, which in this case still contains one MachineVolume.&lt;/p&gt;
</description>
<published>2012-11-28 00:00:00 +0200</published>
<link>http://mariosandreou.com/deltacloud/cloud_api/2012/11/28/cimi-machine-volumes-collection.html</link>
</item>

<item>
<title>Volumes Support in the Deltacloud Openstack Driver</title>
<description>&lt;p&gt;&lt;br /&gt;&lt;/p&gt;

&lt;div class=&quot;blog_title&quot;&gt;

Volumes Support in the Deltacloud Openstack Driver

&lt;/div&gt;

&lt;p&gt;Adding a new feature to a deltacloud driver means first checking that this feature is supported in the cloud provider client being used by that driver. For the Deltacloud Openstack driver, the client is the &lt;a href=&quot;https://rubygems.org/gems/openstack&quot;&gt;openstack rubygem&lt;/a&gt;. The following are some notes about how/why I implemented the Volumes support on both the &lt;a href=&quot;#rubygem&quot;&gt;rubygem side&lt;/a&gt; and the &lt;a href=&quot;#deltacloud&quot;&gt;deltacloud side&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Many thanks to HPCloud for granting me access to the private beta of their Block Storage service which I used to implement this functionality - fwiw I didn’t come across any issues with any of the API calls &lt;a href=&quot;http://api-docs.hpcloud.com/hpcloud-compute/1.0/content/ch_dev-api-block-storage.html&quot;&gt;as documented&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Note: I haven’t yet implemented the storage snapshot support - this will follow soon.&lt;/p&gt;

&lt;hr /&gt;

&lt;h3 id=&quot;volumes-support-in-the-openstack-rubygem&quot;&gt;Volumes support in the Openstack rubygem:&lt;/h3&gt;
&lt;p&gt;&lt;a id=&quot;rubygem&quot;&gt; &lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The main issue that I had to resolve here was quite simply… &lt;a href=&quot;https://lists.launchpad.net/openstack/msg16601.html&quot;&gt;which API&lt;/a&gt;. Basically there is the bona fide, stand-alone Volume service (aka Cinder?) which is exposed @ &lt;strong&gt;v1/{tenant_id}/volumes&lt;/strong&gt;. This volume service is returned in the &lt;a href=&quot;http://docs.openstack.org/api/openstack-identity-service/2.0/content/POST_authenticate_v2.0_tokens_Admin_API_Service_Developer_Operations-d1e1356.html&quot;&gt;serviceCatalog&lt;/a&gt; after authentication against the Keystone service, together with all the other deployed services (compute/nova, object-store/swift etc). Right now (mid November 2012) the full specification for the Volume API 1.0 is not yet available; at the Openstack &lt;a href=&quot;http://docs.openstack.org/api/api-specs.html&quot;&gt;API specs page&lt;/a&gt; the text reads: &lt;em&gt;“Check back for the specification for the Volume API 1.0, all calls are shown on api.openstack.org.”&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;There is however another Volume service which exists as an extension to the compute/nova service. This extension volume service is exposed @ &lt;strong&gt;v1/{tenant_id}/os-volumes&lt;/strong&gt;. Mercifully, the actual API calls are the same for both exposed endpoints, although the ‘bona-fide’ Volume service does not expose operations for attach/detach volume from server.&lt;/p&gt;

&lt;p&gt;To get around this I put &lt;a href=&quot;https://github.com/ruby-openstack/ruby-openstack/blob/master/lib/openstack/volume/connection.rb#L63&quot;&gt;some code&lt;/a&gt; in the definition of Openstack::Volume::Connection to determine which of the two is deployed and so set the endpoint accordingly.&lt;/p&gt;

&lt;p&gt;Another detail point is that since the attach/detach operations aren’t yet exposed for the ‘full’ Volume service but only for the extension, I added the attach/detach functions in the definition of &lt;a href=&quot;https://github.com/ruby-openstack/ruby-openstack/blob/master/lib/openstack/compute/connection.rb#L391&quot;&gt;Openstack::Compute&lt;/a&gt;. Partly because this is where the other extensions live but mainly since the attach/detach operations are called against a given server, that is, against the compute service and not the volume service, e.g.&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;POST v2/{tenant_id}/servers/{server_id}/os-volume_attachments
{
  'volumeAttachment': {
    'volumeId': volume_id,
    'device': device
  }
}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;The result of this is that in order to fully work with storage volumes and servers you need both a handle to the compute service and a handle to the volume service:&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;#get volume service, create a volume:
vs = OpenStack::Connection.create({:username =&amp;gt; &quot;username&quot;, :api_key=&amp;gt;&quot;pass&quot;,
  :auth_url =&amp;gt; &quot;https://region-a.geo-1.identity.hpcloudsvc.com:35357/v2.0/&quot;,
  :authtenant=&amp;gt;&quot;username-default-tenant&quot;, :service_type=&amp;gt;&quot;volume&quot;})

volume = vs.create_volume({:display_name=&amp;gt;&quot;marios volume&quot;, :size=&amp;gt;1,
                      :display_description=&amp;gt;&quot;some new volume bla&quot;})

#get the compute service and attach volume to a running server:
os = OpenStack::Connection.create(:username =&amp;gt; USERNAME, :api_key =&amp;gt; API_KEY,
      :authtenant =&amp;gt; TENANT, :auth_url =&amp;gt; API_URL, :service_type =&amp;gt; &quot;compute&quot;)
os.attach_volume(704289, 90805, &quot;/dev/sde&quot;) #svr_id, vol_id, device
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;The latest version of the Openstack rubygem, &lt;a href=&quot;https://rubygems.org/gems/openstack/versions/1.0.7&quot;&gt;1.0.7&lt;/a&gt; (at time of writing) contains the new Volume functionality.&lt;/p&gt;

&lt;hr /&gt;

&lt;h3 id=&quot;volumes-support-in-the-deltacloud-openstack-driver&quot;&gt;Volumes support in the Deltacloud Openstack driver:&lt;/h3&gt;
&lt;p&gt;&lt;a id=&quot;deltacloud&quot;&gt; &lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Storage Volumes support for Openstack on the Deltacloud side is pretty ‘standard’ - the &lt;a href=&quot;http://deltacloud.apache.org/storage-resources.html#volumes&quot;&gt;StorageVolumes&lt;/a&gt; collection already exists and is implemented for those cloud provider drivers that support it - &lt;a href=&quot;http://deltacloud.apache.org/drivers.html#drivers&quot;&gt;rhevm, fgcp, aruba, ec2&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;After defining the standard operations, the only new addition I made was defining two new &lt;a href=&quot;http://deltacloud.apache.org/api-entry-point.html#feature&quot;&gt;features&lt;/a&gt; - :volume_name and :volume_description. These signal to clients that the given driver will accept a ‘name’ and a ‘description’ parameter for the ‘create storage volume’ API call:&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;===&amp;gt; REQUEST:
curl --user &quot;uname+tenant_name:password&quot; -H &quot;Accept: application/xml&quot;
        http://localhost:3001/api

===&amp;gt; RESPONSE:
&amp;lt;api driver='openstack' provider='https://region-a.geo-1.identity.hpcloudsvc.com:35357/v2.0/'
        version='1.0.5'&amp;gt;

...

&amp;lt;link href='http://localhost:3001/api/storage_volumes' rel='storage_volumes'&amp;gt;
  &amp;lt;feature name='volume_name' rel='create'&amp;gt;
    &amp;lt;param name='name' /&amp;gt;
  &amp;lt;/feature&amp;gt;
  &amp;lt;feature name='volume_description' rel='create'&amp;gt;
    &amp;lt;param name='description' /&amp;gt;
  &amp;lt;/feature&amp;gt;
&amp;lt;/link&amp;gt;

...

&amp;lt;/api&amp;gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

</description>
<published>2012-11-19 00:00:00 +0200</published>
<link>http://mariosandreou.com/deltacloud/cloud_api/2012/11/19/deltacloud-openstack-driver-volumes.html</link>
</item>

<item>
<title>Segmenting Huge Blobs - Part II</title>
<description>&lt;p&gt;&lt;br /&gt;&lt;/p&gt;

&lt;div class=&quot;blog_title&quot;&gt;

Segmenting Huge Blobs - Part II

&lt;/div&gt;

&lt;p&gt;I implemented the ‘multipart’/’segmented blob’ upload as described in my &lt;a href=&quot;/deltacloud/cloud_API/2012/10/08/segmenting-huge-blobs.html&quot;&gt;previous post&lt;/a&gt;. This ‘segmented blob’ API is not yet an official part of the &lt;a href=&quot;http://deltacloud.apache.org/rest-api.html&quot;&gt;Deltacloud API&lt;/a&gt; as it still needs to be discussed/improved/prodded etc. Right now I’ve implemented this functionality for the Openstack and EC2 drivers (i.e. swift and S3 respectively) as a proof of concept - so azure and google storage are still pending.&lt;/p&gt;

&lt;p&gt;For the EC2 driver, some changes were required in the &lt;a href=&quot;https://github.com/appoxy/aws&quot;&gt;aws rubygem&lt;/a&gt; and I’m waiting for those to be &lt;a href=&quot;https://github.com/appoxy/aws/pull/117&quot;&gt;pulled in&lt;/a&gt; - otherwise this functionality (for S3 at least) is not yet available. You could build the gem with this code included from &lt;a href=&quot;https://github.com/marios/aws&quot;&gt;my fork&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;The notes here show the “segmented blob” upload in action using cURL examples:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;#initiate&quot;&gt;initiate&lt;/a&gt;,&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;#upload_segment&quot;&gt;upload segment&lt;/a&gt;,&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;#complete&quot;&gt;complete&lt;/a&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;hr /&gt;

&lt;h3 id=&quot;1-initiate&quot;&gt;1. Initiate:&lt;/h3&gt;
&lt;p&gt;&lt;a id=&quot;initiate&quot;&gt; &lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Need to set the ‘X-Deltacloud-BlobType’ header to ‘segmented’:&lt;/p&gt;

&lt;h4&gt;Request:&lt;/h4&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;[marios@name ~]$ curl -v --user &quot;KEY:PASS&quot; -X PUT -H &quot;X-Deltacloud-BlobType: segmented&quot;
http://localhost:3001/api/buckets/mariosbucket/segmentedblob

&amp;gt; PUT /api/buckets/mariosbucket/segmentedblob HTTP/1.1
&amp;gt; Authorization: Basic DdCeFNttJQJNkdfUVDhXdQUlXRM2KZVEE62N2lLc05MeitIMi9Lg==
&amp;gt; X-Deltacloud-BlobType: segmented
&amp;gt; User-Agent: curl/7.24.0
&amp;gt; Host: localhost:3001
&amp;gt; Accept: */*
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h4&gt;Response:&lt;/h4&gt;

&lt;p&gt;Note the ‘segmented blob ID’ returned in the X-Deltacloud-SegmentedBlob header. This will be needed to upload any segments and to complete the segmented blob upload.&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&amp;lt; HTTP/1.1 204 No Content
&amp;lt; X-Frame-Options: sameorigin
&amp;lt; X-XSS-Protection: 1; mode=block
&amp;lt; X-Deltacloud-SegmentedBlob: WL7dk8sqbtk3Rg6410mLF81T6fpof2Ha_0Upt
&amp;lt; Server: Apache-Deltacloud/1.0.4
&amp;lt; X-Deltacloud-Driver: ec2
&amp;lt; Date: Tue, 23 Oct 2012 13:16:26 GMT
&amp;lt; Connection: close
&amp;lt;
* Closing connection #0
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;hr /&gt;

&lt;h3 id=&quot;2-upload-segment&quot;&gt;2. Upload Segment:&lt;/h3&gt;
&lt;p&gt;&lt;a id=&quot;upload_segment&quot;&gt; &lt;/a&gt;&lt;/p&gt;

&lt;p&gt;As before clients must specify that this is a segmented blob operation with the X-DeltacloudBlobType header set to ‘segmented’. You need to specify the segmented blob ID obtained from step 1 with the X-Deltacloud-SegmentedBlob header, and also specify the order that this given segment should appear when the blob is reassembled using the X-Deltacloud-SegmentOrder header.&lt;/p&gt;

&lt;p&gt;One final note here: each cloud provider may specify a minimum for the size of a blob ‘segment’. For example, in AWS S3 this is &lt;a href=&quot;http://docs.amazonwebservices.com/AmazonS3/latest/dev/qfacts.html&quot;&gt;5 MB&lt;/a&gt; whereas Openstack doesn’t specify a minimum. The back-end provider specified minimums notwithstanding, for Deltacloud a blob segment must be &lt;em&gt;at least&lt;/em&gt; 112 Kbytes or you’ll get a “500 Internal Server Error”. The reason for this is because anything with a body less than 112 KBytes is stored by the &lt;a href=&quot;http://code.macournoyer.com/thin/&quot;&gt;Thin server&lt;/a&gt; in memory rather than being moved to a tempfile. Which means that it wouldn’t hit our Thin monkeypatch for &lt;a href=&quot;https://github.com/apache/deltacloud/blob/master/server/lib/deltacloud/helpers/blob_stream_helper.rb#L82mov&quot;&gt;streaming blobs&lt;/a&gt; - which is where the process of sending the blob data out to the providers begins.&lt;/p&gt;

&lt;h4&gt;Request:&lt;/h4&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;[marios@name ~]$ curl -v --user &quot;KEY:PASS&quot; -H &quot;X-Deltacloud-BlobType: segmented&quot;
 -H &quot;X-Deltacloud-SegmentedBlob: WL7dk8sqbtk3Rg6410mLF81T6fpof2Ha_0Upt&quot;
 -H &quot;X-Deltacloud-SegmentOrder: 2&quot; --upload-file &quot;/home/herp/derp/files/blob2.txt&quot;
 http://localhost:3001/api/buckets/mariosbucket/segmentedblob

&amp;gt; PUT /api/buckets/mariosbucket/segmentedblob HTTP/1.1
&amp;gt; Authorization: Basic DdCeFNttJQJNkdfUVDhXdQUlXRM2KZVEE62N2lLc05MeitIMi9Lg
&amp;gt; X-Deltacloud-BlobType: segmented
&amp;gt; X-Deltacloud-SegmentedBlob: WL7dk8sqbtk3Rg6410mLF81T6fpof2Ha_0Upt
&amp;gt; X-Deltacloud-SegmentOrder: 2
&amp;gt; User-Agent: curl/7.24.0
&amp;gt; Host: localhost:3001
&amp;gt; Accept: */*
&amp;gt; Content-Length: 7454095
&amp;gt; Expect: 100-continue
&amp;gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h4&gt;Response:&lt;/h4&gt;

&lt;p&gt;The response contains the blob segment ID in the ‘X-Deltacloud-BlobSegmentId’ header. This will be needed in order to complete the segmented blob upload in step 3.&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&amp;lt; HTTP/1.1 204 No Content
&amp;lt; X-Frame-Options: sameorigin
&amp;lt; X-XSS-Protection: 1; mode=block
&amp;lt; X-Deltacloud-BlobSegmentId: e7b94a1e959ca066026da3ec63aad321
&amp;lt; Server: Apache-Deltacloud/1.0.4
&amp;lt; X-Deltacloud-Driver: ec2
&amp;lt; Date: Tue, 23 Oct 2012 13:52:57 GMT
&amp;lt; Connection: close
&amp;lt;
* Closing connection #0
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;This step needs to be repeated for as many segments as you have divided your blob into, each time specifying a different value for the ‘X-Deltacloud-SegmentOrder’ header.&lt;/p&gt;

&lt;hr /&gt;

&lt;h3 id=&quot;3-complete-upload&quot;&gt;3. Complete Upload:&lt;/h3&gt;
&lt;p&gt;&lt;a id=&quot;complete&quot;&gt; &lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Finally you need to provide the segmented blob ‘manifest’ in the message body. This specifies the order and ID of each blob segment you have uploaded - e.g. when you uploaded blob segment with “X-Deltacloud-SegmentOrder: 1” and got “X-Deltacloud-BlobSegmentId: FOO” in the response, you would specify this as “1=FOO, 2=BAR… “ etc for each segment. As before, the “X-Deltacloud-BlobType” and “X-Deltacloud-SegmentedBlob” headers must be provided.&lt;/p&gt;

&lt;h4&gt;Request:&lt;/h4&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;curl -v --user &quot;KEY:PASS&quot; -X PUT -H &quot;X-Deltacloud-BlobType: segmented&quot;
-H &quot;X-Deltacloud-SegmentedBlob: WL7dk8sqbtk3Rg6410mLF81T6fpof2Ha_0Upt&quot;
-d &quot;1=78f871f6f01673a4aca05b1f8e26df08, 2=e7b94a1e959ca066026da3ec63aad321&quot;
http://localhost:3001/api/buckets/mariosbucket/segmentedblob?format=xml

&amp;gt; PUT /api/buckets/mariosbucket/segmentedblob?format=xml HTTP/1.1
&amp;gt; Authorization: Basic DdCeFNttJQJNkdfUVDhXdQUlXRM2KZVEE62N2lLc05MeitIMi9Lg
&amp;gt; X-Deltacloud-BlobType: segmented
&amp;gt; X-Deltacloud-SegmentedBlob: WL7dk8sqbtk3Rg6410mLF81T6fpof2Ha_0Upt
&amp;gt; User-Agent: curl/7.24.0
&amp;gt; Host: localhost:3001
&amp;gt; Accept: */*
&amp;gt; Content-Length: 70
&amp;gt; Content-Type: application/x-www-form-urlencoded
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h4&gt;Response:&lt;/h4&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&amp;lt; HTTP/1.1 200 OK
&amp;lt; Content-Type: application/xml
&amp;lt; Server: Apache-Deltacloud/1.0.4
&amp;lt; X-Deltacloud-Driver: ec2
&amp;lt; Content-Length: 430
&amp;lt; ETag: 59f1ee57a61a3ce2c2d5d8923ed77ee9
&amp;lt; Cache-Control: max-age=0, private, must-revalidate
&amp;lt; Date: Thu, 25 Oct 2012 10:13:45 GMT
&amp;lt; Connection: keep-alive
&amp;lt;
&amp;lt;?xml version='1.0' encoding='utf-8' ?&amp;gt;
&amp;lt;blob href='http://localhost:3001/api/buckets/mariosbucket/segmentedblob' id='segmentedblob'&amp;gt;
  &amp;lt;bucket&amp;gt;mariosbucket&amp;lt;/bucket&amp;gt;
  &amp;lt;content_length&amp;gt;&amp;lt;/content_length&amp;gt;
  &amp;lt;content_type&amp;gt;&amp;lt;/content_type&amp;gt;
  &amp;lt;last_modified&amp;gt;&amp;lt;/last_modified&amp;gt;
  &amp;lt;user_metadata&amp;gt;
  &amp;lt;/user_metadata&amp;gt;
  &amp;lt;content href='http://localhost:3001/api/buckets/mariosbucket/segmentedblob/content' rel='blob_content'&amp;gt;&amp;lt;/content&amp;gt;
&amp;lt;/blob&amp;gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

</description>
<published>2012-10-24 00:00:00 +0300</published>
<link>http://mariosandreou.com/deltacloud/cloud_api/2012/10/24/segmenting-huge-blobs-part-2.html</link>
</item>

<item>
<title>Segmenting Huge Blobs</title>
<description>&lt;p&gt;&lt;br /&gt;&lt;/p&gt;

&lt;div class=&quot;blog_title&quot;&gt;

Segmenting Huge Blobs

&lt;/div&gt;

&lt;p&gt;Apart from the compute infrastructure abstractions, &lt;a href=&quot;http://deltacloud.apache.org&quot;&gt;Deltacloud&lt;/a&gt; has support for &lt;a href=&quot;http://deltacloud.apache.org/blob-storage.html&quot;&gt;blob storage&lt;/a&gt; via the 'buckets' collection. Right now you can create a 'blob' via a HTTP PUT on the 'bucket' in which you want the blob to be created:&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;PUT /api/buckets/mybucket/12Jul2011blob?format=xml HTTP/1.1
Authorization: Basic AU1J3UB2121Afd1DdyQWxLaTYTmJMNF4zTXBoRGdhMDh2RUw5ZDAN9zVXVa==
Content-Type: text/plain
Content-Length: 128988
X-Deltacloud-Blobmeta-Version:2.1
X-Deltacloud-Blobmeta-Author:msa

... BLOB DATA ...
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;All the blob-storage cloud providers that deltacloud supports offer a way to do 'multipart' blob uploads - i.e. upload a number of segments or parts individually that will eventually make up a single blob on the provider. We recently &lt;a href=&quot;https://issues.apache.org/jira/browse/DTACLOUD-320&quot;&gt;had a request&lt;/a&gt; for adding this functionality for the Openstack driver. But since Deltacloud is all about cloud abstraction we need to find a 'common' way to implement this across all supported providers. This post is primarily an attempt to organise my notes and help to explore the different approaches that might be taken. I’m leaning towards the term ‘segments’ to describe the individual ‘bits’ or ‘parts’ of the huge blob - hence s/segments/parts/ in the text below:&lt;/p&gt;

&lt;hr /&gt;

&lt;h3 id=&quot;the-native-way&quot;&gt;The native way&lt;/h3&gt;

&lt;p&gt;The ways in which the various supported providers handle segmented blob uploads:&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;&lt;a href=&quot;#openstack_way&quot;&gt;Openstack Swift&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;#s3_way&quot;&gt;Amazon S3&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;#azure_way&quot;&gt;Microsoft Azure&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;#google_way&quot;&gt;Google Cloud Storage&lt;/a&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;hr /&gt;

&lt;h4 id=&quot;openstack-swift&quot;&gt;Openstack Swift&lt;/h4&gt;

&lt;p&gt;&lt;a id=&quot;openstack_way&quot;&gt; &lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Possibly the simplest approach - relevant &lt;a href=&quot;http://docs.openstack.org/api/openstack-object-storage/1.0/content/large-object-creation.html&quot;&gt;api docs&lt;/a&gt;:&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;strong&gt;Upload ‘segments’&lt;/strong&gt;. The rules are that their name must have a common ‘prefix’ and this prefix will determine the order in which the segments will be reassembled.&lt;/p&gt;

    &lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt; PUT /v1.1/12345/my_container/large1

 PUT /v1.1/12345/my_container/large2 ...
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;    &lt;/div&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;strong&gt;Finalise&lt;/strong&gt; - Once you’ve uploaded all the segments, upload a ‘manifest’ which informs the Openstack swift server that you’d like to create a single blob out of all the segments that are named with a particular prefix in a particular container (bucket). The manifest is specified with the ‘X-Object-Manifest’ HTTP header in the request:&lt;/p&gt;

    &lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt; PUT /v1.1/12345/my_container/large_object
 X-Object-Manifest: my_container/large
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;    &lt;/div&gt;
  &lt;/li&gt;
&lt;/ol&gt;

&lt;hr /&gt;

&lt;h4 id=&quot;amazon-s3&quot;&gt;Amazon S3&lt;/h4&gt;

&lt;p&gt;&lt;a id=&quot;s3_way&quot;&gt; &lt;/a&gt;&lt;/p&gt;

&lt;p&gt;AWS uses a 3-step process - relevant API docs &lt;a href=&quot;http://docs.amazonwebservices.com/AmazonS3/latest/API/mpUploadInitiate.html&quot;&gt;initiate&lt;/a&gt;, &lt;a href=&quot;http://docs.amazonwebservices.com/AmazonS3/latest/API/mpUploadUploadPart.html&quot;&gt;send segments&lt;/a&gt;, &lt;a href=&quot;http://docs.amazonwebservices.com/AmazonS3/latest/API/mpUploadComplete.html&quot;&gt;complete&lt;/a&gt;:&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;strong&gt;Initiate&lt;/strong&gt; the multipart upload - by using the ‘?uploads’ parameter in the POST URL. This will return a unique &lt;strong&gt;UploadId&lt;/strong&gt; which needs to be supplied when sending any of the segments that will make up the large blob:&lt;/p&gt;

    &lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt; POST /myobject?uploads

 &amp;lt;InitiateMultipartUploadResult xmlns=&quot;http://s3.amazonaws.com/doc/2006-03-01/&quot;&amp;gt;
   &amp;lt;Bucket&amp;gt;example-bucket&amp;lt;/Bucket&amp;gt;
   &amp;lt;Key&amp;gt;example-object&amp;lt;/Key&amp;gt;
   &amp;lt;UploadId&amp;gt;VXBsb2FkIElEIGZvciA2aWWpbmcncyBteS1tb3ZpZS5tMnRzIHVwbG9hZA&amp;lt;/UploadId&amp;gt;
 &amp;lt;/InitiateMultipartUploadResult&amp;gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;    &lt;/div&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;strong&gt;Upload segments&lt;/strong&gt; - specifying both the &lt;em&gt;partNumber&lt;/em&gt; and the &lt;em&gt;uploadId&lt;/em&gt; obtained from step 1 above. The response will include an ‘etag’ for the part, which clients must retain for use in completing the upload in step 3:&lt;/p&gt;

    &lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt; PUT /ObjectName?partNumber=PartNumber&amp;amp;uploadId=UploadId HTTP/1.1

 HTTP/1.1 200 OK
 ETag: &quot;b54357faf0632cce46e942fa68356b38&quot;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;    &lt;/div&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;strong&gt;Finalize the upload&lt;/strong&gt; - by performing a POST on the object itself and providing the uploadId in the POST URL. Here, the POST body must include a structure detailing the e-tag and part number for each of the uploaded segments:&lt;/p&gt;

    &lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt; POST /ObjectName?uploadId=foo
 &amp;lt;CompleteMultipartUpload&amp;gt;
   &amp;lt;Part&amp;gt;
     &amp;lt;PartNumber&amp;gt;PartNumber&amp;lt;/PartNumber&amp;gt;
     &amp;lt;ETag&amp;gt;ETag&amp;lt;/ETag&amp;gt;
   &amp;lt;/Part&amp;gt;
 ...
 &amp;lt;/CompleteMultipartUpload&amp;gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;    &lt;/div&gt;
  &lt;/li&gt;
&lt;/ol&gt;

&lt;hr /&gt;

&lt;h4 id=&quot;microsoft-azure&quot;&gt;Microsoft Azure&lt;/h4&gt;

&lt;p&gt;&lt;a id=&quot;azure_way&quot;&gt; &lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Azure has 2 types of blob - page and block. Deltacloud support for Azure blob storage applies to page blobs as do the notes here. The approach here is somewhere between that taken by Openstack and that taken by AWS S3 - it is a 2-step process. Relevant API docs - &lt;a href=&quot;http://msdn.microsoft.com/en-us/library/windowsazure/dd135726.aspx&quot;&gt;upload segments&lt;/a&gt; and &lt;a href=&quot;http://msdn.microsoft.com/en-us/library/windowsazure/dd179467.aspx&quot;&gt;upload segment list&lt;/a&gt; which is a manifest detailing all the parts and how they go together:&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;strong&gt;Upload segments&lt;/strong&gt; - using the ?comp=block URL parameter and specifying the blockId which is a unique Base64 string value. If the named blob doesn’t yet exist it is created after you upload the first segment.&lt;/p&gt;

    &lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt; PUT http://myaccount.blob.core.windows.net/mycontainer/myblob?comp=block&amp;amp;blockid=some_id
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;    &lt;/div&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;strong&gt;Upload manifest&lt;/strong&gt; - using the ?comp=blocklist URL parameter and specifying the segments in the request body. The ordering will determine the way the blob is created from the segments. Furthermore, you can also specify whether the given blockId is from the committed (blocks already committed as part of a previous put block list operation and which now form part of an existing blob) or the uncommitted block list (uploaded segments that haven’t yet been committed) - as explained &lt;a href=&quot;http://msdn.microsoft.com/en-us/library/windowsazure/dd179400.aspx&quot;&gt;here&lt;/a&gt;.&lt;/p&gt;

    &lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt; PUT http://myaccount.blob.core.windows.net/mycontainer/myblob?comp=blocklist HTTP/1.1
 Request Body:
 &amp;lt;?xml version=&quot;1.0&quot; encoding=&quot;utf-8&quot;?&amp;gt;
 &amp;lt;BlockList&amp;gt;
   &amp;lt;Uncommitted&amp;gt;ANAAAA==&amp;lt;/Uncommitted&amp;gt;
   &amp;lt;Committed&amp;gt;AQAAAA==&amp;lt;/Committed&amp;gt;
   &amp;lt;Uncommitted&amp;gt;AZAAAA==&amp;lt;/Uncommitted&amp;gt;
 &amp;lt;/BlockList&amp;gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;    &lt;/div&gt;
  &lt;/li&gt;
&lt;/ol&gt;

&lt;hr /&gt;

&lt;h4 id=&quot;google-cloud-storage&quot;&gt;Google Cloud Storage&lt;/h4&gt;

&lt;p&gt;&lt;a id=&quot;google_way&quot;&gt; &lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Google uses a 2-step process, involving initiating the upload to obtain the uploadId and then sending segments using that ID - relevant &lt;a href=&quot;https://developers.google.com/storage/docs/developer-guide#unknownresumables&quot;&gt;API docs&lt;/a&gt;&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;strong&gt;Initiate&lt;/strong&gt; - specifying the ‘x-goog-resumable’ HTTP header and getting the upload_id from the returned Location header:&lt;/p&gt;

    &lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt; POST /myFile.zip HTTP/1.1
 x-goog-resumable: start

 HTTP 201 Created
 Location: https://example.storage.googleapis.com/music.mp3?upload_id=tvA0ExBntDa...gAAEnB2Uowrot
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;    &lt;/div&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;strong&gt;Upload segments&lt;/strong&gt; - supplying the upload_id obtained from step 1 above as a URL parameter. The caveat here though is the size of each segment must be a multiple of 256 kilobytes (except the last). Each uploaded segment must include a ‘Content-Range’ header specifying the relational position of the segment in the blob:&lt;/p&gt;

    &lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt; PUT /myFile.zip?upload_id=tvA0ExBntDa...gAAEnB2Uowrot HTTP/1.1
 Content-Length: 524288
 Content-Range: bytes 0-524287/*
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;    &lt;/div&gt;
  &lt;/li&gt;
&lt;/ol&gt;

&lt;hr /&gt;

&lt;h3 id=&quot;the-deltacloud-way&quot;&gt;The Deltacloud way?&lt;/h3&gt;

&lt;h4 id=&quot;approach-1---lowest-common-denominator-aka-brute-force&quot;&gt;Approach 1 - lowest common denominator (aka ‘brute force’)&lt;/h4&gt;

&lt;p&gt;Here we’d use a 3-step approach - initiate, upload segments, upload manifest/finalize. The hope is that all the approaches above ‘fit’ into this model:&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;strong&gt;Initiate&lt;/strong&gt; - using a URL parameter or HTTP header to signify that this is the start of a ‘segmented’ blob:&lt;/p&gt;

    &lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt; PUT /api/buckets/my_bucket/blob_id?segmented
 X-Deltacloud-BlobType=segmented

 HTTP 200 OK
 X-Deltacloud-SegmentedBlob=ID
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;    &lt;/div&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;strong&gt;Upload Segments&lt;/strong&gt; - specifying the segment order via an integer/string and supplying the ID returned from step 1 above. Again, these can be supplied through the URI or via HTTP headers. This operation would respond with a segment ID in the response:&lt;/p&gt;

    &lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt; PUT /api/buckets/my_bucket/blob_id?segmented&amp;amp;segmented_blob=id&amp;amp;segment_order=1
 X-Deltacloud-BlobType=segmented
 X-Deltacloud-SegmentedBlob=id
 X-Deltacloud-SegmentOrder=1

 HTTP 202 Accepted
 X-Deltacloud-SegmentId=foo123
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;    &lt;/div&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;strong&gt;Finalize&lt;/strong&gt; - complete the upload by specifying the segment order and their ids:&lt;/p&gt;

    &lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt; PUT /api/buckets/my_bucket/blob_id?segmented&amp;amp;segmented_blob=id
 X-Deltacloud-BlobType=segmented
 X-Deltacloud-SegmentedBlob=id

 1=foo123, 2=bar345, 3=baz678 etc
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;    &lt;/div&gt;
  &lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The biggest disadvantage of this approach is that it would make the process more complex for certain providers - like Openstack for example. Of course the advantage is that you could use the same generic process for working with multiple blob storage providers. Perhaps approach 2 can help:&lt;/p&gt;

&lt;h4 id=&quot;approach-2---hybrid&quot;&gt;Approach 2 - hybrid&lt;/h4&gt;

&lt;p&gt;We could use the approach above (or some variant - I’m not convinced/happy with the names of the various parameters yet - segmented_blob, segment_order, segmentId etc) and in addition also allow for ‘shortcuts’. So for example, let’s say you need to work with Openstack and you’re already familiar with the Swift process for uploading segmented blobs. Right now, the only thing missing from the Deltacloud API is the ability to pass in the ‘manifest’ header. We could just allow this header to pass through (or perhaps rename and document it as a ‘Deltacloud-Blob-Manifest’ for example). Thus, if you need to use Deltacloud predominantly with Openstack, you’d use this method. And when you need to work across providers you’d fall back to the generic 3-step process.&lt;/p&gt;

&lt;p&gt;The cost of this of course is adding complexity - exceptions for particular cloud providers. I’m still undecided on the way forward. &lt;a href=&quot;http://deltacloud.apache.org/contact.html&quot;&gt;Comments and suggestions&lt;/a&gt; are very very welcome.&lt;/p&gt;
</description>
<published>2012-10-08 00:00:00 +0300</published>
<link>http://mariosandreou.com/deltacloud/cloud_api/2012/10/08/segmenting-huge-blobs.html</link>
</item>

<item>
<title>An updated ruby-openstack rubygem</title>
<description>&lt;p&gt;&lt;br /&gt;&lt;/p&gt;

&lt;div class=&quot;blog_title&quot;&gt;

An updated ruby-openstack rubygem

&lt;/div&gt;

&lt;p&gt;This post is so long overdue that I’ve forgotten much of the details involved. In short, there’s a new rubygem in town for talking to Openstack. Well - ‘new’ is definitely an exaggeration; the &lt;a href=&quot;http://github.com/ruby-openstack/ruby-openstack&quot;&gt;ruby-openstack&lt;/a&gt; gem is the merger between the &lt;a href=&quot;http://github.com/rackspace/ruby-openstack-compute&quot;&gt;ruby-openstack-compute&lt;/a&gt; and &lt;a href=&quot;http://github.com/rackspace/ruby-cloudfiles&quot;&gt;ruby-cloudfiles&lt;/a&gt; gems.&lt;/p&gt;

&lt;hr /&gt;

&lt;h3 id=&quot;now-why-would-you-want-to-do-that&quot;&gt;Now why would you want to do that?!&lt;/h3&gt;

&lt;p&gt;The &lt;a href=&quot;http://deltacloud.apache.org&quot;&gt;deltacloud&lt;/a&gt; openstack driver was recently (o_O) &lt;a href=&quot;/deltacloud/2012/02/23/deltacloud-openstack_v2API-driver.html&quot;&gt;updated&lt;/a&gt; to work with v2 of the OS (Nova) API. At that time I used the the &lt;a href=&quot;http://github.com/rackspace/ruby-openstack-compute&quot;&gt;ruby-openstack-compute&lt;/a&gt; gem to handle the calls out to the Openstack Nova service.
I got talking to &lt;a href=&quot;https://github.com/dprince&quot;&gt;Dan Prince&lt;/a&gt; who was the main contributer and maintainer of ruby-openstack-compute and we agreed it would be nice to have a single ruby gem to handle all Openstack services. Right now &lt;a href=&quot;http://github.com/ruby-openstack/ruby-openstack&quot;&gt;ruby-openstack&lt;/a&gt; does v2 authentication (Keystone) and handles Nova (Openstack Compute) as well as Swift (Openstack Object storage). The idea is that the codebase will be expanded to add all Openstack services.&lt;/p&gt;

&lt;hr /&gt;

&lt;h3 id=&quot;how-do-i-use-it&quot;&gt;How do I use it?&lt;/h3&gt;

&lt;p&gt;The &lt;a href=&quot;https://github.com/ruby-openstack/ruby-openstack/blob/master/README.rdoc&quot;&gt;README&lt;/a&gt; is pretty self-explanatory. Basically:&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;  sudo gem install openstack
  [sudo] password for herp:
  Successfully installed openstack-1.0.1

  [herp@name lib]$ irb -rubygems
  irb(main):001:0&amp;gt; require 'openstack'
  =&amp;gt; true

  irb(main):002:0&amp;gt; os = OpenStack::Connection.create({:username =&amp;gt; &quot;herp@derp.net&quot;, :api_key=&amp;gt;&quot;1234abcd&quot;, :auth_method=&amp;gt;&quot;password&quot;, :auth_url =&amp;gt; &quot;https://regionerer-g.go-bar.identity.dacloudfoo.herpy:13327/v2.0/&quot;, :authtenant_name =&amp;gt;&quot;herp@derp.net-default-tenant&quot;, :service_type=&amp;gt;&quot;compute&quot;})

  =&amp;gt; #&amp;lt;OpenStack::Compute::Connection:0xb7339070 @connection=#&amp;lt;OpenStack::Connection:0xb73392dc @service_scheme=&quot;https&quot;, @auth_host=&quot;regionerer-g.go-bar.identity.dacloudfoo.herpy&quot;, @http={}, @service_name=nil, @authuser=&quot;herp@derp.net&quot;, @proxy_port=nil, @auth_path=&quot;/v2.0/&quot;, @authtenant={:type=&amp;gt;&quot;tenantName&quot;, :value=&amp;gt;&quot;herp@derp.net-default-tenant&quot;}, @service_port=443, @authkey=&quot;1235abcd&quot;, @authok=true, @service_type=&quot;compute&quot;, @auth_method=&quot;password&quot;, @auth_scheme=&quot;https&quot;, @service_host=&quot;az-2.region-a.geo-1.dacloudfoo.herpy&quot;, @is_debug=nil, @proxy_host=nil, @service_path=&quot;/v1.1/482195756462871&quot;, @auth_port=35357, @auth_url=&quot;https://regionerer-g.go-bar.identity.dacloudfoo.herpy:13327/v2.0/&quot;, @region=nil, @authtoken=&quot;Auth_543254fdsasabd546543a3&quot;, @retry_auth=nil&amp;gt;&amp;gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;i.e., you use OpenStack::Connection.create to get a handle to an OpenStack service - setting the :service_type parameter to either “compute” or “object-store”.&lt;/p&gt;

&lt;hr /&gt;

&lt;h3 id=&quot;next&quot;&gt;Next&lt;/h3&gt;

&lt;p&gt;The latest update to the &lt;a href=&quot;http://rubygems.org/gems/openstack&quot;&gt;gem&lt;/a&gt; adds support for api_extensions. Right now the keypairs extension is implemented (list/create/delete and include in server instance params) with more to follow. The ‘team’ consists of many of the deltacloud core developers and we can certainly do with more help/bug-reports/docs/beer. So if you are using ruby and need to talk to Openstack - &lt;a href=&quot;https://github.com/ruby-openstack/ruby-openstack&quot;&gt;check it out&lt;/a&gt; and feel free to jump in!&lt;/p&gt;

</description>
<published>2012-08-03 00:00:00 +0300</published>
<link>http://mariosandreou.com/deltacloud/cloud_api/2012/08/03/updated-ruby-openstack-gem.html</link>
</item>

<item>
<title>CIMI Networking in Deltacloud - A Work in Progress</title>
<description>&lt;p&gt;&lt;br /&gt;&lt;/p&gt;

&lt;div class=&quot;blog_title&quot;&gt;

CIMI Networking in Deltacloud - A Work in Progress

&lt;/div&gt;

&lt;p&gt;I’m currently implementing the &lt;a href=&quot;/deltacloud/cloud_API/2012/03/05/openstack-cimi-networking.html&quot;&gt;CIMI Network entities&lt;/a&gt; for Deltacloud - this post introduces these and shows some examples of how a client can use Deltacloud to interact with a CIMI server, using the CIMI REST API.&lt;/p&gt;

&lt;p&gt;The DMTF Cloud Infrastructure Management Interface (&lt;strong&gt;CIMI&lt;/strong&gt;) is still a &lt;a href=&quot;http://dmtf.org/standards/cloud&quot;&gt;work-in-progress&lt;/a&gt;. As far as I am aware, Deltacloud is currently the only project offering an &lt;a href=&quot;/documents/fosdem2012.pdf&quot;&gt;implementation&lt;/a&gt; of the CIMI REST API. Since CIMI itself is still a work-in-progress, it naturally follows that its implementation in Deltacloud is also a work-in-progress. Thats all just a round about way of saying the following is very likely to change before CIMI v1.0 ships later this year (likely late Q2 or early Q3 2012) - though hopefully not too much.&lt;/p&gt;

&lt;p&gt;&lt;a id=&quot;top&quot;&gt; &lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;#implemented&quot;&gt;Implemented network entities and the Deltacloud mock driver&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;#operations&quot;&gt;Operation examples with cURL&lt;/a&gt;:
    &lt;ul&gt;
      &lt;li&gt;&lt;a href=&quot;#cep&quot;&gt;Getting the Cloud Entry Point&lt;/a&gt;&lt;/li&gt;
      &lt;li&gt;&lt;a href=&quot;#network_collection&quot;&gt;Getting the NetworkCollection&lt;/a&gt;&lt;/li&gt;
      &lt;li&gt;&lt;a href=&quot;#vsp&quot;&gt;Getting a specific VSP&lt;/a&gt;&lt;/li&gt;
      &lt;li&gt;&lt;a href=&quot;#create_network&quot;&gt;Create/Delete Networks&lt;/a&gt;&lt;/li&gt;
      &lt;li&gt;&lt;a href=&quot;#network_state&quot;&gt;Network state change&lt;/a&gt;&lt;/li&gt;
      &lt;li&gt;&lt;a href=&quot;#create_address&quot;&gt;Create/Delete Address&lt;/a&gt;&lt;/li&gt;
      &lt;li&gt;&lt;a href=&quot;#create_vsp&quot;&gt;Create/Delete VSP&lt;/a&gt;&lt;/li&gt;
      &lt;li&gt;&lt;a href=&quot;#vsp_state&quot;&gt;VSP state change&lt;/a&gt;&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;hr /&gt;

&lt;h3 id=&quot;implemented-network-entities-and-the-deltacloud-mock-driver&quot;&gt;Implemented network entities and the Deltacloud mock driver&lt;/h3&gt;
&lt;p&gt;&lt;a id=&quot;implemented&quot;&gt; &lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The currently implemented entities are:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Network,NetworkTemplate, NetworkConfiguration (+collections)&lt;/li&gt;
  &lt;li&gt;VSP, VSPTemplate, VSPConfiguration (+collections)&lt;/li&gt;
  &lt;li&gt;RoutingGroup, RoutingGroupTemplate (+collections)&lt;/li&gt;
  &lt;li&gt;Address, AddressTemplate (+collections)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The simple ‘GET’ and operation is implemented for all of these - however creation/deletion is currently only supported by Network, VSP and Address.&lt;/p&gt;

&lt;p&gt;Since there aren’t any cloud providers out there that offer a CIMI API - the Deltacloud server is actually using the ‘mock’ driver to simulate a CIMI cloud provider. The mock driver pretends to be a cloud in a way that is transparent to consumers (‘client’ in CIMI); that is a consumer interacts with the mock driver in the same way as they would interact with a ‘real’ CIMI cloud provider. This allows us to implement and test the CIMI API until the ‘real’ implementations arrive.&lt;/p&gt;

&lt;p&gt;For the mock driver, each ‘entity’ is actually a ‘json’ file on disk. json was an arbitrary choice - we could have used xml, or even yaml as is used for the Deltacloud API entities. To start the deltacloud server, exposing the CIMI API and talking to the ‘mock’ cloud provider:&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;deltacloudd --cimi -i mock
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;This will start the deltacloud server on localhost port 3001. There is more information about &lt;a href=&quot;http://deltacloud.apache.org/documentation.html&quot;&gt;getting Deltacloud&lt;/a&gt; and &lt;a href=&quot;http://deltacloud.apache.org/documentation.html#quick_start&quot;&gt;running it&lt;/a&gt; on the project website. Please [get in touch] (http://deltacloud.apache.org/contact.html) if you need any help getting started.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;#top&quot;&gt;index&lt;/a&gt;&lt;/p&gt;

&lt;hr /&gt;

&lt;h3 id=&quot;operation-examples-with-curl&quot;&gt;Operation examples with cURL&lt;/h3&gt;
&lt;p&gt;&lt;a id=&quot;operations&quot;&gt; &lt;/a&gt;&lt;/p&gt;

&lt;h4 id=&quot;getting-the-cloud-entry-point&quot;&gt;Getting the Cloud Entry Point&lt;/h4&gt;
&lt;p&gt;&lt;a id=&quot;cep&quot;&gt; &lt;/a&gt;&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;[marios@name ~]$ curl --user &quot;mockuser:mockpassword&quot;
                 http://localhost:3001/cimi/cloudEntryPoint?format=xml

&amp;lt;CloudEntryPoint xmlns=&quot;http://www.dmtf.org/cimi&quot;&amp;gt;
  &amp;lt;volumeImages href=&quot;http://localhost:3001/cimi/volume_images&quot; /&amp;gt;
  &amp;lt;entityMetadata&amp;gt;&amp;lt;/entityMetadata&amp;gt;
  &amp;lt;addressTemplates href=&quot;http://localhost:3001/cimi/address_templates&quot; /&amp;gt;
  &amp;lt;vspConfigurations href=&quot;http://localhost:3001/cimi/vsp_configurations&quot; /&amp;gt;
  &amp;lt;routingGroupTemplates href=&quot;http://localhost:3001/cimi/routing_group_templates&quot; /&amp;gt;
  &amp;lt;id&amp;gt;http://localhost:3001/cimi/cloudEntryPoint&amp;lt;/id&amp;gt;
  &amp;lt;networkTemplates href=&quot;http://localhost:3001/cimi/network_templates&quot; /&amp;gt;
  &amp;lt;machines href=&quot;http://localhost:3001/cimi/machines&quot; /&amp;gt;
  &amp;lt;addresses href=&quot;http://localhost:3001/cimi/addresses&quot; /&amp;gt;
  &amp;lt;networks href=&quot;http://localhost:3001/cimi/networks&quot; /&amp;gt;
  &amp;lt;volumeConfigurations href=&quot;http://localhost:3001/cimi/volume_configurations&quot; /&amp;gt;
  &amp;lt;machineAdmins href=&quot;http://localhost:3001/cimi/machine_admins&quot; /&amp;gt;
  &amp;lt;volumes href=&quot;http://localhost:3001/cimi/volumes&quot; /&amp;gt;
  &amp;lt;created&amp;gt;Fri Apr 06 16:59:18 +0300 2012&amp;lt;/created&amp;gt;
  &amp;lt;vsps href=&quot;http://localhost:3001/cimi/vsps&quot; /&amp;gt;
  &amp;lt;routingGroups href=&quot;http://localhost:3001/cimi/routing_groups&quot; /&amp;gt;
  &amp;lt;networkConfigurations href=&quot;http://localhost:3001/cimi/network_configurations&quot; /&amp;gt;
  &amp;lt;machineConfigurations href=&quot;http://localhost:3001/cimi/machine_configurations&quot; /&amp;gt;
  &amp;lt;machineImages href=&quot;http://localhost:3001/cimi/machine_images&quot; /&amp;gt;
  &amp;lt;name&amp;gt;mock&amp;lt;/name&amp;gt;
  &amp;lt;vspTemplates href=&quot;http://localhost:3001/cimi/vsp_templates&quot; /&amp;gt;
  &amp;lt;description&amp;gt;Cloud Entry Point for the Deltacloud mock driver&amp;lt;/description&amp;gt;
&amp;lt;/CloudEntryPoint&amp;gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;&lt;a href=&quot;#top&quot;&gt;index&lt;/a&gt;&lt;/p&gt;

&lt;hr /&gt;

&lt;h4 id=&quot;getting-the-networkcollection&quot;&gt;Getting the NetworkCollection&lt;/h4&gt;
&lt;p&gt;&lt;a id=&quot;network_collection&quot;&gt; &lt;/a&gt;&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;[marios@name ~]$ curl --user &quot;mockuser:mockpassword&quot;
                 http://localhost:3001/cimi/networks?format=xml

&amp;lt;NetworkCollection xmlns=&quot;http://www.dmtf.org/cimi&quot;&amp;gt;
  &amp;lt;id&amp;gt;http://localhost:3001/cimi/networks&amp;lt;/id&amp;gt;
  &amp;lt;created&amp;gt;Fri Apr 06 17:08:40 +0300 2012&amp;lt;/created&amp;gt;
  &amp;lt;network href=&quot;http://localhost:3001/cimi/networks/network1&quot; /&amp;gt;
  &amp;lt;network href=&quot;http://localhost:3001/cimi/networks/network2&quot; /&amp;gt;
  &amp;lt;name&amp;gt;default&amp;lt;/name&amp;gt;
  &amp;lt;description&amp;gt;Mock NetworkCollection&amp;lt;/description&amp;gt;
&amp;lt;/NetworkCollection&amp;gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;&lt;a href=&quot;#top&quot;&gt;index&lt;/a&gt;&lt;/p&gt;

&lt;hr /&gt;

&lt;h4 id=&quot;getting-a-specific-vsp&quot;&gt;Getting a specific VSP&lt;/h4&gt;
&lt;p&gt;&lt;a id=&quot;vsp&quot;&gt; &lt;/a&gt;&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;[marios@name ~]$ curl --user &quot;mockuser:mockpassword&quot;
            http://localhost:3001/cimi/vsps/vsp1?format=xml

&amp;lt;VSP xmlns=&quot;http://www.dmtf.org/cimi&quot;&amp;gt;
  &amp;lt;state&amp;gt;STARTED&amp;lt;/state&amp;gt;
  &amp;lt;maxTrafficLoss&amp;gt;100&amp;lt;/maxTrafficLoss&amp;gt;
  &amp;lt;id&amp;gt;http://localhost:3001/cimi/vsps/vsp1&amp;lt;/id&amp;gt;
  &amp;lt;maxTrafficJitter&amp;gt;100000&amp;lt;/maxTrafficJitter&amp;gt;
  &amp;lt;operation href=&quot;http://localhost:3001/cimi/vsps/vsp1&quot; rel=&quot;edit&quot; /&amp;gt;
  &amp;lt;operation href=&quot;http://localhost:3001/cimi/vsps/vsp1&quot; rel=&quot;delete&quot; /&amp;gt;
  &amp;lt;maxTrafficDelay&amp;gt;500000&amp;lt;/maxTrafficDelay&amp;gt;
  &amp;lt;created&amp;gt;Fri Mar 16 17:06:41 EET 2012&amp;lt;/created&amp;gt;
  &amp;lt;trafficPriority&amp;gt;1&amp;lt;/trafficPriority&amp;gt;
  &amp;lt;network href=&quot;http://localhost:3001/cimi/networks/network1&quot; /&amp;gt;
  &amp;lt;name&amp;gt;vsp1&amp;lt;/name&amp;gt;
  &amp;lt;bandwidthReservation&amp;gt;0.5&amp;lt;/bandwidthReservation&amp;gt;
  &amp;lt;description&amp;gt;a mock switchport&amp;lt;/description&amp;gt;
&amp;lt;/VSP&amp;gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;&lt;a href=&quot;#top&quot;&gt;index&lt;/a&gt;&lt;/p&gt;

&lt;hr /&gt;

&lt;h4 id=&quot;createdelete-networks&quot;&gt;Create/Delete Networks&lt;/h4&gt;
&lt;p&gt;&lt;a id=&quot;create_network&quot;&gt; &lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Deleting a Network is the easiest case so we deal with that first. To delete a Network called “my_test_network”:&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;curl -X DELETE --user &quot;mockuser:mockpassword&quot; http://localhost:3001/cimi/networks/my_test_network?format=xml
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;There are 3 ways to create a network, with respect to the NetworkTemplate used. A consumer can i) specify a NetworkTemplate by reference, ii) specify NetworkTemplate by value, but with a NetworkConfig by reference, iii) specify a NetworkTemplate by value, with a NetworkConfig by value:&lt;/p&gt;

&lt;h5 id=&quot;create-a-network-specifying-a-networktemplate-by-reference&quot;&gt;Create a Network, specifying a NetworkTemplate by reference:&lt;/h5&gt;

&lt;p&gt;XML:&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;curl -X POST --user &quot;mockuser:mockpassword&quot; -H &quot;Content-Type: application/CIMI-NetworkCreate+xml&quot;
-d '&amp;lt;NetworkCreate&amp;gt;
      &amp;lt;name&amp;gt; my_test_network &amp;lt;/name&amp;gt;
      &amp;lt;description&amp;gt; A test network &amp;lt;/description&amp;gt;
      &amp;lt;networkTemplate href=&quot;http://localhost:3001/cimi/network_templates/template1&quot;&amp;gt;
      &amp;lt;/networkTemplate&amp;gt;
    &amp;lt;/NetworkCreate&amp;gt;' http://localhost:3001/cimi/networks
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;JSON:&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;curl -X POST --user &quot;mockuser:mockpassword&quot; -H &quot;Content-Type: application/CIMI-NetworkCreate+json&quot;
-d '{ &quot;name&quot;: &quot;my_test_network&quot;, &quot;description&quot;: &quot;a foo network&quot;,
      &quot;networkTemplate&quot;: {
        &quot;href&quot;: &quot;http://localhost:3001/cimi/network_templates/template1&quot;}}'
http://localhost:3001/cimi/networks
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h5 id=&quot;create-a-network-with-networktemplate-by-value-and-networkconfiguration-by-reference&quot;&gt;Create a Network with NetworkTemplate by value and NetworkConfiguration by reference:&lt;/h5&gt;

&lt;p&gt;XML:&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;curl -X POST --user &quot;mockuser:mockpassword&quot; -H &quot;Content-Type: application/CIMI-NetworkCreate+xml&quot;
-d '&amp;lt;NetworkCreate&amp;gt;
      &amp;lt;name&amp;gt; my_test_network &amp;lt;/name&amp;gt;
      &amp;lt;description&amp;gt; A test network &amp;lt;/description&amp;gt;
      &amp;lt;networkTemplate&amp;gt;
        &amp;lt;networkConfig href=&quot;http://localhost:3001/cimi/network_configurations/network_config1&quot;&amp;gt;
        &amp;lt;/networkConfig&amp;gt;
        &amp;lt;routingGroup href=&quot;http://localhost:3001/cimi/routing_groups/group1&quot;&amp;gt;
        &amp;lt;/routingGroup&amp;gt;
      &amp;lt;/networkTemplate&amp;gt;
    &amp;lt;/NetworkCreate&amp;gt;' http://localhost:3001/cimi/networks
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;JSON:&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;curl -X POST --user &quot;mockuser:mockpassword&quot; -H &quot;Content-Type: application/CIMI-NetworkCreate+json&quot;
-d '{ &quot;name&quot;: &quot;my_test_network&quot;, &quot;description&quot;: &quot;a foo network&quot;,
      &quot;networkTemplate&quot;: {
        &quot;networkConfig&quot;:{
          &quot;href&quot;: &quot;http://localhost:3001/cimi/network_configurations/network_config1&quot;},
        &quot;routingGroup&quot;: {
          &quot;href&quot;: &quot;http://localhost:3001/cimi/routing_groups/group1&quot;}}}'
http://localhost:3001/cimi/networks?format=json
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h5 id=&quot;create-a-network-with-networktemplate-by-value-and-networkconfiguration-by-value&quot;&gt;Create a Network with NetworkTemplate by value and NetworkConfiguration by value:&lt;/h5&gt;

&lt;p&gt;XML:&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;curl -X POST --user &quot;mockuser:mockpassword&quot; -H &quot;Content-Type: application/CIMI-NetworkCreate+xml&quot;
-d '&amp;lt;NetworkCreate&amp;gt;
      &amp;lt;name&amp;gt; my_test_network &amp;lt;/name&amp;gt;
      &amp;lt;description&amp;gt; A test network &amp;lt;/description&amp;gt;
      &amp;lt;networkTemplate&amp;gt;
        &amp;lt;networkConfig&amp;gt;
          &amp;lt;access&amp;gt; public &amp;lt;/access&amp;gt;
          &amp;lt;bandwidthLimit&amp;gt; 2 &amp;lt;/bandwidthLimit&amp;gt;
          &amp;lt;trafficPriority&amp;gt; 1 &amp;lt;/trafficPriority&amp;gt;
          &amp;lt;maxTrafficDelay&amp;gt; 500000 &amp;lt;/maxTrafficDelay&amp;gt;
          &amp;lt;maxTrafficLoss&amp;gt; 100 &amp;lt;/maxTrafficLoss&amp;gt;
          &amp;lt;maxTrafficJitter&amp;gt; 100000 &amp;lt;/maxTrafficJitter&amp;gt;
        &amp;lt;/networkConfig&amp;gt;
        &amp;lt;routingGroup href=&quot;http://localhost:3001/cimi/routing_groups/group1&quot;&amp;gt;
        &amp;lt;/routingGroup&amp;gt;
      &amp;lt;/networkTemplate&amp;gt; &amp;lt;/NetworkCreate&amp;gt;'
http://localhost:3001/cimi/networks?format=xml
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;JSON:&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;curl -X POST --user &quot;mockuser:mockpassword&quot; -H &quot;Content-Type: application/CIMI-NetworkCreate+json&quot;
-d '{ &quot;name&quot;: &quot;my_test_network&quot;, &quot;description&quot;: &quot;a foo network&quot;,
    &quot;networkTemplate&quot;: {
      &quot;networkConfig&quot;: {
        &quot;access&quot;: &quot;public&quot;, &quot;bandwidthLimit&quot;: 2, &quot;trafficPriority&quot;: 1,
        &quot;maxTrafficDelay&quot;: 500000, &quot;maxTrafficLoss&quot;: 100, &quot;maxTrafficJitter&quot;: 100000},
      &quot;routingGroup&quot;: {
        &quot;href&quot;: &quot;http://localhost:3001/cimi/routing_groups/group1&quot; } } }'
http://localhost:3001/cimi/networks?format=json
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;In all cases, the consumer gets a representation of the newly created Network - either in json or xml format as specified by the “?format=” parameter of the url (http://localhost:3001/cimi/networks?format=xml):&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&amp;lt;Network xmlns=&quot;http://www.dmtf.org/cimi&quot;&amp;gt;
  &amp;lt;state&amp;gt;STARTED&amp;lt;/state&amp;gt;
  &amp;lt;maxTrafficLoss&amp;gt;100&amp;lt;/maxTrafficLoss&amp;gt;
  &amp;lt;id&amp;gt;http://localhost:3001/cimi/networks/my_test_network &amp;lt;/id&amp;gt;
  &amp;lt;routingGroup href=&quot;http://localhost:3001/cimi/routing_groups/group1&quot; /&amp;gt;
  &amp;lt;maxTrafficJitter&amp;gt;100000&amp;lt;/maxTrafficJitter&amp;gt;
  &amp;lt;operation href=&quot;http://localhost:3001/cimi/networks/my_test_network&quot; rel=&quot;edit&quot; /&amp;gt;
  &amp;lt;operation href=&quot;http://localhost:3001/cimi/networks/my_test_network&quot; rel=&quot;delete&quot; /&amp;gt;
  &amp;lt;maxTrafficDelay&amp;gt;500000&amp;lt;/maxTrafficDelay&amp;gt;
  &amp;lt;access&amp;gt;Public&amp;lt;/access&amp;gt;
  &amp;lt;created&amp;gt;Fri Apr 06 17:15:20 +0300 2012&amp;lt;/created&amp;gt;
  &amp;lt;trafficPriority&amp;gt;1&amp;lt;/trafficPriority&amp;gt;
  &amp;lt;name&amp;gt; my_test_network &amp;lt;/name&amp;gt;
  &amp;lt;description&amp;gt; A test network &amp;lt;/description&amp;gt;
&amp;lt;/Network&amp;gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;&lt;a href=&quot;#top&quot;&gt;index&lt;/a&gt;&lt;/p&gt;

&lt;hr /&gt;

&lt;h4 id=&quot;network-state-change&quot;&gt;Network state change&lt;/h4&gt;
&lt;p&gt;&lt;a id=&quot;network_state&quot;&gt; &lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Networks respond to start, stop and suspend actions. In CIMI, an ‘Action’ entity is used to effect state changes. Below I show only the ‘stop’ example as the others are very similar (using ‘start’ and ‘suspend’ actions to the Network start/suspend URL respectively).&lt;/p&gt;

&lt;p&gt;XML:&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;curl -iv -X POST --user &quot;mockuser:mockpassword&quot; -H &quot;Content-Type: application/xml&quot;
-d '&amp;lt;Action xmlns=&quot;http://www.dmtf.org/cimi&quot;&amp;gt;
      &amp;lt;action&amp;gt; http://www.dmtf.org/cimi/action/stop &amp;lt;/action&amp;gt;
    &amp;lt;/Action&amp;gt; ' http://localhost:3001/cimi/networks/my_test_network/stop?format=xml
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;JSON:&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;curl -iv -X POST --user &quot;mockuser:mockpassword&quot; -H &quot;Content-Type: application/json&quot;
-d '{&quot;entityURI&quot;: &quot;http://www.dmtf.org/cimi/Action&quot;,
    &quot;action&quot;:&quot;http://www.dmtf.org/cimi/action/stop&quot;}'
http://localhost:3001/cimi/networks/my_test_network/stop?format=json
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;&lt;a href=&quot;#top&quot;&gt;index&lt;/a&gt;&lt;/p&gt;

&lt;hr /&gt;

&lt;h4 id=&quot;createdelete-address&quot;&gt;Create/Delete Address&lt;/h4&gt;
&lt;p&gt;&lt;a id=&quot;create_address&quot;&gt; &lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Again, the delete operation is the simplest:&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;curl -X DELETE --user &quot;mockuser:mockpassword&quot;
http://localhost:3001/cimi/addresses/address1?format=xml
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;To create an Address, a consumer can either pass an AddressTemplate by value (inline) or by reference:&lt;/p&gt;

&lt;h5 id=&quot;create-address-using-addresstemplate-by-value&quot;&gt;Create Address using AddressTemplate by value&lt;/h5&gt;

&lt;p&gt;XML:&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;curl -X POST --user &quot;mockuser:mockpassword&quot; -H &quot;Content-Type: application/xml&quot;
-d '&amp;lt;AddressCreate&amp;gt;
      &amp;lt;name&amp;gt; an_address &amp;lt;/name&amp;gt;
      &amp;lt;description&amp;gt; an IP Address &amp;lt;/description&amp;gt;
      &amp;lt;addressTemplate&amp;gt;
        &amp;lt;ip&amp;gt; 192.168.10.100 &amp;lt;/ip&amp;gt;
        &amp;lt;hostname&amp;gt; marios.local &amp;lt;/hostname&amp;gt;
        &amp;lt;allocation&amp;gt; static &amp;lt;/allocation&amp;gt;
        &amp;lt;defaultGateway&amp;gt; 192.168.0.1 &amp;lt;/defaultGateway&amp;gt;
        &amp;lt;dns&amp;gt; 192.168.0.10 &amp;lt;/dns&amp;gt;
        &amp;lt;macAddress&amp;gt;&amp;lt;/macAddress&amp;gt;
        &amp;lt;protocol&amp;gt; IPv4 &amp;lt;/protocol&amp;gt;
        &amp;lt;mask&amp;gt; 255.255.0.0 &amp;lt;/mask&amp;gt;
        &amp;lt;network href=&quot;http://localhost:3001/cimi/networks/network1&quot;&amp;gt;
        &amp;lt;/network&amp;gt;
      &amp;lt;/addressTemplate&amp;gt;
    &amp;lt;/AddressCreate&amp;gt;' http://localhost:3001/cimi/addresses?format=xml
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;JSON:&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;curl -X POST --user &quot;mockuser:mockpassword&quot; -H &quot;Content-Type: application/json&quot;
-d '{ &quot;name&quot;: &quot;an_address&quot;, &quot;description&quot;: &quot;an IP Address&quot;,
&quot;addressTemplate&quot;: {
  &quot;ip&quot;: &quot;192.168.10.100&quot;, &quot;hostname&quot;: &quot;marios.local&quot;,
  &quot;allocation&quot;: &quot;static&quot;, &quot;defaultGateway&quot;: &quot;192.168.0.1&quot;,
  &quot;dns&quot;: &quot;192.168.0.10&quot;,&quot;macAddress&quot;: &quot;&quot;,
  &quot;protocol&quot;: &quot;IPv4&quot;, &quot;mask&quot;: &quot;255.255.0.0&quot;,
  &quot;network&quot;: {&quot;href&quot;: &quot;http://localhost:3001/cimi/networks/network1&quot; }}}'
http://localhost:3001/cimi/addresses?format=json
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h5 id=&quot;create-address-using-addresstemplate-by-reference&quot;&gt;Create Address using AddressTemplate by reference:&lt;/h5&gt;

&lt;p&gt;XML:&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;curl -X POST --user &quot;mockuser:mockpassword&quot; -H &quot;Content-Type: application/xml&quot;
-d '&amp;lt;AddressCreate&amp;gt;
      &amp;lt;name&amp;gt; an_address &amp;lt;/name&amp;gt;
      &amp;lt;description&amp;gt; an IP Address &amp;lt;/description&amp;gt;
      &amp;lt;addressTemplate href=&quot;http://localhost:3001/cimi/address_templates/addr_template1&quot;&amp;gt;
      &amp;lt;/addressTemplate&amp;gt;
    &amp;lt;/AddressCreate&amp;gt;' http://localhost:3001/cimi/addresses?format=xml
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;JSON:&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;curl -X POST --user &quot;mockuser:mockpassword&quot; -H &quot;Content-Type: application/json&quot;
-d '{ &quot;name&quot;: &quot;an_address&quot;, &quot;description&quot;: &quot;an IP Address&quot;,
&quot;addressTemplate&quot;: {
  &quot;href&quot;: &quot;http://localhost:3001/cimi/address_templates/addr_template1&quot;}}'
http://localhost:3001/cimi/addresses?format=json
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;&lt;a href=&quot;#top&quot;&gt;index&lt;/a&gt;&lt;/p&gt;

&lt;hr /&gt;

&lt;h4 id=&quot;createdelete-vsp&quot;&gt;Create/Delete VSP&lt;/h4&gt;
&lt;p&gt;&lt;a id=&quot;create_vsp&quot;&gt; &lt;/a&gt;&lt;/p&gt;

&lt;p&gt;To delete a VSP:&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;curl -X DELETE --user &quot;mockuser:mockpassword&quot; http://localhost:3001/cimi/vsps/vsp1
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;As with Networks, there are 3 ways to create a vsp: i) With a VSPTemplate by value, using a VSPConfiguration by value, ii) with a VSPTemplate by value and a VSPConfiguration by reference, iii) with a VSPTemplate by reference:&lt;/p&gt;

&lt;h5 id=&quot;vsptemplate-by-value-with-a-vspconfiguration-by-value&quot;&gt;VSPTemplate by value, with a VSPConfiguration by value&lt;/h5&gt;

&lt;p&gt;XML:&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;curl -X POST --user &quot;mockuser:mockpassword&quot; -H &quot;Content-Type: application/xml&quot;
-d '&amp;lt;VSPCreate&amp;gt;
      &amp;lt;name&amp;gt; my_vsp &amp;lt;/name&amp;gt; &amp;lt;description&amp;gt; a Virtual Switch Port &amp;lt;/description&amp;gt;
      &amp;lt;vspTemplate&amp;gt;
        &amp;lt;vspConfig&amp;gt;
          &amp;lt;bandwidthReservation&amp;gt; 0.5 &amp;lt;/bandwidthReservation&amp;gt;
          &amp;lt;trafficPriority&amp;gt; 1 &amp;lt;/trafficPriority&amp;gt;
          &amp;lt;maxTrafficDelay&amp;gt; 500000 &amp;lt;/maxTrafficDelay&amp;gt;
          &amp;lt;maxTrafficLoss&amp;gt; 100 &amp;lt;/maxTrafficLoss&amp;gt;
          &amp;lt;maxTrafficJitter&amp;gt; 100000 &amp;lt;/maxTrafficJitter&amp;gt;
        &amp;lt;/vspConfig&amp;gt;
        &amp;lt;network href=&quot;http://localhost:3001/cimi/networks/network1&quot;&amp;gt;
        &amp;lt;/network&amp;gt;
      &amp;lt;/vspTemplate&amp;gt;
    &amp;lt;/VSPCreate&amp;gt;' http://localhost:3001/cimi/vsps?format=xml
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;JSON:&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;curl -X POST --user &quot;mockuser:mockpassword&quot; -H &quot;Content-Type: application/json&quot;
-d '{ &quot;name&quot;: &quot;my_vsp&quot;, &quot;description&quot;: &quot;a Virtual Switch Port&quot;,
&quot;vspTemplate&quot;: {
  &quot;vspConfig&quot;: {
    &quot;bandwidthReservation&quot;: 0.5, &quot;trafficPriority&quot;: 1, &quot;maxTrafficDelay&quot;: 500000,
    &quot;maxTrafficLoss&quot;: 100, &quot;maxTrafficJitter&quot;: 100000},
  &quot;network&quot;: {&quot;href&quot;: &quot;http://localhost:3001/cimi/networks/network1&quot; }}}'
http://localhost:3001/cimi/vsps?format=json
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h5 id=&quot;vsptemplate-by-value-with-a-vspconfiguration-by-reference&quot;&gt;VSPTemplate by value, with a VSPConfiguration by reference&lt;/h5&gt;

&lt;p&gt;XML:&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;curl -X POST --user &quot;mockuser:mockpassword&quot; -H &quot;Content-Type: application/xml&quot;
-d '&amp;lt;VSPCreate&amp;gt;
      &amp;lt;name&amp;gt; my_vsp &amp;lt;/name&amp;gt;
      &amp;lt;description&amp;gt; a Virtual Switch Port &amp;lt;/description&amp;gt;
      &amp;lt;vspTemplate&amp;gt;
        &amp;lt;vspConfig href=&quot;http://localhost:3001/cimi/vsp_configurations/vspconfig1&quot;&amp;gt;
        &amp;lt;/vspConfig&amp;gt;
        &amp;lt;network href=&quot;http://localhost:3001/cimi/networks/network1&quot;&amp;gt; &amp;lt;/network&amp;gt;
      &amp;lt;/vspTemplate&amp;gt;
    &amp;lt;/VSPCreate&amp;gt;' http://localhost:3001/cimi/vsps?format=xml
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;JSON:&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;curl -X POST --user &quot;mockuser:mockpassword&quot; -H &quot;Content-Type: application/json&quot;
-d '{ &quot;name&quot;: &quot;my_vsp&quot;, &quot;description&quot;: &quot;a Virtual Switch Port&quot;,
&quot;vspTemplate&quot;: {
  &quot;vspConfig&quot;: {&quot;href&quot;: &quot;http://localhost:3001/cimi/vsp_configurations/vspconfig1&quot;},
  &quot;network&quot;: {&quot;href&quot;: &quot;http://localhost:3001/cimi/networks/network1&quot; }}}'
http://localhost:3001/cimi/vsps?format=json
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h5 id=&quot;vsptemplate-by-reference&quot;&gt;VSPTemplate by reference&lt;/h5&gt;

&lt;p&gt;XML:&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;curl -X POST --user &quot;mockuser:mockpassword&quot; -H &quot;Content-Type: application/xml&quot;
-d '&amp;lt;VSPCreate&amp;gt;
      &amp;lt;name&amp;gt; my_vsp &amp;lt;/name&amp;gt;
      &amp;lt;description&amp;gt; a Virtual Switch Port &amp;lt;/description&amp;gt;
      &amp;lt;vspTemplate href=&quot;http://localhost:3001/cimi/vsp_templates/template1&quot;&amp;gt;
      &amp;lt;/vspTemplate&amp;gt;
    &amp;lt;/VSPCreate&amp;gt;' http://localhost:3001/cimi/vsps?format=xml
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;JSON:&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;curl -X POST --user &quot;mockuser:mockpassword&quot; -H &quot;Content-Type: application/json&quot;
-d '{ &quot;name&quot;: &quot;my_vsp&quot;, &quot;description&quot;: &quot;a Virtual Switch Port&quot;,
&quot;vspTemplate&quot;: {
  &quot;href&quot;: &quot;http://localhost:3001/cimi/vsp_templates/template1&quot;}}'
http://localhost:3001/cimi/vsps?format=json
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;&lt;a href=&quot;#top&quot;&gt;index&lt;/a&gt;&lt;/p&gt;

&lt;hr /&gt;

&lt;h4 id=&quot;vsp-state-change&quot;&gt;VSP state change&lt;/h4&gt;
&lt;p&gt;&lt;a id=&quot;vsp_state&quot;&gt; &lt;/a&gt;&lt;/p&gt;

&lt;p&gt;VSPs respond to start and stop actions. In CIMI, an ‘Action’ entity is used to effect state changes. Below I show only the ‘stop’ example as start is very similar (using a ‘start’ action to the Network start URL instead).&lt;/p&gt;

&lt;p&gt;XML:&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;curl -iv -X POST --user &quot;mockuser:mockpassword&quot; -H &quot;Content-Type: application/xml&quot;
-d '&amp;lt;Action xmlns=&quot;http://www.dmtf.org/cimi&quot;&amp;gt;
      &amp;lt;action&amp;gt; http://www.dmtf.org/cimi/action/stop &amp;lt;/action&amp;gt;
    &amp;lt;/Action&amp;gt;' http://localhost:3001/cimi/vsps/my_vsp/stop?format=xml
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;JSON:&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;curl -iv -X POST --user &quot;mockuser:mockpassword&quot; -H &quot;Content-Type: application/json&quot;
-d '{&quot;entityURI&quot;: &quot;http://www.dmtf.org/cimi/Action&quot;,
      &quot;action&quot;:&quot;http://www.dmtf.org/cimi/action/stop&quot;}'
http://localhost:3001/cimi/vsps/my_vsp/stop?format=json
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;&lt;a href=&quot;#top&quot;&gt;index&lt;/a&gt;&lt;/p&gt;

&lt;hr /&gt;

</description>
<published>2012-04-06 00:00:00 +0300</published>
<link>http://mariosandreou.com/deltacloud/cloud_api/2012/04/06/cimi-networks-deltacloud.html</link>
</item>

<item>
<title>A look at networking in CIMI and Openstack</title>
<description>&lt;p&gt;&lt;br /&gt;&lt;/p&gt;

&lt;div class=&quot;blog_title&quot;&gt;

A look at networking in CIMI and Openstack

&lt;/div&gt;

&lt;p&gt;First off I should note that the following is not really a head-to-head comparison; that wouldn’t be fair. CIMI is still a &lt;a href=&quot;http://dmtf.org/standards/cloud&quot;&gt;work in progress&lt;/a&gt; - current version at time of writing is &lt;a href=&quot;http://dmtf.org/sites/default/files/standards/documents/DSP0263_1.0.0c.pdf&quot;&gt;1.0.0c&lt;/a&gt;. Similarly, the Openstack Networking API - &lt;a href=&quot;http://docs.openstack.org/incubation/openstack-network/developer/quantum-api-1.0/content/index.html&quot;&gt;Quantum&lt;/a&gt; - is still an &lt;a href=&quot;http://docs.openstack.org/incubation/&quot;&gt;incubator document&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Furthermore, whilst CIMI contains all the ‘bits’ of the Networking API required to (for example) put two Machines on the same subnet, Quantum is only 2/3 of the story. Quantum defines the network entities but relies on &lt;a href=&quot;http://www.openstack.org/projects/compute/&quot;&gt;Nova&lt;/a&gt; (i.e. the ‘compute’ bit of Openstack) to manage the Virtual Interfaces. The current &lt;a href=&quot;http://docs.openstack.org/api/openstack-compute/2/content/index.html&quot;&gt;Nova API&lt;/a&gt; doesn’t have any notion of Virtual Interfaces or how these are to be associated with servers.&lt;/p&gt;

&lt;p&gt;Thus the following is more of a summary of the networking entities and concepts in each API, followed by some high-level &lt;a href=&quot;#conclusions&quot;&gt;conclusions&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;br /&gt;&lt;/p&gt;
&lt;hr /&gt;

&lt;h3 id=&quot;openstack-quantum-networking-api&quot;&gt;Openstack Quantum networking API:&lt;/h3&gt;

&lt;p&gt;The main entities are:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;strong&gt;&lt;em&gt;Network&lt;/em&gt;&lt;/strong&gt; is a “virtual isolated layer-2 broadcast domain”. Networks have ports and ports have Attachments (aka ‘Virtual Interfaces’ VIFs). As I understand it, each Network represents a single logical (layer 2) network switch.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;strong&gt;&lt;em&gt;Port&lt;/em&gt;&lt;/strong&gt; is a “port on a logical network switch”. Each port can have an Attachment ‘plugged into’ it (attachments are VIFs - virtual interfaces).&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;strong&gt;&lt;em&gt;Attachment&lt;/em&gt;&lt;/strong&gt; is a VIF - Virtual Interface. These are owned/managed by an “external service” such as Nova. Once you have a VIF, you can use it as an attachment into a port of a network.&lt;/p&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;###Network&lt;/p&gt;

&lt;p&gt;Standard CRUD operations are offered for each of these entities. Each of the &lt;strong&gt;GET&lt;/strong&gt; ops come in two flavors: ‘standard’ and ‘detail’.&lt;/p&gt;

&lt;p&gt;For instance, a ‘standard’ GET on a specified Network (examples shamelessly copied from the &lt;a href=&quot;http://docs.openstack.org/incubation/openstack-network/developer/quantum-api-1.0/content/index.html&quot;&gt;Quantum API&lt;/a&gt;:&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;GET /tenants/foo/networks/8bec1293-16bd-4568-ba75-1f58bec0b4c3

&amp;lt;network id=&quot;8bec1293-16bd-4568-ba75-1f58bec0b4c3&quot; name=&quot;test_network&quot;/&amp;gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;and a ‘detail’ GET on the same Network:&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;GET /tenants/foo/networks/8bec1293-16bd-4568-ba75-1f58bec0b4c3/detail

&amp;lt;network id=&quot;8bec1293-16bd-4568-ba75-1f58bec0b4c3&quot; name=&quot;test_network&quot;&amp;gt;
  &amp;lt;ports&amp;gt;
    &amp;lt;port id=&quot;98017ddc-efc8-4c25-a915-774b2a633855&quot; status=&quot;DOWN&quot;/&amp;gt;
    &amp;lt;port id=&quot;b832be00-6553-4f69-af33-acd554e36d08&quot; status=&quot;ACTIVE&quot;&amp;gt;
      &amp;lt;attachment id=&quot;some_VIF_id&quot;/&amp;gt;
    &amp;lt;/port&amp;gt;
  &amp;lt;/ports&amp;gt;
&amp;lt;/network&amp;gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Networks are created by specifying only a ‘name’:&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;POST /tenants/foo/networks

&amp;lt;network name=&quot;test_create_network&quot;/&amp;gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;(the operations of &lt;a href=&quot;#openstack_create_port&quot;&gt;adding Port(s)&lt;/a&gt; is actually done on the ports collection).&lt;/p&gt;

&lt;p&gt;###Port&lt;/p&gt;

&lt;p&gt;As with Network, the GET operation has a ‘standard’ and a ‘detail’ version. Ports have an ‘id’ and a ‘state’ - which is either &lt;em&gt;DOWN&lt;/em&gt; or &lt;em&gt;ACTIVE&lt;/em&gt;.&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;GET /tenants/foo/networks/8bec1293-16bd-4568-ba75-1f58bec0b4c3/ports/98017ddc-efc8-4c25-a915-774b2a633855/detail

&amp;lt;port id=&quot;98017ddc-efc8-4c25-a915-774b2a633855&quot; state=&quot;DOWN&quot;&amp;gt;
  &amp;lt;attachment id=&quot;test_interface_identifier&quot;/&amp;gt;
&amp;lt;/port&amp;gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;&lt;a id=&quot;openstack_create_port&quot;&gt; &lt;/a&gt;
You create a port on a Network specified in the POST URL. A message body is &lt;strong&gt;optional&lt;/strong&gt; for this operation - you may specify the state in which the port will be created (defaults to ‘DOWN’):&lt;/p&gt;

&lt;p&gt;Request:&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;POST /tenants/foo/networks/8bec1293-16bd-4568-ba75-1f58bec0b4c3/ports

&amp;lt;port state=&quot;ACTIVE&quot;/&amp;gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Response:&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&amp;lt;port id=&quot;98017ddc-efc8-4c25-a915-774b2a633855&quot;/&amp;gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Ports are deleted with a DELETE operation specifying the port and network in the DELETE URL (failing if the port has Attachments):&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;DELETE /tenants/foo/networks/8bec1293-16bd-4568-ba75-1f58bec0b4c3/ports/98017ddc-efc8-4c25-a915-774b2a633855
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;###Attachment&lt;/p&gt;

&lt;p&gt;These are ‘owned’ by an external service “which uses Quantum, for instance the OpenStack Compute service, Nova”. Thus the Quantum API does not provide operations for creating or deleting Attachments; rather Quantum provides operations for plugging and unplugging an Attachment from a specified Network port.&lt;/p&gt;

&lt;p&gt;Attach operation (I assume that the ‘test_interface_identified’ is provided by the service which created the VIF/Attachment, like Nova):&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;PUT /tenants/foo/networks/8bec1293-16bd-4568-ba75-1f58bec0b4c3/ports/98017ddc-efc8-4c25-a915-774b2a633855/attachment/

&amp;lt;attachment id=&quot;test_interface_identifier&quot;/&amp;gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Detach operation:&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;DELETE /tenants/foo/networks/8bec1293-16bd-4568-ba75-1f58bec0b4c3/ports/98017ddc-efc8-4c25-a915-774b2a633855/attachment
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Show Attachment in a given port:&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;GET /tenants/foo/networks/8bec1293-16bd-4568-ba75-1f58bec0b4c3/ports/98017ddc-efc8-4c25-a915-774b2a633855/attachment

&amp;lt;attachment id=&quot;test_interface_identifier&quot;/&amp;gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;&lt;br /&gt;&lt;/p&gt;
&lt;hr /&gt;

&lt;p&gt;###CIMI networking API:&lt;/p&gt;

&lt;p&gt;The main entities are:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;strong&gt;&lt;em&gt;Network&lt;/em&gt;&lt;/strong&gt; - is an “Abstraction of a layer 2 broadcast domain”. As such a Network has a number of attributes which define the operational properties of the physical Network which is being abstracted. These include a &lt;em&gt;state&lt;/em&gt;, &lt;em&gt;bandwidthLimit&lt;/em&gt;, &lt;em&gt;trafficPriority&lt;/em&gt;, &lt;em&gt;access&lt;/em&gt; (public/privately routable network), &lt;em&gt;maxTrafficDelay&lt;/em&gt;, &lt;em&gt;maxTrafficLoss&lt;/em&gt;, &lt;em&gt;maxTrafficJitter&lt;/em&gt; and a &lt;em&gt;routingGroup&lt;/em&gt;. As with Openstack Quantum, my understanding is that a Network is essentially a logical layer-2 network switch.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;strong&gt;&lt;em&gt;VSP&lt;/em&gt;&lt;/strong&gt; - is a Virtual Switch Port and thus defines the “connection parameters of a network port.” The attributes of a VSP include the Network (i.e. layer-2 switch) to which the port is associated: &lt;em&gt;state&lt;/em&gt;, &lt;em&gt;network&lt;/em&gt;, &lt;em&gt;bandwidthReservation&lt;/em&gt;, &lt;em&gt;trafficPriority&lt;/em&gt;, &lt;em&gt;maxTrafficDelay&lt;/em&gt;, &lt;em&gt;maxTrafficLoss&lt;/em&gt;, &lt;em&gt;maxTrafficJitter&lt;/em&gt;&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;strong&gt;&lt;em&gt;RoutingGroup&lt;/em&gt;&lt;/strong&gt; - is simply a “collection of Networks that route to each other”.&lt;/p&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The link between the Network and the Compute entities of CIMI is through the CIMI &lt;strong&gt;&lt;em&gt;Machine&lt;/em&gt;&lt;/strong&gt; entity. A &lt;strong&gt;&lt;em&gt;Machine&lt;/em&gt;&lt;/strong&gt; has an array of &lt;strong&gt;&lt;em&gt;NetworkInterfaces&lt;/em&gt;&lt;/strong&gt; - each NetworkInterface includes a reference to a &lt;strong&gt;&lt;em&gt;VSP&lt;/em&gt;&lt;/strong&gt; (and other attributes such as MAC address, protocol, IP address etc).&lt;/p&gt;

&lt;p&gt;Before looking at some of the API operations for the network entities, it is necessary to provide a little background on the creation pattern common to all CIMI entities:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;
    &lt;p&gt;Each entity has an equivalent &lt;strong&gt;collection&lt;/strong&gt; which is the grouping of all instances of the given entity. So &lt;strong&gt;&lt;em&gt;Network&lt;/em&gt;&lt;/strong&gt; also has a &lt;strong&gt;&lt;em&gt;NetworkCollection&lt;/em&gt;&lt;/strong&gt;. Besides the grouping, the &lt;strong&gt;collection&lt;/strong&gt; also provides the URI to which a consumer (a ‘client’ in CIMI parlance) should POST for creation of the given entity.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;Each entity has a &lt;strong&gt;configuration&lt;/strong&gt; which is the collection of values used in the instantiation of the given entity. Thus, a &lt;strong&gt;&lt;em&gt;NetworkConfiguration&lt;/em&gt;&lt;/strong&gt; is used to define the parameters of a to-be-created &lt;strong&gt;&lt;em&gt;Network&lt;/em&gt;&lt;/strong&gt;.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;The actual creation of a given entity is achieved through an entity &lt;strong&gt;template&lt;/strong&gt;. Thus, a &lt;strong&gt;&lt;em&gt;Network&lt;/em&gt;&lt;/strong&gt; is created using a &lt;strong&gt;&lt;em&gt;NetworkTemplate&lt;/em&gt;&lt;/strong&gt;, which in turn contains a &lt;strong&gt;&lt;em&gt;NetworkConfiguration&lt;/em&gt;&lt;/strong&gt; together with any other values required for the creation.&lt;/p&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The above explains why at first sight, the number of entities defined by the CIMI API may seem overwhelming. The &lt;a href=&quot;http://dmtf.org/cloud&quot;&gt;CIMI Primer&lt;/a&gt; may be a good place to start when looking at the CIMI API (DSP 2027). Using &lt;strong&gt;&lt;em&gt;Network&lt;/em&gt;&lt;/strong&gt; as an example, the CIMI API defines six related entities in total:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;strong&gt;&lt;em&gt;Network&lt;/em&gt;&lt;/strong&gt;,&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;&lt;em&gt;NetworkCollection&lt;/em&gt;&lt;/strong&gt;,&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;&lt;em&gt;NetworkConfiguration&lt;/em&gt;&lt;/strong&gt;,&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;&lt;em&gt;NetworkConfigurationCollection&lt;/em&gt;&lt;/strong&gt;,&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;&lt;em&gt;NetworkTemplate&lt;/em&gt;&lt;/strong&gt;,&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;&lt;em&gt;NetworkTemplateCollection&lt;/em&gt;&lt;/strong&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3 id=&quot;network_2&quot;&gt;Network&lt;/h3&gt;

&lt;p&gt;A Network is created using a NetworkTemplate. A NetworkTemplate contains the NetworkConfiguration and the RoutingGroup to which the created Network will belong (if any):&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;POST /example.com/networks

&amp;lt;NetworkCreate&amp;gt;
  &amp;lt;name&amp;gt; my_test_network &amp;lt;/name&amp;gt;
  &amp;lt;description&amp;gt; A test network &amp;lt;/description&amp;gt;
  &amp;lt;networkTemplate&amp;gt;
    &amp;lt;networkConfig&amp;gt;
      &amp;lt;access&amp;gt; public &amp;lt;/access&amp;gt;
      &amp;lt;bandwidthLimit&amp;gt; 2 &amp;lt;bandwidthLimit&amp;gt;
      &amp;lt;trafficPriority&amp;gt; 1 &amp;lt;/trafficPriority&amp;gt;
      &amp;lt;maxTrafficDelay&amp;gt; 500,000 &amp;lt;/maxTrafficDelay&amp;gt;
      &amp;lt;maxTrafficLoss&amp;gt; 100 &amp;lt;/maxTrafficLoss&amp;gt;
      &amp;lt;maxTrafficJitter&amp;gt; 100,000 &amp;lt;/maxTrafficJitter&amp;gt;
    &amp;lt;/networkConfig&amp;gt;
    &amp;lt;routingGroup href=&quot;http://example.com/routinggroups/group1&quot;&amp;gt;
  &amp;lt;/networkTemplate&amp;gt;
&amp;lt;/NetworkCreate&amp;gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Note that the above specifies the NetworkConfiguration &lt;em&gt;by-value&lt;/em&gt;; it is possible for a client to specify this &lt;em&gt;by-reference&lt;/em&gt;, that is, using a pre-defined NetworkConfiguration given by the cloud service provider. In such a case, the body for create operation is simplified:&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&amp;lt;NetworkCreate&amp;gt;
  &amp;lt;name&amp;gt; my_test_network &amp;lt;/name&amp;gt;
  &amp;lt;description&amp;gt; A test network &amp;lt;/description&amp;gt;
  &amp;lt;networkTemplate&amp;gt;
    &amp;lt;networkConfig href=&quot;http://example.com/networkconfigs/config1&quot;/&amp;gt;
    &amp;lt;routingGroup href=&quot;http://example.com/routinggroups/group1&quot;&amp;gt;
  &amp;lt;/networkTemplate&amp;gt;
&amp;lt;/NetworkCreate&amp;gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;A GET on the URL of a Network will return the serialized (xml or json) format of that Network. Note that the serialization, as with all CIMI entities, will contain the ‘DELETE’ URL (i.e. the URL to be used for a DELETE operation on that entity):&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;GET /example.com/networks/my_test_network

&amp;lt;Network xmlns=&quot;http://www.dmtf.org/cimi&quot;&amp;gt;
  &amp;lt;id&amp;gt; /example.com/networks/my_test_network &amp;lt;/id&amp;gt;
  &amp;lt;name&amp;gt; my_test_network &amp;lt;/name&amp;gt;
  &amp;lt;description&amp;gt; A test network &amp;lt;/description&amp;gt;
  &amp;lt;created&amp;gt; Mar 1 12:55:02 EET 2012 &amp;lt;/created&amp;gt;
  &amp;lt;updated&amp;gt; Mar 1 12:55:02 EET 2012 &amp;lt;/updated&amp;gt;
  &amp;lt;state&amp;gt;STARTED&amp;lt;/state&amp;gt;
  &amp;lt;access&amp;gt; public &amp;lt;/access&amp;gt;
  &amp;lt;bandwidthLimit&amp;gt; 2 &amp;lt;bandwidthLimit&amp;gt;
  &amp;lt;trafficPriority&amp;gt; 1 &amp;lt;/trafficPriority&amp;gt;
  &amp;lt;maxTrafficDelay&amp;gt; 500,000 &amp;lt;/maxTrafficDelay&amp;gt;
  &amp;lt;maxTrafficLoss&amp;gt; 100 &amp;lt;/maxTrafficLoss&amp;gt;
  &amp;lt;maxTrafficJitter&amp;gt; 100,000 &amp;lt;/maxTrafficJitter&amp;gt;
  &amp;lt;routingGroup href=&quot;http://example.com/routinggroups/group1&quot;/&amp;gt;
  &amp;lt;eventLog href=&quot;http://example.com/events/networks/event1&quot;/&amp;gt;
  &amp;lt;operation rel=&quot;edit&quot; href=&quot;http://example.com/networks/my_test_network&quot;/&amp;gt;
  &amp;lt;operation rel=&quot;delete&quot; href=&quot;http://example.com/networks/my_test_network&quot;/&amp;gt;
&amp;lt;/Network&amp;gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;A Network is deleted using the URL for the ‘delete’ operation returned in the xml/json serialization:&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;DELETE /example.com/networks/my_test_network
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;###VSP&lt;/p&gt;

&lt;p&gt;As with Network, the URL to be used for the VSP creation operation is provided by the VSPCollection. Similarly, a VSP is created using a VSPTemplate, which defines a VSPConfiguration. The VSPTemplate also includes a ‘network’ attribute, identifying the &lt;strong&gt;&lt;em&gt;Network&lt;/em&gt;&lt;/strong&gt; to which this &lt;strong&gt;&lt;em&gt;VSP&lt;/em&gt;&lt;/strong&gt; will be associated:&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;POST /example.com/vsps

&amp;lt;VSPCreate&amp;gt;
  &amp;lt;name&amp;gt; my_switchport &amp;lt;/name&amp;gt;
  &amp;lt;description&amp;gt; A test switchport &amp;lt;/description&amp;gt;
  &amp;lt;vspTemplate&amp;gt;
    &amp;lt;network href=&quot;http://example.com/networks/my_test_network&quot;/&amp;gt;
    &amp;lt;vspConfig&amp;gt;
      &amp;lt;bandwidthReservation&amp;gt; 1 &amp;lt;/bandwidthReservation&amp;gt;
      &amp;lt;trafficPriority&amp;gt; 2 &amp;lt;/trafficPriority&amp;gt;
      &amp;lt;maxTrafficDelay&amp;gt; 500,000 &amp;lt;/maxTrafficDelay&amp;gt;
      &amp;lt;maxTrafficLoss&amp;gt; 100 &amp;lt;/maxTrafficLoss&amp;gt;
      &amp;lt;maxTrafficJitter&amp;gt; 100,000 &amp;lt;/maxTrafficJitter&amp;gt;
    &amp;lt;/vspConfig&amp;gt;
  &amp;lt;/vspTemplate&amp;gt;
&amp;lt;/VSPCreate&amp;gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Again and as with &lt;strong&gt;&lt;em&gt;Network&lt;/em&gt;&lt;/strong&gt; a VSPConfiguration may be passed &lt;em&gt;by-reference&lt;/em&gt; rather than &lt;em&gt;by-value&lt;/em&gt; (i.e. as shown above) simplifying the body of the create operation.&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;GET /example.com/vsps/my_switchport

&amp;lt;VSP xmlns=&quot;http://www.dmtf.org/cimi&quot;&amp;gt;
  &amp;lt;id&amp;gt; /example.com/vsps/my_switchport &amp;lt;/id&amp;gt;
  &amp;lt;name&amp;gt; my_switchport &amp;lt;/name&amp;gt;
  &amp;lt;description&amp;gt; A test switchport &amp;lt;/description&amp;gt;
  &amp;lt;state&amp;gt; STARTED &amp;lt;/state&amp;gt;
  &amp;lt;created&amp;gt; Mar 1 12:56:02 EET 2012 &amp;lt;/created&amp;gt;
  &amp;lt;updated&amp;gt; Mar 1 12:56:02 EET 2012 &amp;lt;/updated&amp;gt;
  &amp;lt;network href=&quot;http://example.com/networks/my_test_network&quot;/&amp;gt;
  &amp;lt;bandwidthReservation&amp;gt; 1 &amp;lt;/bandwidthReservation&amp;gt;
  &amp;lt;trafficPriority&amp;gt; 2 &amp;lt;/trafficPriority&amp;gt;
  &amp;lt;maxTrafficDelay&amp;gt; 500,000 &amp;lt;/maxTrafficDelay&amp;gt;
  &amp;lt;maxTrafficLoss&amp;gt; 100 &amp;lt;/maxTrafficLoss&amp;gt;
  &amp;lt;maxTrafficJitter&amp;gt; 100,000 &amp;lt;/maxTrafficJitter&amp;gt;
  &amp;lt;eventLog href=&quot;http://example.com/events/vsps/event1&quot;/&amp;gt;
  &amp;lt;operation rel=&quot;edit&quot; href=&quot;http://example.com/vsps/my_switchport&quot;/&amp;gt;
  &amp;lt;operation rel=&quot;delete&quot; href=&quot;http://example.com/vsps/my_switchport&quot;/&amp;gt;
&amp;lt;/VSP&amp;gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Following the same pattern as &lt;strong&gt;&lt;em&gt;Network&lt;/em&gt;&lt;/strong&gt; (and all CIMI entities for that matter), retrieving the xml/json serialization of a &lt;strong&gt;&lt;em&gt;VSP&lt;/em&gt;&lt;/strong&gt; will also provide the DELETE URL:&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;DELETE /example.com/vsps/my_switchport
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;###RoutingGroup&lt;/p&gt;

&lt;p&gt;Finally, as with all other CIMI entities, the URL for creation of a RoutingGroup is provided by the RoutingGroupCollection. Furthermore, creation of a RoutingGroup is achieved by specifying a RoutingGroupTemplate:&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;POST /example.com/routing_groups

&amp;lt;RoutingGroupCreate&amp;gt;
  &amp;lt;name&amp;gt; developer_net_group &amp;lt;/name&amp;gt;
  &amp;lt;description&amp;gt; routing group for all developer networks &amp;lt;/description&amp;gt;
  &amp;lt;routingGroupTemplate&amp;gt;
    &amp;lt;network href=&quot;http://example.com/networks/my_test_network&quot;/&amp;gt;
    &amp;lt;network href=&quot;http://example.com/networks/my_test_network2&quot;/&amp;gt;
  &amp;lt;/routingGroupTemplate&amp;gt;
&amp;lt;/RoutingGroupCreate&amp;gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Retrieving a RoutingGroup provides the DELETE and EDIT URLs:&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;GET /example.com/routing_groups/developer_net_group

&amp;lt;RoutingGroup xmlns=&quot;http://www.dmtf.org/cimi&quot;&amp;gt;
  &amp;lt;id&amp;gt; /example.com/routing_groups/developer_net_group &amp;lt;/id&amp;gt;
  &amp;lt;name&amp;gt; developer_net_group &amp;lt;/name&amp;gt;
  &amp;lt;description&amp;gt; routing group for all developer networks &amp;lt;/description&amp;gt;
  &amp;lt;created&amp;gt; Mar 1 12:57:02 EET 2012 &amp;lt;/created&amp;gt;
  &amp;lt;updated&amp;gt; Mar 1 12:57:02 EET 2012 &amp;lt;/updated&amp;gt;
  &amp;lt;network href=&quot;http://example.com/networks/my_test_network&quot;/&amp;gt;
  &amp;lt;network href=&quot;http://example.com/networks/my_test_network2&quot;/&amp;gt;
  &amp;lt;operation rel=&quot;edit&quot; href=&quot;http://example.com/routing_groups/developer_net_group&quot;/&amp;gt;
  &amp;lt;operation rel=&quot;delete&quot; href=&quot;http://example.com/routing_groups/developer_net_group&quot;/&amp;gt;
&amp;lt;/RoutingGroup&amp;gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Using the DELETE URL returned above to Delete a Network:&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;DELETE /example.com/routing_groups/developer_net_group
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;A client may use the EDIT URL to add a new network to the RoutingGroup. In CIMI Update/Edit operations are achieved with HTTP PUT and must include the full description of the entity, together with any new/updated values. Thus, to add the new “dev_net1” Network to the RoutingGroup:&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;PUT /example.com/routing_groups/developer_net_group

&amp;lt;RoutingGroup xmlns=&quot;http://www.dmtf.org/cimi&quot;&amp;gt;
  &amp;lt;id&amp;gt; /example.com/routing_groups/developer_net_group &amp;lt;/id&amp;gt;
  &amp;lt;name&amp;gt; developer_net_group &amp;lt;/name&amp;gt;
  &amp;lt;description&amp;gt; routing group for all developer networks &amp;lt;/description&amp;gt;
  &amp;lt;network href=&quot;http://example.com/networks/my_test_network&quot;/&amp;gt;
  &amp;lt;network href=&quot;http://example.com/networks/my_test_network2&quot;/&amp;gt;
  &amp;lt;network href=&quot;http://example.com/networks/dev_net1&quot;/&amp;gt;
&amp;lt;/RoutingGroup&amp;gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;&lt;br /&gt;&lt;/p&gt;
&lt;hr /&gt;

&lt;p&gt;###Conclusions
&lt;a id=&quot;conclusions&quot;&gt; &lt;/a&gt;
As stated earlier, I will not attempt to judge which of the 2 APIs is ‘better’; for starters that would be entirely subjective and will depend on the use-case. Furthermore, the Quantum API is not a ‘stand-alone’ Networking API and relies on parts of Nova which are yet to be implemented (management of the VIFs/Attachments).&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;
    &lt;p&gt;Both APIs have a similar concept of ‘Network’. Essentially a Network defines a logical layer-2 network switch.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;A CIMI &lt;strong&gt;&lt;em&gt;VSP&lt;/em&gt;&lt;/strong&gt; is essentially a Quantum &lt;strong&gt;&lt;em&gt;Port&lt;/em&gt;&lt;/strong&gt; plus &lt;strong&gt;&lt;em&gt;VIF/Attachment&lt;/em&gt;&lt;/strong&gt;. That is, a VSP defines the operational parameters of the network port, but also serves as the connection for a given CIMI Machine (remember, a Machine has a reference to a VSP). On the other hand, a Quantum Port needs an Attachment to achieve a connection with a given Openstack Compute server.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;The CIMI concept of &lt;strong&gt;&lt;em&gt;RoutingGroup&lt;/em&gt;&lt;/strong&gt; is missing from Quantum.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;The CIMI Network API is undoubtedly the more complex of the two though it allows for more fine-grained control of specific Network parameters, exposing concepts such as bandwidthLimit, trafficPriority, maxTrafficDelay, maxTrafficLoss, maxTrafficJitter and routingGroup.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;Equivalently, one might say that Quantum is more ‘elegant’ but is of course much simpler and affords less control over the virtualised network. It may be that Quantum will evolve before it is finalised, adding similar concepts to the CIMI network API, though this is entirely speculative.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;In &lt;em&gt;general&lt;/em&gt;, the CIMI API is an attempt at a unified interface that can be implemented and provided by cloud service providers with heterogeneous back-end infrastructure. That is, CIMI API makes no assumptions about the hardware or more simply the ‘internal workings’ of the cloud provider infrastructure (e.g. virtualisation technology being used). However, the Openstack API by definition is designed to be served as the interface to an Openstack installation. This may in part explain the (potential) perceived complexity inherent in CIMI networking.&lt;/p&gt;
  &lt;/li&gt;
&lt;/ul&gt;

</description>
<published>2012-03-05 00:00:00 +0200</published>
<link>http://mariosandreou.com/deltacloud/cloud_api/2012/03/05/openstack-cimi-networking.html</link>
</item>

<item>
<title>Updated Openstack v2 API driver in Deltacloud</title>
<description>&lt;p&gt;&lt;br /&gt;&lt;/p&gt;

&lt;div class=&quot;blog_title&quot;&gt;

Updated Openstack v2 API driver in Deltacloud

&lt;/div&gt;

&lt;p&gt;The first iteration of the updated Openstack driver for deltacloud has just been sent to the &lt;a href=&quot;http://mail-archives.apache.org/mod_mbox/deltacloud-dev/&quot;&gt;dev@deltacloud.apache.org&lt;/a&gt; mailing list. For now only ‘compute’ (&lt;em&gt;nova&lt;/em&gt;) is implemented… ‘object-storage’ (&lt;em&gt;swift&lt;/em&gt;) will follow soon. Some work will be needed on the ‘cloudfiles’ rubygem to make it work with the Keystone identity service (will likely end up merging &lt;a href=&quot;https://github.com/rackspace/ruby-cloudfiles&quot;&gt;cloudfiles&lt;/a&gt; and the &lt;a href=&quot;https://github.com/rackspace/ruby-openstack-compute&quot;&gt;openstack/compute rubygem&lt;/a&gt; or some such).&lt;/p&gt;

&lt;hr /&gt;

&lt;p&gt;###Calling all testers!&lt;/p&gt;

&lt;p&gt;If you’ve been looking for a reason to get involved with Deltacloud then please consider testing this new driver. There are likely many issues and bugs that need fixing and all suggestions are welcome.&lt;/p&gt;

&lt;hr /&gt;

&lt;p&gt;###Getting the new driver:&lt;/p&gt;

&lt;p&gt;At the time of writing the new driver is just a patch sitting on the &lt;a href=&quot;http://mail-archives.apache.org/mod_mbox/deltacloud-dev/&quot;&gt;dev@deltacloud.apache.org&lt;/a&gt; mailing list. If you are really keen then you can grab that patch and apply it to the HEAD of the git repo at &lt;strong&gt;https://git-wip-us.apache.org/repos/asf/deltacloud.git&lt;/strong&gt; . The info &lt;a href=&quot;http://deltacloud.apache.org/developers.html&quot;&gt;here&lt;/a&gt; may be of use.&lt;/p&gt;

&lt;p&gt;Within a couple of days and once any obvious issues are resolved the driver will be pushed to the git repo, in which case you can just grab the latest HEAD containing the pushed driver. There is more developer info &lt;a href=&quot;http://deltacloud.apache.org/developers.html#h1_1&quot;&gt;here&lt;/a&gt; but essentially:&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;    mkdir DeltacloudProject
    cd DeltacloudProject
    git clone  https://git-wip-us.apache.org/repos/asf/deltacloud.git &amp;lt;br&amp;gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;hr /&gt;

&lt;p&gt;###Testing the new driver:&lt;/p&gt;

&lt;p&gt;Assuming you are in a directory “DeltacloudProject” and you have cloned the git repo into it (so you have a directory called &lt;strong&gt;deltacloud&lt;/strong&gt;):&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;    cd deltacloud
    ./server/bin/deltacloudd -i openstack -P &quot;URI_OF_OPENSTACK_IDENTITY_SERVICE&quot;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;The &lt;strong&gt;URI_OF_OPENSTACK_IDENTITY_SERVICE&lt;/strong&gt; will be provided by your Openstack server administrator. For example, identity service URL for the Openstack deployment at HP Cloud Service beta looks like &lt;strong&gt;https://region-a.geo-1.identity.hpcloudsvc.com:35357/v2.0/&lt;/strong&gt;. So to use deltacloud against that Openstack setup:&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;    ./server/bin/deltacloudd -i openstack -P &quot;https://region-a.geo-1.identity.hpcloudsvc.com:35357/v2.0/&quot;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;&lt;a href=&quot;/deltacloud/2012/02/16/openstack-hpcloud-beta.html&quot;&gt;Using v2 authentication&lt;/a&gt; requires three parameters: username, password and tenant-name. To provide these when prompted (i.e. if using the HTML UI - by default you should point your browser @ localhost:3001/api), you should concatenate ‘username’ and ‘tenant-name’ with a ‘+’. With cURL this looks like:&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;    curl -iv --user &quot;you@domain.com+you@domain.com-default-tenant:f81jD23F3521FSS!&quot; http://localhost:3001/api/realms?format=xml

    [RESPONSE]:
    &amp;lt;?xml version='1.0' encoding='utf-8' ?&amp;gt;
    &amp;lt;realms&amp;gt;
      &amp;lt;realm href='http://localhost:3001/api/realms/default' id='default'&amp;gt;
      &amp;lt;name&amp;gt;default&amp;lt;/name&amp;gt;
      &amp;lt;state&amp;gt;AVAILABLE&amp;lt;/state&amp;gt;
      &amp;lt;limit&amp;gt;ABSOLUTE &amp;gt;&amp;gt; Max. Instances: 20 Max. RAM: 20480   ||   SERVERS &amp;gt;&amp;gt; Total: 50  Remaining: 50 Time Unit: per DAY&amp;lt;/limit&amp;gt;
      &amp;lt;/realm&amp;gt;
    &amp;lt;/realms&amp;gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Where &lt;strong&gt;you@domain.com&lt;/strong&gt; is the username and &lt;strong&gt;you@domain.com-default-tenant&lt;/strong&gt; is the tenant name. Using ‘+’ as a delimiter is probably not the best solution so suggestions are &lt;a href=&quot;http://deltacloud.org/contact&quot;&gt;very welcome&lt;/a&gt;!&lt;/p&gt;

</description>
<published>2012-02-23 00:00:00 +0200</published>
<link>http://mariosandreou.com/deltacloud/2012/02/23/deltacloud-openstack_v2API-driver.html</link>
</item>

<item>
<title>Using the openstack-compute rubygem with HP Cloud Services</title>
<description>&lt;p&gt;&lt;br /&gt;&lt;/p&gt;

&lt;div class=&quot;blog_title&quot;&gt;

Using the openstack-compute rubygem with HP Cloud Services

&lt;/div&gt;

&lt;p&gt;So the folks at HP are running a private beta of their &lt;a href=&quot;http://www.hpcloud.com/&quot;&gt;HP Cloud Services&lt;/a&gt;. They were kind enough to give me access to their beta program and it was perfect timing as I’m trying to update the &lt;a href=&quot;http://deltacloud.apache.org/drivers.html#h2&quot;&gt;Deltacloud Openstack&lt;/a&gt; driver to v1.1 of the Openstack API.&lt;/p&gt;

&lt;p&gt;I’m using the &lt;a href=&quot;https://github.com/rackspace/ruby-openstack-compute&quot;&gt;openstack-compute&lt;/a&gt; rubygem to talk to the HP cloud. I had some issues getting it all to work, mainly because I’m new to the Openstack API and also because I was trying to authenticate with the new (?) v2.0 &lt;a href=&quot;http://docs.openstack.org/api/openstack-identity-service/2.0/content/&quot;&gt;Keystone&lt;/a&gt; service.&lt;/p&gt;

&lt;hr /&gt;

&lt;p&gt;###1. About the openstack-compute rubygem:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;
    &lt;p&gt;Supports both v1.0 and v2.0 authentication. This is distinguished by the URL of the identity service:&lt;/p&gt;

    &lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;(using v1.1.6 this is in /lib/openstack/compute/authentication.rb)
if conn.auth_path =~ /.*v2.0\/?$/
  AuthV20.new(conn)
else
  AuthV10.new(conn)
end
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;    &lt;/div&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;For v2.0 authentication, it expects ‘username’, ‘password’ and ‘tenant&lt;strong&gt;Name&lt;/strong&gt;’. It is important to note that this is tenant&lt;strong&gt;&lt;em&gt;Name&lt;/em&gt;&lt;/strong&gt; and not tenant&lt;strong&gt;&lt;em&gt;Id&lt;/em&gt;&lt;/strong&gt;. The ‘username’ and ‘password’ are actually the &lt;strong&gt;credentials that you use to login to https://manage.hpcloud.com/login.&lt;/strong&gt;&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;Generally, keystone (i.e. v2.0) Identity service allows you to authenticate in a number of ways… using your API access key/private keys, &lt;strong&gt;OR&lt;/strong&gt; username/password, &lt;strong&gt;AND&lt;/strong&gt; your tenantId &lt;strong&gt;OR&lt;/strong&gt; tenantName. For now though and since I want to use the openstack-compute gem I have to use username, password, tenantName. Right.&lt;/p&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;hr /&gt;

&lt;p&gt;###2. About the hp cloud credentials.&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;
    &lt;p&gt;Once logged into the HP Cloud web console you will find credentials under ‘Account’. You need to use the ‘Tenant Name’ and the URL of the ‘Identity’ service under ‘Service Endpoints’. They look something like:&lt;/p&gt;

    &lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;Service Endpoints

  Tenant ID    98765432109876
  Tenant Name  you@domain.com-default-tenant

  Identity
    https://region-a.geo-1.identity.hpcloudsvc.com:35357/v2.0/
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;    &lt;/div&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;hr /&gt;

&lt;p&gt;###3. Getting it all to work.&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;    [marios@name deltacloud]$ irb -rubygems

    irb(main):001:0&amp;gt; require 'openstack/compute'

    =&amp;gt; true

    irb(main):002:0&amp;gt; os = OpenStack::Compute::Connection.new(:username =&amp;gt; 
    &quot;your_user_name&quot;, :api_key =&amp;gt;    &quot;your_password&quot;, 
    :auth_url =&amp;gt; &quot;https://region-a.geo-1.identity.hpcloudsvc.com:35357v2.0/&quot;, 
    :authtenant=&amp;gt;&quot;you@domain.com-default-tenant&quot;)

    =&amp;gt; #&amp;lt;OpenStack::Compute::Connection:0xb7408ec4 @svrmgmtpath=&quot;/v1.1/98765432109876&quot;, 
    @authok=true, @region=nil, @authtoken=&quot;HPAuth_3f3sd1a14e4b2f8f253735d1&quot;, 
    @auth_scheme=&quot;https&quot;, @auth_url=&quot;https://region-a.geo-1.identity.hpcloudsvc.com:35357/v2.0/&quot;,     
    @svrmgmtscheme=&quot;https&quot;, @proxy_host=nil, @service_name=&quot;compute&quot;, 
    @auth_port=35357, @authuser=&quot;foo@bar.com&quot;, @svrmgmtport=443,
    @retry_auth=nil, @authtenant=&quot;you@domain.com-default-tenant&quot;, 
    @auth_host=&quot;region-a.geo-1.identity.hpcloudsvc.com&quot;, 
    @authkey=&quot;password&quot;, @http={}, @is_debug=nil,
    @svrmgmthost=&quot;az-2.region-a.geo-1.compute.hpcloudsvc.com&quot;, @proxy_port=nil, 
    @auth_path=&quot;/v2.0/&quot;&amp;gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;hr /&gt;

&lt;p&gt;###4. Doing it with cURL:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;
    &lt;p&gt;Using v1.0 authentication:&lt;/p&gt;

    &lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;  curl -iv -H &quot;X-Auth-User: your_username&quot; -H &quot;X-Auth-Key: your_password&quot; 
  &quot;https://region-a.geo-1.identity.hpcloudsvc.com:35357/v1.0/&quot;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;    &lt;/div&gt;

    &lt;p&gt;Note that the same credentials are used here, i.e. username and password that you use to login to https://manage.hpcloud.com/login.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;Using v2.0 authentication:&lt;/p&gt;

    &lt;p&gt;A main difference in v2.0 is that we POST our credentials to the Identity service, rather than using HTTP headers:&lt;/p&gt;

    &lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;  curl -ivX POST -H &quot;Content-Type: application/json&quot; https://region-a.geo-1.identity.hpcloudsvc.com:35357/v2.0/tokens
  -d '{&quot;auth&quot;:{&quot;passwordCredentials&quot;:{&quot;username&quot;:&quot;your_username&quot;, &quot;password&quot;:&quot;your_password&quot;},
  &quot;tenantId&quot;:&quot;yourtenantId&quot;}}'
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;    &lt;/div&gt;

    &lt;p&gt;Note that here I specified the tenant&lt;strong&gt;&lt;em&gt;Id&lt;/em&gt;&lt;/strong&gt;, but you can just as easily use “tenantName”:”yourtenantNAME” in the curl POST data. Since we’re using cURL, we can also use the other credentials if we like, rather than username and password… i.e. the AccessKey and SecretKey (ala EC2). However to use this the Identity service expects slightly different data:&lt;/p&gt;

    &lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;  curl -ivX POST -H &quot;Content-Type: application/json&quot; https://region-a.geo-1.identity.hpcloudsvc.com:35357/v2.0/tokens 
  -d '{&quot;auth&quot;:{&quot;apiAccessKeyCredentials&quot;:{&quot;accessKey&quot;:&quot;AW313FDNF3192W6VBW9X&quot;,
  &quot;secretKey&quot;:&quot;JKL:79823jlkjlkJKLLKJfdFSFSD&quot;}, &quot;tenantName&quot;:&quot;you@domain.com-default-tenant&quot;}}'
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;    &lt;/div&gt;

    &lt;p&gt;i.e. &lt;strong&gt;apiAccessKeyCredentials&lt;/strong&gt;, &lt;strong&gt;accessKey&lt;/strong&gt; and &lt;strong&gt;secretKey&lt;/strong&gt;. You can also use tenantId instead if you prefer.&lt;/p&gt;

    &lt;p&gt;Now that I’ve got a working Openstack cloud to play with, all I have to do it &lt;a href=&quot;http://deltacloud.apache.org/developers.html#h2_4&quot;&gt;write the driver&lt;/a&gt; …&lt;/p&gt;
  &lt;/li&gt;
&lt;/ul&gt;

</description>
<published>2012-02-16 00:00:00 +0200</published>
<link>http://mariosandreou.com/deltacloud/cloud_api/2012/02/16/openstack-hpcloud-beta.html</link>
</item>

<item>
<title>Deltacloud - supporting OpenNebula 3.x API</title>
<description>&lt;p&gt;&lt;br /&gt;&lt;/p&gt;

&lt;div class=&quot;blog_title&quot;&gt;

Deltacloud - supporting OpenNebula 3.x API

&lt;/div&gt;

&lt;p&gt;The OpenNebula driver in Deltacloud has been updated to support version 3.x of the &lt;a href=&quot;http://www.opennebula.org/about:about&quot;&gt;OpenNebula API&lt;/a&gt; . The driver is contributed to Deltacloud by Daniel Molina and it ‘speaks’ to the OpenNebula &lt;a href=&quot;http://www.opennebula.org/documentation:rel3.2:occidd&quot;&gt;OCCI endpoint&lt;/a&gt; (OpenNebula exposes both &lt;a href=&quot;http://www.opennebula.org/cloud:cloud&quot;&gt;EC2 and OCCI interfaces&lt;/a&gt;).&lt;/p&gt;

&lt;p&gt;Daniel Molina has put together a great ‘how-to’ for using OpenNebula through Deltacloud &lt;a href=&quot;http://wiki.opennebula.org/deltacloud&quot;&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Essentially:&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;If you aren’t yet ready to install OpenNebula and just want to try out the Deltacloud-OpenNebula setup, you can use the ‘mock’ OpenNebula cloud; request an account &lt;a href=&quot;http://www.opennebula.org/cloud:gettingaccount&quot;&gt;from here&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;Start your deltacloud server:&lt;/p&gt;

    &lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt; deltacloudd -i opennebula -P https://cloud.opennebula.org/occi
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;    &lt;/div&gt;

    &lt;p&gt;where &lt;strong&gt;https://cloud.opennebula.org/occi&lt;/strong&gt; is the endpoint for the OpenNebula mock OCCI interface. Alternatively you can specify this using environment variables:&lt;/p&gt;

    &lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt; export OCCI_URL=&quot;https://cloud.opennebula.org/occi&quot;
 deltacloudd -i opennebula
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;    &lt;/div&gt;

    &lt;p&gt;You can also do the same per request on the &lt;strong&gt;&lt;em&gt;client&lt;/em&gt;&lt;/strong&gt; side by specifying the provider using the client request HTTP headers; e.g. using cURL and assuming deltacloud running at localhost:3001:&lt;/p&gt;

    &lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt; curl -iv --user &quot;username:userkey&quot; -H &quot;X-Deltacloud-Provider: https://cloud.opennebula.org/occi&quot; http://localhost:3001/api/images?format=xml
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;    &lt;/div&gt;
  &lt;/li&gt;
&lt;/ol&gt;

</description>
<published>2012-02-15 00:00:00 +0200</published>
<link>http://mariosandreou.com/deltacloud/2012/02/15/deltacloud-opennebula.html</link>
</item>

<item>
<title>FOSDEM - 2012</title>
<description>&lt;p&gt;&lt;br /&gt;&lt;/p&gt;

&lt;div class=&quot;blog_title&quot;&gt;

FOSDEM - 2012

&lt;/div&gt;

&lt;p&gt;FOSDEM 2012 was excellent. Red Hat had a very strong presence at FOSDEM this year and especially so in the Virtualization and Cloud &lt;a href=&quot;http://fosdem.org/2012/schedule/track/virtualization_and_cloud_devroom&quot;&gt;Devroom&lt;/a&gt; where I spent most of my time. On Saturday Richard Jones &lt;a href=&quot;https://rwmj.wordpress.com/2012/02/04/libguestfs-talk-at-fosdem/#content&quot;&gt;talked about libguestfs&lt;/a&gt;, Francesco Vollero gave an introduction to the &lt;a href=&quot;http://aeolusproject.org/&quot;&gt;Aeolus Project&lt;/a&gt;, Michal Fojtik &lt;a href=&quot;http://mifo.sk/deltacloud-at-fosdem-2012&quot;&gt;spoke about&lt;/a&gt; Deltacloud and I gave &lt;a href=&quot;/documents/fosdem2012.pdf&quot;&gt;a talk&lt;/a&gt; DMTF CIMI and the work-in-progress implementation of this API in Deltacloud. There were more talks by Red Hatters, including Ryan Lane, Padraig Brady and Daniel Berrange.&lt;/p&gt;

&lt;div class=&quot;img&quot;&gt;
&lt;img src=&quot;/images/Feb2012/fosdem.jpg&quot; alt=&quot;FOSDEM 2012 poster&quot; /&gt;
&lt;/div&gt;

&lt;p&gt;Daniel Molina gave an introduction to the OpenNebula Project. It was great to finally meet Daniel in person; Daniel has contributed the OpenNebula driver to the Deltacloud project and has recently updated this to support v3 of the OpenNebula API.&lt;/p&gt;

&lt;p&gt;On Sunday Itamar Heim gave an &lt;a href=&quot;http://ovirt.org/wiki/File:Fosdem2012-ovirt-clean.pdf&quot;&gt;overview of oVirt&lt;/a&gt;, Omer Frenkel spoke more about the &lt;a href=&quot;http://ovirt.org/wiki/File:Ovirt-engine-core_fosdem_2012.pdf&quot;&gt;oVirt Engine Core&lt;/a&gt; and Federico Simoncelli spoke about VDSM.&lt;/p&gt;

&lt;div class=&quot;img&quot;&gt;
&lt;img src=&quot;/images/Feb2012/fosdem_fork.jpg&quot; alt=&quot;FSF baby t-shirt&quot; /&gt;
&lt;/div&gt;

&lt;p&gt;I picked up a geek-chic t-shirt for my work-in-progress newborn (expected later this year :) ) from the &lt;a href=&quot;http://www.fsfe.org/&quot;&gt;FSFE&lt;/a&gt; stand (thanks to my very Italian friend Franscesco Vollero for the photo). This was my first FOSDEM and I was very impressed by the scale and organisation of the event. It was great to finally put some faces to names and compared to other (e.g. academic) conferences the atmosphere was very friendly and relaxed - especially for those giving talks. I really hope to go again next year.&lt;/p&gt;
</description>
<published>2012-02-13 00:00:00 +0200</published>
<link>http://mariosandreou.com/deltacloud/2012/02/13/fosdem-2012.html</link>
</item>

</channel>
</rss>
