lib/google/compute/client.rb in knife-google-1.2.0 vs lib/google/compute/client.rb in knife-google-1.3.1
- old
+ new
@@ -30,32 +30,37 @@
def initialize(authorization, project, credential_file)
api_client = Google::APIClient.new(:application_name => 'knife-google', :application_version => Knife::Google::VERSION)
api_client.authorization = authorization
api_client.auto_refresh_token = true
@project = project
- @credential_file = credential_file
- @dispatcher = APIDispatcher.new(:project=>project,:api_client=>api_client)
+ if !credential_file
+ @credential_file = File.expand_path(DEFAULT_FILE)
+ else
+ @credential_file = File.expand_path(credential_file)
+ end
+ @dispatcher = APIDispatcher.new(:project=>project, :api_client=>api_client, :credential_file=>@credential_file)
end
def self.from_json(filename = nil)
filename ||= File.expand_path(DEFAULT_FILE)
begin
- credential_data = MultiJson.load(File.read(filename))
+ credential_data = MultiJson.load(File.read(filename))
rescue
$stdout.print "Error reading CREDENTIAL_FILE, please run 'knife google setup'\n"
exit 1
end
authorization = Signet::OAuth2::Client.new(credential_data)
self.new(authorization, credential_data['project'], filename)
end
def self.setup
- $stdout.print "Enter project ID (not name or number): "
+ credential_file ||= File.expand_path(DEFAULT_FILE)
+ $stdout.print "Enter Project ID (ex: my-gce-project): "
project = $stdin.gets.chomp
- $stdout.print "Enter client id: "
+ $stdout.print "Enter Client ID (ex: 123abc4.apps.googleusercontent.com): "
client_id = $stdin.gets.chomp
- $stdout.print "Enter client secret: "
+ $stdout.print "Enter Client secret: "
client_secret = $stdin.gets.chomp
authorization_uri = "https://accounts.google.com/o/oauth2/auth"
token_credential_uri ="https://accounts.google.com/o/oauth2/token"
scope = ["https://www.googleapis.com/auth/compute",
"https://www.googleapis.com/auth/compute.readonly",
@@ -80,34 +85,37 @@
begin
api_client.authorization.fetch_access_token!
rescue Faraday::Error::ConnectionFailed => e
raise ConnectionFail,
- "The SSL certificates validation may not configured for this system. Please refer README to configured SSL certificates validation"\
- if e.message.include? "SSL_connect returned=1 errno=0 state=SSLv3 read server certificate B: certificate verify failed"
- else
- access_token = api_client.authorization.access_token
- refresh_token = api_client.authorization.refresh_token
- id_token = api_client.authorization.id_token
- expires_in = api_client.authorization.expires_in
- issued_at = api_client.authorization.issued_at.to_s
- if !@credential_file
- filepath = File.expand_path(DEFAULT_FILE)
- else
- filepath = File.expand_path(@credential_file)
- end
- File.open(filepath,'w+') do |f|
- f.write(MultiJson.dump({"authorization_uri" => authorization_uri,
- "token_credential_uri"=>"https://accounts.google.com/o/oauth2/token",
- "scope"=>scope,"redirect_uri"=>redirect_uri, "client_id"=>client_id,
- "client_secret"=>client_secret, "access_token"=>access_token,
- "expires_in"=>expires_in,"refresh_token"=> refresh_token, "id_token"=>id_token,
- "issued_at"=>issued_at,"project"=>project }, :pretty=>true))
- end
+ "The SSL certificates validation may not configured for this system. Please refer README to configured SSL certificates validation"
end
+ save_credentials(project, api_client, credential_file)
end
+ def self.save_credentials(project, api_client, credential_file)
+ scope = api_client.authorization.scope
+ client_id = api_client.authorization.client_id
+ client_secret = api_client.authorization.client_secret
+ redirect_uri = api_client.authorization.redirect_uri
+ authorization_uri = "https://accounts.google.com/o/oauth2/auth"
+ access_token = api_client.authorization.access_token
+ refresh_token = api_client.authorization.refresh_token
+ id_token = api_client.authorization.id_token
+ expires_in = api_client.authorization.expires_in
+ issued_at = api_client.authorization.issued_at.to_s
+
+ File.open(credential_file,'w+') do |f|
+ f.write(MultiJson.dump({"authorization_uri" => authorization_uri,
+ "token_credential_uri"=>"https://accounts.google.com/o/oauth2/token",
+ "scope"=>scope,"redirect_uri"=>redirect_uri, "client_id"=>client_id,
+ "client_secret"=>client_secret, "access_token"=>access_token,
+ "expires_in"=>expires_in,"refresh_token"=> refresh_token, "id_token"=>id_token,
+ "issued_at"=>issued_at,"project"=>project }, :pretty=>true))
+ end
+ end
+
def projects
ResourceCollection.new(:resource_class => Google::Compute::Project, :dispatcher => @dispatcher)
end
def disks
@@ -157,15 +165,16 @@
def snapshots
CreatableResourceCollection.new(:resource_class => Google::Compute::Snapshot, :dispatcher=>@dispatcher)
end
class APIDispatcher
- attr_reader :project, :api_client
+ attr_reader :project, :api_client, :credential_file
def initialize(opts)
@project= opts[:project]
@api_client = opts[:api_client]
+ @credential_file = opts[:credential_file]
end
def compute
@compute ||= @api_client.discovered_api('compute','v1')
end
@@ -184,9 +193,15 @@
error_code = response["error"]["code"]
if error_code == 404
raise ResourceNotFound, result.response.body
elsif error_code == 400
raise BadRequest, result.response.body
+ elsif error_code == 401
+ # ok, our credentials aren't working, we need
+ # to get a new refresh token and retry
+ @api_client.authorization.fetch_access_token!
+ Client.save_credentials(@project, @api_client, @credential_file)
+ return dispatch(opts)
else
raise BadRequest, result.response.body
end
end
return MultiJson.load(result.response.body) unless result.response.body.nil?