class Raca::Account
This is your entrypoint to the rackspace API. Start by creating a Raca::Account
object and then use the instance method to access each of the supported rackspace APIs.
Constants
- IDENTITY_URL
Public Class Methods
# File lib/raca/account.rb 13 def initialize(username, key, cache = nil) 14 @username, @key, @cache = username, key, cache 15 @cache ||= if defined?(Rails) 16 Rails.cache 17 else 18 {} 19 end 20 end
Public Instance Methods
Return the temporary token that should be used when making further API requests.
account = Raca::Account.new("username", "secret") puts account.auth_token
# File lib/raca/account.rb 28 def auth_token 29 extract_value(identity_data, "access", "token", "id") 30 end
Return a Raca::Containers
object for a region. Use this to interact with the cloud files service.
account = Raca::Account.new("username", "secret") puts account.containers(:ord)
# File lib/raca/account.rb 87 def containers(region) 88 Raca::Containers.new(self, region) 89 end
Return a Raca::HttpClient
suitable for making requests to hostname.
# File lib/raca/account.rb 143 def http_client(hostname) 144 Raca::HttpClient.new(self, hostname) 145 end
# File lib/raca/account.rb 147 def inspect 148 "#<Raca::Account:#{__id__} username=#{@username}>" 149 end
Return the public API URL for a particular rackspace service.
Use Account#service_names
to see a list of valid service_name’s for this.
Check the project README for an updated list of the available regions.
account = Raca::Account.new("username", "secret") puts account.public_endpoint("cloudServers", :syd)
Some service APIs are not regioned. In those cases, the region code can be left off:
account = Raca::Account.new("username", "secret") puts account.public_endpoint("cloudDNS")
# File lib/raca/account.rb 47 def public_endpoint(service_name, region = nil) 48 return IDENTITY_URL if service_name == "identity" 49 50 endpoints = service_endpoints(service_name) 51 if endpoints.size > 1 && region 52 region = region.to_s.upcase 53 endpoints = endpoints.select { |e| e["region"] == region } || {} 54 elsif endpoints.size > 1 && region.nil? 55 raise ArgumentError, "The requested service exists in multiple regions, please specify a region code" 56 end 57 58 if endpoints.size == 0 59 raise ArgumentError, "No matching services found" 60 else 61 endpoints.first["publicURL"] 62 end 63 end
Raca
classes use this method to occasionally re-authenticate with the rackspace servers. You can probably ignore it.
# File lib/raca/account.rb 114 def refresh_cache 115 # Raca::HttpClient depends on Raca::Account, so we intentionally don't use it here 116 # to avoid a circular dependency 117 Net::HTTP.new(identity_host, 443).tap {|http| 118 http.use_ssl = true 119 }.start {|http| 120 payload = { 121 auth: { 122 'RAX-KSKEY:apiKeyCredentials' => { 123 username: @username, 124 apiKey: @key 125 } 126 } 127 } 128 response = http.post( 129 tokens_path, 130 JSON.dump(payload), 131 {'Content-Type' => 'application/json'}, 132 ) 133 if response.is_a?(Net::HTTPSuccess) 134 cache_write(cache_key, JSON.load(response.body)) 135 else 136 raise_on_error(response) 137 end 138 } 139 end
Return a Raca::Servers
object for a region. Use this to interact with the next gen cloud servers service.
account = Raca::Account.new("username", "secret") puts account.servers(:ord)
# File lib/raca/account.rb 97 def servers(region) 98 Raca::Servers.new(self, region) 99 end
Return the names of the available services. As rackspace add new services and APIs they should appear here.
Any name returned from here can be passe to public_endpoint
to get the API endpoint for that service
account = Raca::Account.new("username", "secret") puts account.service_names
# File lib/raca/account.rb 74 def service_names 75 catalog = extract_value(identity_data, "access", "serviceCatalog") || {} 76 catalog.map { |service| 77 service["name"] 78 } 79 end
Return a Raca::Users
object. Use this to query and manage the users associated with the current account.
account = Raca::Account.new("username", "secret") puts account.users
# File lib/raca/account.rb 107 def users 108 Raca::Users.new(self) 109 end
Private Instance Methods
# File lib/raca/account.rb 233 def cache_key 234 "raca-#{@username}" 235 end
# File lib/raca/account.rb 211 def cache_read(key) 212 if @cache.respond_to?(:read) # rails cache 213 @cache.read(key) 214 else 215 @cache[key] 216 end 217 end
# File lib/raca/account.rb 219 def cache_write(key, value) 220 if @cache.respond_to?(:write) # rails cache 221 @cache.write(key, value) 222 else 223 @cache[key] = value 224 end 225 end
This method is opaque, but it was the best I could come up with using just the standard library. Sorry.
Use this to safely extract values from nested hashes:
data = {a: {b: {c: 1}}} extract_value(data, :a, :b, :c) => 1 extract_value(data, :a, :b, :d) => nil extract_value(data, :d) => nil
# File lib/raca/account.rb 192 def extract_value(data, *keys) 193 if keys.empty? 194 data 195 elsif data.respond_to?(:[]) && data[keys.first] 196 extract_value(data[keys.first], *keys.slice(1,100)) 197 else 198 nil 199 end 200 end
# File lib/raca/account.rb 227 def identity_data 228 refresh_cache unless cache_read(cache_key) 229 230 cache_read(cache_key) || {} 231 end
# File lib/raca/account.rb 153 def identity_host 154 URI.parse(IDENTITY_URL).host 155 end
# File lib/raca/account.rb 157 def identity_path 158 URI.parse(IDENTITY_URL).path 159 end
# File lib/raca/account.rb 165 def raise_on_error(response) 166 error_klass = case response.code.to_i 167 when 400 then BadRequestError 168 when 401 then UnauthorizedError 169 when 404 then NotFoundError 170 when 500 then ServerError 171 else 172 HTTPError 173 end 174 raise error_klass, "Rackspace returned HTTP status #{response.code}" 175 end
An array of all the endpoints for a particular service (like cloud files, cloud servers, dns, etc)
# File lib/raca/account.rb 205 def service_endpoints(service_name) 206 catalog = extract_value(identity_data, "access", "serviceCatalog") || {} 207 service = catalog.detect { |s| s["name"] == service_name } || {} 208 service["endpoints"] || [] 209 end
# File lib/raca/account.rb 161 def tokens_path 162 File.join(identity_path, "tokens") 163 end