Skip to content

Instantly share code, notes, and snippets.

@madbox
Last active December 15, 2016 21:32
Show Gist options
  • Save madbox/03aa14969d4b36bd7b1dcb71f54ecf14 to your computer and use it in GitHub Desktop.
Save madbox/03aa14969d4b36bd7b1dcb71f54ecf14 to your computer and use it in GitHub Desktop.
Simple Openshift Origin API wrapper class with oauth
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