kong_schema 1.1.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 +7 -0
- data/.gitignore +3 -0
- data/.rspec +1 -0
- data/.rubocop.yml +31 -0
- data/.ruby-version +1 -0
- data/CHANGELOG.md +14 -0
- data/Gemfile +4 -0
- data/Gemfile.lock +85 -0
- data/LICENSE.md +14 -0
- data/README.md +197 -0
- data/bin/kong_schema +27 -0
- data/ext/kong/upstream.rb +36 -0
- data/kong_schema.gemspec +29 -0
- data/lib/kong_schema/actions.rb +44 -0
- data/lib/kong_schema/adapter.rb +35 -0
- data/lib/kong_schema/cli.rb +86 -0
- data/lib/kong_schema/client.rb +30 -0
- data/lib/kong_schema/reporter.rb +101 -0
- data/lib/kong_schema/resource/api.rb +57 -0
- data/lib/kong_schema/resource/target.rb +60 -0
- data/lib/kong_schema/resource/upstream.rb +42 -0
- data/lib/kong_schema/resource.rb +3 -0
- data/lib/kong_schema/schema.rb +103 -0
- data/lib/kong_schema/version.rb +5 -0
- data/lib/kong_schema.rb +10 -0
- data/spec/examples.txt +0 -0
- data/spec/kong_schema/reporter_spec.rb +89 -0
- data/spec/kong_schema/resource/api_spec.rb +125 -0
- data/spec/kong_schema/resource/target_spec.rb +209 -0
- data/spec/kong_schema/resource/upstream_spec.rb +122 -0
- data/spec/spec_helper.rb +109 -0
- data/spec/support/coverage.rb +18 -0
- data/spec/support/kong_schema_test_utils.rb +24 -0
- metadata +212 -0
@@ -0,0 +1,101 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'kong_schema'
|
4
|
+
require 'tty-table'
|
5
|
+
require 'json'
|
6
|
+
require 'diffy'
|
7
|
+
require 'pastel'
|
8
|
+
require_relative './actions'
|
9
|
+
|
10
|
+
module KongSchema
|
11
|
+
# Helper class for printing a report of the changes to be committed to Kong
|
12
|
+
# created by {Schema.analyze}.
|
13
|
+
module Reporter
|
14
|
+
extend self
|
15
|
+
|
16
|
+
TableHeader = %w(Change Parameters).freeze
|
17
|
+
|
18
|
+
# @param [Array<KongSchema::Action>] changes
|
19
|
+
# What you get from calling {KongSchema::Schema.analyze}
|
20
|
+
#
|
21
|
+
# @return [String] The report to print to something like STDOUT.
|
22
|
+
def report(changes, object_format: :json)
|
23
|
+
pretty_print = if object_format == :json
|
24
|
+
JSONPrettyPrinter.method(:print)
|
25
|
+
else
|
26
|
+
YAMLPrettyPrinter.method(:print)
|
27
|
+
end
|
28
|
+
|
29
|
+
table = TTY::Table.new header: TableHeader do |t|
|
30
|
+
changes.each do |change|
|
31
|
+
t << print_change(change: change, pretty_print: pretty_print)
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
table.render(:ascii, multiline: true, padding: [0, 1, 0, 1])
|
36
|
+
end
|
37
|
+
|
38
|
+
private
|
39
|
+
|
40
|
+
# Print objects as human-readable JSON
|
41
|
+
class JSONPrettyPrinter
|
42
|
+
def self.print(object)
|
43
|
+
JSON.pretty_generate(YAML.load(YAML.dump(object))) + "\n"
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
# Print objects as YAML
|
48
|
+
class YAMLPrettyPrinter
|
49
|
+
def self.print(object)
|
50
|
+
YAML.dump(object)
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
def print_change(change:, pretty_print:)
|
55
|
+
resource_name = change.model.to_s.split('::').last
|
56
|
+
|
57
|
+
case change
|
58
|
+
when KongSchema::Actions::Create
|
59
|
+
[ "Create #{resource_name}", pretty_print.call(change.params) ]
|
60
|
+
when KongSchema::Actions::Update
|
61
|
+
record_attributes = rewrite_record_attributes(change.record)
|
62
|
+
current_attributes = change.params.keys.reduce({}) do |map, key|
|
63
|
+
map[key] = record_attributes[key]
|
64
|
+
map
|
65
|
+
end
|
66
|
+
|
67
|
+
changed_attributes = pretty_print.call(change.params)
|
68
|
+
current_attributes = pretty_print.call(current_attributes)
|
69
|
+
diff = Diffy::Diff.new(current_attributes, changed_attributes)
|
70
|
+
|
71
|
+
[ "Update #{resource_name}", diff.to_s(:color) ]
|
72
|
+
when KongSchema::Actions::Delete
|
73
|
+
[
|
74
|
+
"Delete #{resource_name}",
|
75
|
+
pretty_print.call(rewrite_record_attributes(change.record))
|
76
|
+
]
|
77
|
+
end
|
78
|
+
end
|
79
|
+
|
80
|
+
# This warrants some explanation.
|
81
|
+
#
|
82
|
+
# For some Kong API objects like Target, the API will accept "indirect"
|
83
|
+
# values for certain parameters like "upstream_id" but in the responses for
|
84
|
+
# those APIs, the payload will contain a value different than what we POSTed
|
85
|
+
# with. In this example, it will accept an upstream_id of either an actual
|
86
|
+
# Upstream.id like "c9633f63-fdaf-4c1c-b9dd-b5a0fa28c780" or an
|
87
|
+
# Upstream.name like "some-upstream.kong-service".
|
88
|
+
#
|
89
|
+
# For our purposes, the user doesn't know about Upstream.id, so we don't
|
90
|
+
# care to show that value, so we will rewrite it with the value they're
|
91
|
+
# meant to input (e.g. target.upstream_id -> target.upstream.name)
|
92
|
+
def rewrite_record_attributes(record)
|
93
|
+
case record
|
94
|
+
when Kong::Target
|
95
|
+
record.attributes.merge('upstream_id' => record.upstream.name)
|
96
|
+
else
|
97
|
+
record.attributes
|
98
|
+
end
|
99
|
+
end
|
100
|
+
end
|
101
|
+
end
|
@@ -0,0 +1,57 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'kong'
|
4
|
+
require_relative '../adapter'
|
5
|
+
|
6
|
+
module KongSchema
|
7
|
+
module Resource
|
8
|
+
module Api
|
9
|
+
extend self
|
10
|
+
|
11
|
+
def identify(record)
|
12
|
+
case record
|
13
|
+
when Kong::Api
|
14
|
+
record.name
|
15
|
+
when Hash
|
16
|
+
record['name']
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
def all(*)
|
21
|
+
Kong::Api.all
|
22
|
+
end
|
23
|
+
|
24
|
+
def create(attributes)
|
25
|
+
Adapter.for(Kong::Api).create(serialize_outbound(attributes))
|
26
|
+
end
|
27
|
+
|
28
|
+
def changed?(record, attributes)
|
29
|
+
Adapter.for(Kong::Api).changed?(record, attributes)
|
30
|
+
end
|
31
|
+
|
32
|
+
def update(record, partial_attributes)
|
33
|
+
Adapter.for(Kong::Api).update(
|
34
|
+
record,
|
35
|
+
serialize_outbound(partial_attributes)
|
36
|
+
)
|
37
|
+
end
|
38
|
+
|
39
|
+
def delete(record)
|
40
|
+
Adapter.for(Kong::Api).delete(record)
|
41
|
+
end
|
42
|
+
|
43
|
+
def serialize_outbound(attributes)
|
44
|
+
attributes.keys.reduce({}) do |map, key|
|
45
|
+
case key
|
46
|
+
when 'hosts', 'uris', 'methods'
|
47
|
+
map[key] = Array(attributes[key]).join(',')
|
48
|
+
else
|
49
|
+
map[key] = attributes[key]
|
50
|
+
end
|
51
|
+
|
52
|
+
map
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
@@ -0,0 +1,60 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'kong'
|
4
|
+
require_relative '../adapter'
|
5
|
+
|
6
|
+
module KongSchema
|
7
|
+
module Resource
|
8
|
+
module Target
|
9
|
+
extend self
|
10
|
+
|
11
|
+
def identify(record)
|
12
|
+
case record
|
13
|
+
when Kong::Target
|
14
|
+
[record.upstream.name, record.target].to_json
|
15
|
+
when Hash
|
16
|
+
[record['upstream_id'], record['target']].to_json
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
def all(*)
|
21
|
+
Kong::Upstream.all.map(&:targets).flatten
|
22
|
+
end
|
23
|
+
|
24
|
+
def create(attributes)
|
25
|
+
with_upstream(attributes) do |upstream|
|
26
|
+
Adapter.for(Kong::Target).create(
|
27
|
+
attributes.merge('upstream_id' => upstream.id)
|
28
|
+
)
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
def changed?(record, directive)
|
33
|
+
(
|
34
|
+
record.target != directive['target'] ||
|
35
|
+
record.weight != directive.fetch('weight', 100) ||
|
36
|
+
record.upstream.name != directive['upstream_id']
|
37
|
+
)
|
38
|
+
end
|
39
|
+
|
40
|
+
def update(record, partial_attributes)
|
41
|
+
delete(record)
|
42
|
+
create(partial_attributes)
|
43
|
+
end
|
44
|
+
|
45
|
+
def delete(target)
|
46
|
+
Adapter.for(Kong::Target).delete(target)
|
47
|
+
end
|
48
|
+
|
49
|
+
private
|
50
|
+
|
51
|
+
def with_upstream(params)
|
52
|
+
upstream = Kong::Upstream.find_by_name(params.fetch('upstream_id', ''))
|
53
|
+
|
54
|
+
fail "Can not add a target without an upstream!" if upstream.nil?
|
55
|
+
|
56
|
+
yield upstream
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
@@ -0,0 +1,42 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'kong'
|
4
|
+
require_relative '../adapter'
|
5
|
+
|
6
|
+
module KongSchema
|
7
|
+
module Resource
|
8
|
+
# https://getkong.org/docs/0.11.x/admin-api/#upstream-objects
|
9
|
+
module Upstream
|
10
|
+
extend self
|
11
|
+
|
12
|
+
def identify(record)
|
13
|
+
case record
|
14
|
+
when Kong::Upstream
|
15
|
+
record.name
|
16
|
+
when Hash
|
17
|
+
record['name']
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
def all(*)
|
22
|
+
Kong::Upstream.all
|
23
|
+
end
|
24
|
+
|
25
|
+
def create(attributes)
|
26
|
+
Adapter.for(Kong::Upstream).create(attributes)
|
27
|
+
end
|
28
|
+
|
29
|
+
def changed?(record, attributes)
|
30
|
+
Adapter.for(Kong::Upstream).changed?(record, attributes)
|
31
|
+
end
|
32
|
+
|
33
|
+
def update(record, partial_attributes)
|
34
|
+
Adapter.for(Kong::Upstream).update(record, partial_attributes)
|
35
|
+
end
|
36
|
+
|
37
|
+
def delete(record)
|
38
|
+
Adapter.for(Kong::Upstream).delete(record)
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
@@ -0,0 +1,103 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'yaml'
|
4
|
+
require 'kong'
|
5
|
+
require 'English'
|
6
|
+
|
7
|
+
require_relative './client'
|
8
|
+
require_relative './resource'
|
9
|
+
|
10
|
+
module KongSchema
|
11
|
+
module Schema
|
12
|
+
extend self
|
13
|
+
|
14
|
+
# Scan for changes between Kong's database and the configuration. To
|
15
|
+
# commit the changes (if any) use {.commit} with the results.
|
16
|
+
#
|
17
|
+
# @param [Object] config
|
18
|
+
# The configuration directives as explain in README.
|
19
|
+
#
|
20
|
+
# @return [Array<Change>]
|
21
|
+
def scan(config)
|
22
|
+
Client.connect(config) do
|
23
|
+
[
|
24
|
+
scan_in(model: Resource::Api, directives: Array(config['apis'])),
|
25
|
+
|
26
|
+
# order matters in some of the resources; Upstream directives must be
|
27
|
+
# handled before Target ones
|
28
|
+
scan_in(model: Resource::Upstream, directives: Array(config['upstreams'])),
|
29
|
+
|
30
|
+
scan_in(model: Resource::Target, directives: Array(config['targets']))
|
31
|
+
].flatten
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
# Commit changes to Kong's database through its REST API.
|
36
|
+
#
|
37
|
+
# @param [Object] config
|
38
|
+
# @param [Array<Change>] changes
|
39
|
+
#
|
40
|
+
# @return NilClass
|
41
|
+
def commit(config, directives)
|
42
|
+
Client.connect(config) do |client|
|
43
|
+
directives.each do |d|
|
44
|
+
begin
|
45
|
+
d.apply(client, config)
|
46
|
+
rescue StandardError
|
47
|
+
e = $ERROR_INFO
|
48
|
+
raise e, "#{e}\nSource:\n#{YAML.dump(d)}", e.backtrace
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
private
|
55
|
+
|
56
|
+
def scan_in(model:, directives:)
|
57
|
+
state = {
|
58
|
+
model: model,
|
59
|
+
defined: model.all.each_with_object({}) do |record, map|
|
60
|
+
map[model.identify(record)] = record
|
61
|
+
end,
|
62
|
+
declared: directives.each_with_object({}) do |directive, map|
|
63
|
+
map[model.identify(directive)] = directive
|
64
|
+
end
|
65
|
+
}
|
66
|
+
|
67
|
+
[
|
68
|
+
build_create_changes(state),
|
69
|
+
build_update_changes(state),
|
70
|
+
build_delete_changes(state)
|
71
|
+
].flatten
|
72
|
+
end
|
73
|
+
|
74
|
+
def build_create_changes(model:, defined:, declared:)
|
75
|
+
to_create = declared.keys - defined.keys
|
76
|
+
to_create.map do |id|
|
77
|
+
Actions::Create.new(model: model, params: declared[id])
|
78
|
+
end
|
79
|
+
end
|
80
|
+
|
81
|
+
def build_update_changes(model:, defined:, declared:)
|
82
|
+
to_update = declared.keys & defined.keys
|
83
|
+
changed = to_update.select do |id|
|
84
|
+
model.changed?(defined[id], declared[id])
|
85
|
+
end
|
86
|
+
|
87
|
+
changed.map do |id|
|
88
|
+
Actions::Update.new(
|
89
|
+
model: model,
|
90
|
+
record: defined[id],
|
91
|
+
params: declared[id]
|
92
|
+
)
|
93
|
+
end
|
94
|
+
end
|
95
|
+
|
96
|
+
def build_delete_changes(model:, defined:, declared:)
|
97
|
+
to_delete = defined.keys - declared.keys
|
98
|
+
to_delete.map do |id|
|
99
|
+
Actions::Delete.new(model: model, record: defined[id])
|
100
|
+
end
|
101
|
+
end
|
102
|
+
end
|
103
|
+
end
|
data/lib/kong_schema.rb
ADDED
@@ -0,0 +1,10 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative '../ext/kong/upstream'
|
4
|
+
require_relative './kong_schema/actions'
|
5
|
+
require_relative './kong_schema/adapter'
|
6
|
+
require_relative './kong_schema/cli'
|
7
|
+
require_relative './kong_schema/reporter'
|
8
|
+
require_relative './kong_schema/resource'
|
9
|
+
require_relative './kong_schema/schema'
|
10
|
+
require_relative './kong_schema/version'
|
data/spec/examples.txt
ADDED
File without changes
|
@@ -0,0 +1,89 @@
|
|
1
|
+
describe KongSchema::Reporter do
|
2
|
+
subject { described_class }
|
3
|
+
|
4
|
+
let(:test_utils) { KongSchemaTestUtils.new }
|
5
|
+
let(:schema) { KongSchema::Schema }
|
6
|
+
|
7
|
+
after(:each) do
|
8
|
+
test_utils.reset_kong
|
9
|
+
end
|
10
|
+
|
11
|
+
let :config do
|
12
|
+
test_utils.generate_config({
|
13
|
+
upstreams: [{ name: 'bridge-learn.kong-service' }]
|
14
|
+
})
|
15
|
+
end
|
16
|
+
|
17
|
+
let :with_updated_config do
|
18
|
+
test_utils.generate_config({
|
19
|
+
upstreams: [{
|
20
|
+
name: 'bridge-learn.kong-service',
|
21
|
+
slots: 50,
|
22
|
+
orderlist: nil
|
23
|
+
}]
|
24
|
+
})
|
25
|
+
end
|
26
|
+
|
27
|
+
let :with_deleted_config do
|
28
|
+
test_utils.generate_config({
|
29
|
+
upstreams: []
|
30
|
+
})
|
31
|
+
end
|
32
|
+
|
33
|
+
it 'reports a resource to be created' do
|
34
|
+
report = subject.report(schema.scan(config))
|
35
|
+
|
36
|
+
expect(report).to include('Create Upstream')
|
37
|
+
end
|
38
|
+
|
39
|
+
it 'reports a resource to be updated [JSON]' do
|
40
|
+
schema.commit(config, schema.scan(config))
|
41
|
+
|
42
|
+
report = subject.report(schema.scan(with_updated_config))
|
43
|
+
|
44
|
+
expect(report).to include('Update Upstream')
|
45
|
+
expect(report).to match(/\-[ ]*"slots": 100/)
|
46
|
+
expect(report).to match(/\+[ ]*"slots": 50/)
|
47
|
+
end
|
48
|
+
|
49
|
+
it 'reports a resource to be updated [YAML]' do
|
50
|
+
schema.commit(config, schema.scan(config))
|
51
|
+
|
52
|
+
report = subject.report(schema.scan(with_updated_config), object_format: :yaml)
|
53
|
+
|
54
|
+
expect(report).to include('Update Upstream')
|
55
|
+
expect(report).to include('-slots: 100')
|
56
|
+
expect(report).to include('+slots: 50')
|
57
|
+
end
|
58
|
+
|
59
|
+
it 'reports a resource to be deleted' do
|
60
|
+
schema.commit(config, schema.scan(config))
|
61
|
+
|
62
|
+
report = subject.report(schema.scan(with_deleted_config))
|
63
|
+
|
64
|
+
expect(report).to include('Delete Upstream')
|
65
|
+
end
|
66
|
+
|
67
|
+
describe '.extract_record_attributes' do
|
68
|
+
context 'Kong::Target' do
|
69
|
+
it 'it rewrites "upstream_id" into the upstream name' do
|
70
|
+
with_target = test_utils.generate_config({
|
71
|
+
upstreams: [{ name: 'foo' }],
|
72
|
+
targets: [{ upstream_id: 'foo', target: '127.0.0.1' }]
|
73
|
+
})
|
74
|
+
|
75
|
+
with_updated_target = test_utils.generate_config({
|
76
|
+
upstreams: [{ name: 'foo' }],
|
77
|
+
targets: []
|
78
|
+
})
|
79
|
+
|
80
|
+
schema.commit(with_target, schema.scan(with_target))
|
81
|
+
|
82
|
+
next_changes = schema.scan(with_updated_target)
|
83
|
+
report = subject.report(next_changes, object_format: :yml)
|
84
|
+
|
85
|
+
expect(report).to include('upstream_id: foo')
|
86
|
+
end
|
87
|
+
end
|
88
|
+
end
|
89
|
+
end
|
@@ -0,0 +1,125 @@
|
|
1
|
+
describe KongSchema::Resource::Api do
|
2
|
+
let(:schema) { KongSchema::Schema }
|
3
|
+
let(:test_utils) { KongSchemaTestUtils.new }
|
4
|
+
|
5
|
+
after(:each) do
|
6
|
+
test_utils.reset_kong
|
7
|
+
end
|
8
|
+
|
9
|
+
describe 'creating APIs' do
|
10
|
+
let :config do
|
11
|
+
test_utils.generate_config({
|
12
|
+
apis: [{
|
13
|
+
name: 'bridge-learn',
|
14
|
+
hosts: ['bridgeapp.com'],
|
15
|
+
upstream_url: 'http://bridge-learn.kong-service'
|
16
|
+
}]
|
17
|
+
})
|
18
|
+
end
|
19
|
+
|
20
|
+
it 'adds an API if it does not exist' do
|
21
|
+
directives = schema.scan(config)
|
22
|
+
|
23
|
+
expect(directives.map(&:class)).to include(KongSchema::Actions::Create)
|
24
|
+
end
|
25
|
+
|
26
|
+
it 'does add an API' do
|
27
|
+
directives = schema.scan(config)
|
28
|
+
|
29
|
+
expect {
|
30
|
+
schema.commit(config, directives)
|
31
|
+
}.to change {
|
32
|
+
KongSchema::Client.connect(config) { Kong::Api.all.count }
|
33
|
+
}.by(1)
|
34
|
+
end
|
35
|
+
|
36
|
+
it 'does not add an API if it exists' do
|
37
|
+
directives = schema.scan(config)
|
38
|
+
|
39
|
+
schema.commit(config, directives)
|
40
|
+
|
41
|
+
next_directives = schema.scan(config)
|
42
|
+
|
43
|
+
expect(next_directives.map(&:class)).not_to include(KongSchema::Actions::Create)
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
describe 'updating APIs' do
|
48
|
+
let :config do
|
49
|
+
test_utils.generate_config({
|
50
|
+
apis: [{
|
51
|
+
name: 'bridge-learn',
|
52
|
+
hosts: ['bridgeapp.com'],
|
53
|
+
upstream_url: 'http://bridge-learn.kong-service'
|
54
|
+
}]
|
55
|
+
})
|
56
|
+
end
|
57
|
+
|
58
|
+
let :with_updated_config do
|
59
|
+
test_utils.generate_config({
|
60
|
+
apis: [{
|
61
|
+
name: 'bridge-learn',
|
62
|
+
hosts: ['bar.com'],
|
63
|
+
upstream_url: 'http://bridge-learn.kong-service'
|
64
|
+
}]
|
65
|
+
})
|
66
|
+
end
|
67
|
+
|
68
|
+
before(:each) do
|
69
|
+
schema.commit(config, schema.scan(config))
|
70
|
+
end
|
71
|
+
|
72
|
+
it 'updates an API' do
|
73
|
+
directives = schema.scan(with_updated_config)
|
74
|
+
expect(directives.map(&:class)).to include(KongSchema::Actions::Update)
|
75
|
+
end
|
76
|
+
|
77
|
+
it 'does update an API' do
|
78
|
+
directives = schema.scan(with_updated_config)
|
79
|
+
|
80
|
+
expect {
|
81
|
+
schema.commit(with_updated_config, directives)
|
82
|
+
}.to change {
|
83
|
+
KongSchema::Client.connect(config) { Kong::Api.all[0].hosts[0] }
|
84
|
+
}.from('bridgeapp.com').to('bar.com')
|
85
|
+
end
|
86
|
+
end
|
87
|
+
|
88
|
+
describe 'deleting APIs' do
|
89
|
+
let :config do
|
90
|
+
test_utils.generate_config({
|
91
|
+
apis: [{
|
92
|
+
name: 'bridge-learn',
|
93
|
+
hosts: ['bar.com'],
|
94
|
+
upstream_url: 'http://bridge-learn.kong-service'
|
95
|
+
}]
|
96
|
+
})
|
97
|
+
end
|
98
|
+
|
99
|
+
let :with_deleted_config do
|
100
|
+
test_utils.generate_config({
|
101
|
+
apis: []
|
102
|
+
})
|
103
|
+
end
|
104
|
+
|
105
|
+
before(:each) do
|
106
|
+
schema.commit(config, schema.scan(config))
|
107
|
+
end
|
108
|
+
|
109
|
+
it 'deletes an API' do
|
110
|
+
directives = schema.scan(with_deleted_config)
|
111
|
+
|
112
|
+
expect(directives.map(&:class)).to include(KongSchema::Actions::Delete)
|
113
|
+
end
|
114
|
+
|
115
|
+
it 'does delete an API' do
|
116
|
+
directives = schema.scan(with_deleted_config)
|
117
|
+
|
118
|
+
expect {
|
119
|
+
schema.commit(with_deleted_config, directives)
|
120
|
+
}.to change {
|
121
|
+
KongSchema::Client.connect(config) { Kong::Api.all.count }
|
122
|
+
}.from(1).to(0)
|
123
|
+
end
|
124
|
+
end
|
125
|
+
end
|