kong_schema 1.2.0 → 1.3.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 413c7b7271ed7feca20d06caeaf0bd671bf5d253
4
- data.tar.gz: b79a0818ae360b7df3e7e9dc6a3ffc84398d3e05
3
+ metadata.gz: a77eb790a5c2e9bc9041918244f463890a598b48
4
+ data.tar.gz: 76815d46d5c50a3d6cc01aee03d13b6b0f870ee0
5
5
  SHA512:
6
- metadata.gz: fab914455b8b170f43ff70537e9604ac8e4489b6264356277257ddaff95f6df25c8cc36cae2107b5fd60987cb9a9bb4455e06319c97e67ea8824a35ce567b194
7
- data.tar.gz: e1861af086a278bd9257469dccc314cc26211814bac1db35d8800171ad480a234b539c4424e25c40ac86ca13b081171577882c47f42dedee5c236ec091992726
6
+ metadata.gz: 8186d7fb699bf6ae80f6534fc66aeedc735dcef9594f063d498361d02375a152fb0efb9e33080ee025928333c9cb1662d8b91ef76647a378fd341d3b9d440edf
7
+ data.tar.gz: 8522830249a8c888dd7ab6dcc5712921e80c8fedc13ffb152f250574e8d405fa94d7da9cea8760348376696e0a3b58fefb3c3a02a91b6c720260a0d7ff421817
data/CHANGELOG.md CHANGED
@@ -1,3 +1,12 @@
1
+ ## 1.3.0
2
+
3
+ - Added support for Kong::Plugin objects.
4
+ - Renamed the CLI command `kong_schema reset` to `kong_schema down` for
5
+ consistency.
6
+ - All CLI commands now accept `-c` or `--config` to point to the config file in
7
+ place of the first argument. This makes it consistent with Kong's binaries
8
+ for user convenience.
9
+
1
10
  ## 1.2.0
2
11
 
3
12
  - Added a new CLI command: `kong_schema reset` for wiping out the Kong database
data/README.md CHANGED
@@ -39,7 +39,7 @@ Run `kong_schema --help` to see the available commands.
39
39
  kong_schema up [path/to/config.yml]
40
40
 
41
41
  # reset configuration
42
- kong_schema reset [path/to/config.yml]
42
+ kong_schema down [path/to/config.yml]
43
43
  ```
44
44
 
45
45
  ## Example
@@ -73,8 +73,9 @@ Then if we run the following command:
73
73
  kong_schema up config/kong.yml
74
74
  ```
75
75
 
76
- kong_schema will read the directives found under the `kong` dictionary and
77
- prompt you with a list of changes it will apply to Kong through the REST API.
76
+ kong_schema will read the directives ("schema") found in the `kong` dictionary
77
+ and prompt you with a list of changes it will apply to Kong through the REST
78
+ API.
78
79
 
79
80
  ```shell
80
81
  +-----------------+------------------------------------------------+
@@ -160,11 +161,29 @@ Nice and easy!
160
161
 
161
162
  ## Configuration
162
163
 
164
+ As mentioned before, you can either use YAML or JSON to write your
165
+ configuration files. YAML tends to be more readable and easier to edit.
166
+ `kong_schema` will know which parser to use based on the file extension; they
167
+ have to end with either `.yml` or `.json` respectively.
168
+
169
+ For further convenience, the CLIs support reading the schema from a specific
170
+ "key" in that configuration file, which by default is set to `"kong"`. This
171
+ allows you to keep your Kong schema alongside other configuration items for
172
+ your application(s) in a single file.
173
+
174
+ If your Kong schema is the root property, just pass `--key ""` to CLI commands
175
+ to make them read the whole file as the schema.
176
+
163
177
  ### `admin_host: String`
164
178
 
179
+ Address at which Kong Admin is listening, like `127.0.0.1:9712`. This is the
180
+ value you specify in `admin_listen` of `kong.conf`.
181
+
165
182
  ### `apis: Array<Kong::Api>`
166
183
 
167
- [Kong::Api](https://getkong.org/docs/0.11.x/admin-api/#add-api) configuration:
184
+ [Kong::Api](https://getkong.org/docs/0.11.x/admin-api/#add-api) configuration.
185
+
186
+ **Properties**
168
187
 
169
188
  - name: String
170
189
  - host: String
@@ -174,10 +193,26 @@ Nice and easy!
174
193
  - upstream_url: String
175
194
  - uris: Array<String>
176
195
 
196
+ ### `plugins: Array<Kong::Plugin>`
197
+
198
+ [Kong::Plugin](https://getkong.org/docs/0.11.x/admin-api/#add-plugin) configuration.
199
+
200
+ Setting `enabled: false` will delete the plugin.
201
+
202
+ **Properties**
203
+
204
+ - name: String
205
+ - enabled: Boolean
206
+ - api_id: String
207
+ - config: Object
208
+ - consumer_id: String
209
+
177
210
  ### `upstreams: Array<Kong::Upstream>`
178
211
 
179
212
  [Kong::Upstream](https://getkong.org/docs/0.11.x/admin-api/#add-upstream)
180
- configuration:
213
+ configuration.
214
+
215
+ **Properties**
181
216
 
182
217
  - name: String
183
218
  - slots: Number
@@ -186,7 +221,9 @@ configuration:
186
221
  ### `targets: Array<Kong::Target>`
187
222
 
188
223
  [Kong::Target](https://getkong.org/docs/0.11.x/admin-api/#add-target)
189
- configuration:
224
+ configuration.
225
+
226
+ **Properties**
190
227
 
191
228
  - upstream_id: String
192
229
  - target: String
@@ -197,10 +234,51 @@ configuration:
197
234
  Add support for the remaining Kong API objects:
198
235
 
199
236
  - [consumers](https://getkong.org/docs/0.11.x/admin-api/#create-consumer)
200
- - [plugins](https://getkong.org/docs/0.11.x/admin-api/#add-plugin)
201
237
  - [certificates](https://getkong.org/docs/0.11.x/admin-api/#add-certificate)
202
238
  - [snis](https://getkong.org/docs/0.11.x/admin-api/#add-sni)
203
239
 
240
+ ## Gotchas
241
+
242
+ Beware of removing keys that were previously defined in your configuration.
243
+ `kong_schema` does not know the default values of options nor does it attempt
244
+ to assign them, so when you omit an option that was previously defined, it can
245
+ not detect that change and it will not be reflected in the API.
246
+
247
+ This symptom may be addressed in the future by changing the implementation so
248
+ that it wipes out Kong's configuration before each application (e.g.
249
+ `kong_schema up`) but for now you have two options to deal with this:
250
+
251
+ 1) Reset the database prior to applying the schema:
252
+
253
+ ```shell
254
+ kong_schema down [file] # database reset
255
+ kong_schema up [file] # database now 100% reflecting config file
256
+ ```
257
+
258
+ 2) Set the values to `null` or an empty property. For example, if we were to no
259
+ longer use the `hosts` property of an Api object, we'd just clear it instead
260
+ of omitting it:
261
+
262
+ ```yaml
263
+ kong:
264
+ apis:
265
+ - name: some-api
266
+ # just clear this, don't omit it
267
+ hosts:
268
+ ```
269
+
270
+ ## Tests
271
+
272
+ **WARNING: RUNNING THE TESTS WILL CLEAR THE KONG DATABASE!!!**
273
+
274
+ A running Kong instance is required to run the tests. By default the admin API
275
+ is expected to be running on `127.0.0.1:9712` but you can change that by
276
+ setting the environment variable `KONG_URI`.
277
+
278
+ Then running the tests is as simple as:
279
+
280
+ COVERAGE=1 bundle exec rspec
281
+
204
282
  ## License
205
283
 
206
284
  Copyright (C) 2017 Instructure, INC.
@@ -16,9 +16,19 @@ module KongSchema
16
16
 
17
17
  sort_help :manually
18
18
 
19
+ flag([ 'c', 'config' ], {
20
+ desc: 'Path to the configuration file (in place of the first argument.)',
21
+ arg_name: 'FILE'
22
+ })
23
+
19
24
  desc 'Apply configuration from a .yml or .json file.'
20
25
  arg(:config_file)
21
26
  command :up do |c|
27
+ c.flag([ 'c', 'config' ], {
28
+ desc: 'Path to the configuration file (in place of the first argument.)',
29
+ arg_name: 'FILE'
30
+ })
31
+
22
32
  c.flag([ 'k', 'key' ], {
23
33
  default_value: 'kong',
24
34
  desc: 'The root configuration property key.',
@@ -38,16 +48,16 @@ module KongSchema
38
48
  desc: 'Prompt for confirmation before applying changes.'
39
49
  })
40
50
 
41
- c.action do |global_options, options, args|
42
- bail! "Missing path to .yml or .json config file" if args.first.nil?
51
+ c.action do |globals, options, args|
52
+ filepath = resolve_config_file!(args: args, globals: globals, options: options)
43
53
 
44
- up(filepath: args.first, options: options)
54
+ up(filepath: filepath, options: options)
45
55
  end
46
56
  end
47
57
 
48
58
  desc 'Reset Kong configuration completely.'
49
59
  arg(:config_file)
50
- command :reset do |c|
60
+ command :down do |c|
51
61
  c.flag([ 'k', 'key' ], {
52
62
  default_value: 'kong',
53
63
  desc: 'The root configuration property key.',
@@ -59,10 +69,10 @@ module KongSchema
59
69
  desc: 'Prompt for confirmation before applying changes.'
60
70
  })
61
71
 
62
- c.action do |global_options, options, args|
63
- bail! "Missing path to .yml or .json config file" if args.first.nil?
72
+ c.action do |globals, options, args|
73
+ filepath = resolve_config_file!(args: args, globals: globals, options: options)
64
74
 
65
- reset(filepath: args.first, options: options)
75
+ down(filepath: filepath, options: options)
66
76
  end
67
77
  end
68
78
 
@@ -91,7 +101,7 @@ module KongSchema
91
101
  end
92
102
  end
93
103
 
94
- def reset(filepath:, options:)
104
+ def down(filepath:, options:)
95
105
  pastel = Pastel.new
96
106
  schema = KongSchema::Schema
97
107
  config = read_property(load_file(filepath), options[:key])
@@ -103,6 +113,16 @@ module KongSchema
103
113
  end
104
114
  end
105
115
 
116
+ def resolve_config_file!(args:, globals:, options:)
117
+ filepath = args.first || options[:config] || globals[:config]
118
+
119
+ if filepath.nil?
120
+ bail! "Missing path to .yml or .json config file"
121
+ else
122
+ filepath
123
+ end
124
+ end
125
+
106
126
  def load_file(filepath)
107
127
  if filepath.end_with?('.json')
108
128
  JSON.parse(File.read(filepath))
@@ -120,7 +140,7 @@ module KongSchema
120
140
  end
121
141
 
122
142
  def yes?(message, default: false)
123
- TTY::Prompt.new.yes?(message, default: default)
143
+ TTY::Prompt.new.yes?(message, default: default, color: false)
124
144
  end
125
145
 
126
146
  def red(text)
@@ -30,6 +30,8 @@ module KongSchema
30
30
  # Reset Kong's database by removing all objects through the API.
31
31
  def self.purge(config)
32
32
  connect(config) do
33
+ KongSchema::Resource::Plugin.all.each(&:delete)
34
+
33
35
  KongSchema::Resource::Upstream.all.each do |upstream|
34
36
  upstream.targets.each(&:delete)
35
37
  upstream.delete
@@ -3,5 +3,13 @@ module KongSchema
3
3
  def blank?(object)
4
4
  object.nil? || object.empty?
5
5
  end
6
+
7
+ def try(recv, meth)
8
+ if recv.nil?
9
+ nil
10
+ else
11
+ recv.send(meth)
12
+ end
13
+ end
6
14
  end
7
15
  end
@@ -1,3 +1,4 @@
1
1
  require_relative './resource/api'
2
+ require_relative './resource/plugin'
2
3
  require_relative './resource/target'
3
4
  require_relative './resource/upstream'
@@ -27,6 +27,10 @@ module KongSchema
27
27
  Adapter.for(Kong::Api).create(serialize_outbound(attributes))
28
28
  end
29
29
 
30
+ def creatable?(*)
31
+ true
32
+ end
33
+
30
34
  def changed?(record, attributes)
31
35
  current = record.attributes.keys.reduce({}) do |map, key|
32
36
  value = record.attributes[key]
@@ -0,0 +1,65 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'kong'
4
+ require_relative '../adapter'
5
+ require_relative '../functional'
6
+
7
+ module KongSchema
8
+ module Resource
9
+ module Plugin
10
+ extend self
11
+ extend Functional
12
+
13
+ def identify(record)
14
+ case record
15
+ when Kong::Plugin
16
+ [ record.name, try(record.api, :name), record.consumer_id ]
17
+ when Hash
18
+ [ record['name'], record['api_id'], record['consumer_id'] ]
19
+ end
20
+ end
21
+
22
+ def all(*)
23
+ Kong::Plugin.all
24
+ end
25
+
26
+ def create(attributes)
27
+ Adapter.for(Kong::Plugin).create(attributes)
28
+ end
29
+
30
+ def creatable?(attributes)
31
+ attributes['enabled'] != false
32
+ end
33
+
34
+ def changed?(record, attributes)
35
+ current = record.attributes.keys.each_with_object({}) do |key, map|
36
+ value = record.attributes[key]
37
+
38
+ map[key] = case key
39
+ when 'api_id'
40
+ record.api.name
41
+ else
42
+ value
43
+ end
44
+ end
45
+
46
+ Adapter.for(Kong::Plugin).changed?(current, attributes)
47
+ end
48
+
49
+ def update(record, partial_attributes)
50
+ if partial_attributes['enabled'] == false
51
+ delete(record)
52
+ else
53
+ Adapter.for(Kong::Plugin).update(
54
+ record,
55
+ partial_attributes.merge('api_id' => record.api.id)
56
+ )
57
+ end
58
+ end
59
+
60
+ def delete(record)
61
+ Adapter.for(Kong::Plugin).delete(record)
62
+ end
63
+ end
64
+ end
65
+ end
@@ -29,6 +29,10 @@ module KongSchema
29
29
  end
30
30
  end
31
31
 
32
+ def creatable?(*)
33
+ true
34
+ end
35
+
32
36
  def changed?(record, directive)
33
37
  (
34
38
  record.target != directive['target'] ||
@@ -26,6 +26,10 @@ module KongSchema
26
26
  Adapter.for(Kong::Upstream).create(attributes)
27
27
  end
28
28
 
29
+ def creatable?(*)
30
+ true
31
+ end
32
+
29
33
  def changed?(record, attributes)
30
34
  Adapter.for(Kong::Upstream).changed?(record.attributes, attributes)
31
35
  end
@@ -23,6 +23,8 @@ module KongSchema
23
23
  [
24
24
  scan_in(model: Resource::Api, directives: Array(config['apis'])),
25
25
 
26
+ scan_in(model: Resource::Plugin, directives: Array(config['plugins'])),
27
+
26
28
  # order matters in some of the resources; Upstream directives must be
27
29
  # handled before Target ones
28
30
  scan_in(model: Resource::Upstream, directives: Array(config['upstreams'])),
@@ -73,7 +75,11 @@ module KongSchema
73
75
 
74
76
  def build_create_changes(model:, defined:, declared:)
75
77
  to_create = declared.keys - defined.keys
76
- to_create.map do |id|
78
+ creatable = to_create.select do |id|
79
+ model.creatable?(declared[id])
80
+ end
81
+
82
+ creatable.map do |id|
77
83
  Actions::Create.new(model: model, params: declared[id])
78
84
  end
79
85
  end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module KongSchema
4
- VERSION = "1.2.0".freeze
4
+ VERSION = "1.3.0".freeze
5
5
  end
File without changes
@@ -0,0 +1,135 @@
1
+ describe KongSchema::CLI do
2
+ let(:test_utils) { KongSchemaTestUtils.new }
3
+ let(:schema) { KongSchema::Schema }
4
+ let(:client) { KongSchema::Client }
5
+
6
+ let(:config) do
7
+ test_utils.generate_config({
8
+ apis: [{
9
+ name: 'my-api',
10
+ hosts: [ 'example.com' ],
11
+ upstream_url: 'http://example'
12
+ }]
13
+ })
14
+ end
15
+
16
+ let(:keyed_config) do
17
+ {
18
+ "kong" => config
19
+ }
20
+ end
21
+
22
+ describe 'up' do
23
+ it 'complains if no file was passed' do
24
+ expect(subject).to receive(:bail!)
25
+ .with('Missing path to .yml or .json config file')
26
+ .and_call_original
27
+
28
+ expect {
29
+ subject.run(["up"])
30
+ }.to output(/Missing path to/).to_stderr_from_any_process
31
+ .and output(/SYNOPSIS/).to_stdout_from_any_process # help listing
32
+ end
33
+
34
+ it 'works' do
35
+ test_utils.generate_config_file(config) do |filepath|
36
+ expect {
37
+ subject.run(["up", filepath, "--no-confirm", "--key", ""])
38
+ }.to change { client.connect(config) { Kong::Api.all.count } }.by(1)
39
+ .and output(/Kong has been reconfigured!/).to_stdout
40
+ end
41
+ end
42
+
43
+ it 'works (with a JSON file)' do
44
+ test_utils.generate_config_file(config, format: :json) do |filepath|
45
+ expect {
46
+ subject.run(["up", filepath, "--no-confirm", "--key", ""])
47
+ }.to change { client.connect(config) { Kong::Api.all.count } }.by(1)
48
+ .and output(/Kong has been reconfigured!/).to_stdout
49
+ end
50
+ end
51
+
52
+ it 'accepts config file using -c for consistency with Kong' do
53
+ test_utils.generate_config_file(keyed_config) do |filepath|
54
+ expect {
55
+ subject.run(["up", "-c", filepath, "--no-confirm"])
56
+ }.to change { client.connect(config) { Kong::Api.all.count } }.by(1)
57
+ .and output(/Kong has been reconfigured!/).to_stdout
58
+ end
59
+ end
60
+
61
+ it 'accepts config file using -c (globally) for convenience' do
62
+ test_utils.generate_config_file(keyed_config) do |filepath|
63
+ expect {
64
+ subject.run(["-c", filepath, "up", "--no-confirm"])
65
+ }.to change { client.connect(config) { Kong::Api.all.count } }.by(1)
66
+ .and output(/Kong has been reconfigured!/).to_stdout
67
+ end
68
+ end
69
+
70
+ it 'reads config from a custom key' do
71
+ test_utils.generate_config_file(keyed_config) do |filepath|
72
+ expect {
73
+ subject.run(["up", filepath, "--no-confirm", "--key", "kong"])
74
+ }.to change { client.connect(config) { Kong::Api.all.count } }.by(1)
75
+ .and output(/Kong has been reconfigured!/).to_stdout
76
+ end
77
+ end
78
+
79
+ it 'prompts for confirmation' do
80
+ test_utils.fake_stdin(["y"]) do
81
+ test_utils.generate_config_file(keyed_config) do |filepath|
82
+ expect {
83
+ subject.run(["up", filepath])
84
+ }.to change { client.connect(config) { Kong::Api.all.count } }.by(1)
85
+ .and output(/Kong has been reconfigured!/).to_stdout
86
+ end
87
+ end
88
+ end
89
+
90
+ it 'aborts if not confirmed' do
91
+ test_utils.fake_stdin(["n"]) do
92
+ test_utils.generate_config_file(keyed_config) do |filepath|
93
+ expect {
94
+ subject.run(["up", filepath])
95
+ }.to change { client.connect(config) { Kong::Api.all.count } }.by(0)
96
+ .and output.to_stdout
97
+ end
98
+ end
99
+ end
100
+
101
+ it 'does nothing if there are no changes to commit' do
102
+ config = test_utils.generate_config({})
103
+
104
+ test_utils.generate_config_file(config) do |filepath|
105
+ expect {
106
+ subject.run(["up", filepath, "--no-confirm", "--key", ""])
107
+ }.to output(/Nothing to update./).to_stdout
108
+ end
109
+ end
110
+ end
111
+
112
+ describe 'down' do
113
+ it 'complains if no file was passed' do
114
+ expect(subject).to receive(:bail!)
115
+ .with('Missing path to .yml or .json config file')
116
+ .and_call_original
117
+
118
+ expect {
119
+ subject.run(["down"])
120
+ }.to output(/Missing path to/).to_stderr_from_any_process
121
+ .and output(/SYNOPSIS/).to_stdout_from_any_process # help listing
122
+ end
123
+
124
+ it 'works' do
125
+ KongSchema::Schema.commit(config, KongSchema::Schema.scan(config))
126
+
127
+ test_utils.generate_config_file(config) do |filepath|
128
+ expect {
129
+ subject.run(["down", filepath, "--no-confirm", "--key", ""])
130
+ }.to change { client.connect(config) { Kong::Api.all.count } }.by(-1)
131
+ .and output(/Kong reset\./).to_stdout
132
+ end
133
+ end
134
+ end
135
+ end
@@ -0,0 +1,9 @@
1
+ describe KongSchema::Client do
2
+ describe 'connect' do
3
+ it 'whines if "admin_host" is undefined' do
4
+ expect {
5
+ described_class.connect({})
6
+ }.to raise_error("Missing 'admin_host' property; can not connect to Kong admin!")
7
+ end
8
+ end
9
+ end
@@ -4,10 +4,6 @@ describe KongSchema::Reporter do
4
4
  let(:test_utils) { KongSchemaTestUtils.new }
5
5
  let(:schema) { KongSchema::Schema }
6
6
 
7
- after(:each) do
8
- test_utils.reset_kong
9
- end
10
-
11
7
  let :config do
12
8
  test_utils.generate_config({
13
9
  upstreams: [{ name: 'bridge-learn.kong-service' }]
@@ -2,10 +2,6 @@ describe KongSchema::Resource::Api do
2
2
  let(:schema) { KongSchema::Schema }
3
3
  let(:test_utils) { KongSchemaTestUtils.new }
4
4
 
5
- after(:each) do
6
- test_utils.reset_kong
7
- end
8
-
9
5
  describe 'creating APIs' do
10
6
  let :config do
11
7
  test_utils.generate_config({
@@ -0,0 +1,117 @@
1
+ describe KongSchema::Resource::Plugin do
2
+ let(:schema) { KongSchema::Schema }
3
+ let(:test_utils) { KongSchemaTestUtils.new }
4
+
5
+ let :plugin_config do
6
+ {
7
+ second: 120
8
+ }
9
+ end
10
+
11
+ let :config do
12
+ test_utils.generate_config({
13
+ apis: [{
14
+ name: 'my-api',
15
+ upstream_url: 'http://example.com',
16
+ hosts: [ 'example.com' ]
17
+ }],
18
+
19
+ plugins: [{
20
+ name: 'rate-limiting',
21
+ api_id: 'my-api',
22
+ enabled: true,
23
+ config: plugin_config
24
+ }]
25
+ })
26
+ end
27
+
28
+ it 'adds a plugin if it does not exist' do
29
+ directives = schema.scan(config)
30
+
31
+ expect(directives.map(&:class)).to eq([
32
+ KongSchema::Actions::Create,
33
+ KongSchema::Actions::Create
34
+ ])
35
+ end
36
+
37
+ it 'does add a plugin' do
38
+ directives = schema.scan(config)
39
+
40
+ expect {
41
+ schema.commit(config, directives)
42
+ }.to change {
43
+ KongSchema::Client.connect(config) {
44
+ Kong::Plugin.all.count
45
+ }
46
+ }.by(1)
47
+ end
48
+
49
+ it 'updates a plugin' do
50
+ schema.commit(config, schema.scan(config))
51
+
52
+ with_update = test_utils.generate_config({
53
+ apis: [{
54
+ name: 'my-api',
55
+ upstream_url: 'http://example.com',
56
+ hosts: [ 'example.com' ]
57
+ }],
58
+
59
+ plugins: [{
60
+ config: plugin_config.merge({ second: 60 }),
61
+ name: 'rate-limiting',
62
+ api_id: 'my-api',
63
+ }]
64
+ })
65
+
66
+ expect { schema.commit(config, schema.scan(with_update)) }.to change {
67
+ KongSchema::Client.connect(config) {
68
+ Kong::Plugin.find_by_name('rate-limiting').config['second']
69
+ }
70
+ }.from(120).to(60)
71
+ end
72
+
73
+ it 'removes the plugin if enabled is set to false' do
74
+ schema.commit(config, schema.scan(config))
75
+
76
+ with_update = test_utils.generate_config({
77
+ apis: [{
78
+ name: 'my-api',
79
+ upstream_url: 'http://example.com',
80
+ hosts: [ 'example.com' ]
81
+ }],
82
+
83
+ plugins: [{
84
+ name: 'rate-limiting',
85
+ api_id: 'my-api',
86
+ config: plugin_config,
87
+ enabled: false
88
+ }]
89
+ })
90
+
91
+ expect { schema.commit(config, schema.scan(with_update)) }.to change {
92
+ KongSchema::Client.connect(config) {
93
+ Kong::Plugin.all.count
94
+ }
95
+ }.by(-1)
96
+ end
97
+
98
+ it 'removes the plugin if it is no longer specified' do
99
+ schema.commit(config, schema.scan(config))
100
+
101
+ with_removal = test_utils.generate_config({
102
+ apis: [{
103
+ name: 'my-api',
104
+ upstream_url: 'http://example.com',
105
+ hosts: [ 'example.com' ]
106
+ }],
107
+
108
+ plugins: []
109
+ })
110
+
111
+ expect { schema.commit(config, schema.scan(with_removal)) }.to change {
112
+ KongSchema::Client.connect(config) {
113
+ Kong::Plugin.all.count
114
+ }
115
+ }.by(-1)
116
+ end
117
+ end
@@ -2,10 +2,6 @@ describe KongSchema::Resource::Target do
2
2
  let(:schema) { KongSchema::Schema }
3
3
  let(:test_utils) { KongSchemaTestUtils.new }
4
4
 
5
- after(:each) do
6
- test_utils.reset_kong
7
- end
8
-
9
5
  describe 'creating targets' do
10
6
  let :config do
11
7
  test_utils.generate_config({
@@ -2,10 +2,6 @@ describe KongSchema::Resource::Upstream do
2
2
  let(:schema) { KongSchema::Schema }
3
3
  let(:test_utils) { KongSchemaTestUtils.new }
4
4
 
5
- after(:each) do
6
- test_utils.reset_kong
7
- end
8
-
9
5
  describe 'creating upstreams' do
10
6
  let :config do
11
7
  test_utils.generate_config({
data/spec/spec_helper.rb CHANGED
@@ -19,8 +19,14 @@ require 'kong_schema'
19
19
  #
20
20
  # See http://rubydoc.info/gems/rspec-core/RSpec/Core/Configuration
21
21
  RSpec.configure do |config|
22
- config.before(:all) do
23
- KongSchemaTestUtils.new.reset_kong
22
+ test_utils = KongSchemaTestUtils.new
23
+
24
+ config.before(:each) do
25
+ test_utils.reset_kong
26
+ end
27
+
28
+ config.after(:each) do
29
+ test_utils.reset_kong
24
30
  end
25
31
 
26
32
  # rspec-expectations config goes here. You can use an alternate
@@ -1,4 +1,5 @@
1
1
  require 'kong_schema'
2
+ require 'fileutils'
2
3
 
3
4
  class KongSchemaTestUtils
4
5
  attr_reader :host
@@ -11,6 +12,38 @@ class KongSchemaTestUtils
11
12
  JSON.parse(JSON.dump({ admin_host: host }.merge(config)))
12
13
  end
13
14
 
15
+ def generate_config_file(config = {}, format: :yaml)
16
+ buffer = case format
17
+ when :json
18
+ JSON.dump(config)
19
+ else
20
+ YAML.dump(config)
21
+ end
22
+
23
+ filename = case format
24
+ when :json
25
+ 'config.json'
26
+ else
27
+ 'config.yaml'
28
+ end
29
+
30
+ filepath = File.join(Dir.pwd, 'spec', 'fixtures', filename)
31
+
32
+ File.write(filepath, buffer)
33
+ yield filepath
34
+ ensure
35
+ FileUtils.rm(filepath)
36
+ end
37
+
38
+ def fake_stdin(*args)
39
+ $stdin = StringIO.new
40
+ $stdin.puts(args.shift) until args.empty?
41
+ $stdin.rewind
42
+ yield
43
+ ensure
44
+ $stdin = STDIN
45
+ end
46
+
14
47
  def reset_kong
15
48
  KongSchema::Client.purge(generate_config)
16
49
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: kong_schema
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.2.0
4
+ version: 1.3.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Ahmad Amireh
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2017-09-12 00:00:00.000000000 Z
11
+ date: 2017-09-13 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: gli
@@ -165,13 +165,18 @@ files:
165
165
  - lib/kong_schema/reporter.rb
166
166
  - lib/kong_schema/resource.rb
167
167
  - lib/kong_schema/resource/api.rb
168
+ - lib/kong_schema/resource/plugin.rb
168
169
  - lib/kong_schema/resource/target.rb
169
170
  - lib/kong_schema/resource/upstream.rb
170
171
  - lib/kong_schema/schema.rb
171
172
  - lib/kong_schema/version.rb
172
173
  - spec/examples.txt
174
+ - spec/fixtures/.gitkeep
175
+ - spec/kong_schema/cli_spec.rb
176
+ - spec/kong_schema/client_spec.rb
173
177
  - spec/kong_schema/reporter_spec.rb
174
178
  - spec/kong_schema/resource/api_spec.rb
179
+ - spec/kong_schema/resource/plugin_spec.rb
175
180
  - spec/kong_schema/resource/target_spec.rb
176
181
  - spec/kong_schema/resource/upstream_spec.rb
177
182
  - spec/spec_helper.rb
@@ -203,8 +208,12 @@ specification_version: 4
203
208
  summary: Configure Kong from a file using its REST API.
204
209
  test_files:
205
210
  - spec/examples.txt
211
+ - spec/fixtures/.gitkeep
212
+ - spec/kong_schema/cli_spec.rb
213
+ - spec/kong_schema/client_spec.rb
206
214
  - spec/kong_schema/reporter_spec.rb
207
215
  - spec/kong_schema/resource/api_spec.rb
216
+ - spec/kong_schema/resource/plugin_spec.rb
208
217
  - spec/kong_schema/resource/target_spec.rb
209
218
  - spec/kong_schema/resource/upstream_spec.rb
210
219
  - spec/spec_helper.rb