kong 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -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
@@ -0,0 +1,5 @@
1
+ require "bundler/gem_tasks"
2
+
3
+ Dir.glob('tasks/*.rake').each { |r| import r }
4
+
5
+ task :default => :spec
@@ -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
@@ -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'
@@ -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
@@ -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,8 @@
1
+ module Kong
2
+ class BasicAuth
3
+ include Base
4
+ include BelongsToConsumer
5
+ ATTRIBUTE_NAMES = %w(id username password consumer_id).freeze
6
+ API_END_POINT = "/basic-auth/".freeze
7
+ end
8
+ 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