kong 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.gitignore +15 -0
- data/.rubocop.yml +360 -0
- data/.travis.yml +8 -0
- data/Gemfile +8 -0
- data/LICENSE +191 -0
- data/README.md +210 -0
- data/Rakefile +5 -0
- data/kong.gemspec +24 -0
- data/lib/kong.rb +13 -0
- data/lib/kong/api.rb +14 -0
- data/lib/kong/base.rb +153 -0
- data/lib/kong/basic_auth.rb +8 -0
- data/lib/kong/belongs_to_api.rb +30 -0
- data/lib/kong/belongs_to_consumer.rb +30 -0
- data/lib/kong/client.rb +226 -0
- data/lib/kong/consumer.rb +71 -0
- data/lib/kong/error.rb +8 -0
- data/lib/kong/key_auth.rb +8 -0
- data/lib/kong/oauth2_token.rb +14 -0
- data/lib/kong/oauth_app.rb +8 -0
- data/lib/kong/plugin.rb +9 -0
- data/lib/kong/version.rb +3 -0
- data/spec/kong/api_spec.rb +27 -0
- data/spec/kong/base_spec.rb +147 -0
- data/spec/kong/basic_auth_spec.rb +26 -0
- data/spec/kong/client_spec.rb +267 -0
- data/spec/kong/consumer_spec.rb +44 -0
- data/spec/kong/key_auth_spec.rb +26 -0
- data/spec/kong/oauth2_token_spec.rb +19 -0
- data/spec/kong/oauth_app_spec.rb +19 -0
- data/spec/kong/plugin_spec.rb +26 -0
- data/spec/spec_helper.rb +19 -0
- data/tasks/rspec.rake +5 -0
- metadata +129 -0
data/README.md
ADDED
@@ -0,0 +1,210 @@
|
|
1
|
+
# Kong Client for Ruby
|
2
|
+
|
3
|
+
[Kong](http://getkong.org) API client for Ruby
|
4
|
+
|
5
|
+
[![Build Status](https://travis-ci.org/kontena/kong-client-ruby.svg?branch=master)](https://travis-ci.org/kontena/kong-client-ruby)
|
6
|
+
|
7
|
+
## Installation
|
8
|
+
Add this line to your application's Gemfile:
|
9
|
+
|
10
|
+
gem 'kong'
|
11
|
+
|
12
|
+
And then execute:
|
13
|
+
|
14
|
+
$ bundle
|
15
|
+
|
16
|
+
Or install it yourself as:
|
17
|
+
|
18
|
+
$ gem install kong
|
19
|
+
|
20
|
+
## Usage
|
21
|
+
|
22
|
+
By default Kong client tries to connect `http://localhost:8001` or address provided by environment variable: `KONG_URI='http://your-kong-url:8001'`.
|
23
|
+
|
24
|
+
You can set it also in your code:
|
25
|
+
```ruby
|
26
|
+
require 'kong'
|
27
|
+
Kong::Client.api_url = 'http://your-kong-url:8001'
|
28
|
+
```
|
29
|
+
|
30
|
+
### Desing
|
31
|
+
|
32
|
+
Kong client follows a design of resoures as Plain Old Ruby objects(tm). For examples to create a new Consumer resource you can do it like this:
|
33
|
+
|
34
|
+
```ruby
|
35
|
+
consumer = Kong::Consumer.create({ username: 'testuser', custom_id: 'custom_id' })
|
36
|
+
```
|
37
|
+
|
38
|
+
OR
|
39
|
+
|
40
|
+
```ruby
|
41
|
+
consumer = Kong::Consumer.new({ username: 'testuser'})
|
42
|
+
consumer.custom_id = '12345'
|
43
|
+
consumer.save
|
44
|
+
```
|
45
|
+
|
46
|
+
To find existing consumer:
|
47
|
+
|
48
|
+
```ruby
|
49
|
+
consumer = Kong::Consumer.find_by_username('testuser')
|
50
|
+
consumer = Kong::Consumer.find_by_custom_id('custom_id')
|
51
|
+
```
|
52
|
+
|
53
|
+
### All Resources and Actions
|
54
|
+
|
55
|
+
#### Consumer
|
56
|
+
|
57
|
+
```ruby
|
58
|
+
Kong::Consumer.list(filters)
|
59
|
+
Kong::Consumer.all()
|
60
|
+
Kong::Consumer.find(id)
|
61
|
+
Kong::Consumer.find_by_*(value)
|
62
|
+
Kong::Consumer.create(attributes)
|
63
|
+
|
64
|
+
consumer = Kong::Consumer.new({ username: 'test-user' })
|
65
|
+
consumer.get # reloads resource
|
66
|
+
consumer.create
|
67
|
+
consumer.update
|
68
|
+
consumer.save # requests create_or_update action
|
69
|
+
consumer.delete
|
70
|
+
|
71
|
+
consumer.plugins
|
72
|
+
consumer.oauth_apps
|
73
|
+
consumer.key_auths
|
74
|
+
consumer.basic_auths
|
75
|
+
consumer.oauth2_tokens
|
76
|
+
```
|
77
|
+
|
78
|
+
#### API
|
79
|
+
|
80
|
+
```ruby
|
81
|
+
Kong::Api.list(filters)
|
82
|
+
Kong::Api.all()
|
83
|
+
Kong::Api.find(id)
|
84
|
+
Kong::Api.find_by_*(value)
|
85
|
+
Kong::Api.create(attributes)
|
86
|
+
|
87
|
+
api = Kong::Api.new({
|
88
|
+
name: 'Mockbin',
|
89
|
+
request_host: 'mockbin.com',
|
90
|
+
request_path: '/someservice',
|
91
|
+
strip_request_path: false,
|
92
|
+
preserve_host: false,
|
93
|
+
upstream_url: 'https://mockbin.com'
|
94
|
+
})
|
95
|
+
api.get # reloads resource
|
96
|
+
api.create
|
97
|
+
api.update
|
98
|
+
api.save # requests create_or_update action
|
99
|
+
api.delete
|
100
|
+
|
101
|
+
api.plugins
|
102
|
+
```
|
103
|
+
|
104
|
+
#### Plugin
|
105
|
+
|
106
|
+
```ruby
|
107
|
+
Kong::Plugin.list(filters)
|
108
|
+
Kong::Plugin.all()
|
109
|
+
Kong::Plugin.find(id)
|
110
|
+
Kong::Plugin.find_by_*(value)
|
111
|
+
Kong::Plugin.create(attributes)
|
112
|
+
|
113
|
+
plugin = Kong::Plugin.new({
|
114
|
+
api_id: '5fd1z584-1adb-40a5-c042-63b19db49x21',
|
115
|
+
consumer_id: 'a3dX2dh2-1adb-40a5-c042-63b19dbx83hF4',
|
116
|
+
name: 'rate-limiting',
|
117
|
+
config: {
|
118
|
+
minute: 20,
|
119
|
+
hour: 500
|
120
|
+
}
|
121
|
+
})
|
122
|
+
|
123
|
+
plugin.get # reloads resource
|
124
|
+
plugin.create
|
125
|
+
plugin.update
|
126
|
+
plugin.save # requests create_or_update action
|
127
|
+
plugin.delete
|
128
|
+
```
|
129
|
+
|
130
|
+
#### OAuthApp
|
131
|
+
|
132
|
+
```ruby
|
133
|
+
Kong::OAuthApp.list(filters)
|
134
|
+
Kong::OAuthApp.all()
|
135
|
+
Kong::OAuthApp.find(consumer_id)
|
136
|
+
Kong::OAuthApp.find_by_*(value)
|
137
|
+
Kong::OAuthApp.create(attributes)
|
138
|
+
|
139
|
+
app = Kong::OAuthApp.new({
|
140
|
+
consumer_id: 'a3dX2dh2-1adb-40a5-c042-63b19dbx83hF4',
|
141
|
+
redirect_uri: 'http://some-domain/endpoint/'
|
142
|
+
})
|
143
|
+
|
144
|
+
app.create
|
145
|
+
app.get # reloads resource
|
146
|
+
app.update
|
147
|
+
app.save # requests create_or_update action
|
148
|
+
app.delete
|
149
|
+
```
|
150
|
+
|
151
|
+
#### KeyAuth
|
152
|
+
|
153
|
+
```ruby
|
154
|
+
Kong::KeyAuth.create(attributes)
|
155
|
+
|
156
|
+
auth = Kong::KeyAuth.new({
|
157
|
+
consumer_id: 'a3dX2dh2-1adb-40a5-c042-63b19dbx83hF4',
|
158
|
+
})
|
159
|
+
|
160
|
+
auth.create
|
161
|
+
auth.get # reloads resource
|
162
|
+
auth.update
|
163
|
+
auth.save # requests create_or_update action
|
164
|
+
auth.delete
|
165
|
+
```
|
166
|
+
|
167
|
+
#### BasicAuth
|
168
|
+
|
169
|
+
```ruby
|
170
|
+
Kong::KeyAuth.create(attributes)
|
171
|
+
|
172
|
+
auth = Kong::BasicAuth.new({
|
173
|
+
consumer_id: 'a3dX2dh2-1adb-40a5-c042-63b19dbx83hF4',
|
174
|
+
username: 'user123',
|
175
|
+
password: 'secret'
|
176
|
+
})
|
177
|
+
|
178
|
+
auth.create
|
179
|
+
auth.get # reloads resource
|
180
|
+
auth.update
|
181
|
+
auth.save # requests create_or_update action
|
182
|
+
auth.delete
|
183
|
+
```
|
184
|
+
|
185
|
+
#### OAuth2Token
|
186
|
+
|
187
|
+
```ruby
|
188
|
+
token = Kong::OAuth2Token.find_by_access_token('SOME-TOKEN')
|
189
|
+
|
190
|
+
token = Kong::OAuth2Token.new({
|
191
|
+
credential_id: 'KONG-APPLICATION-ID',
|
192
|
+
token_type: 'bearer',
|
193
|
+
access_token: 'SOME-TOKEN',
|
194
|
+
refresh_token: 'SOME-TOKEN',
|
195
|
+
expires_in: 3600
|
196
|
+
})
|
197
|
+
|
198
|
+
token.create
|
199
|
+
token.update
|
200
|
+
token.save # requests create_or_update action
|
201
|
+
token.delete
|
202
|
+
```
|
203
|
+
|
204
|
+
## Contributing
|
205
|
+
|
206
|
+
1. Fork it ( https://github.com/kontena/kong-client-ruby/fork )
|
207
|
+
2. Create your feature branch (`git checkout -b my-new-feature`)
|
208
|
+
3. Commit your changes (`git commit -am 'Add some feature'`)
|
209
|
+
4. Push to the branch (`git push origin my-new-feature`)
|
210
|
+
5. Create a new Pull Request
|
data/Rakefile
ADDED
data/kong.gemspec
ADDED
@@ -0,0 +1,24 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
require 'kong/version'
|
5
|
+
|
6
|
+
Gem::Specification.new do |spec|
|
7
|
+
spec.name = "kong"
|
8
|
+
spec.version = Kong::VERSION
|
9
|
+
spec.authors = ["Lauri Nevala"]
|
10
|
+
spec.email = ["lauri@kontena.io"]
|
11
|
+
spec.summary = %q{A Ruby client for the Kong API }
|
12
|
+
spec.description = %q{A Ruby client for the Kong API}
|
13
|
+
spec.homepage = "https://github.com/kontena/kong-client-ruby"
|
14
|
+
spec.license = "Apache-2.0"
|
15
|
+
spec.files = `git ls-files -z`.split("\x0")
|
16
|
+
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
17
|
+
spec.require_paths = ["lib"]
|
18
|
+
|
19
|
+
spec.required_ruby_version = ">= 2.0.0"
|
20
|
+
|
21
|
+
spec.add_development_dependency "bundler", "~> 1.7"
|
22
|
+
spec.add_development_dependency "rake", "~> 10.0"
|
23
|
+
spec.add_runtime_dependency "excon", "~> 0.49.0"
|
24
|
+
end
|
data/lib/kong.rb
ADDED
@@ -0,0 +1,13 @@
|
|
1
|
+
require 'kong/version'
|
2
|
+
require 'kong/base'
|
3
|
+
require 'kong/api'
|
4
|
+
require 'kong/belongs_to_api'
|
5
|
+
require 'kong/client'
|
6
|
+
require 'kong/consumer'
|
7
|
+
require 'kong/belongs_to_consumer'
|
8
|
+
require 'kong/plugin'
|
9
|
+
require 'kong/error'
|
10
|
+
require 'kong/oauth_app'
|
11
|
+
require 'kong/oauth2_token'
|
12
|
+
require 'kong/basic_auth'
|
13
|
+
require 'kong/key_auth'
|
data/lib/kong/api.rb
ADDED
@@ -0,0 +1,14 @@
|
|
1
|
+
module Kong
|
2
|
+
class Api
|
3
|
+
include Base
|
4
|
+
|
5
|
+
ATTRIBUTE_NAMES = %w(id name request_host request_path strip_request_path preserve_host upstream_url).freeze
|
6
|
+
API_END_POINT = '/apis/'.freeze
|
7
|
+
|
8
|
+
##
|
9
|
+
# @return [Array<Kong::Plugin>]
|
10
|
+
def plugins
|
11
|
+
Plugin.list({ api_id: self.id })
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
data/lib/kong/base.rb
ADDED
@@ -0,0 +1,153 @@
|
|
1
|
+
module Kong
|
2
|
+
module Base
|
3
|
+
module ClassMethods
|
4
|
+
|
5
|
+
# List resources
|
6
|
+
# @return [Array]
|
7
|
+
def list(params = {})
|
8
|
+
result = []
|
9
|
+
json_data = Client.instance.get(self::API_END_POINT, params)
|
10
|
+
if json_data['data']
|
11
|
+
json_data['data'].each do |instance|
|
12
|
+
result << self.new(instance)
|
13
|
+
end
|
14
|
+
end
|
15
|
+
result
|
16
|
+
end
|
17
|
+
|
18
|
+
alias_method :all, :list
|
19
|
+
|
20
|
+
# Create resource
|
21
|
+
# @param [Hash] attributes
|
22
|
+
def create(attributes = {})
|
23
|
+
self.new(attributes).create
|
24
|
+
end
|
25
|
+
|
26
|
+
# Find resource
|
27
|
+
# @param [String] id
|
28
|
+
def find(id)
|
29
|
+
self.new.get(id)
|
30
|
+
end
|
31
|
+
|
32
|
+
def method_missing(method, *arguments, &block)
|
33
|
+
if method.to_s.start_with?('find_by_')
|
34
|
+
attribute = method.to_s.sub('find_by_', '')
|
35
|
+
if self.attribute_names.include?(attribute)
|
36
|
+
self.list({ attribute => arguments[0] })[0]
|
37
|
+
else
|
38
|
+
super
|
39
|
+
end
|
40
|
+
else
|
41
|
+
super
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
attr_accessor :attributes, :api_end_point
|
47
|
+
|
48
|
+
def self.included(base)
|
49
|
+
base.extend(ClassMethods)
|
50
|
+
|
51
|
+
base.send(:define_singleton_method, :attribute_names) do
|
52
|
+
base::ATTRIBUTE_NAMES
|
53
|
+
end
|
54
|
+
|
55
|
+
base.send(:define_method, :init_api_end_point) do
|
56
|
+
@api_end_point = base::API_END_POINT
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
##
|
61
|
+
# @param [Hash] attributes
|
62
|
+
def initialize(attributes = {})
|
63
|
+
init_api_end_point
|
64
|
+
init_attributes(attributes)
|
65
|
+
end
|
66
|
+
|
67
|
+
# Get Kong API client
|
68
|
+
# @return [Kong::Client]
|
69
|
+
def client
|
70
|
+
Client.instance
|
71
|
+
end
|
72
|
+
|
73
|
+
|
74
|
+
# Get resource
|
75
|
+
# @param [String] key
|
76
|
+
def get(key = nil)
|
77
|
+
key = self.id if key.nil?
|
78
|
+
path = @api_end_point + key
|
79
|
+
response = client.get(path) rescue nil
|
80
|
+
return nil if response.nil?
|
81
|
+
init_attributes(response)
|
82
|
+
self
|
83
|
+
end
|
84
|
+
|
85
|
+
# Delete resource
|
86
|
+
def delete
|
87
|
+
client.delete("#{@api_end_point}#{self.id}")
|
88
|
+
end
|
89
|
+
|
90
|
+
def new?
|
91
|
+
self.id.nil?
|
92
|
+
end
|
93
|
+
|
94
|
+
# Save resource to Kong
|
95
|
+
def save
|
96
|
+
create_or_update
|
97
|
+
end
|
98
|
+
|
99
|
+
# Create resource
|
100
|
+
def create
|
101
|
+
headers = { 'Content-Type' => 'application/x-www-form-urlencoded' }
|
102
|
+
response = client.post(@api_end_point, nil, attributes, headers)
|
103
|
+
init_attributes(response)
|
104
|
+
self
|
105
|
+
end
|
106
|
+
|
107
|
+
# Create or update resource
|
108
|
+
# Data is sent to Kong in JSON format and HTTP PUT request is used
|
109
|
+
def create_or_update
|
110
|
+
headers = { 'Content-Type' => 'application/json' }
|
111
|
+
response = client.put("#{@api_end_point}", attributes, nil, headers)
|
112
|
+
init_attributes(response)
|
113
|
+
self
|
114
|
+
end
|
115
|
+
|
116
|
+
# Update resource
|
117
|
+
def update
|
118
|
+
headers = { 'Content-Type' => 'application/x-www-form-urlencoded' }
|
119
|
+
response = client.patch("#{@api_end_point}#{self.id}", nil, attributes, headers)
|
120
|
+
init_attributes(response)
|
121
|
+
self
|
122
|
+
end
|
123
|
+
|
124
|
+
def method_missing(method, *arguments, &block)
|
125
|
+
if self.class.attribute_names.include?(method.to_s)
|
126
|
+
@attributes[method.to_s]
|
127
|
+
elsif method.to_s.end_with?('=') && self.class.attribute_names.include?(attribute = method.to_s.split('=').first)
|
128
|
+
@attributes[attribute] = arguments[0]
|
129
|
+
else
|
130
|
+
super
|
131
|
+
end
|
132
|
+
end
|
133
|
+
|
134
|
+
def respond_to?(method, include_private = false)
|
135
|
+
if self.class.attribute_names.include?(method.to_s.split('=')[0])
|
136
|
+
true
|
137
|
+
else
|
138
|
+
super
|
139
|
+
end
|
140
|
+
end
|
141
|
+
|
142
|
+
private
|
143
|
+
|
144
|
+
def init_attributes(attributes)
|
145
|
+
@attributes = {}
|
146
|
+
attributes.each do |key, value|
|
147
|
+
@attributes[key.to_s] = value
|
148
|
+
end
|
149
|
+
use_consumer_end_point if respond_to?(:use_consumer_end_point)
|
150
|
+
use_api_end_point if respond_to?(:use_api_end_point)
|
151
|
+
end
|
152
|
+
end
|
153
|
+
end
|
@@ -0,0 +1,30 @@
|
|
1
|
+
module Kong
|
2
|
+
module BelongsToApi
|
3
|
+
attr_accessor :api
|
4
|
+
|
5
|
+
# Convert API end point relative to Kong API resource
|
6
|
+
def use_api_end_point
|
7
|
+
self.api_end_point = "/apis/#{self.api_id}#{self.class::API_END_POINT}" if self.api_id
|
8
|
+
end
|
9
|
+
|
10
|
+
# Get Api resource
|
11
|
+
# @return [Kong::Api]
|
12
|
+
def api
|
13
|
+
@api ||= Api.find(self.api_id)
|
14
|
+
end
|
15
|
+
|
16
|
+
# Set Api resource
|
17
|
+
# @param [Kong::Api] api
|
18
|
+
def api=(api)
|
19
|
+
@api = api
|
20
|
+
self.api_id = api.id
|
21
|
+
end
|
22
|
+
|
23
|
+
# Set Api id
|
24
|
+
# @param [String] id
|
25
|
+
def api_id=(id)
|
26
|
+
super(id)
|
27
|
+
use_api_end_point
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|