Last active
July 28, 2017 20:00
-
-
Save madbox/110dadf4ae8dc60511cd2f1948cadfd1 to your computer and use it in GitHub Desktop.
Openshift Origin API wrapper class in Ruby
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
# 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