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.
Files changed (43) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +1 -0
  3. data/.rubocop.yml +39 -0
  4. data/.travis.yml +9 -2
  5. data/Gemfile +3 -1
  6. data/Gemfile.lock +127 -0
  7. data/README.md +348 -2
  8. data/Rakefile +13 -3
  9. data/bin/console +4 -3
  10. data/lib/core_extensions/string/transformations.rb +30 -0
  11. data/lib/skull_island/api_client.rb +36 -0
  12. data/lib/skull_island/api_client_base.rb +86 -0
  13. data/lib/skull_island/api_exception.rb +7 -0
  14. data/lib/skull_island/exceptions/api_client_not_configured.rb +9 -0
  15. data/lib/skull_island/exceptions/immutable_modification.rb +9 -0
  16. data/lib/skull_island/exceptions/invalid_arguments.rb +9 -0
  17. data/lib/skull_island/exceptions/invalid_cache_size.rb +9 -0
  18. data/lib/skull_island/exceptions/invalid_options.rb +9 -0
  19. data/lib/skull_island/exceptions/invalid_property.rb +9 -0
  20. data/lib/skull_island/exceptions/invalid_where_query.rb +9 -0
  21. data/lib/skull_island/exceptions/new_instance_with_id.rb +9 -0
  22. data/lib/skull_island/helpers/api_client.rb +64 -0
  23. data/lib/skull_island/helpers/resource.rb +178 -0
  24. data/lib/skull_island/helpers/resource_class.rb +74 -0
  25. data/lib/skull_island/lru_cache.rb +175 -0
  26. data/lib/skull_island/resource.rb +198 -0
  27. data/lib/skull_island/resource_collection.rb +193 -0
  28. data/lib/skull_island/resources/certificate.rb +36 -0
  29. data/lib/skull_island/resources/consumer.rb +20 -0
  30. data/lib/skull_island/resources/plugin.rb +144 -0
  31. data/lib/skull_island/resources/route.rb +83 -0
  32. data/lib/skull_island/resources/service.rb +94 -0
  33. data/lib/skull_island/resources/upstream.rb +129 -0
  34. data/lib/skull_island/resources/upstream_target.rb +86 -0
  35. data/lib/skull_island/rspec/fake_api_client.rb +63 -0
  36. data/lib/skull_island/rspec.rb +3 -0
  37. data/lib/skull_island/simple_api_client.rb +18 -0
  38. data/lib/skull_island/validations/api_client.rb +45 -0
  39. data/lib/skull_island/validations/resource.rb +24 -0
  40. data/lib/skull_island/version.rb +3 -1
  41. data/lib/skull_island.rb +47 -1
  42. data/skull_island.gemspec +16 -13
  43. metadata +66 -7
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: bb050b692cd4d7b01b5b1177d76199bd53c722b63dff53eaf86b09a60d9304df
4
- data.tar.gz: 32fe27433b89c0fd2190666519d0f9c45ce8a63fbc0ac605feffcdfafb7c445c
3
+ metadata.gz: 19ab037beb02518e751019c8d59bd81cdf9165b373ea5b31287ed6dc829a4f21
4
+ data.tar.gz: 1a352da5080eaae1ce030f872fcda1e53dbbbca2dfb39af5536db2cb1772fe8e
5
5
  SHA512:
6
- metadata.gz: c991510e113414534ea96b40fa9f66b510af040b7b772c61af92175562a2475ca9ec018c0b32ea0582cf11f286448ae9924525c56b2c3c441e8ce3e367de8cc4
7
- data.tar.gz: cec7bb4bade7e1cd158d3c79d319dc32ec75301c25152439fd891e063f120916bd055221ceabc95b3d849d2f0a6a315be326d8d74fed8fa5be456ec02af580bc
6
+ metadata.gz: f5f1d27b7b1114ccad775df93c7db93d42279fcdb085cf76323efb2f1c2d5aa09dc6a83132e4ab7dbc9eefd349b420ff10f9f7c3abc53fe39839aa18e787c9cb
7
+ data.tar.gz: ee44a34f72104f02785949a609919230d511e39dbb332ee96ed4c13ec95d800e240d098613570b49b2d0814ac6b81f86f4cc201dfdb8bed93de1cdc320e451c9
data/.gitignore CHANGED
@@ -9,3 +9,4 @@
9
9
 
10
10
  # rspec failure tracking
11
11
  .rspec_status
12
+ *.gem
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
- - 2.5.3
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
@@ -1,4 +1,6 @@
1
- source "https://rubygems.org"
1
+ # frozen_string_literal: true
2
+
3
+ source 'https://rubygems.org'
2
4
 
3
5
  # Specify your gem's dependencies in skull_island.gemspec
4
6
  gemspec
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
- # SkullIsland
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
- require "bundler/gem_tasks"
2
- require "rspec/core/rake_task"
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 :default => :spec
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 "bundler/setup"
4
- require "skull_island"
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 "irb"
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