Last active
December 15, 2016 21:32
-
-
Save madbox/03aa14969d4b36bd7b1dcb71f54ecf14 to your computer and use it in GitHub Desktop.
Simple Openshift Origin API wrapper class with oauth
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
require 'faraday' | |
require 'openssl' | |
require 'uri' | |
require 'json' | |
class OpenshiftAPI | |
class ConnectionError < RuntimeError | |
end | |
class OpenshiftObject | |
attr_accessor :oapi_data | |
def initialize oapi_data | |
raise(ArgumentError, "oapi_data should be a Hash") unless oapi_data.kind_of? Hash | |
raise(ArgumentError, "oapi_data invalid") unless oapi_data.has_key?('kind') | |
@oapi_data = oapi_data | |
end | |
def method_missing method, *args, &block | |
puts method.inspect | |
key_name = method.to_s | |
if @oapi_data.has_key?(key_name) | |
return @oapi_data[key_name] | |
end | |
# Raise error if can't find key in @oapi_data | |
raise NoMethodError, <<ERRORINFO | |
method: #{method} | |
args: #{args.inspect} | |
on: #{self.class.name} | |
ERRORINFO | |
end | |
end | |
# Public: constructor | |
# | |
# api_url - String with Openshift API url. Something like | |
# https://172.17.0.1:8443'. | |
def initialize api_url | |
raise(ArgumentError, 'api_url invalid') unless api_url =~ /\A#{URI::regexp(['http', 'https'])}\z/ | |
@api_url = api_url | |
@access_token = {} | |
end | |
# Public: Execute authorization procedure. | |
# | |
# user, pass - Strings with username and password | |
# | |
# Returns @access_token - hash: | |
# { "access_token"=>"INGZODdekETcXoDV8MRXFW3j1NP-GTuphkkRyx-0UWU", | |
# "expires_in"=>"86400", | |
# "scope"=>"user:full", | |
# "token_type"=>"Bearer" } | |
def login user, pass | |
raise(ArgumentError, "user invalid") unless user.kind_of? String | |
raise(ArgumentError, "pass invalid") unless user.kind_of? String | |
@user = user | |
@pass = pass | |
@access_token = get_access_token | |
end | |
# Public: Check login state. Returns true if @access_token is not | |
# empty. | |
def logged_in? | |
@access_token['access_token'].kind_of?(String) && @access_token.length > 0 | |
end | |
def get_obj api_path | |
OpenshiftObject.new get_json(api_path) | |
end | |
def get_json api_path | |
raise(ArgumentError, "api_path invalid") unless api_path.kind_of? String | |
raise(ArgumentError, "api_path should not be empty") unless api_path.length > 0 | |
conn = Faraday.new(:ssl => {:verify => false}) | |
conn.authorization :Bearer, @access_token['access_token'] | |
conn.url_prefix = @api_url + '/oapi/v1' | |
response = conn.get do |req| | |
req.url api_path | |
req.options.timeout = 5 # open/read timeout in seconds | |
req.options.open_timeout = 2 # connection open timeout in seconds | |
end | |
JSON.parse response.body | |
end | |
private | |
# Private: Get access token using OAuth2.0 Implcit grant auth type | |
# https://tools.ietf.org/html/rfc6749#section-4.2 | |
def get_access_token | |
conn = Faraday.new(:url => @api_url + '/oauth/authorize', :ssl => {:verify => false}) | |
conn.basic_auth @user, @pass | |
conn.params['client_id'] = 'openshift-challenging-client' | |
conn.params['response_type'] = 'token' | |
conn.headers['X-CSRF-Token'] = '1' | |
begin | |
response = conn.get do |req| | |
req.options.timeout = 5 # open/read timeout in seconds | |
req.options.open_timeout = 2 # connection open timeout in seconds | |
end | |
rescue Faraday::Error => e | |
err_msg = "Failed to connect to #{@api_url}: #{e.message}" | |
raise ConnectionError, err_msg | |
end | |
raise(ConnectionError, "Unable to parse 'location' header while getting access token") unless response.headers['location'] | |
location_uri = Faraday::Utils.URI(response.headers['location']) | |
access_token_hash = Hash[*location_uri.fragment.split(/[&=]/)] | |
access_token_hash | |
end | |
end | |
# Example: | |
# MY_URI = 'https://172.17.0.1:8443' | |
# $oapi = OpenshiftAPI.new MY_URI | |
# $oapi.login('admin', 'admin').inspect | |
# projects = $oapi.get_obj 'projects' | |
# project_name = projects.items.first['metadata']['name'] # will work if there is any projects in your Openshift | |
# $oapi.get_obj '/oapi/v1/namespaces/#{project_name}/buildconfigs' |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment