skull_island 1.1.1 → 1.1.2
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 +4 -4
- data/.rubocop.yml +2 -2
- data/Gemfile.lock +1 -1
- data/README.md +26 -8
- data/lib/skull_island/resource.rb +1 -1
- data/lib/skull_island/resources/consumer.rb +29 -1
- data/lib/skull_island/resources/jwt_credential.rb +121 -0
- data/lib/skull_island/resources/plugin.rb +4 -0
- data/lib/skull_island/resources/upstream.rb +7 -12
- data/lib/skull_island/resources/upstream_target.rb +20 -1
- data/lib/skull_island/version.rb +1 -1
- data/lib/skull_island.rb +1 -0
- metadata +4 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 0cadf0fd8b018522876070d358219f78a94ee7fe5ff94efe1045a961758783ba
|
4
|
+
data.tar.gz: 1fb907a4a66a77c9c22ff58ad5c1544001e124c49e8c34610dbcbadaf86da2df
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 8324088d97171e7c91205b09f219391827542b23e8635b06f77793b6cff7e86ec1dab1a0d431f25a8d39b03dff38344db961f4cf8944dac9be9d23a470a23c93
|
7
|
+
data.tar.gz: 876b5971f3955f88baa89dbb2f6395e52130a0b58625ad56f6d38c08402dba437760d7fa4e3dd4769b4bf0a43942717314065a717b13ecd7be8fd5fb52f7dfa6
|
data/.rubocop.yml
CHANGED
data/Gemfile.lock
CHANGED
data/README.md
CHANGED
@@ -318,10 +318,10 @@ From here, the SDK mostly wraps the attributes described in the [Kong API Docs](
|
|
318
318
|
resource = Resources::Certificate.new
|
319
319
|
|
320
320
|
# These attributes can be set and read
|
321
|
-
resource.cert = '-----BEGIN CERTIFICATE-----...'
|
321
|
+
resource.cert = '-----BEGIN CERTIFICATE-----...' # PEM-encoded public key
|
322
322
|
resource.key = '-----BEGIN RSA PRIVATE KEY-----...' # PEM-encoded private key
|
323
|
-
resource.snis = ['example.com', 'example.org']
|
324
|
-
|
323
|
+
resource.snis = ['example.com', 'example.org'] # Array of names for which this cert is valid
|
324
|
+
resource.tags = ['production', 'example'] # Array of tags
|
325
325
|
resource.save
|
326
326
|
|
327
327
|
# These attributes are read-only
|
@@ -333,14 +333,15 @@ resource.created_at
|
|
333
333
|
|
334
334
|
#### Consumers (and their Credentials)
|
335
335
|
|
336
|
-
Note that for Consumer credentials, only [`key-auth`](https://docs.konghq.com/hub/kong-inc/key-auth/) and [`basic-auth`](https://docs.konghq.com/hub/kong-inc/basic-auth/) are currently supported.
|
336
|
+
Note that for Consumer credentials, only [`key-auth`](https://docs.konghq.com/hub/kong-inc/key-auth/), [`jwt`](https://docs.konghq.com/hub/kong-inc/jwt/), and [`basic-auth`](https://docs.konghq.com/hub/kong-inc/basic-auth/) are currently supported.
|
337
337
|
|
338
338
|
```ruby
|
339
339
|
resource = Resources::Consumer.new
|
340
340
|
|
341
341
|
# These attributes can be set and read
|
342
|
-
resource.custom_id = 'user1'
|
343
|
-
resource.username = 'user1'
|
342
|
+
resource.custom_id = 'user1' # A string
|
343
|
+
resource.username = 'user1' # A string
|
344
|
+
resource.tags = ['production', 'example'] # Array of tags
|
344
345
|
|
345
346
|
resource.save
|
346
347
|
|
@@ -375,9 +376,10 @@ Note that this doesn't _install_ plugins; it only allows using them.
|
|
375
376
|
resource = Resources::Plugin.new
|
376
377
|
|
377
378
|
# These attributes can be set and read
|
378
|
-
resource.name = 'rate-limiting'
|
379
|
-
resource.enabled = true
|
379
|
+
resource.name = 'rate-limiting' # The name of the plugin
|
380
|
+
resource.enabled = true # A Boolean
|
380
381
|
resource.config = { 'minute' => 50, 'hour' => 1000 } # A Hash of config keys and values
|
382
|
+
resource.tags = ['production', 'example'] # Array of tags
|
381
383
|
|
382
384
|
# Either reference related resources by ID
|
383
385
|
resource.service = { 'id' => '5fd1z584-1adb-40a5-c042-63b19db49x21' }
|
@@ -418,6 +420,7 @@ Resources::Plugin.schema('acl')
|
|
418
420
|
resource = Resources::Route.new
|
419
421
|
|
420
422
|
# These attributes can be set and read
|
423
|
+
resource.name = 'example_route'
|
421
424
|
resource.hosts = ['example.com', 'example.org']
|
422
425
|
resource.protocols = ['https']
|
423
426
|
resource.methods = ['GET', 'POST']
|
@@ -425,6 +428,19 @@ resource.paths = ['/some/path']
|
|
425
428
|
resource.regex_priority = 10
|
426
429
|
resource.strip_path = false
|
427
430
|
resource.preserve_host = true
|
431
|
+
resource.tags = ['production', 'example']
|
432
|
+
|
433
|
+
# Or, for TCP/TLS routes
|
434
|
+
resource.protocols = ['tcp', 'tls']
|
435
|
+
resource.sources = [
|
436
|
+
{ "ip" => "10.1.0.0/16", "port" => 1234 }
|
437
|
+
]
|
438
|
+
resource.destinations = [
|
439
|
+
{ "ip" => "10.1.0.0/16", "port" => 1234 },
|
440
|
+
{ "ip" => "10.2.2.2" },
|
441
|
+
{ "port" => 9123 }
|
442
|
+
]
|
443
|
+
resource.snis = ['example.com', 'example.org']
|
428
444
|
|
429
445
|
# Either reference related resources by ID
|
430
446
|
resource.service = { 'id' => '4e13f54a-bbf1-47a8-8777-255fed7116f2' }
|
@@ -461,6 +477,7 @@ resource.name = 'example-service'
|
|
461
477
|
resource.retries = 10
|
462
478
|
resource.read_timeout = 60000
|
463
479
|
resource.write_timeout = 60000
|
480
|
+
resource.tags = ['production', 'example']
|
464
481
|
|
465
482
|
resource.save
|
466
483
|
|
@@ -513,6 +530,7 @@ resource.healthchecks = {
|
|
513
530
|
}
|
514
531
|
}
|
515
532
|
}
|
533
|
+
resource.tags = ['production', 'example']
|
516
534
|
|
517
535
|
resource.save
|
518
536
|
|
@@ -30,6 +30,14 @@ module SkullIsland
|
|
30
30
|
test: test
|
31
31
|
)
|
32
32
|
|
33
|
+
JWTCredential.batch_import(
|
34
|
+
(
|
35
|
+
resource_data.dig('credentials', 'jwt') || []
|
36
|
+
).map { |t| t.merge('consumer' => { 'id' => resource.id }) },
|
37
|
+
verbose: verbose,
|
38
|
+
test: test
|
39
|
+
)
|
40
|
+
|
33
41
|
KeyauthCredential.batch_import(
|
34
42
|
(
|
35
43
|
resource_data.dig('credentials', 'key-auth') || []
|
@@ -41,9 +49,19 @@ module SkullIsland
|
|
41
49
|
end
|
42
50
|
|
43
51
|
# Convenience method to add upstream targets
|
52
|
+
# rubocop:disable Metrics/AbcSize
|
53
|
+
# rubocop:disable Metrics/CyclomaticComplexity
|
54
|
+
# rubocop:disable Metrics/PerceivedComplexity
|
44
55
|
def add_credential!(details)
|
45
|
-
r = if [BasicauthCredential, KeyauthCredential].include? details.class
|
56
|
+
r = if [BasicauthCredential, JWTCredential, KeyauthCredential].include? details.class
|
46
57
|
details
|
58
|
+
elsif details.is_a?(Hash) && details.key?(:algorithm)
|
59
|
+
cred = JWTCredential.new(api_client: api_client)
|
60
|
+
cred.algorithm = details[:algorithm]
|
61
|
+
cred.key = details[:key] if details[:key]
|
62
|
+
cred.secret = details[:secret] if details[:secret]
|
63
|
+
cred.rsa_public_key = details[:rsa_public_key] if details[:rsa_public_key]
|
64
|
+
cred
|
47
65
|
elsif details.is_a?(Hash) && details.key?(:key)
|
48
66
|
cred = KeyauthCredential.new(api_client: api_client)
|
49
67
|
cred.key = details[:key]
|
@@ -58,6 +76,9 @@ module SkullIsland
|
|
58
76
|
r.consumer = self
|
59
77
|
r.save
|
60
78
|
end
|
79
|
+
# rubocop:enable Metrics/AbcSize
|
80
|
+
# rubocop:enable Metrics/CyclomaticComplexity
|
81
|
+
# rubocop:enable Metrics/PerceivedComplexity
|
61
82
|
|
62
83
|
def credentials
|
63
84
|
creds = {}
|
@@ -65,6 +86,8 @@ module SkullIsland
|
|
65
86
|
creds['key-auth'] = keyauth_creds if keyauth_creds
|
66
87
|
basicauth_creds = BasicauthCredential.where(:consumer, self, api_client: api_client)
|
67
88
|
creds['basic-auth'] = basicauth_creds if basicauth_creds
|
89
|
+
jwt_creds = JWTCredential.where(:consumer, self, api_client: api_client)
|
90
|
+
creds['jwt'] = jwt_creds if jwt_creds
|
68
91
|
creds
|
69
92
|
end
|
70
93
|
|
@@ -112,6 +135,11 @@ module SkullIsland
|
|
112
135
|
cred.export(exclude: 'consumer')
|
113
136
|
end
|
114
137
|
end
|
138
|
+
unless credentials['jwt'].empty?
|
139
|
+
creds['jwt'] = credentials['jwt'].collect do |cred|
|
140
|
+
cred.export(exclude: 'consumer')
|
141
|
+
end
|
142
|
+
end
|
115
143
|
unless credentials['basic-auth'].empty?
|
116
144
|
creds['basic-auth'] = credentials['basic-auth'].collect do |cred|
|
117
145
|
cred.export(exclude: 'consumer')
|
@@ -0,0 +1,121 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module SkullIsland
|
4
|
+
# Resource classes go here...
|
5
|
+
module Resources
|
6
|
+
# The JWTCredential resource class
|
7
|
+
#
|
8
|
+
# @see https://docs.konghq.com/hub/kong-inc/jwt/ JWT Authentication details
|
9
|
+
class JWTCredential < Resource
|
10
|
+
property :algorithm, required: true, validate: true
|
11
|
+
property :key, validate: true
|
12
|
+
property :secret, validated: true
|
13
|
+
property :rsa_public_key, validated: true
|
14
|
+
property(
|
15
|
+
:consumer,
|
16
|
+
required: true, validate: true, preprocess: true, postprocess: true
|
17
|
+
)
|
18
|
+
property :created_at, read_only: true, postprocess: true
|
19
|
+
|
20
|
+
def self.batch_import(data, verbose: false, test: false)
|
21
|
+
raise(Exceptions::InvalidArguments) unless data.is_a?(Array)
|
22
|
+
|
23
|
+
data.each_with_index do |resource_data, index|
|
24
|
+
resource = new
|
25
|
+
resource.algorithm = resource_data['algorithm']
|
26
|
+
resource.key = resource_data['key'] if resource_data['key']
|
27
|
+
resource.secret = resource_data['secret'] if resource_data['secret']
|
28
|
+
if resource_data['rsa_public_key']
|
29
|
+
resource.rsa_public_key = resource_data['rsa_public_key']
|
30
|
+
end
|
31
|
+
resource.delayed_set(:consumer, resource_data, 'consumer')
|
32
|
+
resource.import_update_or_skip(index: index, verbose: verbose, test: test)
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
def self.relative_uri
|
37
|
+
'jwts'
|
38
|
+
end
|
39
|
+
|
40
|
+
def relative_uri
|
41
|
+
consumer ? "#{consumer.relative_uri}/jwt/#{id}" : nil
|
42
|
+
end
|
43
|
+
|
44
|
+
def save_uri
|
45
|
+
consumer ? "#{consumer.relative_uri}/jwt" : nil
|
46
|
+
end
|
47
|
+
|
48
|
+
def export(options = {})
|
49
|
+
hash = { 'algorithm' => algorithm }
|
50
|
+
hash['key'] = key if key
|
51
|
+
hash['secret'] = secret if secret
|
52
|
+
hash['rsa_public_key'] = rsa_public_key if rsa_public_key
|
53
|
+
hash['consumer'] = "<%= lookup :consumer, '#{consumer.username}' %>" if consumer
|
54
|
+
[*options[:exclude]].each do |exclude|
|
55
|
+
hash.delete(exclude.to_s)
|
56
|
+
end
|
57
|
+
[*options[:include]].each do |inc|
|
58
|
+
hash[inc.to_s] = send(inc.to_sym)
|
59
|
+
end
|
60
|
+
hash.reject { |_, value| value.nil? }
|
61
|
+
end
|
62
|
+
|
63
|
+
# Keys can't be updated, only created or deleted
|
64
|
+
def modified_existing?
|
65
|
+
false
|
66
|
+
end
|
67
|
+
|
68
|
+
private
|
69
|
+
|
70
|
+
def postprocess_consumer(value)
|
71
|
+
if value.is_a?(Hash)
|
72
|
+
Consumer.new(
|
73
|
+
entity: value,
|
74
|
+
lazy: true,
|
75
|
+
tainted: false
|
76
|
+
)
|
77
|
+
else
|
78
|
+
value
|
79
|
+
end
|
80
|
+
end
|
81
|
+
|
82
|
+
def preprocess_consumer(input)
|
83
|
+
if input.is_a?(Hash)
|
84
|
+
input
|
85
|
+
else
|
86
|
+
{ 'id' => input.id }
|
87
|
+
end
|
88
|
+
end
|
89
|
+
|
90
|
+
# Used to validate {#consumer} on set
|
91
|
+
def validate_consumer(value)
|
92
|
+
# allow either a Consumer object or a Hash
|
93
|
+
value.is_a?(Consumer) || value.is_a?(Hash)
|
94
|
+
end
|
95
|
+
|
96
|
+
# Used to validate {#algorithm} on set
|
97
|
+
def validate_algorithm(value)
|
98
|
+
# allow a String
|
99
|
+
%w[HS256 HS384 HS512 RS256 ES256].include? value
|
100
|
+
end
|
101
|
+
|
102
|
+
# Used to validate {#key} on set
|
103
|
+
def validate_key(value)
|
104
|
+
# allow a String
|
105
|
+
value.is_a?(String)
|
106
|
+
end
|
107
|
+
|
108
|
+
# Used to validate {#secret} on set
|
109
|
+
def validate_secret(value)
|
110
|
+
# allow a String
|
111
|
+
value.is_a?(String)
|
112
|
+
end
|
113
|
+
|
114
|
+
# Used to validate {#rsa_public_key} on set
|
115
|
+
def validate_rsa_public_key(value)
|
116
|
+
# allow a String
|
117
|
+
value.is_a?(String)
|
118
|
+
end
|
119
|
+
end
|
120
|
+
end
|
121
|
+
end
|
@@ -30,8 +30,8 @@ module SkullIsland
|
|
30
30
|
resource.name = rdata['name']
|
31
31
|
resource.slots = rdata['slots'] if rdata['slots']
|
32
32
|
resource.hash_on = rdata['hash_on']
|
33
|
-
resource.hash_fallback = rdata['hash_fallback']
|
34
|
-
resource.hash_on_header = rdata['hash_on_header']
|
33
|
+
resource.hash_fallback = rdata['hash_fallback'] if rdata['hash_fallback']
|
34
|
+
resource.hash_on_header = rdata['hash_on_header'] if rdata['hash_on_header']
|
35
35
|
if rdata['hash_fallback_header']
|
36
36
|
resource.hash_fallback_header = rdata['hash_fallback_header']
|
37
37
|
end
|
@@ -78,12 +78,7 @@ module SkullIsland
|
|
78
78
|
end
|
79
79
|
|
80
80
|
def target(target_id)
|
81
|
-
|
82
|
-
entity: { 'id' => target_id, 'upstream' => { 'id' => id } },
|
83
|
-
lazy: true,
|
84
|
-
tainted: false,
|
85
|
-
api_client: api_client
|
86
|
-
)
|
81
|
+
targets.where(id: target_id).first
|
87
82
|
end
|
88
83
|
|
89
84
|
def targets
|
@@ -176,10 +171,10 @@ module SkullIsland
|
|
176
171
|
value.is_a?(String) && [hash_on, hash_fallback].include?('cookie')
|
177
172
|
end
|
178
173
|
|
179
|
-
# Used to validate {#
|
180
|
-
def
|
181
|
-
# only String is allowed
|
182
|
-
value.is_a?(String)
|
174
|
+
# Used to validate {#hash_on_cookie_path} on set
|
175
|
+
def validate_hash_on_cookie_path(value)
|
176
|
+
# only String is allowed
|
177
|
+
value.is_a?(String)
|
183
178
|
end
|
184
179
|
|
185
180
|
# Used to validate {#name} on set
|
@@ -29,6 +29,12 @@ module SkullIsland
|
|
29
29
|
end
|
30
30
|
end
|
31
31
|
|
32
|
+
def self.all(options = {})
|
33
|
+
api_client = options[:api_client] || APIClient.instance
|
34
|
+
|
35
|
+
Upstream.all(api_client: api_client).map(&:targets).reduce(&:merge)
|
36
|
+
end
|
37
|
+
|
32
38
|
def self.get(id, options = {})
|
33
39
|
if options[:upstream]&.is_a?(Upstream)
|
34
40
|
options[:upstream].target(id)
|
@@ -38,6 +44,19 @@ module SkullIsland
|
|
38
44
|
end
|
39
45
|
end
|
40
46
|
|
47
|
+
# Tests for an existing version of this resource based on its properties rather than its `id`
|
48
|
+
def find_by_digest
|
49
|
+
result = self.class.where(:digest, digest) # matching digest means the equivalent resource
|
50
|
+
if result.size == 1
|
51
|
+
@entity = result.first.entity
|
52
|
+
@lazy = false
|
53
|
+
@tainted = false
|
54
|
+
true
|
55
|
+
else
|
56
|
+
false
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
41
60
|
def relative_uri
|
42
61
|
upstream ? "#{upstream.relative_uri}/targets/#{id}" : nil
|
43
62
|
end
|
@@ -111,7 +130,7 @@ module SkullIsland
|
|
111
130
|
def validate_target(value)
|
112
131
|
# only URIs or specific strings
|
113
132
|
value.is_a?(URI) || (
|
114
|
-
value.is_a?(String) && value.match?(
|
133
|
+
value.is_a?(String) && value.match?(/[\w\d.-]+:\d{1,5}/)
|
115
134
|
)
|
116
135
|
end
|
117
136
|
|
data/lib/skull_island/version.rb
CHANGED
data/lib/skull_island.rb
CHANGED
@@ -46,6 +46,7 @@ require 'skull_island/validations/resource'
|
|
46
46
|
require 'skull_island/resource'
|
47
47
|
require 'skull_island/resources/certificate'
|
48
48
|
require 'skull_island/resources/basicauth_credential'
|
49
|
+
require 'skull_island/resources/jwt_credential'
|
49
50
|
require 'skull_island/resources/keyauth_credential'
|
50
51
|
require 'skull_island/resources/consumer'
|
51
52
|
require 'skull_island/resources/plugin'
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: skull_island
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.1.
|
4
|
+
version: 1.1.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Jonathan Gnagy
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2019-
|
11
|
+
date: 2019-06-25 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: deepsort
|
@@ -251,6 +251,7 @@ files:
|
|
251
251
|
- lib/skull_island/resources/basicauth_credential.rb
|
252
252
|
- lib/skull_island/resources/certificate.rb
|
253
253
|
- lib/skull_island/resources/consumer.rb
|
254
|
+
- lib/skull_island/resources/jwt_credential.rb
|
254
255
|
- lib/skull_island/resources/keyauth_credential.rb
|
255
256
|
- lib/skull_island/resources/plugin.rb
|
256
257
|
- lib/skull_island/resources/route.rb
|
@@ -283,7 +284,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
283
284
|
- !ruby/object:Gem::Version
|
284
285
|
version: '0'
|
285
286
|
requirements: []
|
286
|
-
rubygems_version: 3.0.
|
287
|
+
rubygems_version: 3.0.4
|
287
288
|
signing_key:
|
288
289
|
specification_version: 4
|
289
290
|
summary: Ruby SDK for Kong
|