studio_api 2.4.0 → 3.0.0
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/README +1 -3
 - data/VERSION +1 -1
 - data/lib/studio_api/appliance.rb +118 -29
 - data/lib/studio_api/comment.rb +26 -0
 - data/lib/studio_api/gallery.rb +140 -0
 - data/lib/studio_api/generic_request.rb +21 -17
 - data/lib/studio_api/util.rb +11 -0
 - data/lib/studio_api.rb +1 -0
 - data/test/appliance_test.rb +32 -2
 - data/test/gallery_test.rb +49 -0
 - data/test/responses/configuration.xml +108 -0
 - data/test/responses/gallery.xml +311 -0
 - data/test/responses/gallery_appliance.xml +62 -0
 - data/test/responses/manifest.xml +456 -0
 - data/test/responses/users_0.xml +5 -0
 - data/test/responses/users_1.xml +6 -0
 - data/test/responses/users_2.xml +7 -0
 - data/test/responses/versions.xml +12 -0
 - metadata +25 -5
 
    
        data/README
    CHANGED
    
    | 
         @@ -37,9 +37,7 @@ for ActiveResource error handling. 
     | 
|
| 
       37 
37 
     | 
    
         
             
              puts "Created appliance #{appliance.inspect}"
         
     | 
| 
       38 
38 
     | 
    
         | 
| 
       39 
39 
     | 
    
         
             
              #add own rpm built agains SLED11_SP1
         
     | 
| 
       40 
     | 
    
         
            -
             
     | 
| 
       41 
     | 
    
         
            -
            	  StudioApi::Rpm.upload file, "SLED11_SP1"
         
     | 
| 
       42 
     | 
    
         
            -
            	end
         
     | 
| 
      
 40 
     | 
    
         
            +
              StudioApi::Rpm.upload "/home/jreidinger/rpms/kezboard-1.0-1.60.noarch.rpm", "SLED11_SP1"
         
     | 
| 
       43 
41 
     | 
    
         
             
              # and choose it in appliance ( and of course add repository with own rpms)
         
     | 
| 
       44 
42 
     | 
    
         
             
              appliance.add_user_repository
         
     | 
| 
       45 
43 
     | 
    
         
             
              appliance.add_package "kezboard", :version => "1.0-1.60"
         
     | 
    
        data/VERSION
    CHANGED
    
    | 
         @@ -1 +1 @@ 
     | 
|
| 
       1 
     | 
    
         
            -
             
     | 
| 
      
 1 
     | 
    
         
            +
            3.0.0
         
     | 
    
        data/lib/studio_api/appliance.rb
    CHANGED
    
    | 
         @@ -24,6 +24,46 @@ module StudioApi 
     | 
|
| 
       24 
24 
     | 
    
         
             
                  self.element_name = "status"
         
     | 
| 
       25 
25 
     | 
    
         
             
                end
         
     | 
| 
       26 
26 
     | 
    
         | 
| 
      
 27 
     | 
    
         
            +
                class Configuration < ActiveResource::Base
         
     | 
| 
      
 28 
     | 
    
         
            +
                  extend StudioResource
         
     | 
| 
      
 29 
     | 
    
         
            +
                  self.element_name = "configuration"
         
     | 
| 
      
 30 
     | 
    
         
            +
             
     | 
| 
      
 31 
     | 
    
         
            +
                  def self.parse response
         
     | 
| 
      
 32 
     | 
    
         
            +
                    tree = XmlSimple.xml_in(response, "ForceArray" => ["tag","user","eula","autostart","database","volume"])
         
     | 
| 
      
 33 
     | 
    
         
            +
                    tree["tags"] = tree["tags"]["tag"].reduce({}){ |acc,t| acc.merge :tag => t} if tree["tags"]
         
     | 
| 
      
 34 
     | 
    
         
            +
                    tree["users"] = tree["users"]["user"]
         
     | 
| 
      
 35 
     | 
    
         
            +
                    tree["eulas"] = tree["eulas"]["eula"]
         
     | 
| 
      
 36 
     | 
    
         
            +
                    tree["autostarts"] = tree["autostarts"]["autostart"] if tree["autostarts"]
         
     | 
| 
      
 37 
     | 
    
         
            +
                    if tree["databases"]
         
     | 
| 
      
 38 
     | 
    
         
            +
                      tree["databases"]=  tree["databases"]["database"] 
         
     | 
| 
      
 39 
     | 
    
         
            +
                      tree["databases"].each do |d|
         
     | 
| 
      
 40 
     | 
    
         
            +
                        d["users"] = d["users"]["user"] if d["users"]
         
     | 
| 
      
 41 
     | 
    
         
            +
                      end
         
     | 
| 
      
 42 
     | 
    
         
            +
                    end
         
     | 
| 
      
 43 
     | 
    
         
            +
                    tree["lvm"]["volumes"] = tree["lvm"]["volumes"]["volume"] if tree["lvm"] && tree["lvm"]["volumes"]
         
     | 
| 
      
 44 
     | 
    
         
            +
                    Configuration.new tree
         
     | 
| 
      
 45 
     | 
    
         
            +
                  end
         
     | 
| 
      
 46 
     | 
    
         
            +
             
     | 
| 
      
 47 
     | 
    
         
            +
                  def update
         
     | 
| 
      
 48 
     | 
    
         
            +
                    appliance_id = id
         
     | 
| 
      
 49 
     | 
    
         
            +
                    attributes.delete "id"
         
     | 
| 
      
 50 
     | 
    
         
            +
                    rq = GenericRequest.new self.class.studio_connection
         
     | 
| 
      
 51 
     | 
    
         
            +
                    rq.put "/appliances/#{appliance_id.to_i}/configuration", :__raw => to_xml
         
     | 
| 
      
 52 
     | 
    
         
            +
                    attributes["id"] = appliance_id
         
     | 
| 
      
 53 
     | 
    
         
            +
                  end
         
     | 
| 
      
 54 
     | 
    
         
            +
             
     | 
| 
      
 55 
     | 
    
         
            +
                  class Firewall < ActiveResource::Base
         
     | 
| 
      
 56 
     | 
    
         
            +
                    def to_xml(options={})
         
     | 
| 
      
 57 
     | 
    
         
            +
                      if enabled == "false"
         
     | 
| 
      
 58 
     | 
    
         
            +
                        "<firewall><enabled>false</enabled></firewall>"
         
     | 
| 
      
 59 
     | 
    
         
            +
                      else
         
     | 
| 
      
 60 
     | 
    
         
            +
                        openports_xml = open_port.reduce(""){ |acc,p| acc << "<open_port>#{p}</open_port>" } #FIXME escape name
         
     | 
| 
      
 61 
     | 
    
         
            +
                        "<firewall><enabled>true</enabled>#{openports_xml}</firewall>"
         
     | 
| 
      
 62 
     | 
    
         
            +
                      end
         
     | 
| 
      
 63 
     | 
    
         
            +
                    end
         
     | 
| 
      
 64 
     | 
    
         
            +
                  end
         
     | 
| 
      
 65 
     | 
    
         
            +
                end
         
     | 
| 
      
 66 
     | 
    
         
            +
             
     | 
| 
       27 
67 
     | 
    
         
             
                # Represents repository assigned to appliance
         
     | 
| 
       28 
68 
     | 
    
         
             
                # supports find :all and deleting from appliance
         
     | 
| 
       29 
69 
     | 
    
         
             
                class Repository < ActiveResource::Base
         
     | 
| 
         @@ -64,9 +104,7 @@ module StudioApi 
     | 
|
| 
       64 
104 
     | 
    
         
             
                      options[:key] = key.to_s
         
     | 
| 
       65 
105 
     | 
    
         
             
                    end
         
     | 
| 
       66 
106 
     | 
    
         
             
                    request_str = "/appliances/#{appliance_id.to_i}/gpg_keys?name=#{name}"
         
     | 
| 
       67 
     | 
    
         
            -
                     
     | 
| 
       68 
     | 
    
         
            -
                      request_str << "&#{CGI.escape k.to_s}=#{CGI.escape v.to_s}"
         
     | 
| 
       69 
     | 
    
         
            -
                    end
         
     | 
| 
      
 107 
     | 
    
         
            +
                    request_str = Util.add_options request_str, options, false
         
     | 
| 
       70 
108 
     | 
    
         
             
                    response = GenericRequest.new(studio_connection).post request_str, data
         
     | 
| 
       71 
109 
     | 
    
         
             
                    self.new Hash.from_xml(response)["gpg_key"]
         
     | 
| 
       72 
110 
     | 
    
         
             
                  end
         
     | 
| 
         @@ -141,6 +179,69 @@ module StudioApi 
     | 
|
| 
       141 
179 
     | 
    
         
             
                  rq.post "/appliances/#{id}/cmd/add_user_repository"
         
     | 
| 
       142 
180 
     | 
    
         
             
                end
         
     | 
| 
       143 
181 
     | 
    
         | 
| 
      
 182 
     | 
    
         
            +
                def users
         
     | 
| 
      
 183 
     | 
    
         
            +
                  request_str = "/appliances/#{id.to_i}/sharing"
         
     | 
| 
      
 184 
     | 
    
         
            +
                  response = GenericRequest.new(self.class.studio_connection).get request_str
         
     | 
| 
      
 185 
     | 
    
         
            +
                  handle_users_response response
         
     | 
| 
      
 186 
     | 
    
         
            +
                end
         
     | 
| 
      
 187 
     | 
    
         
            +
             
     | 
| 
      
 188 
     | 
    
         
            +
                def add_user name
         
     | 
| 
      
 189 
     | 
    
         
            +
                  request_str = "/appliances/#{id.to_i}/sharing/#{CGI.escape name.to_s}"
         
     | 
| 
      
 190 
     | 
    
         
            +
                  response = GenericRequest.new(self.class.studio_connection).post request_str
         
     | 
| 
      
 191 
     | 
    
         
            +
                  handle_users_response response
         
     | 
| 
      
 192 
     | 
    
         
            +
                end
         
     | 
| 
      
 193 
     | 
    
         
            +
             
     | 
| 
      
 194 
     | 
    
         
            +
                def remove_user name
         
     | 
| 
      
 195 
     | 
    
         
            +
                  request_str = "/appliances/#{id.to_i}/sharing/#{CGI.escape name.to_s}"
         
     | 
| 
      
 196 
     | 
    
         
            +
                  response = GenericRequest.new(self.class.studio_connection).delete request_str
         
     | 
| 
      
 197 
     | 
    
         
            +
                  handle_users_response response
         
     | 
| 
      
 198 
     | 
    
         
            +
                end
         
     | 
| 
      
 199 
     | 
    
         
            +
             
     | 
| 
      
 200 
     | 
    
         
            +
                def manifest_file (build, options={})
         
     | 
| 
      
 201 
     | 
    
         
            +
                  build = build.image_type if build.respond_to?(:image_type)
         
     | 
| 
      
 202 
     | 
    
         
            +
                  request_str = "/appliances/#{id.to_i}/software/manifest/#{CGI.escape build.to_s}"
         
     | 
| 
      
 203 
     | 
    
         
            +
                  request_str = Util.add_options request_str, options
         
     | 
| 
      
 204 
     | 
    
         
            +
                  GenericRequest.new(self.class.studio_connection).get request_str
         
     | 
| 
      
 205 
     | 
    
         
            +
                end
         
     | 
| 
      
 206 
     | 
    
         
            +
             
     | 
| 
      
 207 
     | 
    
         
            +
                def logo
         
     | 
| 
      
 208 
     | 
    
         
            +
                  request_str = "/appliances/#{id.to_i}/configuration/logo"
         
     | 
| 
      
 209 
     | 
    
         
            +
                  GenericRequest.new(self.class.studio_connection).get request_str
         
     | 
| 
      
 210 
     | 
    
         
            +
                end
         
     | 
| 
      
 211 
     | 
    
         
            +
             
     | 
| 
      
 212 
     | 
    
         
            +
                def logo= (logo)
         
     | 
| 
      
 213 
     | 
    
         
            +
                  request_str = "/appliances/#{id.to_i}/configuration/logo"
         
     | 
| 
      
 214 
     | 
    
         
            +
                  if logo.is_a?(IO) && logo.respond_to?(:path)
         
     | 
| 
      
 215 
     | 
    
         
            +
                    GenericRequest.new(self.class.studio_connection).post request_str, :file => logo
         
     | 
| 
      
 216 
     | 
    
         
            +
                  else
         
     | 
| 
      
 217 
     | 
    
         
            +
                    File.open(logo.to_s) do |f| 
         
     | 
| 
      
 218 
     | 
    
         
            +
                      GenericRequest.new(self.class.studio_connection).post request_str, :file => f
         
     | 
| 
      
 219 
     | 
    
         
            +
                    end
         
     | 
| 
      
 220 
     | 
    
         
            +
                  end
         
     | 
| 
      
 221 
     | 
    
         
            +
                end
         
     | 
| 
      
 222 
     | 
    
         
            +
             
     | 
| 
      
 223 
     | 
    
         
            +
                def background
         
     | 
| 
      
 224 
     | 
    
         
            +
                  request_str = "/appliances/#{id.to_i}/configuration/background"
         
     | 
| 
      
 225 
     | 
    
         
            +
                  GenericRequest.new(self.class.studio_connection).get request_str
         
     | 
| 
      
 226 
     | 
    
         
            +
                end
         
     | 
| 
      
 227 
     | 
    
         
            +
             
     | 
| 
      
 228 
     | 
    
         
            +
                def background= (logo)
         
     | 
| 
      
 229 
     | 
    
         
            +
                  request_str = "/appliances/#{id.to_i}/configuration/background"
         
     | 
| 
      
 230 
     | 
    
         
            +
                  if logo.is_a?(IO) && logo.respond_to?(:path)
         
     | 
| 
      
 231 
     | 
    
         
            +
                    GenericRequest.new(self.class.studio_connection).post request_str, :file => logo
         
     | 
| 
      
 232 
     | 
    
         
            +
                  else
         
     | 
| 
      
 233 
     | 
    
         
            +
                    File.open(logo.to_s) do |f| 
         
     | 
| 
      
 234 
     | 
    
         
            +
                      GenericRequest.new(self.class.studio_connection).post request_str, :file => f
         
     | 
| 
      
 235 
     | 
    
         
            +
                    end
         
     | 
| 
      
 236 
     | 
    
         
            +
                  end
         
     | 
| 
      
 237 
     | 
    
         
            +
                end
         
     | 
| 
      
 238 
     | 
    
         
            +
             
     | 
| 
      
 239 
     | 
    
         
            +
                def configuration
         
     | 
| 
      
 240 
     | 
    
         
            +
                  request_str = "/appliances/#{id.to_i}/configuration"
         
     | 
| 
      
 241 
     | 
    
         
            +
                  response = GenericRequest.new(self.class.studio_connection).get request_str
         
     | 
| 
      
 242 
     | 
    
         
            +
                  Configuration.parse response
         
     | 
| 
      
 243 
     | 
    
         
            +
                end
         
     | 
| 
      
 244 
     | 
    
         
            +
             
     | 
| 
       144 
245 
     | 
    
         
             
                # clones appliance or template
         
     | 
| 
       145 
246 
     | 
    
         
             
                # @see (StudioApi::TemplateSet)
         
     | 
| 
       146 
247 
     | 
    
         
             
                # @param (#to_i) source_id id of source appliance
         
     | 
| 
         @@ -148,9 +249,7 @@ module StudioApi 
     | 
|
| 
       148 
249 
     | 
    
         
             
                # @return (StudioApi::Appliance) resulted appliance
         
     | 
| 
       149 
250 
     | 
    
         
             
                def self.clone source_id,options={}
         
     | 
| 
       150 
251 
     | 
    
         
             
                  request_str = "/appliances?clone_from=#{source_id.to_i}"
         
     | 
| 
       151 
     | 
    
         
            -
                   
     | 
| 
       152 
     | 
    
         
            -
                    request_str << "&#{CGI.escape k.to_s}=#{CGI.escape v.to_s}"
         
     | 
| 
       153 
     | 
    
         
            -
                  end
         
     | 
| 
      
 252 
     | 
    
         
            +
                  request_str = Util.add_options request_str, options, false
         
     | 
| 
       154 
253 
     | 
    
         
             
                  response = GenericRequest.new(studio_connection).post request_str, options
         
     | 
| 
       155 
254 
     | 
    
         
             
                  Appliance.new Hash.from_xml(response)["appliance"]
         
     | 
| 
       156 
255 
     | 
    
         
             
                end
         
     | 
| 
         @@ -197,14 +296,7 @@ module StudioApi 
     | 
|
| 
       197 
296 
     | 
    
         
             
                # @return (Array<StudioApi::Package,StudioApi::Pattern>) list of installed packages and patterns
         
     | 
| 
       198 
297 
     | 
    
         
             
                def installed_software (options = {})
         
     | 
| 
       199 
298 
     | 
    
         
             
                  request_str = "/appliances/#{id.to_i}/software/installed"
         
     | 
| 
       200 
     | 
    
         
            -
             
     | 
| 
       201 
     | 
    
         
            -
            				first = true
         
     | 
| 
       202 
     | 
    
         
            -
            				options.each do |k,v|
         
     | 
| 
       203 
     | 
    
         
            -
            					separator = first ? "?" : "&"
         
     | 
| 
       204 
     | 
    
         
            -
            					first = false
         
     | 
| 
       205 
     | 
    
         
            -
            					request_str << "#{separator}#{CGI.escape k.to_s}=#{CGI.escape v.to_s}"
         
     | 
| 
       206 
     | 
    
         
            -
            				end
         
     | 
| 
       207 
     | 
    
         
            -
            			end
         
     | 
| 
      
 299 
     | 
    
         
            +
                  request_str = Util.add_options request_str, options
         
     | 
| 
       208 
300 
     | 
    
         
             
                  response = GenericRequest.new(self.class.studio_connection).get request_str
         
     | 
| 
       209 
301 
     | 
    
         
             
                  attrs = XmlSimple.xml_in response
         
     | 
| 
       210 
302 
     | 
    
         
             
            			res = []
         
     | 
| 
         @@ -222,12 +314,9 @@ module StudioApi 
     | 
|
| 
       222 
314 
     | 
    
         
             
                # @return (Array<StudioApi::Package,StudioApi::Pattern>) list of installed packages and patterns
         
     | 
| 
       223 
315 
     | 
    
         
             
                def search_software (search_string,options={})
         
     | 
| 
       224 
316 
     | 
    
         
             
                  request_str = "/appliances/#{id.to_i}/software/search?q=#{CGI.escape search_string.to_s}"
         
     | 
| 
       225 
     | 
    
         
            -
             
     | 
| 
       226 
     | 
    
         
            -
            				request_str << "&#{CGI.escape k.to_s}=#{CGI.escape v.to_s}"
         
     | 
| 
       227 
     | 
    
         
            -
            			end
         
     | 
| 
      
 317 
     | 
    
         
            +
                  request_str = Util.add_options request_str, options, false
         
     | 
| 
       228 
318 
     | 
    
         
             
                  response = GenericRequest.new(self.class.studio_connection).get request_str
         
     | 
| 
       229 
319 
     | 
    
         
             
                  attrs = XmlSimple.xml_in response
         
     | 
| 
       230 
     | 
    
         
            -
                  return [] unless attrs["repository"]
         
     | 
| 
       231 
320 
     | 
    
         
             
            			res = []
         
     | 
| 
       232 
321 
     | 
    
         
             
            			attrs["repository"].each do |repo|
         
     | 
| 
       233 
322 
     | 
    
         
             
            				options = { "repository_id" => repo["id"].to_i }
         
     | 
| 
         @@ -241,9 +330,7 @@ module StudioApi 
     | 
|
| 
       241 
330 
     | 
    
         
             
                # @param (Hash<#to_s,#to_s>) options additional options, see API documentation
         
     | 
| 
       242 
331 
     | 
    
         
             
                def rpm_content(name, options={})
         
     | 
| 
       243 
332 
     | 
    
         
             
                  request_str = "/appliances/#{id.to_i}/cmd/download_package?name=#{CGI.escape name.to_s}"
         
     | 
| 
       244 
     | 
    
         
            -
                   
     | 
| 
       245 
     | 
    
         
            -
                    request_str << "&#{CGI.escape k.to_s}=#{CGI.escape v.to_s}"
         
     | 
| 
       246 
     | 
    
         
            -
                  end
         
     | 
| 
      
 333 
     | 
    
         
            +
                  request_str = Util.add_options request_str, options, false
         
     | 
| 
       247 
334 
     | 
    
         
             
                  GenericRequest.new(self.class.studio_connection).get request_str
         
     | 
| 
       248 
335 
     | 
    
         
             
                end
         
     | 
| 
       249 
336 
     | 
    
         | 
| 
         @@ -352,16 +439,18 @@ private 
     | 
|
| 
       352 
439 
     | 
    
         | 
| 
       353 
440 
     | 
    
         
             
            		def software_command type, options={}
         
     | 
| 
       354 
441 
     | 
    
         
             
                  request_str = "/appliances/#{id.to_i}/cmd/#{type}"
         
     | 
| 
       355 
     | 
    
         
            -
            			 
     | 
| 
       356 
     | 
    
         
            -
            				first = true
         
     | 
| 
       357 
     | 
    
         
            -
            				options.each do |k,v|
         
     | 
| 
       358 
     | 
    
         
            -
            					separator = first ? "?" : "&"
         
     | 
| 
       359 
     | 
    
         
            -
            					first = false
         
     | 
| 
       360 
     | 
    
         
            -
            					request_str << "#{separator}#{CGI.escape k.to_s}=#{CGI.escape v.to_s}"
         
     | 
| 
       361 
     | 
    
         
            -
            				end
         
     | 
| 
       362 
     | 
    
         
            -
            			end
         
     | 
| 
      
 442 
     | 
    
         
            +
            			request_str = Util.add_options request_str, options
         
     | 
| 
       363 
443 
     | 
    
         
             
                  response = GenericRequest.new(self.class.studio_connection).post request_str, options
         
     | 
| 
       364 
444 
     | 
    
         
             
                  Hash.from_xml(response)["success"]["details"]["status"]
         
     | 
| 
       365 
445 
     | 
    
         
             
            		end
         
     | 
| 
      
 446 
     | 
    
         
            +
             
     | 
| 
      
 447 
     | 
    
         
            +
                def handle_users_response response
         
     | 
| 
      
 448 
     | 
    
         
            +
                  tree = XmlSimple.xml_in(response)
         
     | 
| 
      
 449 
     | 
    
         
            +
                  users = tree["read_users"][0]
         
     | 
| 
      
 450 
     | 
    
         
            +
                  return [] if users["count"].to_i == 0
         
     | 
| 
      
 451 
     | 
    
         
            +
                  users["username"].reduce([]) do |acc,u|
         
     | 
| 
      
 452 
     | 
    
         
            +
                    acc << u
         
     | 
| 
      
 453 
     | 
    
         
            +
                  end
         
     | 
| 
      
 454 
     | 
    
         
            +
                end
         
     | 
| 
       366 
455 
     | 
    
         
             
              end
         
     | 
| 
       367 
456 
     | 
    
         
             
            end
         
     | 
| 
         @@ -0,0 +1,26 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            module StudioApi
         
     | 
| 
      
 2 
     | 
    
         
            +
              # == Comment class
         
     | 
| 
      
 3 
     | 
    
         
            +
              # Represents comment attached to published appliance in gallery.
         
     | 
| 
      
 4 
     | 
    
         
            +
              #
         
     | 
| 
      
 5 
     | 
    
         
            +
              # Allows to read id, time, commenter name and text of comment together
         
     | 
| 
      
 6 
     | 
    
         
            +
              # with attached appliance
         
     | 
| 
      
 7 
     | 
    
         
            +
              class Comment
         
     | 
| 
      
 8 
     | 
    
         
            +
                attr_reader :id, :timestamp, :username, :text, :appliance
         
     | 
| 
      
 9 
     | 
    
         
            +
             
     | 
| 
      
 10 
     | 
    
         
            +
                def initialize hash
         
     | 
| 
      
 11 
     | 
    
         
            +
                  hash.each do |k,v|
         
     | 
| 
      
 12 
     | 
    
         
            +
                    instance_variable_set :"@#{k}", v
         
     | 
| 
      
 13 
     | 
    
         
            +
                  end
         
     | 
| 
      
 14 
     | 
    
         
            +
                end
         
     | 
| 
      
 15 
     | 
    
         
            +
             
     | 
| 
      
 16 
     | 
    
         
            +
                def self.parse(appliance, hash)
         
     | 
| 
      
 17 
     | 
    
         
            +
                  Comment.new hash.merge(:appliance => appliance)
         
     | 
| 
      
 18 
     | 
    
         
            +
                end
         
     | 
| 
      
 19 
     | 
    
         
            +
             
     | 
| 
      
 20 
     | 
    
         
            +
                # Post reply to comment with text
         
     | 
| 
      
 21 
     | 
    
         
            +
                # @param[String] text reply content
         
     | 
| 
      
 22 
     | 
    
         
            +
                def reply text
         
     | 
| 
      
 23 
     | 
    
         
            +
                  appliance.post_comment text, :parent => id
         
     | 
| 
      
 24 
     | 
    
         
            +
                end
         
     | 
| 
      
 25 
     | 
    
         
            +
              end
         
     | 
| 
      
 26 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -0,0 +1,140 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            require "studio_api/studio_resource"
         
     | 
| 
      
 2 
     | 
    
         
            +
            require "studio_api/generic_request"
         
     | 
| 
      
 3 
     | 
    
         
            +
            require "studio_api/comment"
         
     | 
| 
      
 4 
     | 
    
         
            +
            require "xmlsimple"
         
     | 
| 
      
 5 
     | 
    
         
            +
            require "fileutils"
         
     | 
| 
      
 6 
     | 
    
         
            +
            require 'cgi'
         
     | 
| 
      
 7 
     | 
    
         
            +
             
     | 
| 
      
 8 
     | 
    
         
            +
            module StudioApi
         
     | 
| 
      
 9 
     | 
    
         
            +
              class Gallery < ActiveResource::Base
         
     | 
| 
      
 10 
     | 
    
         
            +
                extend StudioApi::StudioResource
         
     | 
| 
      
 11 
     | 
    
         
            +
                self.element_name = "gallery"
         
     | 
| 
      
 12 
     | 
    
         
            +
             
     | 
| 
      
 13 
     | 
    
         
            +
                class Appliance < ActiveResource::Base
         
     | 
| 
      
 14 
     | 
    
         
            +
                  extend StudioApi::StudioResource
         
     | 
| 
      
 15 
     | 
    
         
            +
             
     | 
| 
      
 16 
     | 
    
         
            +
                  # Gets rating details as hash
         
     | 
| 
      
 17 
     | 
    
         
            +
                  # #return[Hash] TODO
         
     | 
| 
      
 18 
     | 
    
         
            +
                  def rating
         
     | 
| 
      
 19 
     | 
    
         
            +
                    request_str = "/gallery/appliances/#{id.to_i}/rating"
         
     | 
| 
      
 20 
     | 
    
         
            +
                    response = GenericRequest.new(self.class.studio_connection).get request_str
         
     | 
| 
      
 21 
     | 
    
         
            +
                    XmlSimple.xml_in(response, "ForceArray" => false)["appliance"]
         
     | 
| 
      
 22 
     | 
    
         
            +
                  end
         
     | 
| 
      
 23 
     | 
    
         
            +
             
     | 
| 
      
 24 
     | 
    
         
            +
                  # Posts own rating of appliance
         
     | 
| 
      
 25 
     | 
    
         
            +
                  # @param[#to_i] value in range 0..5
         
     | 
| 
      
 26 
     | 
    
         
            +
                  # @return[Hash] TODO
         
     | 
| 
      
 27 
     | 
    
         
            +
                  def rate value
         
     | 
| 
      
 28 
     | 
    
         
            +
                    request_str = "/gallery/appliances/#{id.to_i}/rating?rating=#{value.to_i}"
         
     | 
| 
      
 29 
     | 
    
         
            +
                    response = GenericRequest.new(self.class.studio_connection).post request_str
         
     | 
| 
      
 30 
     | 
    
         
            +
                    XmlSimple.xml_in(response, "ForceArray" => false)["appliance"]
         
     | 
| 
      
 31 
     | 
    
         
            +
                  end
         
     | 
| 
      
 32 
     | 
    
         
            +
             
     | 
| 
      
 33 
     | 
    
         
            +
                  # Modifies appliance release notes
         
     | 
| 
      
 34 
     | 
    
         
            +
                  # @param[String] text of release notes
         
     | 
| 
      
 35 
     | 
    
         
            +
                  def release_notes= (text)
         
     | 
| 
      
 36 
     | 
    
         
            +
                    request_str = "/gallery/appliances/#{id.to_i}/version/#{CGI.escape version.to_s}"
         
     | 
| 
      
 37 
     | 
    
         
            +
                    response = GenericRequest.new(studio_connection).put request_str, :__raw => release_notes
         
     | 
| 
      
 38 
     | 
    
         
            +
                  end
         
     | 
| 
      
 39 
     | 
    
         
            +
             
     | 
| 
      
 40 
     | 
    
         
            +
                  # Removes appliance from gallery
         
     | 
| 
      
 41 
     | 
    
         
            +
                  def unpublish
         
     | 
| 
      
 42 
     | 
    
         
            +
                    request_str = "/gallery/appliances/#{id.to_i}/version/#{CGI.escape version.to_s}"
         
     | 
| 
      
 43 
     | 
    
         
            +
                    response = GenericRequest.new(studio_connection).delete request_str
         
     | 
| 
      
 44 
     | 
    
         
            +
                  end
         
     | 
| 
      
 45 
     | 
    
         
            +
             
     | 
| 
      
 46 
     | 
    
         
            +
                  # Gets all available versions of appliance in gallery
         
     | 
| 
      
 47 
     | 
    
         
            +
                  def versions
         
     | 
| 
      
 48 
     | 
    
         
            +
                    request_str = "/gallery/appliances/#{id.to_i}/versions"
         
     | 
| 
      
 49 
     | 
    
         
            +
                    response = GenericRequest.new(self.class.studio_connection).get request_str
         
     | 
| 
      
 50 
     | 
    
         
            +
                    tree = XmlSimple.xml_in response, "ForceArray" => ["version"]
         
     | 
| 
      
 51 
     | 
    
         
            +
                    return tree["appliance"]["versions"]["version"]
         
     | 
| 
      
 52 
     | 
    
         
            +
                  end
         
     | 
| 
      
 53 
     | 
    
         
            +
             
     | 
| 
      
 54 
     | 
    
         
            +
                  # Retrieves information about software used to create appliance
         
     | 
| 
      
 55 
     | 
    
         
            +
                  def software options = {}
         
     | 
| 
      
 56 
     | 
    
         
            +
                    request_str = "/gallery/appliances/#{id.to_i}/software"
         
     | 
| 
      
 57 
     | 
    
         
            +
                    request_str = Util.add_options request_str, options
         
     | 
| 
      
 58 
     | 
    
         
            +
                    response = GenericRequest.new(self.class.studio_connection).get request_str
         
     | 
| 
      
 59 
     | 
    
         
            +
                    #TODO parse response to something usefull
         
     | 
| 
      
 60 
     | 
    
         
            +
                  end
         
     | 
| 
      
 61 
     | 
    
         
            +
             
     | 
| 
      
 62 
     | 
    
         
            +
                  # Retrieves content of logo image
         
     | 
| 
      
 63 
     | 
    
         
            +
                  def logo
         
     | 
| 
      
 64 
     | 
    
         
            +
                    request_str = "/gallery/appliances/#{id.to_i}/logo"
         
     | 
| 
      
 65 
     | 
    
         
            +
                    response = GenericRequest.new(self.class.studio_connection).get request_str
         
     | 
| 
      
 66 
     | 
    
         
            +
                  end
         
     | 
| 
      
 67 
     | 
    
         
            +
             
     | 
| 
      
 68 
     | 
    
         
            +
                  # Retrieves content of background image
         
     | 
| 
      
 69 
     | 
    
         
            +
                  def background
         
     | 
| 
      
 70 
     | 
    
         
            +
                    request_str = "/gallery/appliances/#{id.to_i}/background"
         
     | 
| 
      
 71 
     | 
    
         
            +
                    response = GenericRequest.new(self.class.studio_connection).get request_str
         
     | 
| 
      
 72 
     | 
    
         
            +
                  end
         
     | 
| 
      
 73 
     | 
    
         
            +
             
     | 
| 
      
 74 
     | 
    
         
            +
                  # Starts testdrive and gets information how to use it
         
     | 
| 
      
 75 
     | 
    
         
            +
                  def testdrive options = {}
         
     | 
| 
      
 76 
     | 
    
         
            +
                    request_str = "/gallery/appliances/#{id.to_i}/testdrive"
         
     | 
| 
      
 77 
     | 
    
         
            +
                    request_str = Util.add_options request_str, options
         
     | 
| 
      
 78 
     | 
    
         
            +
                    response = GenericRequest.new(self.class.studio_connection).post request_str
         
     | 
| 
      
 79 
     | 
    
         
            +
                    tree = XmlSimple.xml_in response, "ForceArray" => false
         
     | 
| 
      
 80 
     | 
    
         
            +
                    tree["testdrive"]
         
     | 
| 
      
 81 
     | 
    
         
            +
                  end
         
     | 
| 
      
 82 
     | 
    
         
            +
             
     | 
| 
      
 83 
     | 
    
         
            +
                  # Retrieves all comments to appliance
         
     | 
| 
      
 84 
     | 
    
         
            +
                  # @return [Array[StudioApi::Comment]] list of comments
         
     | 
| 
      
 85 
     | 
    
         
            +
                  def comments
         
     | 
| 
      
 86 
     | 
    
         
            +
                    request_str = "/gallery/appliances/#{id.to_i}/comments"
         
     | 
| 
      
 87 
     | 
    
         
            +
                    response = GenericRequest.new(self.class.studio_connection).get request_str
         
     | 
| 
      
 88 
     | 
    
         
            +
                    tree = XmlSimple.xml_in response, "ForceArray" => ["comment"]
         
     | 
| 
      
 89 
     | 
    
         
            +
                    tree["appliance"]["comments"]["comment"].collect do |c|
         
     | 
| 
      
 90 
     | 
    
         
            +
                      Comment.parse(self,c)
         
     | 
| 
      
 91 
     | 
    
         
            +
                    end
         
     | 
| 
      
 92 
     | 
    
         
            +
                  end
         
     | 
| 
      
 93 
     | 
    
         
            +
             
     | 
| 
      
 94 
     | 
    
         
            +
                  # Adds new comment to appliance
         
     | 
| 
      
 95 
     | 
    
         
            +
                  def post_comment text, options={}
         
     | 
| 
      
 96 
     | 
    
         
            +
                    request_str = "/gallery/appliances/#{id.to_i}/comments"
         
     | 
| 
      
 97 
     | 
    
         
            +
                    request_str = Util.add_options request_str, options
         
     | 
| 
      
 98 
     | 
    
         
            +
                    response = GenericRequest.new(self.class.studio_connection).post request_str, :__raw => text
         
     | 
| 
      
 99 
     | 
    
         
            +
                    tree = XmlSimple.xml_in response, "ForceArray" => ["comment"]
         
     | 
| 
      
 100 
     | 
    
         
            +
                    tree["appliance"]["comments"]["comment"].collect do |c|
         
     | 
| 
      
 101 
     | 
    
         
            +
                      Comment.parse(self,c)
         
     | 
| 
      
 102 
     | 
    
         
            +
                    end
         
     | 
| 
      
 103 
     | 
    
         
            +
                  end
         
     | 
| 
      
 104 
     | 
    
         
            +
                end
         
     | 
| 
      
 105 
     | 
    
         
            +
             
     | 
| 
      
 106 
     | 
    
         
            +
                # Searches for appliance with options specified in API help
         
     | 
| 
      
 107 
     | 
    
         
            +
                # @see http://susestudio.com/help/api/v2#65 for search specification
         
     | 
| 
      
 108 
     | 
    
         
            +
                # @param [#to_s] type type of search
         
     | 
| 
      
 109 
     | 
    
         
            +
                # @param [Hash[#to_s,#to_s]] options additional options
         
     | 
| 
      
 110 
     | 
    
         
            +
                # @return TODO
         
     | 
| 
      
 111 
     | 
    
         
            +
                def self.find_appliance type,options={}
         
     | 
| 
      
 112 
     | 
    
         
            +
                  request_str = "/gallery/appliances?#{CGI.escape type.to_s}"
         
     | 
| 
      
 113 
     | 
    
         
            +
                  request_str = Util.add_options request_str, options, false
         
     | 
| 
      
 114 
     | 
    
         
            +
                  response = GenericRequest.new(studio_connection).get request_str
         
     | 
| 
      
 115 
     | 
    
         
            +
                  tree = XmlSimple.xml_in(response,"ForceArray" => ["appliance"])["appliances"]
         
     | 
| 
      
 116 
     | 
    
         
            +
                  count = tree["pages"].to_i
         
     | 
| 
      
 117 
     | 
    
         
            +
                  page = tree["current_page"].to_i
         
     | 
| 
      
 118 
     | 
    
         
            +
                  appliances = tree["appliance"].reduce([]) do |acc,appl|
         
     | 
| 
      
 119 
     | 
    
         
            +
                    appl.each { |k,v| appl[k] = nil if v.empty? } #avoid empty string, array or hash
         
     | 
| 
      
 120 
     | 
    
         
            +
                    gappl = Gallery::Appliance.dup
         
     | 
| 
      
 121 
     | 
    
         
            +
                    gappl.studio_connection = studio_connection
         
     | 
| 
      
 122 
     | 
    
         
            +
                    acc << gappl.new(appl)
         
     | 
| 
      
 123 
     | 
    
         
            +
                  end
         
     | 
| 
      
 124 
     | 
    
         
            +
                  return :count => count, :page => page, :appliances => appliances
         
     | 
| 
      
 125 
     | 
    
         
            +
                end
         
     | 
| 
      
 126 
     | 
    
         
            +
             
     | 
| 
      
 127 
     | 
    
         
            +
                def self.appliance id, version = nil
         
     | 
| 
      
 128 
     | 
    
         
            +
                  request_str = "/gallery/appliances/#{id.to_i}"
         
     | 
| 
      
 129 
     | 
    
         
            +
                  request_str << "/version/#{CGI.escape version.to_s}" if version
         
     | 
| 
      
 130 
     | 
    
         
            +
                  response = GenericRequest.new(studio_connection).get request_str
         
     | 
| 
      
 131 
     | 
    
         
            +
                  tree = XmlSimple.xml_in(response,"ForceArray" => ["format","account"])["appliance"]
         
     | 
| 
      
 132 
     | 
    
         
            +
                  Gallery::Appliance.new tree
         
     | 
| 
      
 133 
     | 
    
         
            +
                end
         
     | 
| 
      
 134 
     | 
    
         
            +
             
     | 
| 
      
 135 
     | 
    
         
            +
                def self.publish_appliance id, version, release_notes
         
     | 
| 
      
 136 
     | 
    
         
            +
                  request_str = "/gallery/appliances/#{id.to_i}/version/#{CGI.escape version.to_s}"
         
     | 
| 
      
 137 
     | 
    
         
            +
                  response = GenericRequest.new(studio_connection).post request_str, :__raw => release_notes
         
     | 
| 
      
 138 
     | 
    
         
            +
                end
         
     | 
| 
      
 139 
     | 
    
         
            +
              end
         
     | 
| 
      
 140 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -127,25 +127,29 @@ module StudioApi 
     | 
|
| 
       127 
127 
     | 
    
         
             
                end
         
     | 
| 
       128 
128 
     | 
    
         | 
| 
       129 
129 
     | 
    
         
             
                def set_data(request,data)
         
     | 
| 
       130 
     | 
    
         
            -
                   
     | 
| 
       131 
     | 
    
         
            -
             
     | 
| 
       132 
     | 
    
         
            -
                   
     | 
| 
       133 
     | 
    
         
            -
             
     | 
| 
       134 
     | 
    
         
            -
                     
     | 
| 
       135 
     | 
    
         
            -
                    body  
     | 
| 
       136 
     | 
    
         
            -
                     
     | 
| 
       137 
     | 
    
         
            -
                       
     | 
| 
       138 
     | 
    
         
            -
                      body << " 
     | 
| 
       139 
     | 
    
         
            -
                       
     | 
| 
       140 
     | 
    
         
            -
             
     | 
| 
       141 
     | 
    
         
            -
             
     | 
| 
       142 
     | 
    
         
            -
             
     | 
| 
      
 130 
     | 
    
         
            +
                  if data[:__raw]
         
     | 
| 
      
 131 
     | 
    
         
            +
                    request.body = data[:__raw]
         
     | 
| 
      
 132 
     | 
    
         
            +
                  else
         
     | 
| 
      
 133 
     | 
    
         
            +
                    boundary = Time.now.to_i.to_s(16)
         
     | 
| 
      
 134 
     | 
    
         
            +
                    request["Content-Type"] = "multipart/form-data; boundary=#{boundary}"
         
     | 
| 
      
 135 
     | 
    
         
            +
                    body = ""
         
     | 
| 
      
 136 
     | 
    
         
            +
                    data.each do |key,value|
         
     | 
| 
      
 137 
     | 
    
         
            +
                      esc_key = CGI.escape(key.to_s)
         
     | 
| 
      
 138 
     | 
    
         
            +
                      body << "--#{boundary}\r\n"
         
     | 
| 
      
 139 
     | 
    
         
            +
                      if value.respond_to?(:read) && value.respond_to?(:path)
         
     | 
| 
      
 140 
     | 
    
         
            +
                        # ::File is needed to use "Ruby" file instead this one
         
     | 
| 
      
 141 
     | 
    
         
            +
                        body << "Content-Disposition: form-data; name=\"#{esc_key}\"; filename=\"#{::File.basename(value.path)}\"\r\n"
         
     | 
| 
      
 142 
     | 
    
         
            +
                        body << "Content-Type: #{mime_type(value.path)}\r\n\r\n"
         
     | 
| 
      
 143 
     | 
    
         
            +
                        body << value.read
         
     | 
| 
      
 144 
     | 
    
         
            +
                      else
         
     | 
| 
      
 145 
     | 
    
         
            +
                        body << "Content-Disposition: form-data; name=\"#{esc_key}\"\r\n\r\n#{value}"
         
     | 
| 
      
 146 
     | 
    
         
            +
                      end
         
     | 
| 
      
 147 
     | 
    
         
            +
                      body << "\r\n"
         
     | 
| 
       143 
148 
     | 
    
         
             
                    end
         
     | 
| 
       144 
     | 
    
         
            -
                    body << "\r\n"
         
     | 
| 
      
 149 
     | 
    
         
            +
                    body << "--#{boundary}--\r\n\r\n"
         
     | 
| 
      
 150 
     | 
    
         
            +
                    request.body = body
         
     | 
| 
      
 151 
     | 
    
         
            +
                    request["Content-Length"] = request.body.size
         
     | 
| 
       145 
152 
     | 
    
         
             
                  end
         
     | 
| 
       146 
     | 
    
         
            -
                  body << "--#{boundary}--\r\n\r\n"
         
     | 
| 
       147 
     | 
    
         
            -
                  request.body = body
         
     | 
| 
       148 
     | 
    
         
            -
                  request["Content-Length"] = request.body.size
         
     | 
| 
       149 
153 
     | 
    
         
             
                end
         
     | 
| 
       150 
154 
     | 
    
         | 
| 
       151 
155 
     | 
    
         
             
                def mime_type(file)
         
     | 
    
        data/lib/studio_api/util.rb
    CHANGED
    
    | 
         @@ -27,6 +27,17 @@ module StudioApi 
     | 
|
| 
       27 
27 
     | 
    
         
             
                    "#{base}/#{append}"
         
     | 
| 
       28 
28 
     | 
    
         
             
                  end
         
     | 
| 
       29 
29 
     | 
    
         
             
                end
         
     | 
| 
      
 30 
     | 
    
         
            +
             
     | 
| 
      
 31 
     | 
    
         
            +
                def self.add_options request_str,options,first=true
         
     | 
| 
      
 32 
     | 
    
         
            +
            			unless options.empty?
         
     | 
| 
      
 33 
     | 
    
         
            +
            				options.each do |k,v|
         
     | 
| 
      
 34 
     | 
    
         
            +
            					separator = first ? "?" : "&"
         
     | 
| 
      
 35 
     | 
    
         
            +
            					first = false
         
     | 
| 
      
 36 
     | 
    
         
            +
            					request_str << "#{separator}#{CGI.escape k.to_s}=#{CGI.escape v.to_s}"
         
     | 
| 
      
 37 
     | 
    
         
            +
            				end
         
     | 
| 
      
 38 
     | 
    
         
            +
            			end
         
     | 
| 
      
 39 
     | 
    
         
            +
                  request_str
         
     | 
| 
      
 40 
     | 
    
         
            +
                end
         
     | 
| 
       30 
41 
     | 
    
         
             
            private
         
     | 
| 
       31 
42 
     | 
    
         
             
                def self.get_all_usable_class (modul)
         
     | 
| 
       32 
43 
     | 
    
         
             
                  classes = modul.constants.collect{ |c| modul.const_get(c) }
         
     | 
    
        data/lib/studio_api.rb
    CHANGED
    
    
    
        data/test/appliance_test.rb
    CHANGED
    
    | 
         @@ -25,6 +25,7 @@ REPO_ID = 6345 
     | 
|
| 
       25 
25 
     | 
    
         
             
                repositories_out = respond_load "repositories.xml"
         
     | 
| 
       26 
26 
     | 
    
         
             
                gpg_keys_out = respond_load "gpg_keys.xml"
         
     | 
| 
       27 
27 
     | 
    
         
             
                gpg_key_out = respond_load "gpg_key.xml"
         
     | 
| 
      
 28 
     | 
    
         
            +
                conf_out = respond_load "configuration.xml"
         
     | 
| 
       28 
29 
     | 
    
         
             
                ActiveResource::HttpMock.respond_to do |mock|
         
     | 
| 
       29 
30 
     | 
    
         
             
                  mock.get "/api/appliances", {"Authorization"=>"Basic dGVzdDp0ZXN0"},appliances_out,200
         
     | 
| 
       30 
31 
     | 
    
         
             
                  mock.get "/api/appliances/#{APPLIANCE_ID}", {"Authorization"=>"Basic dGVzdDp0ZXN0"},appliance_out,200
         
     | 
| 
         @@ -36,6 +37,7 @@ REPO_ID = 6345 
     | 
|
| 
       36 
37 
     | 
    
         
             
                  mock.get "/api/appliances/#{APPLIANCE_ID}/gpg_keys", {"Authorization"=>"Basic dGVzdDp0ZXN0"},gpg_keys_out,200
         
     | 
| 
       37 
38 
     | 
    
         
             
                  mock.get "/api/appliances/#{APPLIANCE_ID}/gpg_keys/1976", {"Authorization"=>"Basic dGVzdDp0ZXN0"},gpg_key_out,200
         
     | 
| 
       38 
39 
     | 
    
         
             
                  mock.delete "/api/appliances/#{APPLIANCE_ID}/gpg_keys/1976", {"Authorization"=>"Basic dGVzdDp0ZXN0"},gpg_key_out,200
         
     | 
| 
      
 40 
     | 
    
         
            +
                  mock.get "/api/appliances/#{APPLIANCE_ID}/configuration", {"Authorization"=>"Basic dGVzdDp0ZXN0"},conf_out,200
         
     | 
| 
       39 
41 
     | 
    
         
             
                end
         
     | 
| 
       40 
42 
     | 
    
         
             
              end
         
     | 
| 
       41 
43 
     | 
    
         | 
| 
         @@ -73,6 +75,12 @@ REPO_ID = 6345 
     | 
|
| 
       73 
75 
     | 
    
         
             
                assert StudioApi::Appliance.clone APPLIANCE_ID
         
     | 
| 
       74 
76 
     | 
    
         
             
              end
         
     | 
| 
       75 
77 
     | 
    
         | 
| 
      
 78 
     | 
    
         
            +
              def test_manifest
         
     | 
| 
      
 79 
     | 
    
         
            +
                manifest_out = respond_load "manifest.xml"
         
     | 
| 
      
 80 
     | 
    
         
            +
                StudioApi::GenericRequest.any_instance.stubs(:get).with("/appliances/#{APPLIANCE_ID}/software/manifest/vmx").returns(manifest_out).once
         
     | 
| 
      
 81 
     | 
    
         
            +
                assert StudioApi::Appliance.new(:id => APPLIANCE_ID).manifest_file "vmx"
         
     | 
| 
      
 82 
     | 
    
         
            +
              end
         
     | 
| 
      
 83 
     | 
    
         
            +
             
     | 
| 
       76 
84 
     | 
    
         
             
              def test_delete
         
     | 
| 
       77 
85 
     | 
    
         
             
                assert StudioApi::Appliance.delete APPLIANCE_ID
         
     | 
| 
       78 
86 
     | 
    
         
             
                assert StudioApi::Appliance.find(APPLIANCE_ID).destroy #same but different way
         
     | 
| 
         @@ -104,6 +112,28 @@ REPO_ID = 6345 
     | 
|
| 
       104 
112 
     | 
    
         
             
                assert StudioApi::Appliance.new(:id => APPLIANCE_ID).add_user_repository
         
     | 
| 
       105 
113 
     | 
    
         
             
              end
         
     | 
| 
       106 
114 
     | 
    
         | 
| 
      
 115 
     | 
    
         
            +
              def test_configuration
         
     | 
| 
      
 116 
     | 
    
         
            +
                conf_out = respond_load "configuration.xml"
         
     | 
| 
      
 117 
     | 
    
         
            +
                StudioApi::GenericRequest.any_instance.stubs(:get).with("/appliances/#{APPLIANCE_ID}/configuration").returns(conf_out).once
         
     | 
| 
      
 118 
     | 
    
         
            +
                conf= StudioApi::Appliance.new(:id => APPLIANCE_ID).configuration
         
     | 
| 
      
 119 
     | 
    
         
            +
                assert conf.to_xml
         
     | 
| 
      
 120 
     | 
    
         
            +
                assert conf
         
     | 
| 
      
 121 
     | 
    
         
            +
              end
         
     | 
| 
      
 122 
     | 
    
         
            +
             
     | 
| 
      
 123 
     | 
    
         
            +
              def test_user_repository_add
         
     | 
| 
      
 124 
     | 
    
         
            +
                users0 = respond_load "users_0.xml"
         
     | 
| 
      
 125 
     | 
    
         
            +
                users1 = respond_load "users_1.xml"
         
     | 
| 
      
 126 
     | 
    
         
            +
                users2 = respond_load "users_2.xml"
         
     | 
| 
      
 127 
     | 
    
         
            +
                StudioApi::GenericRequest.any_instance.stubs(:post).with("/appliances/#{APPLIANCE_ID}/sharing/test1").returns(users2).once
         
     | 
| 
      
 128 
     | 
    
         
            +
                StudioApi::GenericRequest.any_instance.stubs(:get).with("/appliances/#{APPLIANCE_ID}/sharing").returns(users1).once
         
     | 
| 
      
 129 
     | 
    
         
            +
                StudioApi::GenericRequest.any_instance.stubs(:delete).with("/appliances/#{APPLIANCE_ID}/sharing/test1").returns(users1).once
         
     | 
| 
      
 130 
     | 
    
         
            +
                assert_equal 1, StudioApi::Appliance.new(:id => APPLIANCE_ID).users.size
         
     | 
| 
      
 131 
     | 
    
         
            +
                assert_equal 2, StudioApi::Appliance.new(:id => APPLIANCE_ID).add_user("test1").size
         
     | 
| 
      
 132 
     | 
    
         
            +
                assert_equal 1, StudioApi::Appliance.new(:id => APPLIANCE_ID).remove_user("test1").size
         
     | 
| 
      
 133 
     | 
    
         
            +
                StudioApi::GenericRequest.any_instance.stubs(:get).with("/appliances/#{APPLIANCE_ID}/sharing").returns(users0).once
         
     | 
| 
      
 134 
     | 
    
         
            +
                assert_equal 0, StudioApi::Appliance.new(:id => APPLIANCE_ID).users.size
         
     | 
| 
      
 135 
     | 
    
         
            +
              end
         
     | 
| 
      
 136 
     | 
    
         
            +
             
     | 
| 
       107 
137 
     | 
    
         
             
              def test_selected_software
         
     | 
| 
       108 
138 
     | 
    
         
             
                software_out = respond_load "software.xml"
         
     | 
| 
       109 
139 
     | 
    
         
             
                StudioApi::GenericRequest.any_instance.stubs(:get).with("/appliances/#{APPLIANCE_ID}/software").returns(software_out).once
         
     | 
| 
         @@ -181,8 +211,8 @@ EOF 
     | 
|
| 
       181 
211 
     | 
    
         | 
| 
       182 
212 
     | 
    
         
             
              def test_add_gpg_key
         
     | 
| 
       183 
213 
     | 
    
         
             
                gpg_key_out = respond_load "gpg_key.xml"
         
     | 
| 
       184 
     | 
    
         
            -
                StudioApi::GenericRequest.any_instance.stubs(:post).with("/appliances/#{APPLIANCE_ID}/gpg_keys?name=test&target=rpm&key=test", 
     | 
| 
       185 
     | 
    
         
            -
                StudioApi::GenericRequest.any_instance.stubs(:post).with("/appliances/#{APPLIANCE_ID}/gpg_keys?name=test&key=test&target=rpm", 
     | 
| 
      
 214 
     | 
    
         
            +
                StudioApi::GenericRequest.any_instance.stubs(:post).with("/appliances/#{APPLIANCE_ID}/gpg_keys?name=test&target=rpm&key=test",{}).returns(gpg_key_out)
         
     | 
| 
      
 215 
     | 
    
         
            +
                StudioApi::GenericRequest.any_instance.stubs(:post).with("/appliances/#{APPLIANCE_ID}/gpg_keys?name=test&key=test&target=rpm",{}).returns(gpg_key_out)
         
     | 
| 
       186 
216 
     | 
    
         
             
                assert StudioApi::Appliance::GpgKey.create APPLIANCE_ID, "test", "test"
         
     | 
| 
       187 
217 
     | 
    
         
             
                assert StudioApi::Appliance.new(:id => APPLIANCE_ID).add_gpg_key "test", "test"
         
     | 
| 
       188 
218 
     | 
    
         
             
              end
         
     | 
| 
         @@ -0,0 +1,49 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            require 'rubygems'
         
     | 
| 
      
 2 
     | 
    
         
            +
            require 'active_support'
         
     | 
| 
      
 3 
     | 
    
         
            +
            $:.unshift File.join( File.dirname(__FILE__),'..','lib')
         
     | 
| 
      
 4 
     | 
    
         
            +
            require 'studio_api/gallery'
         
     | 
| 
      
 5 
     | 
    
         
            +
            require 'studio_api/connection'
         
     | 
| 
      
 6 
     | 
    
         
            +
            require 'studio_api/generic_request'
         
     | 
| 
      
 7 
     | 
    
         
            +
            require 'studio_api/util'
         
     | 
| 
      
 8 
     | 
    
         
            +
            require 'active_resource/http_mock'
         
     | 
| 
      
 9 
     | 
    
         
            +
            require 'mocha'
         
     | 
| 
      
 10 
     | 
    
         
            +
            require 'test/unit'
         
     | 
| 
      
 11 
     | 
    
         
            +
             
     | 
| 
      
 12 
     | 
    
         
            +
            class GalleryTest < Test::Unit::TestCase
         
     | 
| 
      
 13 
     | 
    
         
            +
              APPLIANCE_ID = 130166
         
     | 
| 
      
 14 
     | 
    
         
            +
              APPL_VERSION = "0.1.1"
         
     | 
| 
      
 15 
     | 
    
         
            +
              def respond_load name
         
     | 
| 
      
 16 
     | 
    
         
            +
                IO.read(File.join(File.dirname(__FILE__),"responses",name))
         
     | 
| 
      
 17 
     | 
    
         
            +
              end
         
     | 
| 
      
 18 
     | 
    
         
            +
             
     | 
| 
      
 19 
     | 
    
         
            +
              def setup
         
     | 
| 
      
 20 
     | 
    
         
            +
                @connection = StudioApi::Connection.new("test","test","http://localhost/api/")
         
     | 
| 
      
 21 
     | 
    
         
            +
                StudioApi::Util.configure_studio_connection @connection
         
     | 
| 
      
 22 
     | 
    
         
            +
              end
         
     | 
| 
      
 23 
     | 
    
         
            +
             
     | 
| 
      
 24 
     | 
    
         
            +
              def teardown
         
     | 
| 
      
 25 
     | 
    
         
            +
                Mocha::Mockery.instance.stubba.unstub_all
         
     | 
| 
      
 26 
     | 
    
         
            +
              end
         
     | 
| 
      
 27 
     | 
    
         
            +
             
     | 
| 
      
 28 
     | 
    
         
            +
              def test_find
         
     | 
| 
      
 29 
     | 
    
         
            +
                gallery_out = respond_load "gallery.xml"
         
     | 
| 
      
 30 
     | 
    
         
            +
                StudioApi::GenericRequest.any_instance.stubs(:get).with("/gallery/appliances?popular&per_page=10").returns(gallery_out)
         
     | 
| 
      
 31 
     | 
    
         
            +
                out = StudioApi::Gallery.find_appliance :popular, :per_page => 10
         
     | 
| 
      
 32 
     | 
    
         
            +
                assert 10, out[:appliances].size
         
     | 
| 
      
 33 
     | 
    
         
            +
              end
         
     | 
| 
      
 34 
     | 
    
         
            +
             
     | 
| 
      
 35 
     | 
    
         
            +
              def test_appliance
         
     | 
| 
      
 36 
     | 
    
         
            +
                gallery_appliance_out = respond_load "gallery_appliance.xml"
         
     | 
| 
      
 37 
     | 
    
         
            +
                StudioApi::GenericRequest.any_instance.stubs(:get).with("/gallery/appliances/#{APPLIANCE_ID}/version/#{APPL_VERSION}").returns(gallery_appliance_out)
         
     | 
| 
      
 38 
     | 
    
         
            +
                out = StudioApi::Gallery.appliance APPLIANCE_ID, APPL_VERSION
         
     | 
| 
      
 39 
     | 
    
         
            +
                assert out
         
     | 
| 
      
 40 
     | 
    
         
            +
              end
         
     | 
| 
      
 41 
     | 
    
         
            +
             
     | 
| 
      
 42 
     | 
    
         
            +
              def test_gallery_appliance_versions
         
     | 
| 
      
 43 
     | 
    
         
            +
                versions_out = respond_load "versions.xml"
         
     | 
| 
      
 44 
     | 
    
         
            +
                StudioApi::GenericRequest.any_instance.stubs(:get).with("/gallery/appliances/#{APPLIANCE_ID}/versions").returns(versions_out)
         
     | 
| 
      
 45 
     | 
    
         
            +
                out = StudioApi::Gallery::Appliance.new(:id => APPLIANCE_ID).versions
         
     | 
| 
      
 46 
     | 
    
         
            +
                assert_equal 6,out.size
         
     | 
| 
      
 47 
     | 
    
         
            +
              end
         
     | 
| 
      
 48 
     | 
    
         
            +
             
     | 
| 
      
 49 
     | 
    
         
            +
            end
         
     |