Skip to content

Instantly share code, notes, and snippets.

@madbox
Last active July 28, 2017 20:00
Show Gist options
  • Save madbox/110dadf4ae8dc60511cd2f1948cadfd1 to your computer and use it in GitHub Desktop.
Save madbox/110dadf4ae8dc60511cd2f1948cadfd1 to your computer and use it in GitHub Desktop.
Openshift Origin API wrapper class in Ruby
# coding: utf-8
require 'faraday'
require 'openssl'
require 'uri'
require 'json'
# CLI exampe API
# echo -n "developer:developer" | base64
# curl -v -k -H "X-CSRF-Token: 1" -H "Authorization: Basic ZGV2ZWxvcGVyOmRldmVsb3Blcg==" "https://172.17.0.1:8443/oauth/authorize?response_type=token&client_id=openshift-challenging-client"
# curl -vkL -H "Authorization: Bearer 90VKUi5EmPr0rZNYaX3yzeUKpnn8_Muu6-e8YqC1hUM" "https://172.17.0.1:8443/api/v1/projects"
# curl -vkL -H "Authorization: Bearer 90VKUi5EmPr0rZNYaX3yzeUKpnn8_Muu6-e8YqC1hUM" "https://172.17..1:8443/oapi/v1/namespaces/myproject/builds"
# Example
# MY_URI = 'https://172.17.0.1:8443'
# MY_URI = 'http://localhost:4567'
# $oapi = OpenshiftAPI.new MY_URI
# puts $oapi.login('admin', 'admin').inspect
# #####
class OpenshiftAPI
HTTP_TIMEOUT = 17
HTTP_OPEN_TIMEOUT = 10
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 = HTTP_TIMEOUT # open/read timeout in seconds
req.options.open_timeout = HTTP_OPEN_TIMEOUT # 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 = HTTP_TIMEOUT # open/read timeout in seconds
req.options.open_timeout = HTTP_OPEN_TIMEOUT # 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
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment