kongrations 0.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/.gitignore +3 -0
- data/.rspec +2 -0
- data/.rubocop.yml +33 -0
- data/Gemfile +5 -0
- data/Gemfile.lock +69 -0
- data/LICENSE.txt +21 -0
- data/README.md +174 -0
- data/Rakefile +4 -0
- data/bin/kongrations +7 -0
- data/kongrations.gemspec +32 -0
- data/lib/kongrations/current_environment.rb +41 -0
- data/lib/kongrations/environment.rb +38 -0
- data/lib/kongrations/hash_ext.rb +12 -0
- data/lib/kongrations/migration.rb +68 -0
- data/lib/kongrations/migration_data.rb +41 -0
- data/lib/kongrations/request.rb +43 -0
- data/lib/kongrations/requests/change_api_request.rb +21 -0
- data/lib/kongrations/requests/change_plugin_request.rb +23 -0
- data/lib/kongrations/requests/create_api_request.rb +15 -0
- data/lib/kongrations/requests/create_plugin_request.rb +21 -0
- data/lib/kongrations/requests/delete_api_request.rb +21 -0
- data/lib/kongrations/requests/delete_plugin_request.rb +23 -0
- data/lib/kongrations/response.rb +33 -0
- data/lib/kongrations/responses/create_plugin_response.rb +20 -0
- data/lib/kongrations/version.rb +5 -0
- data/lib/kongrations.rb +51 -0
- metadata +157 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 545381fabd1ab7b6df0c4bc5fb341a1ee96ec2b1
|
4
|
+
data.tar.gz: d0bbcc1e92fcb6c7a4ab792342be7e2ab0dbe467
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 0a095700de6afeca8fc6bf31ad638661845fa8add224e576219209a8db4a6f8629ad30ebe68be931f64a325dabd02aec2fe56b36f5fee4028dea53aee2630047
|
7
|
+
data.tar.gz: b34226c452f75a3cf5419aaaa859fee3d494c88d57857572fedda15a0c1545a026b340a1bba2335c6cb2d9d9951c8a4cf9470cb1be59519236863dfefd706f97
|
data/.gitignore
ADDED
data/.rspec
ADDED
data/.rubocop.yml
ADDED
@@ -0,0 +1,33 @@
|
|
1
|
+
AllCops:
|
2
|
+
Exclude:
|
3
|
+
- './spec/fixtures/migrations/**/*.rb'
|
4
|
+
TargetRubyVersion: 2.4
|
5
|
+
DisplayCopNames: true
|
6
|
+
|
7
|
+
Style/Encoding:
|
8
|
+
Enabled: true
|
9
|
+
|
10
|
+
Style/FrozenStringLiteralComment:
|
11
|
+
EnforcedStyle: always
|
12
|
+
|
13
|
+
Metrics/LineLength:
|
14
|
+
Max: 120
|
15
|
+
|
16
|
+
Metrics/ModuleLength:
|
17
|
+
Max: 120
|
18
|
+
|
19
|
+
Metrics/BlockLength:
|
20
|
+
Exclude:
|
21
|
+
- './spec/**/*.rb'
|
22
|
+
|
23
|
+
Metrics/MethodLength:
|
24
|
+
Max: 20
|
25
|
+
|
26
|
+
Metrics/AbcSize:
|
27
|
+
Max: 20
|
28
|
+
|
29
|
+
Style/Encoding:
|
30
|
+
Enabled: false
|
31
|
+
|
32
|
+
Style/Documentation:
|
33
|
+
Enabled: false
|
data/Gemfile
ADDED
data/Gemfile.lock
ADDED
@@ -0,0 +1,69 @@
|
|
1
|
+
PATH
|
2
|
+
remote: .
|
3
|
+
specs:
|
4
|
+
kongrations (0.1.0)
|
5
|
+
|
6
|
+
GEM
|
7
|
+
remote: https://rubygems.org/
|
8
|
+
specs:
|
9
|
+
addressable (2.5.2)
|
10
|
+
public_suffix (>= 2.0.2, < 4.0)
|
11
|
+
ast (2.4.0)
|
12
|
+
coderay (1.1.2)
|
13
|
+
crack (0.4.3)
|
14
|
+
safe_yaml (~> 1.0.0)
|
15
|
+
diff-lcs (1.3)
|
16
|
+
hashdiff (0.3.7)
|
17
|
+
method_source (0.9.0)
|
18
|
+
parallel (1.12.1)
|
19
|
+
parser (2.5.0.4)
|
20
|
+
ast (~> 2.4.0)
|
21
|
+
powerpack (0.1.1)
|
22
|
+
pry (0.11.3)
|
23
|
+
coderay (~> 1.1.0)
|
24
|
+
method_source (~> 0.9.0)
|
25
|
+
public_suffix (3.0.2)
|
26
|
+
rainbow (3.0.0)
|
27
|
+
rake (10.5.0)
|
28
|
+
rspec (3.7.0)
|
29
|
+
rspec-core (~> 3.7.0)
|
30
|
+
rspec-expectations (~> 3.7.0)
|
31
|
+
rspec-mocks (~> 3.7.0)
|
32
|
+
rspec-core (3.7.1)
|
33
|
+
rspec-support (~> 3.7.0)
|
34
|
+
rspec-expectations (3.7.0)
|
35
|
+
diff-lcs (>= 1.2.0, < 2.0)
|
36
|
+
rspec-support (~> 3.7.0)
|
37
|
+
rspec-mocks (3.7.0)
|
38
|
+
diff-lcs (>= 1.2.0, < 2.0)
|
39
|
+
rspec-support (~> 3.7.0)
|
40
|
+
rspec-support (3.7.1)
|
41
|
+
rubocop (0.54.0)
|
42
|
+
parallel (~> 1.10)
|
43
|
+
parser (>= 2.5)
|
44
|
+
powerpack (~> 0.1)
|
45
|
+
rainbow (>= 2.2.2, < 4.0)
|
46
|
+
ruby-progressbar (~> 1.7)
|
47
|
+
unicode-display_width (~> 1.0, >= 1.0.1)
|
48
|
+
ruby-progressbar (1.9.0)
|
49
|
+
safe_yaml (1.0.4)
|
50
|
+
unicode-display_width (1.3.0)
|
51
|
+
webmock (3.3.0)
|
52
|
+
addressable (>= 2.3.6)
|
53
|
+
crack (>= 0.3.2)
|
54
|
+
hashdiff
|
55
|
+
|
56
|
+
PLATFORMS
|
57
|
+
ruby
|
58
|
+
|
59
|
+
DEPENDENCIES
|
60
|
+
bundler (~> 1.16)
|
61
|
+
kongrations!
|
62
|
+
pry (= 0.11.3)
|
63
|
+
rake (~> 10.0)
|
64
|
+
rspec (= 3.7.0)
|
65
|
+
rubocop (= 0.54.0)
|
66
|
+
webmock (= 3.3.0)
|
67
|
+
|
68
|
+
BUNDLED WITH
|
69
|
+
1.16.0
|
data/LICENSE.txt
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
The MIT License (MIT)
|
2
|
+
|
3
|
+
Copyright (c) 2018 Danilo Albuquerque
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
7
|
+
in the Software without restriction, including without limitation the rights
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
10
|
+
furnished to do so, subject to the following conditions:
|
11
|
+
|
12
|
+
The above copyright notice and this permission notice shall be included in
|
13
|
+
all copies or substantial portions of the Software.
|
14
|
+
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
21
|
+
THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,174 @@
|
|
1
|
+
# Kongrations
|
2
|
+
|
3
|
+
## Description
|
4
|
+
|
5
|
+
Kongrations is a migrations like for [Kong](https://github.com/Kong/kong) APIs and its associations like consumers and plugins.
|
6
|
+
You configure an environment and start creating files that will reproduce the specified changes into Kong using [Kong Admin API](https://getkong.org/docs/0.13.x/admin-api/).
|
7
|
+
|
8
|
+
Example of a migration to create an API:
|
9
|
+
```ruby
|
10
|
+
create_api do |api|
|
11
|
+
api.payload = {
|
12
|
+
name: 'my-api',
|
13
|
+
uris: '/myapi'
|
14
|
+
upstream_url: 'https://myapi.mycompany.com',
|
15
|
+
}
|
16
|
+
end
|
17
|
+
```
|
18
|
+
|
19
|
+
## Why Kongrations?
|
20
|
+
|
21
|
+
- Control what happens into Kong APIs.
|
22
|
+
- Keep track of every change.
|
23
|
+
- Apply same changes to different environments.
|
24
|
+
|
25
|
+
All of this using a readable Ruby syntax to describe the migrations.
|
26
|
+
|
27
|
+
## Compatibility
|
28
|
+
|
29
|
+
Kongrations was built upon Kong 0.13.x documentation.
|
30
|
+
|
31
|
+
## Getting Started
|
32
|
+
|
33
|
+
Kongrations depends on Ruby. Make sure you have it installed, then install Kongrations gem.
|
34
|
+
|
35
|
+
```ruby
|
36
|
+
gem install kongrations
|
37
|
+
```
|
38
|
+
|
39
|
+
### Configuring environments
|
40
|
+
|
41
|
+
You need to create a file called `kongrations.yml` and specify the desired environments of Kong.
|
42
|
+
You can use environments variables on the file too.
|
43
|
+
|
44
|
+
```yaml
|
45
|
+
environments:
|
46
|
+
- name: default
|
47
|
+
kong-admin-url: kong-admin-url.domain.com # Do not include HTTP or HTTPS here.
|
48
|
+
kong-admin-api-key: 123456789
|
49
|
+
|
50
|
+
- name: production
|
51
|
+
kong-admin-url: kong-admin-url-for-production.domain.com
|
52
|
+
kong-admin-api-key: <%= ENV['MY_ENV_VARIABLE'] %>
|
53
|
+
```
|
54
|
+
|
55
|
+
### Working with environments
|
56
|
+
|
57
|
+
Kongrations allows you to use parameters to specify differences across environments. You can do it as follows:
|
58
|
+
```ruby
|
59
|
+
config_env 'default' do |env|
|
60
|
+
env.upstream_url = 'https://myapi-staging.mycompany.com'
|
61
|
+
env.retries = 0
|
62
|
+
end
|
63
|
+
|
64
|
+
config_env 'production' do |env|
|
65
|
+
env.upstream_url = 'https://myapi.mycompany.com'
|
66
|
+
env.retries = 2
|
67
|
+
end
|
68
|
+
|
69
|
+
create__api do |api|
|
70
|
+
api.payload = {
|
71
|
+
name: 'my-api',
|
72
|
+
uris: '/myapi',
|
73
|
+
upstream_url: env.upstream_url,
|
74
|
+
retries: env.retries
|
75
|
+
}
|
76
|
+
end
|
77
|
+
```
|
78
|
+
|
79
|
+
First, you need to set the variables for your existing environments specified on `kongrations.yml` file.
|
80
|
+
Then, you use them through `env` name, like: `env.defined_variable`.
|
81
|
+
|
82
|
+
### Basic usage of the migrations
|
83
|
+
|
84
|
+
Defined migrations are mapped into HTTP requests to Kong Admin API accordingly to the [documentation](https://getkong.org/docs/0.13.x/admin-api).
|
85
|
+
Every request body described oh the Kong Admin API documentation must be set using the `payload` name.
|
86
|
+
|
87
|
+
After running the migration, Kongrations create a file on `./migrations-data` for each Kong environment to store its state. This file should be commited into your version control system. Also, it's extremely important not to touch this file directly, since it's crucial for Kongrations to work normally.
|
88
|
+
|
89
|
+
To run the migrations, use Kongrations cli, passing an optional parameter to specify the environment name (default environment name is `default`).
|
90
|
+
Examples:
|
91
|
+
```shell
|
92
|
+
$ kongrations # runs for default environment
|
93
|
+
$ kongrations production
|
94
|
+
```
|
95
|
+
|
96
|
+
### Available migrations
|
97
|
+
|
98
|
+
#### Create API
|
99
|
+
|
100
|
+
- [Kong Admin API Reference](https://getkong.org/docs/0.13.x/admin-api/#add-api)
|
101
|
+
- Usage: pass the request body through `api.payload`.
|
102
|
+
- Example:
|
103
|
+
```ruby
|
104
|
+
create_api do |api|
|
105
|
+
api.payload = {
|
106
|
+
name: 'my-api',
|
107
|
+
uris: '/myapi',
|
108
|
+
upstream_url: 'https://myapi.mycompany.com'
|
109
|
+
}
|
110
|
+
end
|
111
|
+
```
|
112
|
+
|
113
|
+
#### Update API
|
114
|
+
|
115
|
+
- [Kong Admin API Reference](https://getkong.org/docs/0.13.x/admin-api/#update-api)
|
116
|
+
- Usage: pass your API name right after `change_api` method, then pass the request body through `api.payload`.
|
117
|
+
- Example:
|
118
|
+
```ruby
|
119
|
+
change_api 'api-name' do |api|
|
120
|
+
api.payload = {
|
121
|
+
upstream_url: 'https://my-api.mycompany.com'
|
122
|
+
}
|
123
|
+
end
|
124
|
+
```
|
125
|
+
|
126
|
+
#### Delete API
|
127
|
+
|
128
|
+
- [Kong Admin API Reference](https://getkong.org/docs/0.13.x/admin-api/#delete-api)
|
129
|
+
- Usage: pass your API name right after `delete_api` method.
|
130
|
+
- Example:
|
131
|
+
```ruby
|
132
|
+
delete_api 'api-name'
|
133
|
+
```
|
134
|
+
|
135
|
+
#### Create Plugin
|
136
|
+
|
137
|
+
- [Kong Admin API Reference](https://getkong.org/docs/0.13.x/admin-api/#add-plugin)
|
138
|
+
- Usage: pass your API name right after `create_plugin_for_api` method, then pass the request body through `plugin.payload`.
|
139
|
+
- Example:
|
140
|
+
```ruby
|
141
|
+
create_plugin_for_api 'api-name' do |plugin|
|
142
|
+
plugin.payload = {
|
143
|
+
name: 'cors',
|
144
|
+
config: {
|
145
|
+
origins: '*',
|
146
|
+
methods: 'GET, POST'
|
147
|
+
}
|
148
|
+
}
|
149
|
+
end
|
150
|
+
```
|
151
|
+
|
152
|
+
#### Update Plugin
|
153
|
+
|
154
|
+
- [Kong Admin API Reference](https://getkong.org/docs/0.13.x/admin-api/#update-plugin)
|
155
|
+
- Usage: pass your API and plugin names right after `change_plugin_for_api` method, then pass the request body through `plugin.payload`.
|
156
|
+
- Example:
|
157
|
+
```ruby
|
158
|
+
change_plugin_for_api 'api-name', 'cors' do |plugin|
|
159
|
+
plugin.payload = {
|
160
|
+
config: {
|
161
|
+
methods: 'GET'
|
162
|
+
}
|
163
|
+
}
|
164
|
+
end
|
165
|
+
```
|
166
|
+
|
167
|
+
#### Delete Plugin
|
168
|
+
|
169
|
+
- [Kong Admin API Reference](https://getkong.org/docs/0.13.x/admin-api/#delete-plugin)
|
170
|
+
- Usage: pass your API and plugin names right after `delete_plugin_for_api` method.
|
171
|
+
- Example:
|
172
|
+
```ruby
|
173
|
+
delete_plugin_for_api 'api-name', 'cors'
|
174
|
+
```
|
data/Rakefile
ADDED
data/bin/kongrations
ADDED
data/kongrations.gemspec
ADDED
@@ -0,0 +1,32 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
lib = File.expand_path('lib', __dir__)
|
4
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
5
|
+
require 'kongrations/version'
|
6
|
+
|
7
|
+
Gem::Specification.new do |spec|
|
8
|
+
spec.name = 'kongrations'
|
9
|
+
spec.version = Kongrations::VERSION
|
10
|
+
spec.authors = ['Danilo Albuquerque']
|
11
|
+
spec.email = ['danilospalbuquerque@gmail.com']
|
12
|
+
|
13
|
+
spec.summary = 'Migrations for Kong APIs, plugin and consumers.'
|
14
|
+
spec.description = 'Migrations like for your Kong APIs, plugin and consumers.
|
15
|
+
It enables you to create files which describes the operations to be performed on Kong.'
|
16
|
+
spec.homepage = 'https://github.com/danilospa/kongrations'
|
17
|
+
spec.license = 'MIT'
|
18
|
+
|
19
|
+
spec.executables << 'kongrations'
|
20
|
+
|
21
|
+
spec.files = `git ls-files -z`.split("\x0").reject do |f|
|
22
|
+
f.match(%r{^(test|spec|features)/})
|
23
|
+
end
|
24
|
+
spec.require_paths = ['lib']
|
25
|
+
|
26
|
+
spec.add_development_dependency 'bundler', '~> 1.16'
|
27
|
+
spec.add_development_dependency 'pry', '0.11.3'
|
28
|
+
spec.add_development_dependency 'rake', '~> 10.0'
|
29
|
+
spec.add_development_dependency 'rspec', '3.7.0'
|
30
|
+
spec.add_development_dependency 'rubocop', '0.54.0'
|
31
|
+
spec.add_development_dependency 'webmock', '3.3.0'
|
32
|
+
end
|
@@ -0,0 +1,41 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'yaml'
|
4
|
+
require 'erb'
|
5
|
+
|
6
|
+
module Kongrations
|
7
|
+
module CurrentEnvironment
|
8
|
+
FILE_NAME = 'kongrations.yml'
|
9
|
+
|
10
|
+
def self.load!(name)
|
11
|
+
yaml = File.read(FILE_NAME)
|
12
|
+
|
13
|
+
template = ERB.new(yaml)
|
14
|
+
yaml = template.result(binding)
|
15
|
+
|
16
|
+
config = YAML.safe_load(yaml)
|
17
|
+
environment = config['environments'].detect { |e| e['name'] == name }
|
18
|
+
|
19
|
+
@migrations_folder = config.fetch('path', './migrations')
|
20
|
+
@name = name
|
21
|
+
@kong_admin_url = environment['kong-admin-url']
|
22
|
+
@kong_admin_api_key = environment['kong-admin-api-key']
|
23
|
+
end
|
24
|
+
|
25
|
+
def self.migrations_folder
|
26
|
+
@migrations_folder
|
27
|
+
end
|
28
|
+
|
29
|
+
def self.name
|
30
|
+
@name
|
31
|
+
end
|
32
|
+
|
33
|
+
def self.kong_admin_url
|
34
|
+
@kong_admin_url
|
35
|
+
end
|
36
|
+
|
37
|
+
def self.kong_admin_api_key
|
38
|
+
@kong_admin_api_key
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
@@ -0,0 +1,38 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
class Environment
|
4
|
+
def method_missing(*args)
|
5
|
+
method = args.first
|
6
|
+
return super unless respond_to_missing?(method.to_s)
|
7
|
+
|
8
|
+
create_getter_and_setter(method[0..-2])
|
9
|
+
value = args[1]
|
10
|
+
send(method, value)
|
11
|
+
end
|
12
|
+
|
13
|
+
def respond_to_missing?(method_name, include_private = false)
|
14
|
+
method_name.end_with?('=') || super
|
15
|
+
end
|
16
|
+
|
17
|
+
private
|
18
|
+
|
19
|
+
def assign_method?(method)
|
20
|
+
method.to_s.end_with?('=')
|
21
|
+
end
|
22
|
+
|
23
|
+
def create_getter_and_setter(method)
|
24
|
+
instance_eval(getter_and_setter(method))
|
25
|
+
end
|
26
|
+
|
27
|
+
def getter_and_setter(method)
|
28
|
+
"
|
29
|
+
def #{method}=(value)
|
30
|
+
@method = value
|
31
|
+
end
|
32
|
+
|
33
|
+
def #{method}
|
34
|
+
@method
|
35
|
+
end
|
36
|
+
"
|
37
|
+
end
|
38
|
+
end
|
@@ -0,0 +1,12 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Kongrations
|
4
|
+
module HashExt
|
5
|
+
refine Hash do
|
6
|
+
def deep_merge!(second)
|
7
|
+
merger = proc { |_key, v1, v2| v1.is_a?(Hash) && v2.is_a?(Hash) ? v1.merge(v2, &merger) : v2 }
|
8
|
+
merge!(second, &merger)
|
9
|
+
end
|
10
|
+
end
|
11
|
+
end
|
12
|
+
end
|
@@ -0,0 +1,68 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'kongrations/environment'
|
4
|
+
Dir["#{__dir__}/requests/*.rb"].each { |file| require file }
|
5
|
+
|
6
|
+
module Kongrations
|
7
|
+
class Migration
|
8
|
+
def initialize(migration_name, current_env)
|
9
|
+
@migration_name = migration_name
|
10
|
+
@current_env = current_env
|
11
|
+
@environments = {}
|
12
|
+
end
|
13
|
+
|
14
|
+
def run
|
15
|
+
response = change.execute
|
16
|
+
response.save_data(@migration_name) if response.success?
|
17
|
+
response
|
18
|
+
end
|
19
|
+
|
20
|
+
def config_env(env_name)
|
21
|
+
environment = Environment.new
|
22
|
+
yield(environment)
|
23
|
+
@environments[env_name.to_s] = environment
|
24
|
+
end
|
25
|
+
|
26
|
+
def env
|
27
|
+
@environments[@current_env]
|
28
|
+
end
|
29
|
+
|
30
|
+
def create_api
|
31
|
+
create_api_request = CreateApiRequest.new
|
32
|
+
yield(create_api_request)
|
33
|
+
create_api_request
|
34
|
+
end
|
35
|
+
|
36
|
+
def change_api(name)
|
37
|
+
change_api_request = ChangeApiRequest.new(name)
|
38
|
+
yield(change_api_request)
|
39
|
+
change_api_request
|
40
|
+
end
|
41
|
+
|
42
|
+
def delete_api(name)
|
43
|
+
DeleteApiRequest.new(name)
|
44
|
+
end
|
45
|
+
|
46
|
+
def create_plugin_for_api(api_name)
|
47
|
+
create_plugin_request = CreatePluginRequest.new(api_name)
|
48
|
+
yield(create_plugin_request)
|
49
|
+
create_plugin_request
|
50
|
+
end
|
51
|
+
|
52
|
+
def change_plugin_for_api(api_name, plugin_name)
|
53
|
+
change_plugin_request = ChangePluginRequest.new(api_name, plugin_name)
|
54
|
+
yield(change_plugin_request)
|
55
|
+
change_plugin_request
|
56
|
+
end
|
57
|
+
|
58
|
+
def delete_plugin_for_api(api_name, plugin_name)
|
59
|
+
DeletePluginRequest.new(api_name, plugin_name)
|
60
|
+
end
|
61
|
+
|
62
|
+
def self.build(migration_name, current_env, conten_to_eval)
|
63
|
+
klass = new(migration_name, current_env)
|
64
|
+
klass.instance_eval("def change; #{conten_to_eval}; end", __FILE__, __LINE__)
|
65
|
+
klass
|
66
|
+
end
|
67
|
+
end
|
68
|
+
end
|
@@ -0,0 +1,41 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'kongrations/hash_ext'
|
4
|
+
require 'kongrations/current_environment'
|
5
|
+
|
6
|
+
module Kongrations
|
7
|
+
using HashExt
|
8
|
+
|
9
|
+
module MigrationData
|
10
|
+
PATH = './migrations-data'
|
11
|
+
|
12
|
+
def self.load!
|
13
|
+
@data = File.exist?(file_name) ? JSON.parse(File.read(file_name)) : {}
|
14
|
+
end
|
15
|
+
|
16
|
+
def self.last_migration
|
17
|
+
@data['last_migration']
|
18
|
+
end
|
19
|
+
|
20
|
+
def self.save(migration_name, data)
|
21
|
+
@data['last_migration'] = migration_name
|
22
|
+
@data.deep_merge!(data) unless data.nil?
|
23
|
+
save_file
|
24
|
+
end
|
25
|
+
|
26
|
+
def self.data
|
27
|
+
@data
|
28
|
+
end
|
29
|
+
|
30
|
+
def self.file_name
|
31
|
+
"#{PATH}/#{CurrentEnvironment.name}.json"
|
32
|
+
end
|
33
|
+
|
34
|
+
def self.save_file
|
35
|
+
Dir.mkdir(PATH) unless File.exist?(PATH)
|
36
|
+
File.open(file_name, 'w') { |f| f.puts @data.to_json }
|
37
|
+
end
|
38
|
+
|
39
|
+
private_class_method :save_file
|
40
|
+
end
|
41
|
+
end
|
@@ -0,0 +1,43 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'net/http'
|
4
|
+
require 'json'
|
5
|
+
require 'kongrations/migration_data'
|
6
|
+
require 'kongrations/current_environment'
|
7
|
+
|
8
|
+
Dir["#{__dir__}/responses/*.rb"].each { |file| require file }
|
9
|
+
|
10
|
+
module Kongrations
|
11
|
+
class Request
|
12
|
+
attr_accessor :payload
|
13
|
+
|
14
|
+
METHODS_MAPPER = {
|
15
|
+
post: Net::HTTP::Post,
|
16
|
+
patch: Net::HTTP::Patch,
|
17
|
+
delete: Net::HTTP::Delete
|
18
|
+
}.freeze
|
19
|
+
|
20
|
+
def execute
|
21
|
+
http = Net::HTTP.new(CurrentEnvironment.kong_admin_url, 80)
|
22
|
+
headers = {
|
23
|
+
'Content-Type' => 'application/json',
|
24
|
+
'apikey' => CurrentEnvironment.kong_admin_api_key
|
25
|
+
}
|
26
|
+
|
27
|
+
request = METHODS_MAPPER[method].new(path, headers)
|
28
|
+
request.body = payload.to_json unless payload.nil?
|
29
|
+
response = http.request(request)
|
30
|
+
initialize_response_class(response)
|
31
|
+
end
|
32
|
+
|
33
|
+
def initialize_response_class(response)
|
34
|
+
class_name = self.class.to_s.gsub('Request', 'Response')
|
35
|
+
klass = Object.const_defined?(class_name) ? Object.const_get(class_name) : Response
|
36
|
+
klass.new(response, self)
|
37
|
+
end
|
38
|
+
|
39
|
+
def migration_data
|
40
|
+
MigrationData.data
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'kongrations/request'
|
4
|
+
|
5
|
+
module Kongrations
|
6
|
+
class ChangeApiRequest < Request
|
7
|
+
attr_accessor :name
|
8
|
+
|
9
|
+
def initialize(name)
|
10
|
+
@name = name
|
11
|
+
end
|
12
|
+
|
13
|
+
def path
|
14
|
+
"/apis/#{name}"
|
15
|
+
end
|
16
|
+
|
17
|
+
def method
|
18
|
+
:patch
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'kongrations/request'
|
4
|
+
|
5
|
+
module Kongrations
|
6
|
+
class ChangePluginRequest < Request
|
7
|
+
attr_accessor :api_name, :plugin_name
|
8
|
+
|
9
|
+
def initialize(api_name, plugin_name)
|
10
|
+
@api_name = api_name
|
11
|
+
@plugin_name = plugin_name
|
12
|
+
end
|
13
|
+
|
14
|
+
def path
|
15
|
+
plugin_id = migration_data[api_name]['plugins'][plugin_name]
|
16
|
+
"/apis/#{api_name}/plugins/#{plugin_id}"
|
17
|
+
end
|
18
|
+
|
19
|
+
def method
|
20
|
+
:patch
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'kongrations/request'
|
4
|
+
|
5
|
+
module Kongrations
|
6
|
+
class CreatePluginRequest < Request
|
7
|
+
attr_accessor :api_name
|
8
|
+
|
9
|
+
def initialize(api_name)
|
10
|
+
@api_name = api_name
|
11
|
+
end
|
12
|
+
|
13
|
+
def path
|
14
|
+
"/apis/#{api_name}/plugins"
|
15
|
+
end
|
16
|
+
|
17
|
+
def method
|
18
|
+
:post
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'kongrations/request'
|
4
|
+
|
5
|
+
module Kongrations
|
6
|
+
class DeleteApiRequest < Request
|
7
|
+
attr_accessor :name
|
8
|
+
|
9
|
+
def initialize(name)
|
10
|
+
@name = name
|
11
|
+
end
|
12
|
+
|
13
|
+
def path
|
14
|
+
"/apis/#{name}"
|
15
|
+
end
|
16
|
+
|
17
|
+
def method
|
18
|
+
:delete
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'kongrations/request'
|
4
|
+
|
5
|
+
module Kongrations
|
6
|
+
class DeletePluginRequest < Request
|
7
|
+
attr_accessor :api_name, :plugin_name
|
8
|
+
|
9
|
+
def initialize(api_name, plugin_name)
|
10
|
+
@api_name = api_name
|
11
|
+
@plugin_name = plugin_name
|
12
|
+
end
|
13
|
+
|
14
|
+
def path
|
15
|
+
plugin_id = migration_data[api_name]['plugins'][plugin_name]
|
16
|
+
"/apis/#{api_name}/plugins/#{plugin_id}"
|
17
|
+
end
|
18
|
+
|
19
|
+
def method
|
20
|
+
:delete
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
@@ -0,0 +1,33 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'json'
|
4
|
+
require 'kongrations/migration_data'
|
5
|
+
|
6
|
+
module Kongrations
|
7
|
+
class Response
|
8
|
+
def initialize(response, request)
|
9
|
+
@response = response
|
10
|
+
@request = request
|
11
|
+
end
|
12
|
+
|
13
|
+
def success?
|
14
|
+
@response.is_a?(Net::HTTPSuccess)
|
15
|
+
end
|
16
|
+
|
17
|
+
def error?
|
18
|
+
!success?
|
19
|
+
end
|
20
|
+
|
21
|
+
def body
|
22
|
+
JSON.parse(@response.body, symbolize_names: true) unless @response.body.nil?
|
23
|
+
end
|
24
|
+
|
25
|
+
def data_to_save
|
26
|
+
nil
|
27
|
+
end
|
28
|
+
|
29
|
+
def save_data(migration_name)
|
30
|
+
MigrationData.save(migration_name, data_to_save)
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'kongrations/response'
|
4
|
+
|
5
|
+
module Kongrations
|
6
|
+
class CreatePluginResponse < Response
|
7
|
+
def data_to_save
|
8
|
+
api_name = @request.api_name
|
9
|
+
plugin_name = @request.payload[:name]
|
10
|
+
plugin_id = body[:id]
|
11
|
+
{
|
12
|
+
api_name => {
|
13
|
+
'plugins' => {
|
14
|
+
plugin_name => plugin_id
|
15
|
+
}
|
16
|
+
}
|
17
|
+
}
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
data/lib/kongrations.rb
ADDED
@@ -0,0 +1,51 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'kongrations/version'
|
4
|
+
require 'kongrations/migration'
|
5
|
+
require 'kongrations/migration_data'
|
6
|
+
require 'kongrations/current_environment'
|
7
|
+
|
8
|
+
module Kongrations
|
9
|
+
def self.run(env = 'default')
|
10
|
+
CurrentEnvironment.load!(env)
|
11
|
+
|
12
|
+
migrations = migrations_to_run
|
13
|
+
|
14
|
+
migrations.each do |migration_file|
|
15
|
+
migration_name = File.basename(migration_file)
|
16
|
+
migration_content = File.read(migration_file)
|
17
|
+
|
18
|
+
migration = Migration.build(migration_name, env, migration_content)
|
19
|
+
|
20
|
+
response = migration.run
|
21
|
+
|
22
|
+
print "-- Migration #{migration_name} --"
|
23
|
+
print response.body
|
24
|
+
if response.error?
|
25
|
+
print 'Error when executing migration on Kong'
|
26
|
+
break
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
def self.migrations_to_run
|
32
|
+
folder = CurrentEnvironment.migrations_folder
|
33
|
+
migration_files = Dir.glob(File.join(folder, '*.rb'))
|
34
|
+
|
35
|
+
MigrationData.load!
|
36
|
+
last_migration = MigrationData.last_migration
|
37
|
+
return migration_files if last_migration.nil?
|
38
|
+
|
39
|
+
last_migration_index = migration_files.find_index { |m| m.end_with?(last_migration) }
|
40
|
+
migration_files.slice!(0, last_migration_index + 1)
|
41
|
+
migration_files
|
42
|
+
end
|
43
|
+
|
44
|
+
def self.print(data)
|
45
|
+
puts data unless test_env?
|
46
|
+
end
|
47
|
+
|
48
|
+
def self.test_env?
|
49
|
+
ENV['GEM_ENV'] == 'test'
|
50
|
+
end
|
51
|
+
end
|
metadata
ADDED
@@ -0,0 +1,157 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: kongrations
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.1
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Danilo Albuquerque
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2018-04-06 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: bundler
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - "~>"
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '1.16'
|
20
|
+
type: :development
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - "~>"
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '1.16'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: pry
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - '='
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: 0.11.3
|
34
|
+
type: :development
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - '='
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: 0.11.3
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: rake
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - "~>"
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '10.0'
|
48
|
+
type: :development
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - "~>"
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '10.0'
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: rspec
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - '='
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: 3.7.0
|
62
|
+
type: :development
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - '='
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: 3.7.0
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: rubocop
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
72
|
+
requirements:
|
73
|
+
- - '='
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: 0.54.0
|
76
|
+
type: :development
|
77
|
+
prerelease: false
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
79
|
+
requirements:
|
80
|
+
- - '='
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: 0.54.0
|
83
|
+
- !ruby/object:Gem::Dependency
|
84
|
+
name: webmock
|
85
|
+
requirement: !ruby/object:Gem::Requirement
|
86
|
+
requirements:
|
87
|
+
- - '='
|
88
|
+
- !ruby/object:Gem::Version
|
89
|
+
version: 3.3.0
|
90
|
+
type: :development
|
91
|
+
prerelease: false
|
92
|
+
version_requirements: !ruby/object:Gem::Requirement
|
93
|
+
requirements:
|
94
|
+
- - '='
|
95
|
+
- !ruby/object:Gem::Version
|
96
|
+
version: 3.3.0
|
97
|
+
description: |-
|
98
|
+
Migrations like for your Kong APIs, plugin and consumers.
|
99
|
+
It enables you to create files which describes the operations to be performed on Kong.
|
100
|
+
email:
|
101
|
+
- danilospalbuquerque@gmail.com
|
102
|
+
executables:
|
103
|
+
- kongrations
|
104
|
+
extensions: []
|
105
|
+
extra_rdoc_files: []
|
106
|
+
files:
|
107
|
+
- ".gitignore"
|
108
|
+
- ".rspec"
|
109
|
+
- ".rubocop.yml"
|
110
|
+
- Gemfile
|
111
|
+
- Gemfile.lock
|
112
|
+
- LICENSE.txt
|
113
|
+
- README.md
|
114
|
+
- Rakefile
|
115
|
+
- bin/kongrations
|
116
|
+
- kongrations.gemspec
|
117
|
+
- lib/kongrations.rb
|
118
|
+
- lib/kongrations/current_environment.rb
|
119
|
+
- lib/kongrations/environment.rb
|
120
|
+
- lib/kongrations/hash_ext.rb
|
121
|
+
- lib/kongrations/migration.rb
|
122
|
+
- lib/kongrations/migration_data.rb
|
123
|
+
- lib/kongrations/request.rb
|
124
|
+
- lib/kongrations/requests/change_api_request.rb
|
125
|
+
- lib/kongrations/requests/change_plugin_request.rb
|
126
|
+
- lib/kongrations/requests/create_api_request.rb
|
127
|
+
- lib/kongrations/requests/create_plugin_request.rb
|
128
|
+
- lib/kongrations/requests/delete_api_request.rb
|
129
|
+
- lib/kongrations/requests/delete_plugin_request.rb
|
130
|
+
- lib/kongrations/response.rb
|
131
|
+
- lib/kongrations/responses/create_plugin_response.rb
|
132
|
+
- lib/kongrations/version.rb
|
133
|
+
homepage: https://github.com/danilospa/kongrations
|
134
|
+
licenses:
|
135
|
+
- MIT
|
136
|
+
metadata: {}
|
137
|
+
post_install_message:
|
138
|
+
rdoc_options: []
|
139
|
+
require_paths:
|
140
|
+
- lib
|
141
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
142
|
+
requirements:
|
143
|
+
- - ">="
|
144
|
+
- !ruby/object:Gem::Version
|
145
|
+
version: '0'
|
146
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
147
|
+
requirements:
|
148
|
+
- - ">="
|
149
|
+
- !ruby/object:Gem::Version
|
150
|
+
version: '0'
|
151
|
+
requirements: []
|
152
|
+
rubyforge_project:
|
153
|
+
rubygems_version: 2.6.11
|
154
|
+
signing_key:
|
155
|
+
specification_version: 4
|
156
|
+
summary: Migrations for Kong APIs, plugin and consumers.
|
157
|
+
test_files: []
|