Class: Puppet::GoogleAPI Private
- Inherits:
-
Object
- Object
- Puppet::GoogleAPI
- Defined in:
- lib/puppet/google_api.rb
Overview
This class is part of a private API. You should avoid using this class if possible, as it may be removed or be changed in the future.
A helper to capture logic around authentication and interaction with the Google API, especially around authentication with the OAuth2 system.
Constant Summary collapse
- StandardImageProjects =
This constant is part of a private API. You should avoid using this constant if possible, as it may be removed or be changed in the future.
The list of “standard” projects to search for images when hunting by name; the Google supplied images live in these.
['debian-cloud', 'centos-cloud']
- StandardKernelProjects =
This constant is part of a private API. You should avoid using this constant if possible, as it may be removed or be changed in the future.
The list of “standard” projects to search for kernels when hunting by name; the Google supplied kernels live in these.
['google']
Class Method Summary collapse
-
.hash_to_human_s(hash) ⇒ Object
private
A helper to render a hash as human-focused text.
Instance Method Summary collapse
- #compute ⇒ Object private
- #discover(name, version) ⇒ Object private
- #execute(method, parameters = {}, body = nil) ⇒ Object private
-
#initialize(client_id = nil, client_secret = nil) ⇒ GoogleAPI
constructor
private
Create a new instance; this will implicitly authorize if required, or otherwise refresh the access token.
Constructor Details
#initialize(client_id = nil, client_secret = nil) ⇒ GoogleAPI
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
you are under no obligation to supply a client id or secret while
Create a new instance; this will implicitly authorize if required, or otherwise refresh the access token. It makes state changes in the rest of the system – potentially storing the refresh token in the statedir, or updating cached data about the token for other clients.
password-equivalent authorization, we need to make sure that we treat the file content as atomic, as well as secure, against cross-process activity.
policy for handling on-disk storage of tokens, since no other guidance was given by Google documentation. No effort has been made to, eg, merge partial updates to authentication state, etc.
the registration / auth query process if that is required
the registration / auth query process if that is required.
setting this up and, in most cases, you probably shouldn’t supply them. If a previous set were given we will have them stored away in our state supply as required – and if not, the user should call ‘register` at the face level and provide them. Don’t routinely supply these data.
44 45 46 47 48 49 50 51 |
# File 'lib/puppet/google_api.rb', line 44 def initialize(client_id = nil, client_secret = nil) # First, load our state from disk if it is available. load_state! # ...and now try and authenticate with the server; this will request # authorization if required. authenticate!(client_id, client_secret) end |
Class Method Details
.hash_to_human_s(hash) ⇒ Object
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
danielp 2013-09-16: I don’t like putting this here, but there
A helper to render a hash as human-focused text
doesn’t seem to be anywhere better, and Puppet doesn’t offer the capability. The default behaviour is “render as a human-hostile JSON string”, so that won’t do either. Oh, well.
122 123 124 125 126 127 128 |
# File 'lib/puppet/google_api.rb', line 122 def self.hash_to_human_s(hash) keylen = hash.keys.map{|k| k.to_s.length}.max hash.map do |key, value| key.to_s.rjust(keylen) + ': ' + value.to_s.gsub("\n", "\n#{' ' * (keylen + 2)}") end.join("\n") end |
Instance Method Details
#compute ⇒ Object
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
111 112 113 |
# File 'lib/puppet/google_api.rb', line 111 def compute @compute ||= Puppet::GoogleAPI::Compute.new(self) end |
#discover(name, version) ⇒ Object
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
53 54 55 56 57 58 59 60 61 62 63 |
# File 'lib/puppet/google_api.rb', line 53 def discover(name, version) # @todo danielp 2013-09-13: we should cache the discovery document and # reuse it if it is fresh enough here; see # https://code.google.com/p/google-api-ruby-client/#APIs_Discovery_Service # for an example of the `register_discovery_document`; basically, cache # the "discovery document" hash to disk, and feed it through that. # # Right now we take the hit of a full HTTP fetch for every discovery which # is going to be heavier and slower than we ultimately want in production. client.discovered_api(name, version) end |
#execute(method, parameters = {}, body = nil) ⇒ Object
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 |
# File 'lib/puppet/google_api.rb', line 65 def execute(method, parameters = {}, body = nil) # We have to do our own handling, as the execute! method -- which throws # great errors most of the time -- doesn't have anything to support 401 # specially, and worse, doesn't have suitable hooks to allow us to stash # away our auth state if and only if it changed. args = { :api_method => method, :parameters => parameters, :body_object => body } result = client.execute(args) if result.status == 401 # reauthenticate and retry authenticate! execute(method, parameters) elsif result.status != 200 # @todo danielp 2013-09-17: I am thinking that maybe a 404 result should # return either an empty array (for convenience in punning) or nil, # since that is a more "normal" failure than any of the alternatives... raise "#{method} failed #{result.status}: #{result. || 'unknown error'}" end # We return the data content; that includes support for fetching further # pages, which we handle here, returning an array of one or more bodies to # the caller. if result.data.respond_to?('next_page_token') # We might have multiple pages of results, collect them all, and return # them in an array of multiple items. Since they potentially have # specialized item storage formats by type, we can't generically do # anything to vivify the final object format. page = result.data results = [] while page do results << page page = page.next_page_token ? page.next_page : nil end results else # Just return the single result, in an array, to match the API with the # paged data above. # # @todo danielp 2013-09-16: it isn't clear this is needed, since we # already need specialized knowledge in the caller, but ... [result.data] end end |