occi 2.5.7 → 2.5.8
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/.gitignore +1 -0
- data/Gemfile +2 -1
- data/Gemfile.lock +2 -0
- data/README.md +164 -40
- data/bin/occi +121 -4
- data/examples/x509auth_example.rb +13 -12
- data/lib/occi/api/client.rb +3 -2
- data/lib/occi/client/occiopts.rb +146 -0
- data/lib/occi/collection.rb +7 -0
- data/lib/occi/core/category.rb +5 -0
- data/lib/occi/core/entity.rb +24 -0
- data/lib/occi/version.rb +1 -1
- data/occi.gemspec +2 -1
- data/spec/occiantlr/parser_spec.rb +4 -4
- metadata +19 -2
    
        data/.gitignore
    CHANGED
    
    
    
        data/Gemfile
    CHANGED
    
    
    
        data/Gemfile.lock
    CHANGED
    
    
    
        data/README.md
    CHANGED
    
    | @@ -8,7 +8,7 @@ Requirements | |
| 8 8 |  | 
| 9 9 | 
             
            The following setup is recommended
         | 
| 10 10 |  | 
| 11 | 
            -
            * usage of the Ruby Version  | 
| 11 | 
            +
            * usage of the Ruby Version Manager
         | 
| 12 12 | 
             
            * Ruby 1.9.3
         | 
| 13 13 | 
             
            * RubyGems installed
         | 
| 14 14 |  | 
| @@ -19,29 +19,52 @@ Installation | |
| 19 19 |  | 
| 20 20 | 
             
            Usage
         | 
| 21 21 | 
             
            -----
         | 
| 22 | 
            +
            ### Client
         | 
| 23 | 
            +
            The OCCI gem includes a client you can use directly from shell with the following auth methods: x509 (with --password, --user-cred and --ca-path), basic (with --username and --password), digest (with --username and --password), none. If you won't set a password using --password, the client will run in an interactive mode and ask for it later on.
         | 
| 22 24 |  | 
| 23 | 
            -
             | 
| 24 | 
            -
            to start irb from the command line:
         | 
| 25 | 
            +
            To find out more about available options and defaults use
         | 
| 25 26 |  | 
| 26 | 
            -
                 | 
| 27 | 
            +
                occi --help
         | 
| 27 28 |  | 
| 28 | 
            -
             | 
| 29 | 
            -
            should load occi:
         | 
| 29 | 
            +
            To list available resources use
         | 
| 30 30 |  | 
| 31 | 
            -
                 | 
| 32 | 
            -
                 | 
| 31 | 
            +
                occi --endpoint https://<ENDPOINT>:<PORT>/ --action list --resource compute --auth x509
         | 
| 32 | 
            +
                occi --endpoint https://<ENDPOINT>:<PORT>/ --action list --resource storage --auth x509
         | 
| 33 | 
            +
                occi --endpoint https://<ENDPOINT>:<PORT>/ --action list --resource network --auth x509
         | 
| 33 34 |  | 
| 34 | 
            -
             | 
| 35 | 
            +
            To describe available resources use
         | 
| 35 36 |  | 
| 36 | 
            -
                 | 
| 37 | 
            -
                 | 
| 37 | 
            +
                occi --endpoint https://<ENDPOINT>:<PORT>/ --action describe --resource compute --auth x509
         | 
| 38 | 
            +
                occi --endpoint https://<ENDPOINT>:<PORT>/ --action describe --resource storage --auth x509
         | 
| 39 | 
            +
                occi --endpoint https://<ENDPOINT>:<PORT>/ --action describe --resource network --auth x509
         | 
| 38 40 |  | 
| 39 | 
            -
             | 
| 41 | 
            +
            To describe specific resources use
         | 
| 42 | 
            +
             | 
| 43 | 
            +
                occi --endpoint https://<ENDPOINT>:<PORT>/ --action describe --resource https://<ENDPOINT>:<PORT>/compute/<OCCI_ID> --auth x509
         | 
| 44 | 
            +
                occi --endpoint https://<ENDPOINT>:<PORT>/ --action describe --resource https://<ENDPOINT>:<PORT>/storage/<OCCI_ID> --auth x509
         | 
| 45 | 
            +
                occi --endpoint https://<ENDPOINT>:<PORT>/ --action describe --resource https://<ENDPOINT>:<PORT>/network/<OCCI_ID> --auth x509
         | 
| 46 | 
            +
             | 
| 47 | 
            +
            To list available OS templates or Resource templates use
         | 
| 48 | 
            +
             | 
| 49 | 
            +
                occi --endpoint https://<ENDPOINT>:<PORT>/ --action list --resource os_tpl --auth x509
         | 
| 50 | 
            +
                occi --endpoint https://<ENDPOINT>:<PORT>/ --action list --resource resource_tpl --auth x509
         | 
| 51 | 
            +
             | 
| 52 | 
            +
            To describe a specific OS template or Resource template use
         | 
| 40 53 |  | 
| 41 | 
            -
             | 
| 42 | 
            -
             | 
| 43 | 
            -
             | 
| 44 | 
            -
             | 
| 54 | 
            +
                occi --endpoint https://<ENDPOINT>:<PORT>/ --action describe --resource os_tpl#debian6 --auth x509
         | 
| 55 | 
            +
                occi --endpoint https://<ENDPOINT>:<PORT>/ --action describe --resource resource_tpl#small --auth x509
         | 
| 56 | 
            +
             | 
| 57 | 
            +
            To create a compute resource with mixins use
         | 
| 58 | 
            +
             | 
| 59 | 
            +
                occi --endpoint https://<ENDPOINT>:<PORT>/ --action create --resource compute --mixin os_tpl#debian6 --mixin resource_tpl#small --resource-title "My rOCCI VM" --auth x509
         | 
| 60 | 
            +
             | 
| 61 | 
            +
            To delete a compute resource use
         | 
| 62 | 
            +
             | 
| 63 | 
            +
                occi --endpoint https://<ENDPOINT>:<PORT>/ --action delete --resource https://<ENDPOINT>:<PORT>/compute/<OCCI_ID> --auth x509
         | 
| 64 | 
            +
             | 
| 65 | 
            +
            ### Client scripting
         | 
| 66 | 
            +
             | 
| 67 | 
            +
            #### Auth
         | 
| 45 68 |  | 
| 46 69 | 
             
            For Basic auth use
         | 
| 47 70 |  | 
| @@ -49,7 +72,7 @@ For Basic auth use | |
| 49 72 | 
             
                auth.type = 'basic'
         | 
| 50 73 | 
             
                auth.username = 'user'
         | 
| 51 74 | 
             
                auth.password = 'mypass'
         | 
| 52 | 
            -
             | 
| 75 | 
            +
             
         | 
| 53 76 | 
             
            For Digest auth use
         | 
| 54 77 |  | 
| 55 78 | 
             
                auth = Hashie::Mash.new
         | 
| @@ -58,52 +81,153 @@ For Digest auth use | |
| 58 81 | 
             
                auth.password = 'mypass'
         | 
| 59 82 |  | 
| 60 83 | 
             
            For X.509 auth use
         | 
| 61 | 
            -
             | 
| 84 | 
            +
             
         | 
| 62 85 | 
             
                auth = Hashie::Mash.new
         | 
| 63 86 | 
             
                auth.type = 'x509'
         | 
| 64 87 | 
             
                auth.user_cert = '/Path/To/My/usercert.pem'
         | 
| 65 88 | 
             
                auth.user_cert_password = 'MyPassword'
         | 
| 66 89 | 
             
                auth.ca_path = '/Path/To/root-certificates'
         | 
| 67 90 |  | 
| 91 | 
            +
            #### DSL
         | 
| 92 | 
            +
            In your scripts, you can use the OCCI client DSL.
         | 
| 93 | 
            +
             | 
| 94 | 
            +
            To include the DSL definitions in your script use
         | 
| 95 | 
            +
             | 
| 96 | 
            +
                extend OCCI::DSL
         | 
| 97 | 
            +
             | 
| 98 | 
            +
            To connect to an OCCI endpoint/server (e.g. running on http://localhost:3000/ )
         | 
| 99 | 
            +
             | 
| 100 | 
            +
                connect('http://localhost:3300',auth||=nil)
         | 
| 101 | 
            +
             | 
| 102 | 
            +
            To get the list of available resource types or mixin types use
         | 
| 103 | 
            +
             | 
| 104 | 
            +
                resource_types
         | 
| 105 | 
            +
                mixin_types
         | 
| 106 | 
            +
             | 
| 107 | 
            +
            To get compute, storage or network descriptions use
         | 
| 108 | 
            +
             | 
| 109 | 
            +
                describe "compute"
         | 
| 110 | 
            +
                describe "storage"
         | 
| 111 | 
            +
                describe "network"
         | 
| 112 | 
            +
             | 
| 113 | 
            +
            To get the location of compute, storage or network resources use
         | 
| 114 | 
            +
             | 
| 115 | 
            +
                list "compute"
         | 
| 116 | 
            +
                list "storage"
         | 
| 117 | 
            +
                list "network"
         | 
| 118 | 
            +
             | 
| 119 | 
            +
            To get the identifiers of specific mixins in specific mixin types use
         | 
| 120 | 
            +
             | 
| 121 | 
            +
                mixin "my_template", "os_tpl"
         | 
| 122 | 
            +
                mixin "small", "resource_tpl"
         | 
| 123 | 
            +
             | 
| 124 | 
            +
            To get the identifiers of specific mixins with unknown types use
         | 
| 125 | 
            +
             | 
| 126 | 
            +
                mixin "medium"
         | 
| 127 | 
            +
             | 
| 128 | 
            +
            To get mixin descriptions use
         | 
| 129 | 
            +
             | 
| 130 | 
            +
                mixin "medium", nil, true
         | 
| 131 | 
            +
                mixin "my_template", "os_tpl", true
         | 
| 132 | 
            +
             | 
| 133 | 
            +
            To get a list of names of all / OS templates / Resource templates mixins use
         | 
| 134 | 
            +
             | 
| 135 | 
            +
                mixins
         | 
| 136 | 
            +
                mixins "os_tpl"
         | 
| 137 | 
            +
                mixins "resource_tpl"
         | 
| 138 | 
            +
             | 
| 139 | 
            +
            To create a new compute resource use
         | 
| 140 | 
            +
             | 
| 141 | 
            +
                os = mixin 'my_os', 'os_tpl'
         | 
| 142 | 
            +
                size = mixin 'large', 'resource_tpl'
         | 
| 143 | 
            +
                cmpt = resource "compute"
         | 
| 144 | 
            +
                cmpt.mixins << os << size
         | 
| 145 | 
            +
                cmpt.attributes.occi!.core!.title = "My VM"
         | 
| 146 | 
            +
                create cmpt
         | 
| 147 | 
            +
             | 
| 148 | 
            +
            To get a description of a specific resource use
         | 
| 149 | 
            +
             | 
| 150 | 
            +
                describe "https://<ENDPOINT>:<PORT>/compute/<OCCI_ID>"
         | 
| 151 | 
            +
                describe "https://<ENDPOINT>:<PORT>/storage/<OCCI_ID>"
         | 
| 152 | 
            +
                describe "https://<ENDPOINT>:<PORT>/network/<OCCI_ID>"
         | 
| 153 | 
            +
             | 
| 154 | 
            +
            To delete a specific resource use
         | 
| 155 | 
            +
             | 
| 156 | 
            +
                delete "https://<ENDPOINT>:<PORT>/compute/<OCCI_ID>"
         | 
| 157 | 
            +
                delete "https://<ENDPOINT>:<PORT>/storage/<OCCI_ID>"
         | 
| 158 | 
            +
                delete "https://<ENDPOINT>:<PORT>/network/<OCCI_ID>"
         | 
| 159 | 
            +
             | 
| 160 | 
            +
            #### API
         | 
| 161 | 
            +
            If you need low level access to parts of the OCCI client or need to use more than one instance
         | 
| 162 | 
            +
            at a time, you should use the OCCI client API directly.
         | 
| 163 | 
            +
             | 
| 68 164 | 
             
            To connect to an OCCI endpoint/server (e.g. running on http://localhost:3000/ )
         | 
| 69 165 |  | 
| 70 | 
            -
                client = OCCI::Client.new('http:// | 
| 166 | 
            +
                client = OCCI::Client.new('http://localhost:3300',auth||=nil)
         | 
| 71 167 |  | 
| 72 168 | 
             
            All available categories are automatically registered to the OCCI model during client initialization. You can get them via
         | 
| 73 169 |  | 
| 74 170 | 
             
                client.model
         | 
| 75 171 |  | 
| 76 | 
            -
            To get  | 
| 172 | 
            +
            To get the list of available resource types or mixin types use
         | 
| 173 | 
            +
             | 
| 174 | 
            +
                client.get_resource_types
         | 
| 175 | 
            +
                client.get_mixin_types
         | 
| 176 | 
            +
             | 
| 177 | 
            +
            To get compute, storage or network descriptions use
         | 
| 178 | 
            +
             | 
| 179 | 
            +
                client.describe "compute"
         | 
| 180 | 
            +
                client.describe "storage"
         | 
| 181 | 
            +
                client.describe "network"
         | 
| 77 182 |  | 
| 78 | 
            -
             | 
| 183 | 
            +
            To get the location of compute, storage or network resources use
         | 
| 79 184 |  | 
| 80 | 
            -
             | 
| 185 | 
            +
                client.list "compute"
         | 
| 186 | 
            +
                client.list "storage"
         | 
| 187 | 
            +
                client.list "network"
         | 
| 81 188 |  | 
| 82 | 
            -
             | 
| 83 | 
            -
                client.get storage
         | 
| 84 | 
            -
                client.get network
         | 
| 189 | 
            +
            To get the identifiers of specific mixins in specific mixin types use
         | 
| 85 190 |  | 
| 86 | 
            -
             | 
| 191 | 
            +
                client.find_mixin "my_template", "os_tpl"
         | 
| 192 | 
            +
                client.find_mixin "small", "resource_tpl"
         | 
| 87 193 |  | 
| 88 | 
            -
             | 
| 194 | 
            +
            To get the identifiers of specific mixins with unknown types use
         | 
| 89 195 |  | 
| 90 | 
            -
             | 
| 196 | 
            +
                client.find_mixin "medium"
         | 
| 91 197 |  | 
| 92 | 
            -
            To get  | 
| 198 | 
            +
            To get mixin descriptions use
         | 
| 93 199 |  | 
| 94 | 
            -
                client. | 
| 95 | 
            -
                client. | 
| 200 | 
            +
                client.find_mixin "medium", nil, true
         | 
| 201 | 
            +
                client.find_mixin "my_template", "os_tpl", true
         | 
| 202 | 
            +
             | 
| 203 | 
            +
            To get a list of names of all / OS templates / Resource templates mixins use
         | 
| 204 | 
            +
             | 
| 205 | 
            +
                client.get_mixins
         | 
| 206 | 
            +
                client.get_mixins "os_tpl"
         | 
| 207 | 
            +
                client.get_mixins "resource_tpl"
         | 
| 96 208 |  | 
| 97 209 | 
             
            To create a new compute resource use
         | 
| 98 210 |  | 
| 99 | 
            -
                os = client. | 
| 100 | 
            -
                size = client. | 
| 101 | 
            -
                cmpt =  | 
| 211 | 
            +
                os = client.find_mixin 'my_os', 'os_tpl'
         | 
| 212 | 
            +
                size = client.find_mixin 'large', 'resource_tpl'
         | 
| 213 | 
            +
                cmpt = client.get_resource "compute"
         | 
| 102 214 | 
             
                cmpt.mixins << os << size
         | 
| 103 215 | 
             
                cmpt.attributes.occi!.core!.title = "My VM"
         | 
| 104 216 | 
             
                client.create cmpt
         | 
| 105 217 |  | 
| 106 | 
            -
             | 
| 218 | 
            +
            To get a description of a specific resource use
         | 
| 219 | 
            +
             | 
| 220 | 
            +
                client.describe "https://<ENDPOINT>:<PORT>/compute/<OCCI_ID>"
         | 
| 221 | 
            +
                client.describe "https://<ENDPOINT>:<PORT>/storage/<OCCI_ID>"
         | 
| 222 | 
            +
                client.describe "https://<ENDPOINT>:<PORT>/network/<OCCI_ID>"
         | 
| 223 | 
            +
             | 
| 224 | 
            +
            To delete a specific resource use
         | 
| 225 | 
            +
             | 
| 226 | 
            +
                client.delete "https://<ENDPOINT>:<PORT>/compute/<OCCI_ID>"
         | 
| 227 | 
            +
                client.delete "https://<ENDPOINT>:<PORT>/storage/<OCCI_ID>"
         | 
| 228 | 
            +
                client.delete "https://<ENDPOINT>:<PORT>/network/<OCCI_ID>"
         | 
| 229 | 
            +
             | 
| 230 | 
            +
            #### Logging
         | 
| 107 231 |  | 
| 108 232 | 
             
            The OCCI gem includes its own logging mechanism using a message queue. By default, no one is listening to that queue.
         | 
| 109 233 | 
             
            A new OCCI Logger can be initialized by specifying the log destination (either a filename or an IO object like
         | 
| @@ -117,7 +241,7 @@ You can always, even if there is no logger defined, log output using the class m | |
| 117 241 |  | 
| 118 242 | 
             
                OCCI::Log.info("Test message")
         | 
| 119 243 |  | 
| 120 | 
            -
             | 
| 244 | 
            +
            #### Registering categories in the OCCI Model
         | 
| 121 245 |  | 
| 122 246 | 
             
            Before the parser may be used, the available categories have to be registered in the OCCI Model.
         | 
| 123 247 |  | 
| @@ -129,7 +253,7 @@ For categories already specified by the OCCI WG a method exists in the OCCI Mode | |
| 129 253 | 
             
            Further categories can either be registered from files which include OCCI collections in JSON formator or from parsed
         | 
| 130 254 | 
             
             JSON objects (e.g. from the query interface of an OCCI service endpoint).
         | 
| 131 255 |  | 
| 132 | 
            -
             | 
| 256 | 
            +
            #### Parsing OCCI messages
         | 
| 133 257 |  | 
| 134 258 | 
             
            The OCCI gem includes a Parser to easily parse OCCI messages. With a given media type (e.g. json,
         | 
| 135 259 | 
             
            xml or plain text) the parser analyses the content of the message body and, if supplied,
         | 
| @@ -139,11 +263,11 @@ category and a message with an entity which has a kind, it has to be specified i | |
| 139 263 |  | 
| 140 264 | 
             
            OCCI messages can be parsed to an OCCI collection for example like
         | 
| 141 265 |  | 
| 142 | 
            -
                media_type = text/plain
         | 
| 266 | 
            +
                media_type = 'text/plain'
         | 
| 143 267 | 
             
                body = %Q|Category: compute; scheme="http://schemas.ogf.org/occi/infrastructure#"; class="kind"|
         | 
| 144 268 | 
             
                collection=OCCI::Parser.parse(media_type, body)
         | 
| 145 269 |  | 
| 146 | 
            -
             | 
| 270 | 
            +
            #### Parsing OVF / OVA files
         | 
| 147 271 |  | 
| 148 272 | 
             
            Parsing of OVF/OVA files is partly supported and will be improved in future versions.
         | 
| 149 273 |  | 
| @@ -236,4 +360,4 @@ Install dependencies for deployment | |
| 236 360 | 
             
            2. Create a branch (git checkout -b my_markup)
         | 
| 237 361 | 
             
            3. Commit your changes (git commit -am "My changes")
         | 
| 238 362 | 
             
            4. Push to the branch (git push origin my_markup)
         | 
| 239 | 
            -
            5. Create an Issue with a link to your branch
         | 
| 363 | 
            +
            5. Create an Issue with a link to your branch
         | 
    
        data/bin/occi
    CHANGED
    
    | @@ -17,13 +17,130 @@ | |
| 17 17 | 
             
            require 'rubygems'
         | 
| 18 18 | 
             
            require 'occi'
         | 
| 19 19 | 
             
            require 'pp'
         | 
| 20 | 
            -
            require ' | 
| 20 | 
            +
            require 'highline/import'
         | 
| 21 | 
            +
            require 'openssl'
         | 
| 21 22 |  | 
| 22 | 
            -
             | 
| 23 | 
            +
            # OcciOpts is not part of the occi required above
         | 
| 24 | 
            +
            require 'occi/client/occiopts'
         | 
| 25 | 
            +
             | 
| 26 | 
            +
            extend OCCI::DSL
         | 
| 27 | 
            +
             | 
| 28 | 
            +
            # get arguments and validate/parse them to an ostruct
         | 
| 29 | 
            +
            options = OcciOpts.parse ARGV
         | 
| 30 | 
            +
             | 
| 31 | 
            +
            # initiate the Logger
         | 
| 32 | 
            +
            logger = OCCI::Log.new(options.log[:out])
         | 
| 33 | 
            +
            logger.level = options.log[:level]
         | 
| 34 | 
            +
            options.log[:logger] = logger
         | 
| 35 | 
            +
             | 
| 36 | 
            +
            OCCI::Log.info "Starting OCCI client ..."
         | 
| 37 | 
            +
            OCCI::Log.debug "Options: #{options}"
         | 
| 38 | 
            +
             | 
| 39 | 
            +
            # running with an empty password?
         | 
| 40 | 
            +
            if options.auth[:password].nil? or options.auth[:user_cert_password].nil?
         | 
| 41 | 
            +
              options.auth[:password] = options.auth[:user_cert_password] = ask("Enter password: ") { |q| q.echo = false } unless options.auth[:type] == "none"
         | 
| 42 | 
            +
            end
         | 
| 23 43 |  | 
| 24 44 | 
             
            begin
         | 
| 25 | 
            -
             | 
| 45 | 
            +
             | 
| 46 | 
            +
              OCCI::Log.info "Establishing a connection to #{options.endpoint} ..."
         | 
| 47 | 
            +
              connect options.endpoint, options.auth, options.log, true, options.media_type
         | 
| 48 | 
            +
             | 
| 49 | 
            +
              OCCI::Log.info "Executing action #{options.action.to_s} on #{options.resource} ..."
         | 
| 50 | 
            +
              case options.action
         | 
| 51 | 
            +
              when :list
         | 
| 52 | 
            +
             | 
| 53 | 
            +
                if resource_types.include? options.resource or resource_type_identifiers.include? options.resource
         | 
| 54 | 
            +
                  pp list options.resource
         | 
| 55 | 
            +
                elsif mixin_types.include? options.resource
         | 
| 56 | 
            +
                  pp mixins options.resource
         | 
| 57 | 
            +
                elsif mixin_type_identifiers.include? options.resource
         | 
| 58 | 
            +
                  pp mixins options.resource.split('#').last
         | 
| 59 | 
            +
                else 
         | 
| 60 | 
            +
                  puts "Unknown resource #{options.resource}, there is nothing to list here!"
         | 
| 61 | 
            +
                end
         | 
| 62 | 
            +
             | 
| 63 | 
            +
              when :describe
         | 
| 64 | 
            +
             | 
| 65 | 
            +
                if resource_types.include? options.resource or resource_type_identifiers.include? options.resource or options.resource.start_with? options.endpoint
         | 
| 66 | 
            +
                  pp describe options.resource
         | 
| 67 | 
            +
                elsif mixin_types.include? options.resource
         | 
| 68 | 
            +
                  mixins(options.resource).each do |mxn|
         | 
| 69 | 
            +
                    mxn = mxn.split("#").last
         | 
| 70 | 
            +
                    pp mixin(mxn, options.resource, true)
         | 
| 71 | 
            +
                  end
         | 
| 72 | 
            +
                elsif mixin_type_identifiers.include? options.resource
         | 
| 73 | 
            +
                  mixins(options.resource.split('#').last).each do |mxn|
         | 
| 74 | 
            +
                    mxn = mxn.split("#").last
         | 
| 75 | 
            +
                    pp mixin(mxn, options.resource, true)
         | 
| 76 | 
            +
                  end
         | 
| 77 | 
            +
                elsif mixins.include? options.resource
         | 
| 78 | 
            +
                  mxn_type,mxn = options.resource.split("/").last.split('#')
         | 
| 79 | 
            +
                  pp mixin(mxn, mxn_type, true)
         | 
| 80 | 
            +
                elsif mixin_types.include? options.resource.split('#').first
         | 
| 81 | 
            +
                  mxn_type,mxn = options.resource.split('#')
         | 
| 82 | 
            +
                  pp mixin(mxn, mxn_type, true)
         | 
| 83 | 
            +
                else
         | 
| 84 | 
            +
                  puts "Unknown resource #{options.resource}, there is nothing to describe here!"
         | 
| 85 | 
            +
                end
         | 
| 86 | 
            +
             | 
| 87 | 
            +
              when :create
         | 
| 88 | 
            +
                
         | 
| 89 | 
            +
                if resource_types.include? options.resource or resource_type_identifiers.include? options.resource
         | 
| 90 | 
            +
                  raise "Not yet implemented!" unless options.resource.include? "compute"
         | 
| 91 | 
            +
                  
         | 
| 92 | 
            +
                  res = resource options.resource
         | 
| 93 | 
            +
             | 
| 94 | 
            +
                  OCCI::Log.debug "Creating #{options.resource}:\n#{res.inspect}"
         | 
| 95 | 
            +
                  OCCI::Log.debug "with mixins:#{options.mixin}"
         | 
| 96 | 
            +
                  
         | 
| 97 | 
            +
                  options.mixin.keys.each do |type|
         | 
| 98 | 
            +
                    OCCI::Log.debug "Adding mixins of type #{type} to #{options.resource}"
         | 
| 99 | 
            +
                    options.mixin[type].each do |name|
         | 
| 100 | 
            +
                      mxn = mixin name, type
         | 
| 101 | 
            +
             | 
| 102 | 
            +
                      raise "Unknown mixin #{type}##{name}, stopping here!" if mxn.nil?
         | 
| 103 | 
            +
                      OCCI::Log.debug "Adding mixin #{mxn} to #{options.resource}"
         | 
| 104 | 
            +
                      res.mixins << mxn
         | 
| 105 | 
            +
                    end
         | 
| 106 | 
            +
                  end
         | 
| 107 | 
            +
             | 
| 108 | 
            +
                  #TODO: set other attributes
         | 
| 109 | 
            +
                  res.attributes.occi!.core!.title = options.resource_title
         | 
| 110 | 
            +
             | 
| 111 | 
            +
                  puts create res
         | 
| 112 | 
            +
                else
         | 
| 113 | 
            +
                  puts "Unknown resource #{options.resource}, there is nothing to create here!"
         | 
| 114 | 
            +
                end
         | 
| 115 | 
            +
             | 
| 116 | 
            +
              when :delete
         | 
| 117 | 
            +
                result = delete options.resource
         | 
| 118 | 
            +
             | 
| 119 | 
            +
                if result
         | 
| 120 | 
            +
                  puts "Resource #{options.resource} successfully removed!"
         | 
| 121 | 
            +
                else
         | 
| 122 | 
            +
                  puts "Failed to remove resource #{options.resource}!"
         | 
| 123 | 
            +
                end
         | 
| 124 | 
            +
              when :trigger
         | 
| 125 | 
            +
                raise "Not yet implemented!"
         | 
| 126 | 
            +
              else
         | 
| 127 | 
            +
                raise "Unknown action [#{options.action}]!"
         | 
| 128 | 
            +
              end
         | 
| 129 | 
            +
             | 
| 130 | 
            +
            rescue OpenSSL::SSL::SSLError => ssl_ex
         | 
| 131 | 
            +
              OCCI::Log.error "An SSL Auth Error occurred! Please, make sure your credentials are valid and the endpoind is trusted! Message: #{ssl_ex.message}"
         | 
| 132 | 
            +
              raise ssl_ex if options.debug
         | 
| 133 | 
            +
              exit!
         | 
| 134 | 
            +
            rescue OpenSSL::PKey::RSAError => key_ex
         | 
| 135 | 
            +
              OCCI::Log.error "An X509 Error occurred! Please, check your credentials! Message: #{key_ex.message}"
         | 
| 136 | 
            +
              raise key_ex if options.debug
         | 
| 137 | 
            +
              exit!
         | 
| 26 138 | 
             
            rescue Exception => ex
         | 
| 27 | 
            -
               | 
| 139 | 
            +
              OCCI::Log.error "An error occurred! Message: #{ex.message}"
         | 
| 140 | 
            +
              raise ex if options.debug
         | 
| 28 141 | 
             
              exit!
         | 
| 29 142 | 
             
            end
         | 
| 143 | 
            +
             | 
| 144 | 
            +
            OCCI::Log.info "OCCI client is shutting down ..."
         | 
| 145 | 
            +
             | 
| 146 | 
            +
            exit!(true)
         | 
| @@ -3,23 +3,24 @@ require 'occi' | |
| 3 3 | 
             
            require 'pp'
         | 
| 4 4 |  | 
| 5 5 | 
             
            ## options
         | 
| 6 | 
            -
            use_os_temlate = true | 
| 7 | 
            -
            OS_TEMPLATE | 
| 6 | 
            +
            use_os_temlate = true         # use OS_TEMPLATE or NETWORK + STORAGE + INSTANCE TYPE
         | 
| 7 | 
            +
            OS_TEMPLATE    = 'monitoring' # name of the VM template in ON
         | 
| 8 8 |  | 
| 9 | 
            -
            clean_up_compute = true | 
| 9 | 
            +
            clean_up_compute = true       # issue DELETE <RESOURCE> after we are done
         | 
| 10 10 |  | 
| 11 | 
            -
            USER_CERT | 
| 11 | 
            +
            USER_CERT          = ENV['HOME'] + '/.globus/usercred.pem'
         | 
| 12 12 | 
             
            USER_CERT_PASSWORD = 'mypassphrase'
         | 
| 13 | 
            -
            CA_PATH | 
| 13 | 
            +
            CA_PATH            = '/etc/grid-security/certificates'
         | 
| 14 | 
            +
            ENDPOINT           = 'https://localhost:3300'
         | 
| 14 15 |  | 
| 15 16 | 
             
            ## get an OCCI::Client instance
         | 
| 16 | 
            -
            client = OCCI::Client.new( | 
| 17 | 
            -
             | 
| 18 | 
            -
             | 
| 19 | 
            -
             | 
| 20 | 
            -
             | 
| 21 | 
            -
             | 
| 22 | 
            -
             | 
| 17 | 
            +
            client = OCCI::Client.new(ENDPOINT,
         | 
| 18 | 
            +
                    { :type               => "x509",
         | 
| 19 | 
            +
                      :user_cert          => USER_CERT,
         | 
| 20 | 
            +
                      :user_cert_password => USER_CERT_PASSWORD,
         | 
| 21 | 
            +
                      :ca_path            => CA_PATH },
         | 
| 22 | 
            +
                    { :out   => STDERR,
         | 
| 23 | 
            +
                      :level => OCCI::Log::DEBUG })
         | 
| 23 24 |  | 
| 24 25 | 
             
            puts "\n\nListing all available resource types:"
         | 
| 25 26 | 
             
            client.get_resource_types.each do |type|
         | 
    
        data/lib/occi/api/client.rb
    CHANGED
    
    | @@ -428,12 +428,13 @@ module OCCI | |
| 428 428 | 
             
                  response = if filter
         | 
| 429 429 | 
             
                    categories = filter.categories.collect { |category| category.to_text }.join(',')
         | 
| 430 430 | 
             
                    attributes = filter.entities.collect { |entity| entity.attributes.combine.collect { |k, v| k + '=' + v } }.join(',')
         | 
| 431 | 
            +
                    
         | 
| 431 432 | 
             
                    headers = self.class.headers.clone
         | 
| 432 433 | 
             
                    headers['Content-Type'] = 'text/occi'
         | 
| 433 434 | 
             
                    headers['Category'] = categories unless categories.empty?
         | 
| 434 435 | 
             
                    headers['X-OCCI-Attributes'] = attributes unless attributes.empty?
         | 
| 435 | 
            -
             | 
| 436 | 
            -
             | 
| 436 | 
            +
             | 
| 437 | 
            +
                    self.class.get(@endpoint + path, :headers => headers)
         | 
| 437 438 | 
             
                  else
         | 
| 438 439 | 
             
                    self.class.get(@endpoint + path)
         | 
| 439 440 | 
             
                  end
         | 
| @@ -0,0 +1,146 @@ | |
| 1 | 
            +
            require 'ostruct'
         | 
| 2 | 
            +
            require 'optparse'
         | 
| 3 | 
            +
             | 
| 4 | 
            +
            class OcciOpts
         | 
| 5 | 
            +
             | 
| 6 | 
            +
              def self.parse(args)
         | 
| 7 | 
            +
             | 
| 8 | 
            +
                options = OpenStruct.new
         | 
| 9 | 
            +
                
         | 
| 10 | 
            +
                options.debug = false
         | 
| 11 | 
            +
                options.verbose = false
         | 
| 12 | 
            +
                
         | 
| 13 | 
            +
                options.log = {}
         | 
| 14 | 
            +
                options.log[:out] = STDERR
         | 
| 15 | 
            +
                options.log[:level] = OCCI::Log::WARN
         | 
| 16 | 
            +
                
         | 
| 17 | 
            +
                options.endpoint = "https://localhost:3300/"
         | 
| 18 | 
            +
                
         | 
| 19 | 
            +
                options.auth = {}
         | 
| 20 | 
            +
                options.auth[:type] = "none"
         | 
| 21 | 
            +
                options.auth[:user_cert] = ENV['HOME'] + "/.globus/usercred.pem"
         | 
| 22 | 
            +
                options.auth[:ca_path] = "/etc/grid-security/certificates"
         | 
| 23 | 
            +
                options.auth[:username] = "anonymous"
         | 
| 24 | 
            +
                
         | 
| 25 | 
            +
                options.media_type = "application/occi+json"
         | 
| 26 | 
            +
             | 
| 27 | 
            +
                opts = OptionParser.new do |opts|
         | 
| 28 | 
            +
                  opts.banner = "Usage: occi [OPTIONS]"
         | 
| 29 | 
            +
             | 
| 30 | 
            +
                  opts.separator ""
         | 
| 31 | 
            +
                  opts.separator "Options:"
         | 
| 32 | 
            +
             | 
| 33 | 
            +
                  opts.on("--endpoint URI", String, "OCCI server URI, defaults to '#{options.endpoint}'") do |endpoint|
         | 
| 34 | 
            +
                    options.endpoint = endpoint
         | 
| 35 | 
            +
                  end
         | 
| 36 | 
            +
             | 
| 37 | 
            +
                  opts.on("--auth METHOD", [:x509, :basic, :digest, :none], "Authentication method, defaults to '#{options.auth[:type]}'") do |auth|
         | 
| 38 | 
            +
                    options.auth[:type] = auth.to_s
         | 
| 39 | 
            +
                  end
         | 
| 40 | 
            +
             | 
| 41 | 
            +
                  opts.on("--username USER", String, "Username for basic or digest authentication, defaults to '#{options.auth[:username]}'") do |username|
         | 
| 42 | 
            +
                    options.auth[:username] = username
         | 
| 43 | 
            +
                  end
         | 
| 44 | 
            +
             | 
| 45 | 
            +
                  opts.on("--password PASSWORD", String, "Password for basic, digest or x509 authentication") do |password|
         | 
| 46 | 
            +
                    options.auth[:password] = password
         | 
| 47 | 
            +
                    options.auth[:user_cert_password] = password
         | 
| 48 | 
            +
                  end
         | 
| 49 | 
            +
             | 
| 50 | 
            +
                  opts.on("--ca-path PATH", String, "Path to CA certificates, defaults to '#{options.auth[:ca_path]}'") do |ca_path|
         | 
| 51 | 
            +
                    options.auth[:ca_path] = ca_path
         | 
| 52 | 
            +
                  end
         | 
| 53 | 
            +
             | 
| 54 | 
            +
                  opts.on("--user-cred X509_CREDENTIALS", String, "Path to user's x509 credentials, defaults to '#{options.auth[:user_cert]}'") do |user_cred|
         | 
| 55 | 
            +
                    options.auth[:user_cert] = user_cred
         | 
| 56 | 
            +
                  end
         | 
| 57 | 
            +
             | 
| 58 | 
            +
                  opts.on("--media-type MEDIA_TYPE", ["application/occi+json", "application/occi+xml", "text/plain"], "Media type for client <-> server communication, defaults to '#{options.media_type}'") do |media_type|
         | 
| 59 | 
            +
                    options.media_type = media_type
         | 
| 60 | 
            +
                  end
         | 
| 61 | 
            +
             | 
| 62 | 
            +
                  opts.on("--resource RESOURCE", String, "Resource to be queried (e.g. network, compute, storage etc.), required") do |resource|
         | 
| 63 | 
            +
                    options.resource = resource
         | 
| 64 | 
            +
                  end
         | 
| 65 | 
            +
             | 
| 66 | 
            +
                  opts.on("--resource-title TITLE", String, "Resource title for new resources") do |resource_title|
         | 
| 67 | 
            +
                    options.resource_title = resource_title
         | 
| 68 | 
            +
                  end
         | 
| 69 | 
            +
             | 
| 70 | 
            +
                  opts.on("--action ACTION", [:list, :describe, :create, :delete, :trigger], "Action to be performed on the resource, required") do |action|
         | 
| 71 | 
            +
                    options.action = action
         | 
| 72 | 
            +
                  end
         | 
| 73 | 
            +
             | 
| 74 | 
            +
                  opts.on("--mixin NAME", String, "Type and name of the mixin as TYPE#NAME (e.g. os_tpl#monitoring, resource_tpl#medium)") do |mixin|
         | 
| 75 | 
            +
                    parts = mixin.split("#")
         | 
| 76 | 
            +
             | 
| 77 | 
            +
                    raise "Unknown mixin format! Use TYPE#NAME!" unless parts.length == 2
         | 
| 78 | 
            +
             | 
| 79 | 
            +
                    options.mixin = {} if options.mixin.nil?
         | 
| 80 | 
            +
                    options.mixin[parts[0]] = [] if options.mixin[parts[0]].nil?
         | 
| 81 | 
            +
                    options.mixin[parts[0]] << parts[1]
         | 
| 82 | 
            +
                  end
         | 
| 83 | 
            +
             | 
| 84 | 
            +
                  opts.on("--trigger-action TRIGGER_ACTION", String, "Action to be triggered on the resource") do |trigger_action|
         | 
| 85 | 
            +
                    options.trigger_action = trigger_action
         | 
| 86 | 
            +
                  end
         | 
| 87 | 
            +
             | 
| 88 | 
            +
                  opts.on("--log-to OUTPUT", [:STDOUT, :stdout, :STDERR, :stderr], "Log to the specified device, defaults to 'STDERR'") do |log_to|
         | 
| 89 | 
            +
                    options.log[:out] = STDOUT if log_to == :stdout or log_to == :STDOUT
         | 
| 90 | 
            +
                  end
         | 
| 91 | 
            +
             | 
| 92 | 
            +
                  opts.on_tail("--debug", "Enable debugging messages") do |debug|
         | 
| 93 | 
            +
                    options.debug = debug
         | 
| 94 | 
            +
                    options.log[:level] = OCCI::Log::DEBUG
         | 
| 95 | 
            +
                  end
         | 
| 96 | 
            +
             | 
| 97 | 
            +
                  opts.on_tail("--verbose", "Be more verbose, less intrusive than debug mode") do |verbose|
         | 
| 98 | 
            +
                    options.verbose = verbose
         | 
| 99 | 
            +
                    options.log[:level] = OCCI::Log::INFO unless options.log[:level] == OCCI::Log::DEBUG
         | 
| 100 | 
            +
                  end
         | 
| 101 | 
            +
             | 
| 102 | 
            +
                  opts.on_tail("-h", "--help", "Show this message") do
         | 
| 103 | 
            +
                    puts opts
         | 
| 104 | 
            +
                    exit!
         | 
| 105 | 
            +
                  end
         | 
| 106 | 
            +
             | 
| 107 | 
            +
                  opts.on_tail("--version", "Show version") do
         | 
| 108 | 
            +
                    puts OCCI::VERSION
         | 
| 109 | 
            +
                    exit!(true)
         | 
| 110 | 
            +
                  end
         | 
| 111 | 
            +
             | 
| 112 | 
            +
                end
         | 
| 113 | 
            +
             | 
| 114 | 
            +
                begin
         | 
| 115 | 
            +
                  opts.parse!(args)
         | 
| 116 | 
            +
                rescue Exception => ex
         | 
| 117 | 
            +
                  puts ex.message.capitalize
         | 
| 118 | 
            +
                  puts opts
         | 
| 119 | 
            +
                  exit!
         | 
| 120 | 
            +
                end
         | 
| 121 | 
            +
             | 
| 122 | 
            +
                mandatory = []
         | 
| 123 | 
            +
             | 
| 124 | 
            +
                if options.action == :trigger
         | 
| 125 | 
            +
                  mandatory << :trigger_action
         | 
| 126 | 
            +
                end
         | 
| 127 | 
            +
             | 
| 128 | 
            +
                if options.action == :create
         | 
| 129 | 
            +
                  mandatory << :mixin << :resource_title
         | 
| 130 | 
            +
                end
         | 
| 131 | 
            +
             | 
| 132 | 
            +
                mandatory.concat [:resource, :action]
         | 
| 133 | 
            +
                
         | 
| 134 | 
            +
                options_hash = options.marshal_dump
         | 
| 135 | 
            +
             | 
| 136 | 
            +
                missing = mandatory.select{ |param| options_hash[param].nil? }
         | 
| 137 | 
            +
                if not missing.empty?
         | 
| 138 | 
            +
                  puts "Missing required arguments: #{missing.join(', ')}"
         | 
| 139 | 
            +
                  puts opts
         | 
| 140 | 
            +
                  exit!
         | 
| 141 | 
            +
                end
         | 
| 142 | 
            +
             | 
| 143 | 
            +
                options
         | 
| 144 | 
            +
              end
         | 
| 145 | 
            +
             | 
| 146 | 
            +
            end
         | 
    
        data/lib/occi/collection.rb
    CHANGED
    
    | @@ -59,6 +59,13 @@ module OCCI | |
| 59 59 | 
             
                  text
         | 
| 60 60 | 
             
                end
         | 
| 61 61 |  | 
| 62 | 
            +
                def to_header
         | 
| 63 | 
            +
                  header = Hashie::Mash.new
         | 
| 64 | 
            +
                  header[:Category] = self.categories.collect {|category| category.to_text}.join(',') if self.categories.any?
         | 
| 65 | 
            +
                  header = self.entities.first.to_header if self.entities.any?
         | 
| 66 | 
            +
                  header
         | 
| 67 | 
            +
                end
         | 
| 68 | 
            +
             | 
| 62 69 | 
             
                def inspect
         | 
| 63 70 | 
             
                  JSON.pretty_generate(JSON.parse(to_json))
         | 
| 64 71 | 
             
                end
         | 
    
        data/lib/occi/core/category.rb
    CHANGED
    
    
    
        data/lib/occi/core/entity.rb
    CHANGED
    
    | @@ -167,6 +167,30 @@ module OCCI | |
| 167 167 | 
             
                    text
         | 
| 168 168 | 
             
                  end
         | 
| 169 169 |  | 
| 170 | 
            +
                  def to_header
         | 
| 171 | 
            +
                    scheme, term      = self.kind.split('#')
         | 
| 172 | 
            +
                    header            = Hashie::Mash.new
         | 
| 173 | 
            +
                    header['Category'] = term + ';scheme=' + scheme.inspect + ';class="kind"'
         | 
| 174 | 
            +
                    @mixins.each do |mixin|
         | 
| 175 | 
            +
                      scheme, term      = mixin.split('#')
         | 
| 176 | 
            +
                      header['Category'] += ',' + term + ';scheme=' + scheme.inspect + ';class="mixin"'
         | 
| 177 | 
            +
                    end
         | 
| 178 | 
            +
                    attributes = []
         | 
| 179 | 
            +
                    @attributes.combine.each_pair do |name, value|
         | 
| 180 | 
            +
                      name = name.inspect if name.kind_of? String
         | 
| 181 | 
            +
                      value = value.inspect if value.kind_of? String
         | 
| 182 | 
            +
                      attributes << name + '=' + value
         | 
| 183 | 
            +
                    end
         | 
| 184 | 
            +
                    header['X-OCCI-Attribute'] = attributes.join(',') if attributes.any?
         | 
| 185 | 
            +
                    links = []
         | 
| 186 | 
            +
                    @actions.each do |action|
         | 
| 187 | 
            +
                      _, term = mixin.split('#')
         | 
| 188 | 
            +
                      links << self.location + '?action=' + term + '>;rel=' + action.inspect
         | 
| 189 | 
            +
                    end
         | 
| 190 | 
            +
                    header['Link'] = links.join(',') if links.any?
         | 
| 191 | 
            +
                    header
         | 
| 192 | 
            +
                  end
         | 
| 193 | 
            +
             | 
| 170 194 | 
             
                  def inspect
         | 
| 171 195 | 
             
                    JSON.pretty_generate(JSON.parse(to_json))
         | 
| 172 196 | 
             
                  end
         | 
    
        data/lib/occi/version.rb
    CHANGED
    
    
    
        data/occi.gemspec
    CHANGED
    
    
| @@ -44,9 +44,9 @@ module OCCI | |
| 44 44 | 
             
                      self_location                                = '/link/networkinterface/456'
         | 
| 45 45 | 
             
                      kind                                     = 'http://schemas.ogf.org/occi/infrastructure#networkinterface'
         | 
| 46 46 | 
             
                      attributes                                   = Hashie::Mash.new
         | 
| 47 | 
            -
                      attributes.occi!.networkinterface!.interface = ' | 
| 48 | 
            -
                      attributes.occi!.networkinterface!.mac       = ' | 
| 49 | 
            -
                      attributes.occi!.networkinterface!.state     = ' | 
| 47 | 
            +
                      attributes.occi!.networkinterface!.interface = 'eth0'
         | 
| 48 | 
            +
                      attributes.occi!.networkinterface!.mac       = '00:11:22:33:44:55'
         | 
| 49 | 
            +
                      attributes.occi!.networkinterface!.state     = 'active'
         | 
| 50 50 | 
             
                      attributes_string                            = %Q{occi.networkinterface.interface="eth0";occi.networkinterface.mac="00:11:22:33:44:55";occi.networkinterface.state="active"}
         | 
| 51 51 | 
             
                      link_string                                  = %Q{Link: <#{target}>; rel="#{rel}"; self="#{self_location}"; category="#{kind}"; #{attributes_string}}
         | 
| 52 52 |  | 
| @@ -62,7 +62,7 @@ module OCCI | |
| 62 62 | 
             
                  describe "#X-OCCI-Attribute" do
         | 
| 63 63 | 
             
                    it "is parsed successful" do
         | 
| 64 64 | 
             
                      attribute                             = Hashie::Mash.new
         | 
| 65 | 
            -
                      attribute.occi!.compute!.architecture = ' | 
| 65 | 
            +
                      attribute.occi!.compute!.architecture = 'x86_64'
         | 
| 66 66 |  | 
| 67 67 | 
             
                      x_occi_attributes_string = %Q{X-OCCI-Attribute: occi.compute.architecture="x86_64"}
         | 
| 68 68 |  | 
    
        metadata
    CHANGED
    
    | @@ -1,7 +1,7 @@ | |
| 1 1 | 
             
            --- !ruby/object:Gem::Specification
         | 
| 2 2 | 
             
            name: occi
         | 
| 3 3 | 
             
            version: !ruby/object:Gem::Version
         | 
| 4 | 
            -
              version: 2.5. | 
| 4 | 
            +
              version: 2.5.8
         | 
| 5 5 | 
             
              prerelease: 
         | 
| 6 6 | 
             
            platform: ruby
         | 
| 7 7 | 
             
            authors:
         | 
| @@ -10,7 +10,7 @@ authors: | |
| 10 10 | 
             
            autorequire: 
         | 
| 11 11 | 
             
            bindir: bin
         | 
| 12 12 | 
             
            cert_chain: []
         | 
| 13 | 
            -
            date: 2012-09- | 
| 13 | 
            +
            date: 2012-09-11 00:00:00.000000000 Z
         | 
| 14 14 | 
             
            dependencies:
         | 
| 15 15 | 
             
            - !ruby/object:Gem::Dependency
         | 
| 16 16 | 
             
              name: json
         | 
| @@ -124,6 +124,22 @@ dependencies: | |
| 124 124 | 
             
                - - ! '>='
         | 
| 125 125 | 
             
                  - !ruby/object:Gem::Version
         | 
| 126 126 | 
             
                    version: '0'
         | 
| 127 | 
            +
            - !ruby/object:Gem::Dependency
         | 
| 128 | 
            +
              name: highline
         | 
| 129 | 
            +
              requirement: !ruby/object:Gem::Requirement
         | 
| 130 | 
            +
                none: false
         | 
| 131 | 
            +
                requirements:
         | 
| 132 | 
            +
                - - ! '>='
         | 
| 133 | 
            +
                  - !ruby/object:Gem::Version
         | 
| 134 | 
            +
                    version: '0'
         | 
| 135 | 
            +
              type: :runtime
         | 
| 136 | 
            +
              prerelease: false
         | 
| 137 | 
            +
              version_requirements: !ruby/object:Gem::Requirement
         | 
| 138 | 
            +
                none: false
         | 
| 139 | 
            +
                requirements:
         | 
| 140 | 
            +
                - - ! '>='
         | 
| 141 | 
            +
                  - !ruby/object:Gem::Version
         | 
| 142 | 
            +
                    version: '0'
         | 
| 127 143 | 
             
            - !ruby/object:Gem::Dependency
         | 
| 128 144 | 
             
              name: i18n
         | 
| 129 145 | 
             
              requirement: !ruby/object:Gem::Requirement
         | 
| @@ -175,6 +191,7 @@ files: | |
| 175 191 | 
             
            - lib/occi.rb
         | 
| 176 192 | 
             
            - lib/occi/api/client.rb
         | 
| 177 193 | 
             
            - lib/occi/api/dsl.rb
         | 
| 194 | 
            +
            - lib/occi/client/occiopts.rb
         | 
| 178 195 | 
             
            - lib/occi/collection.rb
         | 
| 179 196 | 
             
            - lib/occi/core.rb
         | 
| 180 197 | 
             
            - lib/occi/core/action.rb
         |