megam_api 0.8.1 → 0.8.2

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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: a7fec9b83d86dbf90747da9bc441fcd090f15f2b
4
- data.tar.gz: 24c8f581bb48ce1b094bdca1995219ec37daa591
3
+ metadata.gz: ea07146eea7fd29325b48224874415a83953875e
4
+ data.tar.gz: e0fc1cc6c4220220b5ca3fedab8fde4f6e2ef492
5
5
  SHA512:
6
- metadata.gz: 31c0aa4dcadca1422d6d51406d5f73efae369838ef630960b635cabc66be7ebb3dcf2ff16e321bca94855645e47b0a3629e690075df3ac5c77a0bcf9882830ab
7
- data.tar.gz: e35d039644391bb7cabf6b2570b4d23330cd6787c0268e079f35b1c16a29414faf4c2ee90ba376202457724fea07b97f7051f690a3dc378a2eeb9d935a28d367
6
+ metadata.gz: c3cfea38cfcfbaf3ba37d3dc29fccb848977f48ca79430feda954b70db0fa6e1cce030e45955ba998d172974de1505dda56017042f87db81f93f9317feefc44d
7
+ data.tar.gz: fc0faa8e998c1901e506665cce2139091924fcf6531f6d944150c7854ddcd02ed7caf6446362b87d43e0f4a631bc3ddb5cdef8418ca02153b22a42d929c62823
data/lib/megam/api.rb CHANGED
@@ -28,6 +28,7 @@ require "megam/api/predef_clouds"
28
28
  require "megam/api/cloud_tools"
29
29
  require "megam/api/cloud_tool_settings"
30
30
  require "megam/api/sshkeys"
31
+ require "megam/api/marketplaces"
31
32
  require "megam/core/server_api"
32
33
  require "megam/core/config"
33
34
  require "megam/core/stuff"
@@ -66,6 +67,8 @@ require "megam/core/cloudtoolsetting"
66
67
  require "megam/core/cloudtoolsetting_collection"
67
68
  require "megam/core/sshkey"
68
69
  require "megam/core/sshkey_collection"
70
+ require "megam/core/marketplace"
71
+ require "megam/core/marketplace_collection"
69
72
 
70
73
  #we may nuke logs out of the api
71
74
  #require "megam/api/logs"
@@ -0,0 +1,50 @@
1
+ module Megam
2
+ class API
3
+
4
+ # GET /nodes
5
+ def get_marketplaceapps
6
+ @options = {:path => '/marketplaces',:body => ""}.merge(@options)
7
+
8
+ request(
9
+ :expects => 200,
10
+ :method => :get,
11
+ :body => @options[:body]
12
+ )
13
+ end
14
+
15
+ def get_meraketplaceapp(id)
16
+ @options = {:path => "/marketplaces/#{id}",:body => ""}.merge(@options)
17
+
18
+ request(
19
+ :expects => 200,
20
+ :method => :get,
21
+ :body => @options[:body]
22
+ )
23
+ end
24
+
25
+ def post_marketplaceapp(new_node)
26
+ @options = {:path => '/marketplaces/content',
27
+ :body => Megam::JSONCompat.to_json(new_node)}.merge(@options)
28
+
29
+ request(
30
+ :expects => 201,
31
+ :method => :post,
32
+ :body => @options[:body]
33
+ )
34
+ end
35
+
36
+ #Yet to be tested
37
+ # DELETE /marketplacess/:node_id
38
+ def delete_marketplaceapp(node_id)
39
+ @options = {:path => '/marketplaces/#{node_id}',
40
+ :body => ""}.merge(@options)
41
+
42
+ request(
43
+ :expects => 200,
44
+ :method => :delete,
45
+ :body => @options[:body]
46
+ )
47
+ end
48
+
49
+ end
50
+ end
@@ -1,5 +1,5 @@
1
1
  module Megam
2
2
  class API
3
- VERSION = "0.8.1"
3
+ VERSION = "0.8.2"
4
4
  end
5
5
  end
@@ -26,7 +26,7 @@ module Megam
26
26
  end
27
27
 
28
28
  def megam_rest
29
- Megam::API.new(Megam::Config[:email], Megam::Config[:api_key])
29
+ Megam::Scm.new(Megam::Config[:name], Megam::Config[:displayName], Megam::Config[:mail], Megam::Config[:password])
30
30
  end
31
31
 
32
32
  def some_msg(arg=nil)
@@ -53,6 +53,8 @@ module Megam
53
53
  MEGAM_CLOUDINSTRUCTIONGROUP = "Megam::CloudInstructionGroup".freeze
54
54
  MEGAM_SSHKEY = "Megam::SshKey".freeze
55
55
  MEGAM_SSHKEYCOLLECTION = "Megam::SshKeyCollection".freeze
56
+ MEGAM_MARKETPLACE = "Megam::MarketPlace".freeze
57
+ MEGAM_MARKETPLACECOLLECTION = "Megam::MarketPlaceCollection".freeze
56
58
  class <<self
57
59
  # Increase the max nesting for JSON, which defaults
58
60
  # to 19, and isn't enough for some (for example, a Node within a Node)
@@ -185,6 +187,10 @@ module Megam
185
187
  Megam::SshKey
186
188
  when MEGAM_SSHKEYCOLLECTION
187
189
  Megam::SshKeyCollection
190
+ when MEGAM_MARKETPLACE
191
+ Megam::MarketPlace
192
+ when MEGAM_MARKETPLACECOLLECTION
193
+ Megam::MarketPlaceCollection
188
194
  else
189
195
  raise JSON::ParserError, "Unsupported `json_class` type '#{json_class}'"
190
196
  end
@@ -0,0 +1,263 @@
1
+ # Copyright:: Copyright (c) 2012, 2013 Megam Systems
2
+ # License:: Apache License, Version 2.0
3
+ #
4
+ # Licensed under the Apache License, Version 2.0 (the "License");
5
+ # you may not use this file except in compliance with the License.
6
+ # You may obtain a copy of the License at
7
+ #
8
+ # http://www.apache.org/licenses/LICENSE-2.0
9
+ #
10
+ # Unless required by applicable law or agreed to in writing, software
11
+ # distributed under the License is distributed on an "AS IS" BASIS,
12
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ # See the License for the specific language governing permissions and
14
+ # limitations under the License.
15
+ #
16
+ require 'hashie'
17
+
18
+ module Megam
19
+ class MarketPlace < Megam::ServerAPI
20
+ def initialize(email=nil, api_key=nil)
21
+ @id = nil
22
+ @name = nil
23
+ @logo = nil
24
+ @catagory = nil
25
+ @pricetype = nil
26
+ @features={}
27
+ @plan={}
28
+ @attach =nil
29
+ @predefnode=nil
30
+ @some_msg = {}
31
+ @approved = nil
32
+ @created_at = nil
33
+ super(email, api_key)
34
+ end
35
+
36
+ def market_place
37
+ self
38
+ end
39
+
40
+
41
+ def name(arg=nil)
42
+ if arg != nil
43
+ @name = arg
44
+ else
45
+ @name
46
+ end
47
+ end
48
+
49
+ def logo(arg=nil)
50
+ if arg != nil
51
+ @logo = arg
52
+ else
53
+ @logo
54
+ end
55
+ end
56
+
57
+ def catagory(arg=nil)
58
+ if arg != nil
59
+ @catagory = arg
60
+ else
61
+ @catagory
62
+ end
63
+ end
64
+
65
+ def id(arg=nil)
66
+ if arg != nil
67
+ @id = arg
68
+ else
69
+ @id
70
+ end
71
+ end
72
+
73
+ def pricetype(arg=nil)
74
+ if arg != nil
75
+ @pricetype = arg
76
+ else
77
+ @pricetype
78
+ end
79
+ end
80
+
81
+ def features(arg=nil)
82
+ if arg != nil
83
+ @features = arg
84
+ else
85
+ @features
86
+ end
87
+ end
88
+
89
+ def plan(arg=nil)
90
+ if arg != nil
91
+ @plan = arg
92
+ else
93
+ @plan
94
+ end
95
+ end
96
+
97
+ def predefnode(arg=nil)
98
+ if arg != nil
99
+ @predefnode = arg
100
+ else
101
+ @predefnode
102
+ end
103
+ end
104
+
105
+ def attach(arg=nil)
106
+ if arg != nil
107
+ @attach = arg
108
+ else
109
+ @attach
110
+ end
111
+ end
112
+
113
+ def approved(arg=nil)
114
+ if arg != nil
115
+ @approved = arg
116
+ else
117
+ @approved
118
+ end
119
+ end
120
+
121
+ def created_at(arg=nil)
122
+ if arg != nil
123
+ @created_at = arg
124
+ else
125
+ @created_at
126
+ end
127
+ end
128
+
129
+ def some_msg(arg=nil)
130
+ if arg != nil
131
+ @some_msg = arg
132
+ else
133
+ @some_msg
134
+ end
135
+ end
136
+
137
+ def error?
138
+ crocked = true if (some_msg.has_key?(:msg_type) && some_msg[:msg_type] == "error")
139
+ end
140
+
141
+ # Transform the ruby obj -> to a Hash
142
+ def to_hash
143
+ index_hash = Hash.new
144
+ index_hash["json_claz"] = self.class.name
145
+ index_hash["id"] = id
146
+ index_hash["name"] = name
147
+ index_hash["logo"] = logo
148
+ index_hash["catagory"] = catagory
149
+ index_hash["pricetype"] = pricetype
150
+ index_hash["features"] = features
151
+ index_hash["plan"] = plan
152
+ index_hash["attach"] = attach
153
+ index_hash["predefnode"] = predefnode
154
+ index_hash["approved"] = approved
155
+ index_hash["some_msg"] = some_msg
156
+ index_hash["created_at"] = created_at
157
+ index_hash
158
+ end
159
+
160
+ # Serialize this object as a hash: called from JsonCompat.
161
+ # Verify if this called from JsonCompat during testing.
162
+ def to_json(*a)
163
+ for_json.to_json(*a)
164
+ end
165
+
166
+ def for_json
167
+ result = {
168
+ "id" => id,
169
+ "name" => name,
170
+ "logo" => logo,
171
+ "catagory" => catagory,
172
+ "pricetype" => pricetype,
173
+ "features" => features,
174
+ "plan" => plan,
175
+ "attach" => attach,
176
+ "predefnode" => predefnode,
177
+ "approved" => approved,
178
+ "created_at" => created_at
179
+ }
180
+ result
181
+ end
182
+
183
+ def self.json_create(o)
184
+ app = new
185
+ app.id(o["id"]) if o.has_key?("id")
186
+ app.name(o["name"]) if o.has_key?("name")
187
+ app.logo(o["logo"]) if o.has_key?("logo")
188
+ app.catagory(o["catagory"]) if o.has_key?("catagory")
189
+ app.pricetype(o["pricetype"]) if o.has_key?("pricetype")
190
+ app.attach(["attach"]) if o.has_key?("attach")
191
+ app.predefnode(o["predefnode"]) if o.has_key?("predefnode")
192
+ app.approved(o["approved"]) if o.has_key?("approved")
193
+ app.created_at(o["created_at"]) if o.has_key?("created_at")
194
+ #requests
195
+ oq = o["features"]
196
+ app.features[:feature1] = oq["feature1"] if oq && oq.has_key?("feature1")
197
+ app.features[:feature2] = oq["feature2"] if oq && oq.has_key?("feature2")
198
+ app.features[:feature3] = oq["feature3"] if oq && oq.has_key?("feature3")
199
+ app.features[:feature4] = oq["feature4"] if oq && oq.has_key?("feature4")
200
+
201
+ op = o["plan"]
202
+ app.plan[:price] = op["price"] if op && op.has_key?("price")
203
+ app.plan[:description] = op["description"] if op && op.has_key?("description")
204
+ app.plan[:plantype]= op["plantype"] if op && op.has_key?("plantype")
205
+
206
+ #success or error
207
+ app.some_msg[:code] = o["code"] if o.has_key?("code")
208
+ app.some_msg[:msg_type] = o["msg_type"] if o.has_key?("msg_type")
209
+ app.some_msg[:msg]= o["msg"] if o.has_key?("msg")
210
+ app.some_msg[:links] = o["links"] if o.has_key?("links")
211
+
212
+ app
213
+ end
214
+
215
+ def self.from_hash(o,tmp_email=nil, tmp_api_key=nil)
216
+ app = self.new(tmp_email, tmp_api_key)
217
+ app.from_hash(o)
218
+ app
219
+ end
220
+
221
+ def from_hash(o)
222
+ @name = o["name"] if o.has_key?("name")
223
+ @catagory = o["catagory"] if o.has_key?("catagory")
224
+ @id = o["id"] if o.has_key?("id")
225
+ @logo = o["logo"] if o.has_key?("logo")
226
+ @pricetype = o["pricetype"] if o.has_key?("pricetype")
227
+ @features = o["features"] if o.has_key?("features")
228
+ @plan = o["plan"] if o.has_key?("plan")
229
+ @attach = o["attach"] if o.has_key?("attach")
230
+ @predefnode = o["predefnode"] if o.has_key?("predefnode")
231
+ @approved = o["approved"] if o.has_key?("approved")
232
+ @created_at = o["created_at"] if o.has_key?("created_at")
233
+ self
234
+ end
235
+
236
+ def self.create(o,tmp_email=nil, tmp_api_key=nil)
237
+ acct = from_hash(o, tmp_email, tmp_api_key)
238
+ acct.create
239
+ end
240
+
241
+ # Create the marketplace app via the REST API
242
+ def create
243
+ megam_rest.post_marketplaceapp(to_hash)
244
+ end
245
+
246
+ # Load a account by email_p
247
+ def self.show(name, tmp_email=nil, tmp_api_key=nil)
248
+ app = self.new(tmp_email, tmp_api_key)
249
+ app.megam_rest.get_marketplaceapp(name)
250
+ end
251
+
252
+ def self.list(tmp_email=nil, tmp_api_key=nil)
253
+ app = self.new(tmp_email, tmp_api_key)
254
+ app.megam_rest.get_marketplaceapps
255
+ end
256
+
257
+ def to_s
258
+ Megam::Stuff.styled_hash(to_hash)
259
+ #"---> Megam::Account:[error=#{error?}]\n"+
260
+ end
261
+
262
+ end
263
+ end
@@ -0,0 +1,148 @@
1
+ # Copyright:: Copyright (c) 2012, 2013 Megam Systems
2
+ # License:: Apache License, Version 2.0
3
+ #
4
+ # Licensed under the Apache License, Version 2.0 (the "License");
5
+ # you may not use this file except in compliance with the License.
6
+ # You may obtain a copy of the License at
7
+ #
8
+ # http://www.apache.org/licenses/LICENSE-2.0
9
+ #
10
+ # Unless required by applicable law or agreed to in writing, software
11
+ # distributed under the License is distributed on an "AS IS" BASIS,
12
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ # See the License for the specific language governing permissions and
14
+ # limitations under the License.
15
+ #
16
+ module Megam
17
+ class MarketPlaceCollection
18
+ include Enumerable
19
+
20
+
21
+ attr_reader :iterator
22
+ def initialize
23
+ @apps = Array.new
24
+ @apps_by_name = Hash.new
25
+ @insert_after_idx = nil
26
+ end
27
+
28
+ def all_apps
29
+ @apps
30
+ end
31
+
32
+ def [](index)
33
+ @apps[index]
34
+ end
35
+
36
+ def []=(index, arg)
37
+ is_megam_app(arg)
38
+ @apps[index] = arg
39
+ @apps_by_name[arg.name] = index
40
+ end
41
+
42
+ def <<(*args)
43
+ args.flatten.each do |a|
44
+ is_megam_app(a)
45
+ @apps << a
46
+ @apps_by_name[a.name] = @apps.length - 1
47
+ end
48
+ self
49
+ end
50
+
51
+ # 'push' is an alias method to <<
52
+ alias_method :push, :<<
53
+
54
+ def insert(app)
55
+ is_megam_app(app)
56
+ if @insert_after_idx
57
+ # in the middle of executing a run, so any nodes inserted now should
58
+ # be placed after the most recent addition done by the currently executing
59
+ # node
60
+ @apps.insert(@insert_after_idx + 1, app)
61
+ # update name -> location mappings and register new node
62
+ @apps_by_name.each_key do |key|
63
+ @apps_by_name[key] += 1 if @apps_by_name[key] > @insert_after_idx
64
+ end
65
+ @apps_by_name[app.name] = @insert_after_idx + 1
66
+ @insert_after_idx += 1
67
+ else
68
+ @apps << app
69
+ @apps_by_name[app.name] = @apps.length - 1
70
+ end
71
+ end
72
+
73
+ def each
74
+ @apps.each do |app|
75
+ yield app
76
+ end
77
+ end
78
+
79
+ def each_index
80
+ @apps.each_index do |i|
81
+ yield i
82
+ end
83
+ end
84
+
85
+ def empty?
86
+ @apps.empty?
87
+ end
88
+
89
+ def lookup(app)
90
+ lookup_by = nil
91
+ if app.kind_of?(Megam::MarketPlace)
92
+ lookup_by = app.name
93
+ elsif app.kind_of?(String)
94
+ lookup_by = app
95
+ else
96
+ raise ArgumentError, "Must pass a Megam::MarketPlace or String to lookup"
97
+ end
98
+ res = @apps_by_name[lookup_by]
99
+ unless res
100
+ raise ArgumentError, "Cannot find a app matching #{lookup_by} (did you define it first?)"
101
+ end
102
+ @apps[res]
103
+ end
104
+
105
+ # Transform the ruby obj -> to a Hash
106
+ def to_hash
107
+ index_hash = Hash.new
108
+ self.each do |app|
109
+ index_hash[app.name] = app.to_s
110
+ end
111
+ index_hash
112
+ end
113
+
114
+ # Serialize this object as a hash: called from JsonCompat.
115
+ # Verify if this called from JsonCompat during testing.
116
+ def to_json(*a)
117
+ for_json.to_json(*a)
118
+ end
119
+
120
+
121
+ def self.json_create(o)
122
+ collection = self.new()
123
+ o["results"].each do |apps_list|
124
+ apps_array = apps_list.kind_of?(Array) ? apps_list : [ apps_list ]
125
+ apps_array.each do |app|
126
+ collection.insert(app)
127
+ end
128
+ end
129
+ collection
130
+ end
131
+
132
+ private
133
+
134
+
135
+
136
+ def is_megam_app(arg)
137
+ unless arg.kind_of?(Megam::MarketPlace)
138
+ raise ArgumentError, "Members must be Megam::MarketPlace's"
139
+ end
140
+ true
141
+ end
142
+
143
+ def to_s
144
+ Megam::Stuff.styled_hash(to_hash)
145
+ end
146
+
147
+ end
148
+ end
@@ -0,0 +1,100 @@
1
+ require File.expand_path("#{File.dirname(__FILE__)}/test_helper")
2
+
3
+ class TestMarketplaces < MiniTest::Unit::TestCase
4
+ =begin
5
+ def test_post_marketplace
6
+ tmp_hash = {
7
+ "name" => "sample",
8
+ "logo" => "riak.logo",
9
+ "catagory" => "DB",
10
+ "pricetype" => "free",
11
+ "features" => {"feature1" => "feature1","feature2" => "feature2","feature3" => "feature3","feature4" => "feature4"},
12
+ "plan" => {"price" => "50","description" => "description","plantype" => "free"},
13
+ "attach" => "attach",
14
+ "predefnode" => "predefnode",
15
+ "approved" => "approved" }
16
+
17
+ response = megams.post_marketplaceapp(tmp_hash)
18
+ assert_equal(201, response.status)
19
+ end
20
+ =end
21
+ =begin
22
+ def test_post_node2
23
+ tmp_hash = {
24
+ "node_name" => "sundown.megam.co",
25
+ "command" => "commands2",
26
+ "predefs" => {"name" => "rails", "scm" => "https://github.com/awesome.git",
27
+ "db" => "postgres@postgresql2.megam.com/morning.megam.co", "war" => "http://s3pub.com/0.1/orion.war", "queue" => "rabbit@queue1"}
28
+ }
29
+ response = megams.post_node(tmp_hash)
30
+ assert_equal(201, response.status)
31
+ end
32
+ =end
33
+ def test_get_marketplaces
34
+ response = megams.get_marketplaceapps
35
+ assert_equal(200, response.status)
36
+ end
37
+ =begin
38
+ def test_get_node0
39
+ response = megams.get_node("black1.megam.co")
40
+ assert_equal(200, response.status)
41
+ end
42
+
43
+ def test_get_node1
44
+ response = megams.get_node("night.megam.co")
45
+ assert_equal(200, response.status)
46
+ end
47
+
48
+ def test_get_node_not_found
49
+ assert_raises(Megam::API::Errors::NotFound) do
50
+ megams.get_node("stupid.megam.co")
51
+ end
52
+ end
53
+
54
+ def test_delete_node1
55
+
56
+ @com = {
57
+ "systemprovider" => {
58
+ "provider" => {
59
+ "prov" => "chef"
60
+ }
61
+ },
62
+ "compute" => {
63
+ "cctype" => "ec2",
64
+ "cc" => {
65
+ "groups" => "",
66
+ "image" => "",
67
+ "flavor" => "",
68
+ "tenant_id" => ""
69
+ },
70
+ "access" => {
71
+ "ssh_key" => "megam_ec2",
72
+ "identity_file" => "~/.ssh/megam_ec2.pem",
73
+ "ssh_user" => "",
74
+ "vault_location" => "https://s3-ap-southeast-1.amazonaws.com/cloudkeys/sandy@megamsandbox.com/default",
75
+ "sshpub_location" => "",
76
+ "zone" => "",
77
+ "region" => "region"
78
+ }
79
+ },
80
+ "cloudtool" => {
81
+ "chef" => {
82
+ "command" => "knife",
83
+ "plugin" => "ec2 server delete", #ec2 server delete or create
84
+ "run_list" => "",
85
+ "name" => ""
86
+ }
87
+ }
88
+ }
89
+
90
+ tmp_hash = {
91
+ "node_name" => "black1.megam.co",
92
+ "req_type" => "delete", #CREATE OR DELETE
93
+ "command" => @com
94
+ }
95
+
96
+ response = megams.post_request(tmp_hash)
97
+ assert_equal(201, response.status)
98
+ end
99
+ =end
100
+ end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: megam_api
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.8.1
4
+ version: 0.8.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Kishorekumar Neelamegam, Thomas Alrin, Subash Sethurajan, Rajthilak
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2014-02-17 00:00:00.000000000 Z
11
+ date: 2014-03-05 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: excon
@@ -138,6 +138,7 @@ files:
138
138
  - lib/megam/api/errors.rb
139
139
  - lib/megam/api/login.rb
140
140
  - lib/megam/api/logs.rb
141
+ - lib/megam/api/marketplaces.rb
141
142
  - lib/megam/api/nodes.rb
142
143
  - lib/megam/api/predef_clouds.rb
143
144
  - lib/megam/api/predefs.rb
@@ -169,6 +170,8 @@ files:
169
170
  - lib/megam/core/error.rb
170
171
  - lib/megam/core/json_compat.rb
171
172
  - lib/megam/core/log.rb
173
+ - lib/megam/core/marketplace.rb
174
+ - lib/megam/core/marketplace_collection.rb
172
175
  - lib/megam/core/monologger.rb
173
176
  - lib/megam/core/node.rb
174
177
  - lib/megam/core/node_collection.rb
@@ -196,6 +199,7 @@ files:
196
199
  - test/test_helper.rb
197
200
  - test/test_login.rb
198
201
  - test/test_logs.rb
202
+ - test/test_marketplaces.rb
199
203
  - test/test_nodes.rb
200
204
  - test/test_predefclouds.rb
201
205
  - test/test_predefs.rb
@@ -221,7 +225,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
221
225
  version: '0'
222
226
  requirements: []
223
227
  rubyforge_project:
224
- rubygems_version: 2.2.0
228
+ rubygems_version: 2.1.11
225
229
  signing_key:
226
230
  specification_version: 4
227
231
  summary: Ruby Client for the Megam Cloud