Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[WIP] Allow to operate against multiple Kong API servers #26

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions lib/kong.rb
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
require 'kong/version'
require_relative 'kong/base'
require_relative 'kong/rootless'
require_relative 'kong/collection'
require_relative 'kong/api'
require_relative 'kong/belongs_to_api'
require_relative 'kong/client'
Expand Down
2 changes: 1 addition & 1 deletion lib/kong/api.rb
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ class Api
##
# @return [Array<Kong::Plugin>]
def plugins
Plugin.list({ api_id: self.id })
Plugin.list({ api_id: self.id }, client: self.client)
end
end
end
65 changes: 46 additions & 19 deletions lib/kong/base.rb
Original file line number Diff line number Diff line change
Expand Up @@ -4,36 +4,46 @@ module ClassMethods

# List resources
# @return [Array]
def list(params = {})
def list(params = {}, opts = {})
opts = {} if opts.nil?
client = opts[:client] ? opts[:client] : Client.instance
collection = opts[:collection] ? opts[:collection] : Collection.new(self, client)
api_end_point = opts[:api_end_point] ? opts[:api_end_point] : self::API_END_POINT
result = []
json_data = Client.instance.get(self::API_END_POINT, params)
json_data = client.get(api_end_point, params)
if json_data['data']
json_data['data'].each do |instance|
result << self.new(instance)
result << self.new(instance, { client: client, collection: collection })
end
end
result
end

alias_method :all, :list
def all(params = {}, opts = {})
self.list({ size: 9999999 }, opts)
end

def first(opts={})

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Surrounding space missing in default value assignment.

self.list({},opts).first

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Space missing after comma.

end

# Create resource
# @param [Hash] attributes
def create(attributes = {})
self.new(attributes).create
def create(attributes = {}, opts = {})
self.new(attributes, opts).create
end

# Find resource
# @param [String] id
def find(id)
self.new.get(id)
def find(id, opts = {})
self.new({}, opts).get(id)
end

def method_missing(method, *arguments, &block)
if method.to_s.start_with?('find_by_')
attribute = method.to_s.sub('find_by_', '')
if self.attribute_names.include?(attribute)
self.list({ attribute => arguments[0] })[0]
self.list({ attribute => arguments[0] }, arguments[1])[0]
else
super
end
Expand All @@ -57,6 +67,7 @@ def respond_to?(method, include_private = false)
end

attr_accessor :attributes, :api_end_point
attr_reader :client, :collection

def self.included(base)
base.extend(ClassMethods)
Expand All @@ -72,18 +83,13 @@ def self.included(base)

##
# @param [Hash] attributes
def initialize(attributes = {})
def initialize(attributes = {}, opts = {})
@client = opts[:client] ? opts[:client] : Client.instance
@collection = opts[:collection] ? opts[:collection] : Collection.new(self.class, @client)
init_api_end_point
init_attributes(attributes)
end

# Get Kong API client
# @return [Kong::Client]
def client
Client.instance
end


# Get resource
# @param [String] key
def get(key = nil)
Expand All @@ -104,13 +110,30 @@ def new?
self.id.nil?
end

def set(attributes)
self.attributes = attributes
self.attributes
end

def to_s
self.attributes.to_s
end

def to_json
self.attributes.to_json
end

def inspect
self.attributes.inspect
end
# Save resource to Kong
def save
create_or_update
end

# Create resource
def create
def create(attributes = {})
attributes = self.attributes.merge(attributes)
headers = { 'Content-Type' => 'application/x-www-form-urlencoded' }
response = client.post(@api_end_point, nil, attributes, headers)
init_attributes(response)
Expand Down Expand Up @@ -156,8 +179,12 @@ def respond_to?(method, include_private = false)

def init_attributes(attributes)
@attributes = {}
self.attributes = attributes
end

def attributes=(attributes)
attributes.each do |key, value|
@attributes[key.to_s] = value
@attributes[key.to_s] = value if self.class.attribute_names.include?(key.to_s)
end
use_consumer_end_point if respond_to?(:use_consumer_end_point)
use_api_end_point if respond_to?(:use_api_end_point)
Expand Down
2 changes: 1 addition & 1 deletion lib/kong/belongs_to_api.rb
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ def use_api_end_point
# Get Api resource
# @return [Kong::Api]
def api
@api ||= Api.find(self.api_id)
@api ||= Api.find(self.api_id, client: self.client)
end

# Set Api resource
Expand Down
2 changes: 1 addition & 1 deletion lib/kong/belongs_to_consumer.rb
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ def use_consumer_end_point
# Get Consumer resource
# @return [Kong::Consumer]
def consumer
@consumer ||= Consumer.find(self.consumer_id)
@consumer ||= Consumer.find(self.consumer_id, client: self.client)
end

# Set Consumer resource
Expand Down
77 changes: 57 additions & 20 deletions lib/kong/client.rb
Original file line number Diff line number Diff line change
@@ -1,25 +1,25 @@
require 'singleton'

require 'json'
require 'excon'
require_relative './error'

module Kong
class Client
class << self
attr_accessor :http_client
end

include Singleton

attr_accessor :default_headers
attr_accessor :default_headers, :http_client, :api_url

# Initialize api client
#
def initialize
def initialize(url = nil)
Excon.defaults[:ssl_verify_peer] = false if ignore_ssl_errors?
@api_url = api_url
self.class.http_client = Excon.new(@api_url, omit_default_port: true)
if url
@api_url = url
else
@api_url = self.class.api_url
end
@http_client = Excon.new(@api_url, omit_default_port: true)
@default_headers = { 'Accept' => 'application/json' }
@collections = {}
end

def self.api_url
Expand All @@ -28,22 +28,55 @@ def self.api_url

def self.api_url=(url)
@api_url = url
@http_client = Excon.new(self.api_url, omit_default_port: true)
@instance = self.new
end

def http_client
self.class.http_client
def self.instance
@instance ||= self.new
end

# Kong Admin API URL
#
# @return [String]
def api_url
self.class.api_url
def consumers
collection(Consumer)
end

def api_url=(url)
@api_url = url
def apis
collection(Api)
end

def oauth_apps
collection(OAuthApp)
end

def oauth2_tokens
collection(OAuth2Token)
end

def plugins
collection(Plugin)
end

def targets
collection(Target)
end

def info
get('/')
end

def status
get('/status')
end

def cluster
get('/cluster')
end

def version
self.info['version'] rescue nil
end

def remove_node(name)
delete("/cluster/nodes/#{name}")
end


Expand Down Expand Up @@ -161,6 +194,10 @@ def delete(path, body = nil, params = {}, headers = {})

private

def collection(klass)
@collections[klass.name] || @collections[klass.name] = Collection.new(klass, self)
end

##
# Get request headers
#
Expand Down
31 changes: 31 additions & 0 deletions lib/kong/collection.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
module Kong
class Collection
def initialize(klass, client, api_end_point = nil)
@klass = klass
@client = client
@api_end_point = api_end_point
end

def first
self.list.first
end

def last
self.all.last
end

def method_missing(method, *arguments, &block)
opts = { client: @client, collection: self, api_end_point: @api_end_point }
if arguments.size == 0
arguments = [{}, opts]
else
arguments << opts
end
@klass.send(method, *arguments)
end

def respond_to?(method, include_private = false)
@klass.respond_to?(method, include_private)
end
end
end

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Final newline missing.

Loading