skull_island 0.1.0 → 0.1.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.gitignore +1 -0
- data/.rubocop.yml +39 -0
- data/.travis.yml +9 -2
- data/Gemfile +3 -1
- data/Gemfile.lock +127 -0
- data/README.md +348 -2
- data/Rakefile +13 -3
- data/bin/console +4 -3
- data/lib/core_extensions/string/transformations.rb +30 -0
- data/lib/skull_island/api_client.rb +36 -0
- data/lib/skull_island/api_client_base.rb +86 -0
- data/lib/skull_island/api_exception.rb +7 -0
- data/lib/skull_island/exceptions/api_client_not_configured.rb +9 -0
- data/lib/skull_island/exceptions/immutable_modification.rb +9 -0
- data/lib/skull_island/exceptions/invalid_arguments.rb +9 -0
- data/lib/skull_island/exceptions/invalid_cache_size.rb +9 -0
- data/lib/skull_island/exceptions/invalid_options.rb +9 -0
- data/lib/skull_island/exceptions/invalid_property.rb +9 -0
- data/lib/skull_island/exceptions/invalid_where_query.rb +9 -0
- data/lib/skull_island/exceptions/new_instance_with_id.rb +9 -0
- data/lib/skull_island/helpers/api_client.rb +64 -0
- data/lib/skull_island/helpers/resource.rb +178 -0
- data/lib/skull_island/helpers/resource_class.rb +74 -0
- data/lib/skull_island/lru_cache.rb +175 -0
- data/lib/skull_island/resource.rb +198 -0
- data/lib/skull_island/resource_collection.rb +193 -0
- data/lib/skull_island/resources/certificate.rb +36 -0
- data/lib/skull_island/resources/consumer.rb +20 -0
- data/lib/skull_island/resources/plugin.rb +144 -0
- data/lib/skull_island/resources/route.rb +83 -0
- data/lib/skull_island/resources/service.rb +94 -0
- data/lib/skull_island/resources/upstream.rb +129 -0
- data/lib/skull_island/resources/upstream_target.rb +86 -0
- data/lib/skull_island/rspec/fake_api_client.rb +63 -0
- data/lib/skull_island/rspec.rb +3 -0
- data/lib/skull_island/simple_api_client.rb +18 -0
- data/lib/skull_island/validations/api_client.rb +45 -0
- data/lib/skull_island/validations/resource.rb +24 -0
- data/lib/skull_island/version.rb +3 -1
- data/lib/skull_island.rb +47 -1
- data/skull_island.gemspec +16 -13
- metadata +66 -7
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 19ab037beb02518e751019c8d59bd81cdf9165b373ea5b31287ed6dc829a4f21
|
4
|
+
data.tar.gz: 1a352da5080eaae1ce030f872fcda1e53dbbbca2dfb39af5536db2cb1772fe8e
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: f5f1d27b7b1114ccad775df93c7db93d42279fcdb085cf76323efb2f1c2d5aa09dc6a83132e4ab7dbc9eefd349b420ff10f9f7c3abc53fe39839aa18e787c9cb
|
7
|
+
data.tar.gz: ee44a34f72104f02785949a609919230d511e39dbb332ee96ed4c13ec95d800e240d098613570b49b2d0814ac6b81f86f4cc201dfdb8bed93de1cdc320e451c9
|
data/.gitignore
CHANGED
data/.rubocop.yml
ADDED
@@ -0,0 +1,39 @@
|
|
1
|
+
AllCops:
|
2
|
+
TargetRubyVersion: 2.5
|
3
|
+
|
4
|
+
Metrics/MethodLength:
|
5
|
+
Max: 50
|
6
|
+
|
7
|
+
Metrics/LineLength:
|
8
|
+
Max: 100
|
9
|
+
|
10
|
+
Metrics/ClassLength:
|
11
|
+
Max: 165
|
12
|
+
|
13
|
+
Metrics/ModuleLength:
|
14
|
+
Max: 165
|
15
|
+
|
16
|
+
Metrics/CyclomaticComplexity:
|
17
|
+
Max: 7
|
18
|
+
|
19
|
+
Metrics/AbcSize:
|
20
|
+
Max: 25
|
21
|
+
|
22
|
+
Metrics/BlockLength:
|
23
|
+
Max: 35
|
24
|
+
Exclude:
|
25
|
+
- '*.gemspec'
|
26
|
+
- Rakefile
|
27
|
+
- 'spec/**/*_spec.rb'
|
28
|
+
- 'spec/spec_helper.rb'
|
29
|
+
|
30
|
+
Layout/IndentHeredoc:
|
31
|
+
Enabled: false
|
32
|
+
|
33
|
+
Security/Eval:
|
34
|
+
Exclude:
|
35
|
+
- Gemfile
|
36
|
+
|
37
|
+
Style/NumericLiterals:
|
38
|
+
Exclude:
|
39
|
+
- 'spec/**/*_spec.rb'
|
data/.travis.yml
CHANGED
@@ -1,7 +1,14 @@
|
|
1
|
-
---
|
2
1
|
sudo: false
|
3
2
|
language: ruby
|
4
3
|
cache: bundler
|
5
4
|
rvm:
|
6
|
-
|
5
|
+
- 2.5.3
|
7
6
|
before_install: gem install bundler -v 2.0.1
|
7
|
+
deploy:
|
8
|
+
provider: rubygems
|
9
|
+
api_key:
|
10
|
+
secure: Gj3+sg3iSZytx7vNsnu6U/I61BVwz2rFB3WoclMoFuqdWwUyK/4qd2wC0OIvQQJg6Ex1nBwws6VjHUUOCtRiUIF62yR7pDE/ITHkzjjEtZ/ru/6ZKkyHmpenV6Pu0TzENgEY7EIu7pGOJr/57INUuuq7bZM0qV5Rew6Feg2t9n3o8hAONS614MB64Ig6PHRSiGUkm9iogaksQodeb2RvHrQgCXNnhAxq/TdU0TPV7DDDtx4piM1hpdm4sMwznCqZKC89WV7WajeWhQJdaXoGWxDq2ZmF3gM5q8cnK5Uh5wf2pKWce3N8ikeOuiLe06RLQ2pH7UBU9ku9u3+naqFjDZb3d/2DRoxZFjy/P6CRinfoOrsR0k74pc5lnsyQlkxJsJILoOLz7hV4oi9MBi8tDafGz6XVi+UMGE34Nj/7oZjvnbmIuYRJSC+7564y7tsPykOXuCOV6BuDUclXLxTbaLUTLCRcbDluzNrxymbxs3KSZBfM6jli66oXroagaYCdL5zPiGDD5W0crv0c6eDRQAuDOTUllQy/75FRGFn5hbomHQBVM18pm9sx/k6AB+thanIcottdRKst6xh/EN3KnQsLV1M2hSq3gG8EyoqObkIhvcOtCKqfG5VId8qOxT01UcaKui4exyqAv8LAW0WCAL1kyl6Oty1ArZao5fibGUI=
|
11
|
+
gem: skull_island
|
12
|
+
on:
|
13
|
+
tags: true
|
14
|
+
repo: jgnagy/skull_island
|
data/Gemfile
CHANGED
data/Gemfile.lock
ADDED
@@ -0,0 +1,127 @@
|
|
1
|
+
PATH
|
2
|
+
remote: .
|
3
|
+
specs:
|
4
|
+
skull_island (0.1.1)
|
5
|
+
json (~> 2.0)
|
6
|
+
linguistics (~> 2.1)
|
7
|
+
rest-client (~> 2.0)
|
8
|
+
will_paginate (~> 3.1)
|
9
|
+
|
10
|
+
GEM
|
11
|
+
remote: https://rubygems.org/
|
12
|
+
specs:
|
13
|
+
addressable (2.4.0)
|
14
|
+
ast (2.4.0)
|
15
|
+
backports (3.12.0)
|
16
|
+
diff-lcs (1.3)
|
17
|
+
docile (1.3.1)
|
18
|
+
domain_name (0.5.20180417)
|
19
|
+
unf (>= 0.0.5, < 1.0.0)
|
20
|
+
ethon (0.12.0)
|
21
|
+
ffi (>= 1.3.0)
|
22
|
+
faraday (0.15.4)
|
23
|
+
multipart-post (>= 1.2, < 3)
|
24
|
+
faraday_middleware (0.13.1)
|
25
|
+
faraday (>= 0.7.4, < 1.0)
|
26
|
+
ffi (1.10.0)
|
27
|
+
gh (0.15.1)
|
28
|
+
addressable (~> 2.4.0)
|
29
|
+
backports
|
30
|
+
faraday (~> 0.8)
|
31
|
+
multi_json (~> 1.0)
|
32
|
+
net-http-persistent (~> 2.9)
|
33
|
+
net-http-pipeline
|
34
|
+
highline (1.7.10)
|
35
|
+
http-cookie (1.0.3)
|
36
|
+
domain_name (~> 0.5)
|
37
|
+
jaro_winkler (1.5.2)
|
38
|
+
json (2.1.0)
|
39
|
+
launchy (2.4.3)
|
40
|
+
addressable (~> 2.3)
|
41
|
+
linguistics (2.1.0)
|
42
|
+
loggability (~> 0.11)
|
43
|
+
loggability (0.14.0)
|
44
|
+
mime-types (3.2.2)
|
45
|
+
mime-types-data (~> 3.2015)
|
46
|
+
mime-types-data (3.2018.0812)
|
47
|
+
multi_json (1.13.1)
|
48
|
+
multipart-post (2.0.0)
|
49
|
+
net-http-persistent (2.9.4)
|
50
|
+
net-http-pipeline (1.0.1)
|
51
|
+
netrc (0.11.0)
|
52
|
+
parallel (1.13.0)
|
53
|
+
parser (2.6.0.0)
|
54
|
+
ast (~> 2.4.0)
|
55
|
+
powerpack (0.1.2)
|
56
|
+
psych (3.1.0)
|
57
|
+
pusher-client (0.6.2)
|
58
|
+
json
|
59
|
+
websocket (~> 1.0)
|
60
|
+
rainbow (3.0.0)
|
61
|
+
rake (10.5.0)
|
62
|
+
rest-client (2.0.2)
|
63
|
+
http-cookie (>= 1.0.2, < 2.0)
|
64
|
+
mime-types (>= 1.16, < 4.0)
|
65
|
+
netrc (~> 0.8)
|
66
|
+
rspec (3.8.0)
|
67
|
+
rspec-core (~> 3.8.0)
|
68
|
+
rspec-expectations (~> 3.8.0)
|
69
|
+
rspec-mocks (~> 3.8.0)
|
70
|
+
rspec-core (3.8.0)
|
71
|
+
rspec-support (~> 3.8.0)
|
72
|
+
rspec-expectations (3.8.2)
|
73
|
+
diff-lcs (>= 1.2.0, < 2.0)
|
74
|
+
rspec-support (~> 3.8.0)
|
75
|
+
rspec-mocks (3.8.0)
|
76
|
+
diff-lcs (>= 1.2.0, < 2.0)
|
77
|
+
rspec-support (~> 3.8.0)
|
78
|
+
rspec-support (3.8.0)
|
79
|
+
rubocop (0.65.0)
|
80
|
+
jaro_winkler (~> 1.5.1)
|
81
|
+
parallel (~> 1.10)
|
82
|
+
parser (>= 2.5, != 2.5.1.1)
|
83
|
+
powerpack (~> 0.1)
|
84
|
+
psych (>= 3.1.0)
|
85
|
+
rainbow (>= 2.2.2, < 4.0)
|
86
|
+
ruby-progressbar (~> 1.7)
|
87
|
+
unicode-display_width (~> 1.4.0)
|
88
|
+
ruby-progressbar (1.10.0)
|
89
|
+
simplecov (0.16.1)
|
90
|
+
docile (~> 1.1)
|
91
|
+
json (>= 1.8, < 3)
|
92
|
+
simplecov-html (~> 0.10.0)
|
93
|
+
simplecov-html (0.10.2)
|
94
|
+
travis (1.8.9)
|
95
|
+
backports
|
96
|
+
faraday (~> 0.9)
|
97
|
+
faraday_middleware (~> 0.9, >= 0.9.1)
|
98
|
+
gh (~> 0.13)
|
99
|
+
highline (~> 1.6)
|
100
|
+
launchy (~> 2.1)
|
101
|
+
pusher-client (~> 0.4)
|
102
|
+
typhoeus (~> 0.6, >= 0.6.8)
|
103
|
+
typhoeus (0.8.0)
|
104
|
+
ethon (>= 0.8.0)
|
105
|
+
unf (0.1.4)
|
106
|
+
unf_ext
|
107
|
+
unf_ext (0.0.7.5)
|
108
|
+
unicode-display_width (1.4.1)
|
109
|
+
websocket (1.2.8)
|
110
|
+
will_paginate (3.1.6)
|
111
|
+
yard (0.9.18)
|
112
|
+
|
113
|
+
PLATFORMS
|
114
|
+
ruby
|
115
|
+
|
116
|
+
DEPENDENCIES
|
117
|
+
bundler (~> 2.0)
|
118
|
+
rake (~> 10.0)
|
119
|
+
rspec (~> 3.0)
|
120
|
+
rubocop (~> 0.50)
|
121
|
+
simplecov (~> 0.15)
|
122
|
+
skull_island!
|
123
|
+
travis (~> 1.8)
|
124
|
+
yard (~> 0.9)
|
125
|
+
|
126
|
+
BUNDLED WITH
|
127
|
+
2.0.1
|
data/README.md
CHANGED
@@ -1,6 +1,352 @@
|
|
1
|
-
#
|
1
|
+
# Skull Island
|
2
2
|
|
3
|
-
Work In Progress
|
3
|
+
Work In Progress for a full-featured SDK for Kong 0.14.x (with 1.0.x details added for future development).
|
4
|
+
|
5
|
+
## Installation
|
6
|
+
|
7
|
+
Either:
|
8
|
+
|
9
|
+
```sh
|
10
|
+
gem install skull_island
|
11
|
+
```
|
12
|
+
|
13
|
+
Or add this to your Gemfile:
|
14
|
+
|
15
|
+
```ruby
|
16
|
+
gem 'skull_island', '~>0.1'
|
17
|
+
```
|
18
|
+
|
19
|
+
Or add this to your .gemspec:
|
20
|
+
|
21
|
+
```ruby
|
22
|
+
Gem::Specification.new do |spec|
|
23
|
+
# ...
|
24
|
+
spec.add_runtime_dependency 'skull_island', '~> 0.1'
|
25
|
+
# ...
|
26
|
+
end
|
27
|
+
```
|
28
|
+
|
29
|
+
## Usage
|
30
|
+
|
31
|
+
The API Client requires configuration before it can be used. For now, this is a matter of calling `APIClient.configure()`, passing a Hash, with Symbols for keys:
|
32
|
+
|
33
|
+
```ruby
|
34
|
+
require 'skull_island'
|
35
|
+
include SkullIsland
|
36
|
+
|
37
|
+
APIClient.configure(
|
38
|
+
server: 'https://api-admin.mydomain.com',
|
39
|
+
username: 'my-basicauth-user',
|
40
|
+
password: 'my-basicauth-password'
|
41
|
+
)
|
42
|
+
```
|
43
|
+
|
44
|
+
This assumes that a basic-auth reverse proxy sits in front of your Kong Admin API. If this isn't the case (it really should be), then just don't pass `username` and `password` and the API client will work just fine.
|
45
|
+
|
46
|
+
### The APIClient Singleton
|
47
|
+
|
48
|
+
The API client provides a few helpful methods of its own. To learn about the overall service you've connected to (via the [node information endpoint](https://docs.konghq.com/0.14.x/admin-api/#retrieve-node-information)):
|
49
|
+
|
50
|
+
```ruby
|
51
|
+
APIClient.about_service
|
52
|
+
# => {"plugins"=>...
|
53
|
+
```
|
54
|
+
|
55
|
+
It is also possible to check on the server status of the node you're accessing via the [node status endpoint](https://docs.konghq.com/0.14.x/admin-api/#retrieve-node-status):
|
56
|
+
|
57
|
+
```ruby
|
58
|
+
APIClient.server_status
|
59
|
+
# => {"database"=>{"reachable"=>true...
|
60
|
+
```
|
61
|
+
|
62
|
+
This SDK also makes automatic (and mostly unobtrusive) caching behind the scenes. As long as this tool is the only tool making changes to the Admin API (at least while it is being used), this should be fine. Eventually, there will be an option to disable this cache (at the cost of poor performance). For now, it is possible to query this cache and even flushed it manually when required:
|
63
|
+
|
64
|
+
```ruby
|
65
|
+
APIClient.lru_cache
|
66
|
+
# => #<SkullIsland::LRUCache:0x00007f9f1ebf3898 @max_size=1000...
|
67
|
+
APIClient.lru_cache.flush # this empties the cache and resets statistics
|
68
|
+
# => true
|
69
|
+
```
|
70
|
+
|
71
|
+
### Resources
|
72
|
+
|
73
|
+
Most value provided by this SDK is through the ability to manipulate resources managed through the Admin API. These resources almost all have a few methods in common.
|
74
|
+
|
75
|
+
For example, finder methods like these:
|
76
|
+
|
77
|
+
```ruby
|
78
|
+
# Get all instances of a resource type through `.all()`, returning a special collection class
|
79
|
+
Resources::Consumer.all
|
80
|
+
# => #<SkullIsland::ResourceCollection:0x00007f9f1e3f9b38...
|
81
|
+
|
82
|
+
# Find instances matching some criteria using `.where()`, returning the same kind of collection
|
83
|
+
Resources::Consumer.where(:username, /.*foo.*/) # finds all Consumers with a matching username
|
84
|
+
# => #<SkullIsland::ResourceCollection:0x00007f9f1e3351c0...
|
85
|
+
|
86
|
+
# Finding using other types of comparisons, like `<`
|
87
|
+
# Here, we find all Consumers made more than an hour ago
|
88
|
+
Resources::Consumer.where(
|
89
|
+
:created_at, (Time.now - 3600).to_datetime, comparison: :<
|
90
|
+
)
|
91
|
+
# => #<SkullIsland::ResourceCollection:0x00007f9f1e380924...
|
92
|
+
|
93
|
+
# Finder methods can also be chained
|
94
|
+
Resources::Consumer.where(:username, /.*foo.*/).and(:username, /\w{10,}/)
|
95
|
+
# => #<SkullIsland::ResourceCollection:0x00007f9f1e358964...
|
96
|
+
Resources::Consumer.where(:username, /.*foo.*/).or(:custom_id, /.*bar.*/)
|
97
|
+
# => #<SkullIsland::ResourceCollection:0x00007f9f1e568410...
|
98
|
+
|
99
|
+
# If you have the `id` of a particular resource, you can find it directly
|
100
|
+
Resources::Consumer.get('1cad3055-1027-459d-b76e-f590dc5f0071')
|
101
|
+
# => #<SkullIsland::Resources::Consumer:0x00007f9f201f6c58...
|
102
|
+
```
|
103
|
+
|
104
|
+
Once you have a resource, you can modify it:
|
105
|
+
|
106
|
+
```ruby
|
107
|
+
my_consumer = Resources::Consumer.get('1cad3055-1027-459d-b76e-f590dc5f0071')
|
108
|
+
my_consumer.username
|
109
|
+
# => "testuser"
|
110
|
+
my_consumer.tainted?
|
111
|
+
# => false
|
112
|
+
my_consumer.username = 'someuser'
|
113
|
+
my_consumer.tainted?
|
114
|
+
# => true
|
115
|
+
my_consumer.save
|
116
|
+
# => true
|
117
|
+
my_consumer.tainted?
|
118
|
+
# => false
|
119
|
+
my_consumer.username
|
120
|
+
# => "someuser"
|
121
|
+
```
|
122
|
+
|
123
|
+
Some resource types are related to others, such as `Routes` and `Services`:
|
124
|
+
|
125
|
+
```ruby
|
126
|
+
service = Resources::Services.all.first
|
127
|
+
# => #<SkullIsland::Resources::Services:0x00007f9f201f6f44...
|
128
|
+
service.routes
|
129
|
+
# => #<SkullIsland::ResourceCollection:0x00007f9f1e569e1d...
|
130
|
+
service.routes.size
|
131
|
+
# => 3
|
132
|
+
my_route = Resources::Route.new
|
133
|
+
my_route.hosts = ['example.com', 'example.org']
|
134
|
+
my_route.protocols = ['http', 'https']
|
135
|
+
my_route.strip_path = true
|
136
|
+
my_route.preserve_host = false
|
137
|
+
service.add_route!(my_route)
|
138
|
+
# => true
|
139
|
+
service.routes.size
|
140
|
+
# => 4
|
141
|
+
```
|
142
|
+
|
143
|
+
From here, the SDK mostly wraps the attributes described in the [Kong API Docs](https://docs.konghq.com/0.14.x/admin-api/). For simplicity, I'll go over the resource types and attributes this SDK supports manipulating. Rely on the API documentation to determine which attributes are required and under which conditions.
|
144
|
+
|
145
|
+
#### Certificates
|
146
|
+
|
147
|
+
```ruby
|
148
|
+
resource = Resources::Certificate.new
|
149
|
+
|
150
|
+
# These attributes can be set and read
|
151
|
+
resource.cert = '-----BEGIN CERTIFICATE-----...' # PEM-encoded public key
|
152
|
+
resource.key = '-----BEGIN RSA PRIVATE KEY-----...' # PEM-encoded private key
|
153
|
+
resource.snis = ['example.com', 'example.org'] # Array of names for which this cert is valid
|
154
|
+
|
155
|
+
resource.save
|
156
|
+
|
157
|
+
# These attributes are read-only
|
158
|
+
resource.id
|
159
|
+
# => "1cad3055-1027-459d-b76e-f590dc5f0071"
|
160
|
+
resource.created_at
|
161
|
+
# => #<DateTime: 2018-07-17T12:51:28+00:00 ((2458317j,46288s,0n),+0s,2299161j)>
|
162
|
+
```
|
163
|
+
|
164
|
+
#### Consumers
|
165
|
+
|
166
|
+
```ruby
|
167
|
+
resource = Resources::Consumer.new
|
168
|
+
|
169
|
+
# These attributes can be set and read
|
170
|
+
resource.custom_id = 'user1' # A string
|
171
|
+
resource.username = 'user1' # A string
|
172
|
+
|
173
|
+
resource.save
|
174
|
+
|
175
|
+
# These attributes are read-only
|
176
|
+
resource.id
|
177
|
+
# => "1cad3055-1027-459d-b76e-f590dc5f0071"
|
178
|
+
resource.created_at
|
179
|
+
# => #<DateTime: 2018-07-17T12:51:28+00:00 ((2458317j,46288s,0n),+0s,2299161j)>
|
180
|
+
resource.plugins
|
181
|
+
# => #<SkullIsland::ResourceCollection:0x00007f9f1e564f3e...
|
182
|
+
```
|
183
|
+
|
184
|
+
#### Plugins
|
185
|
+
|
186
|
+
Note that this doesn't _install_ plugins; it only allows using them.
|
187
|
+
|
188
|
+
```ruby
|
189
|
+
resource = Resources::Plugin.new
|
190
|
+
|
191
|
+
# These attributes can be set and read
|
192
|
+
resource.name = 'rate-limiting' # The name of the plugin
|
193
|
+
resource.enabled = true # A Boolean
|
194
|
+
resource.config = { 'minute' => 50, 'hour' => 1000 } # A Hash of config keys and values
|
195
|
+
|
196
|
+
# Either reference related resources by ID
|
197
|
+
resource.service = { 'id' => '5fd1z584-1adb-40a5-c042-63b19db49x21' }
|
198
|
+
resource.service
|
199
|
+
# => #<SkullIsland::Resources::Services:0x00007f9f201f6f44...
|
200
|
+
|
201
|
+
# Or reference related resources directly
|
202
|
+
resource.consumer = Resources::Consumer.get('a3dX2dh2-1adb-40a5-c042-63b19dbx83hF4')
|
203
|
+
resource.consumer
|
204
|
+
# => #<SkullIsland::Resources::Consumer:0x00007f9f201f6f98...
|
205
|
+
|
206
|
+
resource.route = Resources::Route.get('1cad3055-1027-459d-b76e-f590dc5f0023')
|
207
|
+
resource.route
|
208
|
+
# => #<SkullIsland::Resources::Route:0x00007f9f201f6f98...
|
209
|
+
|
210
|
+
resource.save
|
211
|
+
|
212
|
+
# These attributes are read-only
|
213
|
+
resource.id
|
214
|
+
# => "1cad3055-1027-459d-b76e-f590dc5f0071"
|
215
|
+
resource.created_at
|
216
|
+
# => #<DateTime: 2018-07-17T12:51:28+00:00 ((2458317j,46288s,0n),+0s,2299161j)>
|
217
|
+
|
218
|
+
# The resource class itself allows the following methods as well:
|
219
|
+
|
220
|
+
# This provides a list of plugin names that are enabled
|
221
|
+
Resources::Plugin.enabled_names
|
222
|
+
# => ["response-transformer",...
|
223
|
+
|
224
|
+
# This looks up the configuration schema for a particular plugin by its name
|
225
|
+
Resources::Plugin.schema('acl')
|
226
|
+
# => {"fields"=>{"hide_groups_header"=>{"default"=>false...
|
227
|
+
```
|
228
|
+
|
229
|
+
#### Routes
|
230
|
+
|
231
|
+
```ruby
|
232
|
+
resource = Resources::Route.new
|
233
|
+
|
234
|
+
# These attributes can be set and read
|
235
|
+
resource.hosts = ['example.com', 'example.org']
|
236
|
+
resource.protocols = ['https']
|
237
|
+
resource.methods = ['GET', 'POST']
|
238
|
+
resource.paths = ['/some/path']
|
239
|
+
resource.regex_priority = 10
|
240
|
+
resource.strip_path = false
|
241
|
+
resource.preserve_host = true
|
242
|
+
|
243
|
+
# Either reference related resources by ID
|
244
|
+
resource.service = { 'id' => '4e13f54a-bbf1-47a8-8777-255fed7116f2' }
|
245
|
+
# Or reference related resources directly
|
246
|
+
resource.service = Resources::Service.get('4e13f54a-bbf1-47a8-8777-255fed7116f2')
|
247
|
+
resource.service
|
248
|
+
# => #<SkullIsland::Resources::Service:0x00007f9f201f6f98...
|
249
|
+
|
250
|
+
resource.save
|
251
|
+
|
252
|
+
# These attributes are read-only
|
253
|
+
resource.id
|
254
|
+
# => "1cad3055-1027-459d-b76e-f590dc5f0071"
|
255
|
+
resource.created_at
|
256
|
+
# => #<DateTime: 2018-07-17T12:51:28+00:00 ((2458317j,46288s,0n),+0s,2299161j)>
|
257
|
+
resource.updated_at
|
258
|
+
# => #<DateTime: 2018-07-17T12:51:28+00:00 ((2458317j,46288s,0n),+0s,2299161j)>
|
259
|
+
resource.plugins
|
260
|
+
# => #<SkullIsland::ResourceCollection:0x00007f9f1e564f3e...
|
261
|
+
```
|
262
|
+
|
263
|
+
#### Services
|
264
|
+
|
265
|
+
```ruby
|
266
|
+
resource = Resources::Service.new
|
267
|
+
|
268
|
+
# These attributes can be set and read
|
269
|
+
resource.protocol = 'http'
|
270
|
+
resource.connect_timeout = 60000
|
271
|
+
resource.host = 'example.com'
|
272
|
+
resource.port = 80
|
273
|
+
resource.path = '/api'
|
274
|
+
resource.name = 'example-service'
|
275
|
+
resource.retries = 10
|
276
|
+
resource.read_timeout = 60000
|
277
|
+
resource.write_timeout = 60000
|
278
|
+
|
279
|
+
resource.save
|
280
|
+
|
281
|
+
# Add a related route
|
282
|
+
my_route = Resources::Route.get(...)
|
283
|
+
resource.add_route!(my_route) # adds a route to the service
|
284
|
+
# => true
|
285
|
+
|
286
|
+
# These attributes are read-only
|
287
|
+
resource.id
|
288
|
+
# => "1cad3055-1027-459d-b76e-f590dc5f0071"
|
289
|
+
resource.created_at
|
290
|
+
# => #<DateTime: 2018-07-17T12:51:28+00:00 ((2458317j,46288s,0n),+0s,2299161j)>
|
291
|
+
resource.updated_at
|
292
|
+
# => #<DateTime: 2018-07-17T12:51:28+00:00 ((2458317j,46288s,0n),+0s,2299161j)>
|
293
|
+
resource.routes
|
294
|
+
# => #<SkullIsland::ResourceCollection:0x00007f9f1e564f3f...
|
295
|
+
resource.plugins
|
296
|
+
# => #<SkullIsland::ResourceCollection:0x00007f9f1e564f3e...
|
297
|
+
```
|
298
|
+
|
299
|
+
#### Upstreams (and their Targets)
|
300
|
+
|
301
|
+
```ruby
|
302
|
+
resource = Resources::Upstream.new
|
303
|
+
|
304
|
+
# These attributes can be set and read
|
305
|
+
resource.name = 'service.v1.xyz'
|
306
|
+
resource.hash_on = 'none'
|
307
|
+
resource.hash_fallback = 'none'
|
308
|
+
resource.slots = 1000
|
309
|
+
resource.healthchecks = {
|
310
|
+
'active' => {
|
311
|
+
'concurrency' => 5,
|
312
|
+
'healthy' => {
|
313
|
+
'http_statuses' => [200, 302],
|
314
|
+
'interval' => 0,
|
315
|
+
'successes' => 0
|
316
|
+
},
|
317
|
+
'http_path' => '/',
|
318
|
+
'timeout' => 1,
|
319
|
+
'unhealthy' => {
|
320
|
+
'http_failures' => 0,
|
321
|
+
'http_statuses' => [
|
322
|
+
429, 404, 500, 501, 502, 503, 504, 505
|
323
|
+
],
|
324
|
+
'interval' => 0,
|
325
|
+
'tcp_failures' => 0,
|
326
|
+
'timeouts' => 0
|
327
|
+
}
|
328
|
+
}
|
329
|
+
}
|
330
|
+
|
331
|
+
resource.save
|
332
|
+
|
333
|
+
my_upstream_node = Resources::UpstreamTarget.new
|
334
|
+
my_upstream_node.target = '4.5.6.7:80'
|
335
|
+
my_upstream_node.weight = 15
|
336
|
+
resource.add_target!(my_upstream_node) # adds a target to the upstream
|
337
|
+
# => true
|
338
|
+
|
339
|
+
# These attributes are read-only
|
340
|
+
resource.id
|
341
|
+
# => "1cad3055-1027-459d-b76e-f590dc5f0071"
|
342
|
+
resource.created_at
|
343
|
+
# => #<DateTime: 2018-07-17T12:51:28+00:00 ((2458317j,46288s,0n),+0s,2299161j)>
|
344
|
+
resource.health # returns a Hash of all upstream targets and their health statuses
|
345
|
+
# => #<Hash...
|
346
|
+
resource.targets
|
347
|
+
# => #<SkullIsland::ResourceCollection:0x00007f9f1e564f3f...
|
348
|
+
resource.target('1bef3055-1027-459d-b76e-f590dc5f0071') # get an Upstream Target by id
|
349
|
+
```
|
4
350
|
|
5
351
|
## License
|
6
352
|
|
data/Rakefile
CHANGED
@@ -1,6 +1,16 @@
|
|
1
|
-
|
2
|
-
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'bundler/gem_tasks'
|
4
|
+
require 'rspec/core/rake_task'
|
5
|
+
require 'rubocop/rake_task'
|
6
|
+
require 'yard'
|
3
7
|
|
4
8
|
RSpec::Core::RakeTask.new(:spec)
|
9
|
+
RuboCop::RakeTask.new(:rubocop)
|
10
|
+
YARD::Rake::YardocTask.new do |y|
|
11
|
+
y.options = [
|
12
|
+
'--markup', 'markdown'
|
13
|
+
]
|
14
|
+
end
|
5
15
|
|
6
|
-
task :
|
16
|
+
task default: %i[spec rubocop yard]
|
data/bin/console
CHANGED
@@ -1,7 +1,8 @@
|
|
1
1
|
#!/usr/bin/env ruby
|
2
|
+
# frozen_string_literal: true
|
2
3
|
|
3
|
-
require
|
4
|
-
require
|
4
|
+
require 'bundler/setup'
|
5
|
+
require 'skull_island'
|
5
6
|
|
6
7
|
# You can add fixtures and/or initialization code here to make experimenting
|
7
8
|
# with your gem easier. You can also use a different console, if you like.
|
@@ -10,5 +11,5 @@ require "skull_island"
|
|
10
11
|
# require "pry"
|
11
12
|
# Pry.start
|
12
13
|
|
13
|
-
require
|
14
|
+
require 'irb'
|
14
15
|
IRB.start(__FILE__)
|
@@ -0,0 +1,30 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module CoreExtensions
|
4
|
+
module String
|
5
|
+
# Monkey-patches for String to add some simple missing transformations
|
6
|
+
module Transformations
|
7
|
+
# Convert CamelCase to underscored_text
|
8
|
+
# @return [String]
|
9
|
+
def to_underscore
|
10
|
+
gsub(/::/, '/')
|
11
|
+
.gsub(/([A-Z]+)([A-Z][a-z])/, '\1_\2')
|
12
|
+
.gsub(/([a-z\d])([A-Z])/, '\1_\2')
|
13
|
+
.tr('-', '_')
|
14
|
+
.downcase
|
15
|
+
end
|
16
|
+
|
17
|
+
# Convert underscored_text to CamelCase
|
18
|
+
# @return [String]
|
19
|
+
def to_camel
|
20
|
+
split('_').map(&:capitalize).join
|
21
|
+
end
|
22
|
+
|
23
|
+
# Attempt to guess a more human-like view of a string
|
24
|
+
# @return [String]
|
25
|
+
def humanize
|
26
|
+
gsub(/_id$/, '').tr('_', ' ').capitalize
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
@@ -0,0 +1,36 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module SkullIsland
|
4
|
+
# The API Client Singleton class
|
5
|
+
class APIClient < APIClientBase
|
6
|
+
include Singleton
|
7
|
+
|
8
|
+
def self.configure(opts = {})
|
9
|
+
instance.configure(opts)
|
10
|
+
end
|
11
|
+
|
12
|
+
def self.about_service
|
13
|
+
instance.about_service
|
14
|
+
end
|
15
|
+
|
16
|
+
def self.lru_cache
|
17
|
+
instance.lru_cache
|
18
|
+
end
|
19
|
+
|
20
|
+
def self.server_status
|
21
|
+
instance.server_status
|
22
|
+
end
|
23
|
+
|
24
|
+
def configure(opts = {})
|
25
|
+
# validations
|
26
|
+
validate_opts(opts)
|
27
|
+
|
28
|
+
# Set up the client's state
|
29
|
+
@server = opts[:server] || 'http://localhost:8001'
|
30
|
+
@username = opts[:username]
|
31
|
+
@password = opts[:password]
|
32
|
+
@cache = LRUCache.new(1000) # LRU cache of up to 1000 items
|
33
|
+
@configured = true
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|