kong_schema 1.2.0 → 1.3.0

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 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