skull_island 1.2.13 → 1.4.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/Gemfile.lock +6 -6
- data/README.md +54 -26
- data/lib/skull_island/cli.rb +13 -6
- data/lib/skull_island/helpers/cli_erb.rb +20 -0
- data/lib/skull_island/helpers/migration.rb +9 -1
- data/lib/skull_island/helpers/resource.rb +1 -1
- data/lib/skull_island/resources/access_control_list.rb +2 -2
- data/lib/skull_island/resources/basicauth_credential.rb +3 -3
- data/lib/skull_island/resources/ca_certificate.rb +71 -0
- data/lib/skull_island/resources/certificate.rb +2 -2
- data/lib/skull_island/resources/jwt_credential.rb +3 -5
- data/lib/skull_island/resources/keyauth_credential.rb +2 -2
- data/lib/skull_island/resources/plugin.rb +4 -4
- data/lib/skull_island/resources/route.rb +30 -8
- data/lib/skull_island/resources/service.rb +31 -3
- data/lib/skull_island/resources/upstream.rb +19 -0
- data/lib/skull_island/resources/upstream_target.rb +2 -2
- data/lib/skull_island/version.rb +2 -2
- data/lib/skull_island.rb +2 -0
- metadata +3 -1
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 1cd4dad5c51622b123e9a28d07515e340fd3bf2aa2633edc408df2eb7016eef2
|
4
|
+
data.tar.gz: 91f778ff415330fb0c8c2c6f3118c6c894a76c77b42338ff345ff0848b0fd332
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 820eb9e9833274cf58dce2b3200c55bdddb29adf331457141a76a517048b33e1ee86d823a0367f32207ec4ec4287046f9b2f35e4f35f12daebcd3a215eb163a8
|
7
|
+
data.tar.gz: 13027398c076a86a7eee66824e72ed848cd0bce3d063a4f6ac441929c79379541ef2946669385dc2fc6c5c0c50ee3d1c1d4e1a28349f4195c93a04061ab942b2
|
data/Gemfile.lock
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
PATH
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
|
-
skull_island (1.
|
4
|
+
skull_island (1.4.0)
|
5
5
|
deepsort (~> 0.4)
|
6
6
|
erubi (~> 1.8)
|
7
7
|
json (~> 2.1)
|
@@ -53,7 +53,7 @@ GEM
|
|
53
53
|
linguistics (2.1.0)
|
54
54
|
loggability (~> 0.11)
|
55
55
|
loggability (0.14.0)
|
56
|
-
mime-types (3.3
|
56
|
+
mime-types (3.3)
|
57
57
|
mime-types-data (~> 3.2015)
|
58
58
|
mime-types-data (3.2019.1009)
|
59
59
|
multi_json (1.14.1)
|
@@ -62,7 +62,7 @@ GEM
|
|
62
62
|
net-http-pipeline (1.0.1)
|
63
63
|
netrc (0.11.0)
|
64
64
|
parallel (1.19.1)
|
65
|
-
parser (2.
|
65
|
+
parser (2.6.5.0)
|
66
66
|
ast (~> 2.4.0)
|
67
67
|
pusher-client (0.6.2)
|
68
68
|
json
|
@@ -78,15 +78,15 @@ GEM
|
|
78
78
|
rspec-core (~> 3.9.0)
|
79
79
|
rspec-expectations (~> 3.9.0)
|
80
80
|
rspec-mocks (~> 3.9.0)
|
81
|
-
rspec-core (3.9.
|
82
|
-
rspec-support (~> 3.9.
|
81
|
+
rspec-core (3.9.0)
|
82
|
+
rspec-support (~> 3.9.0)
|
83
83
|
rspec-expectations (3.9.0)
|
84
84
|
diff-lcs (>= 1.2.0, < 2.0)
|
85
85
|
rspec-support (~> 3.9.0)
|
86
86
|
rspec-mocks (3.9.0)
|
87
87
|
diff-lcs (>= 1.2.0, < 2.0)
|
88
88
|
rspec-support (~> 3.9.0)
|
89
|
-
rspec-support (3.9.
|
89
|
+
rspec-support (3.9.0)
|
90
90
|
rubocop (0.78.0)
|
91
91
|
jaro_winkler (~> 1.5.1)
|
92
92
|
parallel (~> 1.10)
|
data/README.md
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
# Skull Island
|
2
2
|
|
3
|
-
A full-featured SDK for [Kong](https://konghq.com/kong/) 1.
|
3
|
+
A full-featured SDK for [Kong](https://konghq.com/kong/) 1.4.x (with support for migrating from 0.14.x, 1.1.x, and 1.2.x). Note that this is unofficial (meaning this project is in no way officially endorsed, recommended, or related to Kong [as a company](https://konghq.com/) or an [open-source project](https://github.com/Kong/kong)). It is also in no way related to the [pet toy company](https://www.kongcompany.com/) by the same name (but hopefully that was obvious).
|
4
4
|
|
5
5
|
![Gem](https://img.shields.io/gem/v/skull_island)
|
6
6
|
![Travis (.org)](https://img.shields.io/travis/jgnagy/skull_island)
|
@@ -30,7 +30,7 @@ gem install skull_island
|
|
30
30
|
Or add this to your Gemfile:
|
31
31
|
|
32
32
|
```ruby
|
33
|
-
gem 'skull_island', '~> 1.
|
33
|
+
gem 'skull_island', '~> 1.4'
|
34
34
|
```
|
35
35
|
|
36
36
|
Or add this to your .gemspec:
|
@@ -38,7 +38,7 @@ Or add this to your .gemspec:
|
|
38
38
|
```ruby
|
39
39
|
Gem::Specification.new do |spec|
|
40
40
|
# ...
|
41
|
-
spec.add_runtime_dependency 'skull_island', '~> 1.
|
41
|
+
spec.add_runtime_dependency 'skull_island', '~> 1.4'
|
42
42
|
# ...
|
43
43
|
end
|
44
44
|
```
|
@@ -47,7 +47,7 @@ end
|
|
47
47
|
|
48
48
|
Skull Island comes with an executable called `skull_island` that leverages the SDK under the hood. Learn about what it can do via `help`:
|
49
49
|
|
50
|
-
```
|
50
|
+
```sh
|
51
51
|
$ skull_island help
|
52
52
|
Commands:
|
53
53
|
skull_island export [OPTIONS] [OUTPUT|-] # Export the current configuration to OUTPUT
|
@@ -63,7 +63,7 @@ Options:
|
|
63
63
|
|
64
64
|
To use the commands that interact with the Kong API, set environment variables for the required parameters:
|
65
65
|
|
66
|
-
```
|
66
|
+
```sh
|
67
67
|
KONG_ADMIN_URL='https://api-admin.mydomain.com' \
|
68
68
|
KONG_ADMIN_USERNAME='my-basicauth-user' \
|
69
69
|
KONG_ADMIN_PASSWORD='my-basicauth-password' \
|
@@ -74,7 +74,7 @@ Note that you can skip `KONG_ADMIN_USERNAME` and `KONG_ADMIN_PASSWORD` if you ar
|
|
74
74
|
|
75
75
|
Also note that if you're having SSL issues (such as with a private CA), you can have Ruby make use of a custom CA public key using `SSL_CERT_FILE`:
|
76
76
|
|
77
|
-
```
|
77
|
+
```sh
|
78
78
|
SSL_CERT_FILE=/path/to/cabundle.pem \
|
79
79
|
KONG_ADMIN_URL='https://api-admin.mydomain.com' \
|
80
80
|
KONG_ADMIN_USERNAME='my-basicauth-user' \
|
@@ -88,14 +88,14 @@ The CLI allows you to export an existing configuration to a YAML + ERB document
|
|
88
88
|
|
89
89
|
The `export` command will default to outputting to STDOUT if you don't provide an output file location. Otherwise, simply specify the filename you'd like to export to:
|
90
90
|
|
91
|
-
```
|
91
|
+
```sh
|
92
92
|
KONG_ADMIN_URL='https://api-admin.mydomain.com' \
|
93
93
|
skull_island export /path/to/export.yml
|
94
94
|
```
|
95
95
|
|
96
96
|
You can also get a little more information by turning on `--verbose`:
|
97
97
|
|
98
|
-
```
|
98
|
+
```sh
|
99
99
|
KONG_ADMIN_URL='https://api-admin.mydomain.com' \
|
100
100
|
skull_island export --verbose /path/to/export.yml
|
101
101
|
```
|
@@ -110,14 +110,14 @@ For most credential types, exporting works as expected (you'll see the plaintext
|
|
110
110
|
|
111
111
|
Skull Island also supports importing configurations (both partial and full) from a YAML + ERB document:
|
112
112
|
|
113
|
-
```
|
113
|
+
```sh
|
114
114
|
KONG_ADMIN_URL='https://api-admin.mydomain.com' \
|
115
115
|
skull_island import /path/to/export.yml
|
116
116
|
```
|
117
117
|
|
118
118
|
It'll also read from STDIN if you don't specify a file path (or if you specify `-` as the path):
|
119
119
|
|
120
|
-
```
|
120
|
+
```sh
|
121
121
|
cat /path/to/export.yml | KONG_ADMIN_URL='https://api-admin.mydomain.com' skull_island import
|
122
122
|
# OR
|
123
123
|
KONG_ADMIN_URL='https://api-admin.mydomain.com' skull_island import < /path/to/export.yml
|
@@ -125,14 +125,14 @@ KONG_ADMIN_URL='https://api-admin.mydomain.com' skull_island import < /path/to/e
|
|
125
125
|
|
126
126
|
You can also get a little more information by turning on `--verbose`:
|
127
127
|
|
128
|
-
```
|
128
|
+
```sh
|
129
129
|
KONG_ADMIN_URL='https://api-admin.mydomain.com' \
|
130
130
|
skull_island import --verbose /path/to/export.yml
|
131
131
|
```
|
132
132
|
|
133
133
|
Importing also supports a "dry run" functionality that shows you what it would do (but makes no changes) using `--test`:
|
134
134
|
|
135
|
-
```
|
135
|
+
```sh
|
136
136
|
KONG_ADMIN_URL='https://api-admin.mydomain.com' \
|
137
137
|
skull_island import --verbose --test /path/to/export.yml
|
138
138
|
```
|
@@ -141,7 +141,7 @@ Note that `--test` has a high likelihood of generating errors with a complicated
|
|
141
141
|
|
142
142
|
#### Importing with Projects
|
143
143
|
|
144
|
-
Skull Island 1.2.1
|
144
|
+
Skull Island 1.2.1 introduced the ability to use a special top-level key in the configuration called `project` that uses meta-data to track which resources belong to a project. This meta-data can safely be added at another time as this tool will "adopt" otherwise matching resources into a project.
|
145
145
|
|
146
146
|
To use this functionality, either add the `project` key to your configuration file (usually directly below the `version` key) with some value that will be unique on your gateway, or use `--project foo` (where `foo` is the name of your project) as a CLI flag.
|
147
147
|
|
@@ -149,17 +149,17 @@ When using the `project` feature of Skull Island, the CLI tool will automaticall
|
|
149
149
|
|
150
150
|
### Migrating
|
151
151
|
|
152
|
-
With Skull Island, it is possible to migrate a configuration from a 0.14.x
|
152
|
+
With Skull Island, it is possible to migrate a configuration from a 0.14.x, 1.1.x, or 1.2.x gateway to the most recent compatible gateway. If you have a previous export, you can just run `skull_island migrate /path/to/export.yml` and you'll receive a 1.4 compatible config on standard out. If you'd prefer, you can have that config written to a file as well (just like the export command) like so:
|
153
153
|
|
154
|
-
```
|
154
|
+
```sh
|
155
155
|
skull_island migrate /path/to/export.yml /output/location/migrated.yml
|
156
156
|
```
|
157
157
|
|
158
|
-
While this hasn't been heavily tested for all possible use-cases, any configuration generated or usable by the `'~> 0.14'` version of this gem should safely convert using the migration command. This tool also makes no guarantees about plugin functionality, configuration compatibility across versions, or that the same plugins are installed and available in your newer gateway. It should go without saying that you should **test and confirm** that all of your functionality was successfully migrated.
|
158
|
+
While this hasn't been heavily tested for all possible use-cases, any configuration generated or usable by the `'~> 0.14'` or `'~> 1.2'` version of this gem should safely convert using the migration command. This tool also makes no guarantees about plugin functionality, configuration compatibility across versions, or that the same plugins are installed and available in your newer gateway. It should go without saying that you should **test and confirm** that all of your functionality was successfully migrated.
|
159
159
|
|
160
|
-
If you don't have a previous export, you'll need to install an older version of this gem using `gem install --version '~> 0.14' skull_island`, then perform an `export`, then you can switch back to the latest version of the gem for migrating and importing.
|
160
|
+
If you don't have a previous export, you'll need to install an older version of this gem using something like `gem install --version '~> 0.14' skull_island`, then perform an `export`, then you can switch back to the latest version of the gem for migrating and importing.
|
161
161
|
|
162
|
-
While it would be possible to make migration _automatic_ for the `import` command, `skull_island` intentionally doesn't do this to avoid the appearance that the config is losslessly compatible across versions. In reality, the newer config version has additional features (like tagging) that
|
162
|
+
While it would be possible to make migration _automatic_ for the `import` command, `skull_island` intentionally doesn't do this to avoid the appearance that the config is losslessly compatible across versions. In reality, the newer config version has additional features (like tagging) that are used heavily by skull_island. It makes sense to this author to maintain the migration component and the normal functionality as distinct features to encourage the use of the newer capabilities in 1.1 and beyond.
|
163
163
|
|
164
164
|
### Reset A Gateway
|
165
165
|
|
@@ -167,7 +167,7 @@ Skull Island can completely clear the configuration from a Kong instance using t
|
|
167
167
|
|
168
168
|
Fully resetting a gateway looks like this:
|
169
169
|
|
170
|
-
```
|
170
|
+
```sh
|
171
171
|
skull_island reset --force
|
172
172
|
```
|
173
173
|
|
@@ -175,7 +175,7 @@ You can, of course, include `--verbose` to see `skull_island` do its work, thoug
|
|
175
175
|
|
176
176
|
You can also restrict the reset to just resources associated with a particular project using the `--project` flag:
|
177
177
|
|
178
|
-
```
|
178
|
+
```sh
|
179
179
|
skull_island reset --force --project foo
|
180
180
|
```
|
181
181
|
|
@@ -185,10 +185,10 @@ This assumes the project is called `foo`.
|
|
185
185
|
|
186
186
|
If you're wondering what version of `skull_island` is installed, use:
|
187
187
|
|
188
|
-
```
|
188
|
+
```sh
|
189
189
|
$ skull_island version
|
190
190
|
|
191
|
-
SkullIsland Version: 1.
|
191
|
+
SkullIsland Version: 1.4.1
|
192
192
|
```
|
193
193
|
|
194
194
|
### File Format
|
@@ -197,9 +197,14 @@ The import/export/migrate CLI functions produce YAML with support for embedded R
|
|
197
197
|
|
198
198
|
```yaml
|
199
199
|
---
|
200
|
-
version: '1.
|
200
|
+
version: '1.4'
|
201
201
|
project: FooV2
|
202
202
|
certificates: []
|
203
|
+
ca_certificates:
|
204
|
+
- cert: |-
|
205
|
+
-----BEGIN CERTIFICATE-----
|
206
|
+
MIIFUzCCA...
|
207
|
+
-----END CERTIFICATE-----
|
203
208
|
consumers:
|
204
209
|
- username: foo
|
205
210
|
custom_id: foo
|
@@ -265,9 +270,9 @@ plugins:
|
|
265
270
|
service: "<%= lookup :service, 'search_api' %>"
|
266
271
|
```
|
267
272
|
|
268
|
-
All top-level keys (other than `version` and `project`) require an Array as a parameter, either by providing a list of entries or an empty Array (`[]`). The above shows how to use the `lookup()` function to refer to another resource. This "looks up" the resource type (`service` in this case) by `name` (`search_api` in this case) and resolves its `id`. This function can also be used to lookup a `route` or `upstream` by its `name`, or a `consumer` by its `username`. Note that Kong itself doesn't _require_ `route` resources to have unique names, so you'll need to enforce that practice yourself for `lookup` to be useful for Routes.
|
273
|
+
All top-level keys (other than `version` and `project`) require an Array as a parameter, either by providing a list of entries or an empty Array (`[]`), or they can be omitted entirely which is the same as providing an empty Array. The above shows how to use the `lookup()` function to refer to another resource. This "looks up" the resource type (`service` in this case) by `name` (`search_api` in this case) and resolves its `id`. This function can also be used to lookup a `route` or `upstream` by its `name`, or a `consumer` by its `username`. Note that Kong itself doesn't _require_ `route` resources to have unique names, so you'll need to enforce that practice yourself for `lookup` to be useful for Routes.
|
269
274
|
|
270
|
-
Note that while this configuration looks a lot like the [DB-less](https://docs.konghq.com/1.
|
275
|
+
Note that while this configuration looks a lot like the [DB-less](https://docs.konghq.com/1.4.x/db-less-and-declarative-config/) configuration (and even may, at times, be interchangeable), this is merely a coincidence. **Skull Island doesn't support the DB-less mode for Kong.** This may potentially change in the future, but for now it is not a goal of this project.
|
271
276
|
|
272
277
|
#### Embedded Ruby
|
273
278
|
|
@@ -277,6 +282,8 @@ While technically _any_ Ruby is valid, the following are pretty helpful for temp
|
|
277
282
|
|
278
283
|
* `ENV.fetch('VARIABLE_NAME', 'default value')` - This allows looking up the environment variable `VARIABLE_NAME` and using its value, or, if it isn't defined, it uses `default value` as the value. With this we could change `host: api.example.com` to `host: <%= ENV.fetch('API_HOST', 'api.example.com') %>`. With this, if `API_HOST` is provided, it'll use that, otherwise it will default to `api.example.com`. This is especially helpful for sensitive information; you can version control the configuration but pass in things like credentials via environment variables at runtime.
|
279
284
|
|
285
|
+
Note also that 1.4.x and beyond of Skull Island support two phases of embedded ruby: first, a simple phase that treats the **entire file** as just text, allowing you to use the full power of ruby for things like loops, conditional logic, and more; the second phase is applied for individual attributes within the rendered YAML document. This is where the `lookup()` function above is used.
|
286
|
+
|
280
287
|
## SDK Usage
|
281
288
|
|
282
289
|
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:
|
@@ -391,7 +398,26 @@ service.routes.size
|
|
391
398
|
# => 4
|
392
399
|
```
|
393
400
|
|
394
|
-
From here, the SDK mostly wraps the attributes described in the [Kong API Docs](https://docs.konghq.com/1.
|
401
|
+
From here, the SDK mostly wraps the attributes described in the [Kong API Docs](https://docs.konghq.com/1.4.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.
|
402
|
+
|
403
|
+
#### CA Certificates
|
404
|
+
|
405
|
+
These are used by the gateway to verify upstream certificates when connecting to them via HTTPS. These are not used to allow Kong to _generate_ certificates. Thus, there is only a public key (`cert`) attribute for this resource.
|
406
|
+
|
407
|
+
```ruby
|
408
|
+
resource = Resources::CACertificate.new
|
409
|
+
|
410
|
+
# These attributes can be set and read
|
411
|
+
resource.cert = '-----BEGIN CERTIFICATE-----...' # PEM-encoded public key
|
412
|
+
resource.tags = ['production', 'example'] # Array of tags
|
413
|
+
resource.save
|
414
|
+
|
415
|
+
# These attributes are read-only
|
416
|
+
resource.id
|
417
|
+
# => "1cad3055-1027-459d-b76e-f590dc5f0071"
|
418
|
+
resource.created_at
|
419
|
+
# => #<DateTime: 2018-07-17T12:51:28+00:00 ((2458317j,46288s,0n),+0s,2299161j)>
|
420
|
+
```
|
395
421
|
|
396
422
|
#### Certificates
|
397
423
|
|
@@ -554,6 +580,7 @@ resource = Resources::Service.new
|
|
554
580
|
|
555
581
|
# These attributes can be set and read
|
556
582
|
resource.protocol = 'http'
|
583
|
+
resource.client_certificate = { 'id' => '77e32ff2-...' }
|
557
584
|
resource.connect_timeout = 60000
|
558
585
|
resource.host = 'example.com'
|
559
586
|
resource.port = 80
|
@@ -591,6 +618,7 @@ resource = Resources::Upstream.new
|
|
591
618
|
|
592
619
|
# These attributes can be set and read
|
593
620
|
resource.name = 'service.v1.xyz'
|
621
|
+
resource.algorithm = 'round-robin'
|
594
622
|
resource.hash_on = 'none'
|
595
623
|
resource.hash_fallback = 'none'
|
596
624
|
resource.slots = 1000
|
data/lib/skull_island/cli.rb
CHANGED
@@ -11,6 +11,7 @@ module SkullIsland
|
|
11
11
|
# Base CLI for SkullIsland
|
12
12
|
class CLI < Thor
|
13
13
|
include Helpers::Migration
|
14
|
+
include Helpers::CliErb
|
14
15
|
|
15
16
|
class_option :verbose, type: :boolean
|
16
17
|
|
@@ -29,10 +30,11 @@ module SkullIsland
|
|
29
30
|
|
30
31
|
validate_server_version
|
31
32
|
|
32
|
-
output = { 'version' => '1.
|
33
|
+
output = { 'version' => '1.4' }
|
33
34
|
output['project'] = options['project'] if options['project']
|
34
35
|
|
35
36
|
[
|
37
|
+
Resources::CACertificate,
|
36
38
|
Resources::Certificate,
|
37
39
|
Resources::Consumer,
|
38
40
|
Resources::Upstream,
|
@@ -54,7 +56,7 @@ module SkullIsland
|
|
54
56
|
raw ||= acquire_input(input_file, options['verbose'])
|
55
57
|
|
56
58
|
# rubocop:disable Security/YAMLLoad
|
57
|
-
input = YAML.load(raw)
|
59
|
+
input = YAML.load(erb_preprocess(raw))
|
58
60
|
# rubocop:enable Security/YAMLLoad
|
59
61
|
|
60
62
|
validate_config_version input['version']
|
@@ -63,12 +65,16 @@ module SkullIsland
|
|
63
65
|
input['project'] = options['project'] if options['project']
|
64
66
|
|
65
67
|
[
|
68
|
+
Resources::CACertificate,
|
66
69
|
Resources::Certificate,
|
67
70
|
Resources::Consumer,
|
68
71
|
Resources::Upstream,
|
69
72
|
Resources::Service,
|
70
73
|
Resources::Plugin
|
71
|
-
].each
|
74
|
+
].each do |clname|
|
75
|
+
input[clname.route_key] = [] unless input[clname.route_key] # enforce all top-level keys
|
76
|
+
import_class(clname, input, import_time)
|
77
|
+
end
|
72
78
|
end
|
73
79
|
|
74
80
|
desc(
|
@@ -117,6 +123,7 @@ module SkullIsland
|
|
117
123
|
warn '[WARN] ! FULLY Resetting gateway'
|
118
124
|
end
|
119
125
|
[
|
126
|
+
Resources::CACertificate,
|
120
127
|
Resources::Certificate,
|
121
128
|
Resources::Consumer,
|
122
129
|
Resources::Upstream,
|
@@ -184,9 +191,9 @@ module SkullIsland
|
|
184
191
|
end
|
185
192
|
|
186
193
|
def validate_config_version(version)
|
187
|
-
if version && ['1.
|
194
|
+
if version && ['1.4'].include?(version)
|
188
195
|
validate_server_version
|
189
|
-
elsif version && ['0.14', '1.0'].include?(version)
|
196
|
+
elsif version && ['0.14', '1.0', '1.1', '1.2'].include?(version)
|
190
197
|
warn '[CRITICAL] Config version is too old. Try `migrate` instead of `import`.'
|
191
198
|
exit 2
|
192
199
|
else
|
@@ -206,7 +213,7 @@ module SkullIsland
|
|
206
213
|
|
207
214
|
def validate_server_version
|
208
215
|
server_version = SkullIsland::APIClient.about_service['version']
|
209
|
-
if server_version.match?(/^1.[
|
216
|
+
if server_version.match?(/^1.[4]/)
|
210
217
|
true
|
211
218
|
else
|
212
219
|
warn '[CRITICAL] Server version mismatch!'
|
@@ -0,0 +1,20 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module SkullIsland
|
4
|
+
module Helpers
|
5
|
+
# Performs a simple, first pass ERb preprocess on the entire input file for the CLI
|
6
|
+
module CliErb
|
7
|
+
def erb_preprocess(input)
|
8
|
+
warn '[INFO] Preprocessing template' if options['verbose']
|
9
|
+
# rubocop:disable Security/Eval
|
10
|
+
eval(Erubi::Engine.new(input).src)
|
11
|
+
# rubocop:enable Security/Eval
|
12
|
+
end
|
13
|
+
|
14
|
+
# At this phase, we want to leave this alone...
|
15
|
+
def lookup(type, value)
|
16
|
+
"<%= lookup :#{type}, '#{value}' %>"
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
@@ -6,7 +6,9 @@ module SkullIsland
|
|
6
6
|
module Migration
|
7
7
|
def migrate_config(config)
|
8
8
|
if config['version'] == '0.14'
|
9
|
-
migrate_0_14_to_1_1(config)
|
9
|
+
migrate_config migrate_0_14_to_1_1(config)
|
10
|
+
elsif ['1.1', '1.2', '1.3'].include?(config['version'])
|
11
|
+
migrate_1_1_to_1_4(config)
|
10
12
|
else
|
11
13
|
false # Just return false if it can't be migrated
|
12
14
|
end
|
@@ -29,6 +31,12 @@ module SkullIsland
|
|
29
31
|
new_config['version'] = '1.1'
|
30
32
|
new_config
|
31
33
|
end
|
34
|
+
|
35
|
+
def migrate_1_1_to_1_4(config)
|
36
|
+
new_config = config.dup
|
37
|
+
new_config['version'] = '1.4'
|
38
|
+
new_config
|
39
|
+
end
|
32
40
|
end
|
33
41
|
end
|
34
42
|
end
|
@@ -21,8 +21,8 @@ module SkullIsland
|
|
21
21
|
|
22
22
|
data.each_with_index do |resource_data, index|
|
23
23
|
resource = new
|
24
|
-
resource.delayed_set(:group, resource_data
|
25
|
-
resource.delayed_set(:consumer, resource_data
|
24
|
+
resource.delayed_set(:group, resource_data)
|
25
|
+
resource.delayed_set(:consumer, resource_data)
|
26
26
|
resource.import_update_or_skip(index: index, verbose: verbose, test: test)
|
27
27
|
known_ids << resource.id
|
28
28
|
end
|
@@ -24,9 +24,9 @@ module SkullIsland
|
|
24
24
|
|
25
25
|
data.each_with_index do |resource_data, index|
|
26
26
|
resource = new
|
27
|
-
resource.delayed_set(:username, resource_data
|
28
|
-
resource.delayed_set(:password, resource_data
|
29
|
-
resource.delayed_set(:consumer, resource_data
|
27
|
+
resource.delayed_set(:username, resource_data)
|
28
|
+
resource.delayed_set(:password, resource_data) if resource_data['password']
|
29
|
+
resource.delayed_set(:consumer, resource_data)
|
30
30
|
resource.import_update_or_skip(index: index, verbose: verbose, test: test)
|
31
31
|
known_ids << resource.id
|
32
32
|
end
|
@@ -0,0 +1,71 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module SkullIsland
|
4
|
+
# Resource classes go here...
|
5
|
+
module Resources
|
6
|
+
# The CA Certificate resource class
|
7
|
+
#
|
8
|
+
# @see https://docs.konghq.com/1.4.x/admin-api/#ca-certificate-object CA Certificate definition
|
9
|
+
class CACertificate < Resource
|
10
|
+
include Helpers::Meta
|
11
|
+
|
12
|
+
property :cert, required: true, validate: true
|
13
|
+
property :created_at, read_only: true, postprocess: true
|
14
|
+
property :tags, validate: true, preprocess: true, postprocess: true
|
15
|
+
|
16
|
+
def self.batch_import(data, verbose: false, test: false, project: nil, time: nil)
|
17
|
+
raise(Exceptions::InvalidArguments) unless data.is_a?(Array)
|
18
|
+
|
19
|
+
known_ids = []
|
20
|
+
|
21
|
+
data.each_with_index do |resource_data, index|
|
22
|
+
resource = new
|
23
|
+
resource.delayed_set(:cert, resource_data)
|
24
|
+
resource.tags = resource_data['tags'] if resource_data['tags']
|
25
|
+
resource.project = project if project
|
26
|
+
resource.import_time = (time || Time.now.utc.to_i) if project
|
27
|
+
resource.import_update_or_skip(index: index, verbose: verbose, test: test)
|
28
|
+
known_ids << resource.id
|
29
|
+
end
|
30
|
+
|
31
|
+
cleanup_except(project, known_ids) if project
|
32
|
+
end
|
33
|
+
|
34
|
+
def export(options = {})
|
35
|
+
hash = { 'cert' => cert }
|
36
|
+
hash['tags'] = tags unless tags.empty?
|
37
|
+
[*options[:exclude]].each do |exclude|
|
38
|
+
hash.delete(exclude.to_s)
|
39
|
+
end
|
40
|
+
[*options[:include]].each do |inc|
|
41
|
+
hash[inc.to_s] = send(inc.to_sym)
|
42
|
+
end
|
43
|
+
hash.reject { |_, value| value.nil? }
|
44
|
+
end
|
45
|
+
|
46
|
+
def modified_existing?
|
47
|
+
return false unless new?
|
48
|
+
|
49
|
+
# Find CA certs of the same cert
|
50
|
+
same_cert = self.class.where(:cert, cert)
|
51
|
+
|
52
|
+
existing = same_cert.size == 1 ? same_cert.first : nil
|
53
|
+
|
54
|
+
if existing
|
55
|
+
@entity['id'] = existing.id
|
56
|
+
save
|
57
|
+
else
|
58
|
+
false
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
private
|
63
|
+
|
64
|
+
# Used to validate {#cert} on set
|
65
|
+
def validate_cert(value)
|
66
|
+
# only String is allowed
|
67
|
+
value.is_a?(String)
|
68
|
+
end
|
69
|
+
end
|
70
|
+
end
|
71
|
+
end
|
@@ -24,8 +24,8 @@ module SkullIsland
|
|
24
24
|
|
25
25
|
data.each_with_index do |resource_data, index|
|
26
26
|
resource = new
|
27
|
-
resource.delayed_set(:cert, resource_data
|
28
|
-
resource.delayed_set(:key, resource_data
|
27
|
+
resource.delayed_set(:cert, resource_data)
|
28
|
+
resource.delayed_set(:key, resource_data)
|
29
29
|
resource.snis = resource_data['snis'] if resource_data['snis']
|
30
30
|
resource.tags = resource_data['tags'] if resource_data['tags']
|
31
31
|
resource.project = project if project
|
@@ -25,11 +25,9 @@ module SkullIsland
|
|
25
25
|
data.each_with_index do |resource_data, index|
|
26
26
|
resource = new
|
27
27
|
resource.algorithm = resource_data['algorithm']
|
28
|
-
resource.delayed_set(:key, resource_data
|
29
|
-
resource.delayed_set(:secret, resource_data
|
30
|
-
if resource_data['rsa_public_key']
|
31
|
-
resource.delayed_set(:rsa_public_key, resource_data, 'rsa_public_key')
|
32
|
-
end
|
28
|
+
resource.delayed_set(:key, resource_data) if resource_data['key']
|
29
|
+
resource.delayed_set(:secret, resource_data) if resource_data['secret']
|
30
|
+
resource.delayed_set(:rsa_public_key, resource_data) if resource_data['rsa_public_key']
|
33
31
|
resource.delayed_set(:consumer, resource_data, 'consumer')
|
34
32
|
resource.import_update_or_skip(index: index, verbose: verbose, test: test)
|
35
33
|
known_ids << resource.id
|
@@ -21,8 +21,8 @@ module SkullIsland
|
|
21
21
|
|
22
22
|
data.each_with_index do |resource_data, index|
|
23
23
|
resource = new
|
24
|
-
resource.delayed_set(:key, resource_data
|
25
|
-
resource.delayed_set(:consumer, resource_data
|
24
|
+
resource.delayed_set(:key, resource_data)
|
25
|
+
resource.delayed_set(:consumer, resource_data)
|
26
26
|
resource.import_update_or_skip(index: index, verbose: verbose, test: test)
|
27
27
|
known_ids << resource.id
|
28
28
|
end
|
@@ -31,13 +31,13 @@ module SkullIsland
|
|
31
31
|
resource.name = resource_data['name']
|
32
32
|
resource.enabled = resource_data['enabled']
|
33
33
|
resource.run_on = resource_data['run_on'] if resource_data['run_on']
|
34
|
-
resource.delayed_set(:config, resource_data
|
34
|
+
resource.delayed_set(:config, resource_data) if resource_data['config']
|
35
35
|
resource.tags = resource_data['tags'] if resource_data['tags']
|
36
36
|
resource.project = project if project
|
37
37
|
resource.import_time = (time || Time.now.utc.to_i) if project
|
38
|
-
resource.delayed_set(:consumer, resource_data
|
39
|
-
resource.delayed_set(:route, resource_data
|
40
|
-
resource.delayed_set(:service, resource_data
|
38
|
+
resource.delayed_set(:consumer, resource_data)
|
39
|
+
resource.delayed_set(:route, resource_data)
|
40
|
+
resource.delayed_set(:service, resource_data)
|
41
41
|
resource.import_update_or_skip(index: index, verbose: verbose, test: test)
|
42
42
|
known_ids << resource.id
|
43
43
|
end
|
@@ -5,7 +5,7 @@ module SkullIsland
|
|
5
5
|
module Resources
|
6
6
|
# The Route resource class
|
7
7
|
#
|
8
|
-
# @see https://docs.konghq.com/1.
|
8
|
+
# @see https://docs.konghq.com/1.4.x/admin-api/#route-object Route API definition
|
9
9
|
class Route < Resource
|
10
10
|
include Helpers::Meta
|
11
11
|
|
@@ -13,7 +13,9 @@ module SkullIsland
|
|
13
13
|
property :methods
|
14
14
|
property :paths
|
15
15
|
property :protocols, validate: true
|
16
|
+
property :headers, validate: true
|
16
17
|
property :hosts, validate: true
|
18
|
+
property :https_redirect_status_code, validate: true
|
17
19
|
property :regex_priority, validate: true
|
18
20
|
property :strip_path, type: :boolean
|
19
21
|
property :preserve_host, type: :boolean
|
@@ -39,15 +41,19 @@ module SkullIsland
|
|
39
41
|
resource.methods = rdata['methods'] if rdata['methods']
|
40
42
|
resource.paths = rdata['paths'] if rdata['paths']
|
41
43
|
resource.protocols = rdata['protocols'] if rdata['protocols']
|
42
|
-
resource.delayed_set(:hosts, rdata
|
44
|
+
resource.delayed_set(:hosts, rdata) if rdata['hosts']
|
45
|
+
resource.delayed_set(:headers, rdata) if rdata['headers']
|
46
|
+
if rdata['https_redirect_status_code']
|
47
|
+
resource.https_redirect_status_code = rdata['https_redirect_status_code']
|
48
|
+
end
|
43
49
|
resource.regex_priority = rdata['regex_priority'] if rdata['regex_priority']
|
44
50
|
resource.strip_path = rdata['strip_path'] unless rdata['strip_path'].nil?
|
45
51
|
resource.preserve_host = rdata['preserve_host'] unless rdata['preserve_host'].nil?
|
46
|
-
resource.delayed_set(:snis, rdata
|
52
|
+
resource.delayed_set(:snis, rdata) if rdata['snis']
|
47
53
|
resource.tags = rdata['tags'] if rdata['tags']
|
48
54
|
resource.project = project if project
|
49
55
|
resource.import_time = (time || Time.now.utc.to_i) if project
|
50
|
-
resource.delayed_set(:service, rdata
|
56
|
+
resource.delayed_set(:service, rdata)
|
51
57
|
resource.import_update_or_skip(index: index, verbose: verbose, test: test)
|
52
58
|
known_ids << resource.id
|
53
59
|
end
|
@@ -71,12 +77,14 @@ module SkullIsland
|
|
71
77
|
'paths' => paths,
|
72
78
|
'protocols' => protocols,
|
73
79
|
'hosts' => hosts,
|
80
|
+
'https_redirect_status_code' => https_redirect_status_code,
|
74
81
|
'regex_priority' => regex_priority,
|
75
82
|
'strip_path' => strip_path?,
|
76
83
|
'preserve_host' => preserve_host?
|
77
84
|
}
|
78
85
|
hash['service'] = "<%= lookup :service, '#{service.name}' %>" if service
|
79
86
|
hash['snis'] = snis if snis && !snis.empty?
|
87
|
+
hash['headers'] = headers if headers && !headers.empty?
|
80
88
|
hash['tags'] = tags unless tags.empty?
|
81
89
|
[*options[:exclude]].each do |exclude|
|
82
90
|
hash.delete(exclude.to_s)
|
@@ -129,10 +137,19 @@ module SkullIsland
|
|
129
137
|
|
130
138
|
# Used to validate {#protocols} on set
|
131
139
|
def validate_protocols(value)
|
132
|
-
|
133
|
-
|
134
|
-
value.
|
135
|
-
|
140
|
+
valid_protos = %w[http https tls tcp grpc grpcs]
|
141
|
+
value.is_a?(Array) && # Must be an array
|
142
|
+
(1..4).cover?(value.size) && # Must be exactly 1..4 in size
|
143
|
+
value.uniq == value && # Must not have duplicate values
|
144
|
+
(value - valid_protos).empty? # Must only contain appropriate protocols
|
145
|
+
end
|
146
|
+
|
147
|
+
# Validates the {#headers} on set
|
148
|
+
def validate_headers(value)
|
149
|
+
value.is_a?(Hash) &&
|
150
|
+
value.keys.map(&:class).uniq == [String] &&
|
151
|
+
value.values.map(&:class).uniq == [Array] &&
|
152
|
+
value.values.map { |v| v.map(&:class) }.flatten.uniq == [String]
|
136
153
|
end
|
137
154
|
|
138
155
|
# Used to validate {#hosts} on set
|
@@ -144,6 +161,11 @@ module SkullIsland
|
|
144
161
|
true
|
145
162
|
end
|
146
163
|
|
164
|
+
# Validates the {#https_redirect_status_code} on set
|
165
|
+
def validate_https_redirect_status_code(value)
|
166
|
+
value.is_a?(Integer) && value <= 599 && value >= 100
|
167
|
+
end
|
168
|
+
|
147
169
|
# Used to validate {#regex_priority} on set
|
148
170
|
def validate_regex_priority(value)
|
149
171
|
# only positive Integers are allowed
|
@@ -18,6 +18,7 @@ module SkullIsland
|
|
18
18
|
property :connect_timeout, validate: true
|
19
19
|
property :write_timeout, validate: true
|
20
20
|
property :read_timeout, validate: true
|
21
|
+
property :client_certificate, validate: true, preprocess: true, postprocess: true
|
21
22
|
property :created_at, read_only: true, postprocess: true
|
22
23
|
property :updated_at, read_only: true, postprocess: true
|
23
24
|
property :tags, validate: true, preprocess: true, postprocess: true
|
@@ -35,12 +36,13 @@ module SkullIsland
|
|
35
36
|
resource.name = rdata['name']
|
36
37
|
resource.retries = rdata['retries'] if rdata['retries']
|
37
38
|
resource.protocol = rdata['protocol']
|
38
|
-
resource.delayed_set(:host, rdata
|
39
|
-
resource.delayed_set(:port, rdata
|
39
|
+
resource.delayed_set(:host, rdata)
|
40
|
+
resource.delayed_set(:port, rdata)
|
40
41
|
resource.path = rdata['path'] if rdata['path']
|
41
42
|
resource.connect_timeout = rdata['connect_timeout'] if rdata['connect_timeout']
|
42
43
|
resource.write_timeout = rdata['write_timeout'] if rdata['write_timeout']
|
43
44
|
resource.read_timeout = rdata['read_timeout'] if rdata['read_timeout']
|
45
|
+
resource.delayed_set(:client_certificate, rdata) if rdata['client_certificate']
|
44
46
|
resource.tags = rdata['tags'] if rdata['tags']
|
45
47
|
resource.project = project if project
|
46
48
|
resource.import_time = (time || Time.now.utc.to_i) if project
|
@@ -50,7 +52,9 @@ module SkullIsland
|
|
50
52
|
Route.batch_import(
|
51
53
|
(rdata['routes'] || []).map { |r| r.merge('service' => { 'id' => resource.id }) },
|
52
54
|
verbose: verbose,
|
53
|
-
test: test
|
55
|
+
test: test,
|
56
|
+
project: project,
|
57
|
+
time: time
|
54
58
|
)
|
55
59
|
end
|
56
60
|
|
@@ -83,6 +87,7 @@ module SkullIsland
|
|
83
87
|
Plugin.where(:service, self, api_client: api_client)
|
84
88
|
end
|
85
89
|
|
90
|
+
# rubocop:disable Metrics/AbcSize
|
86
91
|
def export(options = {})
|
87
92
|
hash = {
|
88
93
|
'name' => name,
|
@@ -97,6 +102,7 @@ module SkullIsland
|
|
97
102
|
}
|
98
103
|
hash['routes'] = routes.collect { |route| route.export(exclude: 'service') }
|
99
104
|
hash['tags'] = tags unless tags.empty?
|
105
|
+
hash['client_certificate'] = client_certificate if client_certificate
|
100
106
|
[*options[:exclude]].each do |exclude|
|
101
107
|
hash.delete(exclude.to_s)
|
102
108
|
end
|
@@ -105,6 +111,7 @@ module SkullIsland
|
|
105
111
|
end
|
106
112
|
hash.reject { |_, value| value.nil? }
|
107
113
|
end
|
114
|
+
# rubocop:enable Metrics/AbcSize
|
108
115
|
|
109
116
|
def modified_existing?
|
110
117
|
return false unless new?
|
@@ -139,6 +146,27 @@ module SkullIsland
|
|
139
146
|
|
140
147
|
private
|
141
148
|
|
149
|
+
def postprocess_client_certificate(value)
|
150
|
+
if value.is_a?(Hash)
|
151
|
+
Certificate.new(
|
152
|
+
entity: value,
|
153
|
+
lazy: true,
|
154
|
+
tainted: false,
|
155
|
+
api_client: api_client
|
156
|
+
)
|
157
|
+
else
|
158
|
+
value
|
159
|
+
end
|
160
|
+
end
|
161
|
+
|
162
|
+
def preprocess_client_certificate(input)
|
163
|
+
if input.is_a?(Hash)
|
164
|
+
input
|
165
|
+
else
|
166
|
+
{ 'id' => input.id }
|
167
|
+
end
|
168
|
+
end
|
169
|
+
|
142
170
|
# Used to validate {#protocol} on set
|
143
171
|
def validate_protocol(value)
|
144
172
|
# only HTTP and HTTPS are allowed
|
@@ -10,6 +10,7 @@ module SkullIsland
|
|
10
10
|
include Helpers::Meta
|
11
11
|
|
12
12
|
property :name, required: true, validate: true
|
13
|
+
property :algorithm, validate: true
|
13
14
|
property :slots, validate: true
|
14
15
|
property :hash_on, validate: true
|
15
16
|
property :hash_fallback, validate: true
|
@@ -18,6 +19,7 @@ module SkullIsland
|
|
18
19
|
property :hash_on_cookie, validate: true
|
19
20
|
property :hash_on_cookie_path, validate: true
|
20
21
|
property :healthchecks, validate: true
|
22
|
+
property :host_header, validate: true
|
21
23
|
property :created_at, read_only: true, postprocess: true
|
22
24
|
property :tags, validate: true, preprocess: true, postprocess: true
|
23
25
|
|
@@ -32,6 +34,7 @@ module SkullIsland
|
|
32
34
|
data.each_with_index do |rdata, index|
|
33
35
|
resource = new
|
34
36
|
resource.name = rdata['name']
|
37
|
+
resource.algorithm = rdata['algorithm'] if rdata['algorithm']
|
35
38
|
resource.slots = rdata['slots'] if rdata['slots']
|
36
39
|
resource.hash_on = rdata['hash_on']
|
37
40
|
resource.hash_fallback = rdata['hash_fallback'] if rdata['hash_fallback']
|
@@ -44,6 +47,7 @@ module SkullIsland
|
|
44
47
|
resource.hash_on_cookie_path = rdata['hash_on_cookie_path']
|
45
48
|
end
|
46
49
|
resource.healthchecks = rdata['healthchecks'] if rdata['healthchecks']
|
50
|
+
resource.host_header = rdata['host_header'] if rdata['host_header']
|
47
51
|
resource.tags = rdata['tags'] if rdata['tags']
|
48
52
|
resource.project = project if project
|
49
53
|
resource.import_time = (time || Time.now.utc.to_i) if project
|
@@ -111,6 +115,7 @@ module SkullIsland
|
|
111
115
|
)
|
112
116
|
end
|
113
117
|
|
118
|
+
# rubocop:disable Metrics/AbcSize
|
114
119
|
def export(options = {})
|
115
120
|
hash = {
|
116
121
|
'name' => name,
|
@@ -123,7 +128,9 @@ module SkullIsland
|
|
123
128
|
'hash_on_cookie_path' => hash_on_cookie_path,
|
124
129
|
'healthchecks' => healthchecks
|
125
130
|
}
|
131
|
+
hash['algorithm'] = algorithm if algorithm
|
126
132
|
hash['targets'] = targets.collect { |target| target.export(exclude: 'upstream') }
|
133
|
+
hash['host_header'] = host_header if host_header
|
127
134
|
hash['tags'] = tags unless tags.empty?
|
128
135
|
[*options[:exclude]].each do |exclude|
|
129
136
|
hash.delete(exclude.to_s)
|
@@ -133,6 +140,7 @@ module SkullIsland
|
|
133
140
|
end
|
134
141
|
hash.reject { |_, value| value.nil? }
|
135
142
|
end
|
143
|
+
# rubocop:enable Metrics/AbcSize
|
136
144
|
|
137
145
|
def modified_existing?
|
138
146
|
return false unless new?
|
@@ -152,6 +160,11 @@ module SkullIsland
|
|
152
160
|
|
153
161
|
private
|
154
162
|
|
163
|
+
# Validates the upstream balancing {#algorithm}
|
164
|
+
def validate_algorithm(value)
|
165
|
+
%w[round-robin consistent-hashing least-connections].include?(value)
|
166
|
+
end
|
167
|
+
|
155
168
|
# Used to validate {#hash_on} on set
|
156
169
|
def validate_hash_on(value)
|
157
170
|
# only String of an acceptable value are allowed
|
@@ -206,6 +219,12 @@ module SkullIsland
|
|
206
219
|
# only Hash is allowed
|
207
220
|
value.is_a?(Hash)
|
208
221
|
end
|
222
|
+
|
223
|
+
# Enforces valid host headers for upstreams
|
224
|
+
def validate_host_header(value)
|
225
|
+
# allow only valid hostnames
|
226
|
+
value.match?(host_regex) && !value.match?(/_/)
|
227
|
+
end
|
209
228
|
end
|
210
229
|
end
|
211
230
|
end
|
@@ -27,8 +27,8 @@ module SkullIsland
|
|
27
27
|
|
28
28
|
data.each_with_index do |resource_data, index|
|
29
29
|
resource = new
|
30
|
-
resource.delayed_set(:target, resource_data
|
31
|
-
resource.delayed_set(:upstream, resource_data
|
30
|
+
resource.delayed_set(:target, resource_data)
|
31
|
+
resource.delayed_set(:upstream, resource_data)
|
32
32
|
resource.weight = resource_data['weight'] if resource_data['weight']
|
33
33
|
resource.tags = resource_data['tags'] if resource_data['tags']
|
34
34
|
resource.project = project if project
|
data/lib/skull_island/version.rb
CHANGED
data/lib/skull_island.rb
CHANGED
@@ -39,6 +39,7 @@ require 'skull_island/api_client_base'
|
|
39
39
|
require 'skull_island/api_client'
|
40
40
|
require 'skull_island/simple_api_client'
|
41
41
|
require 'skull_island/resource_collection'
|
42
|
+
require 'skull_island/helpers/cli_erb'
|
42
43
|
require 'skull_island/helpers/meta'
|
43
44
|
require 'skull_island/helpers/resource'
|
44
45
|
require 'skull_island/helpers/resource_class'
|
@@ -46,6 +47,7 @@ require 'skull_island/helpers/migration'
|
|
46
47
|
require 'skull_island/validations/resource'
|
47
48
|
require 'skull_island/resource'
|
48
49
|
require 'skull_island/resources/access_control_list'
|
50
|
+
require 'skull_island/resources/ca_certificate'
|
49
51
|
require 'skull_island/resources/certificate'
|
50
52
|
require 'skull_island/resources/basicauth_credential'
|
51
53
|
require 'skull_island/resources/jwt_credential'
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: skull_island
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.
|
4
|
+
version: 1.4.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Jonathan Gnagy
|
@@ -257,6 +257,7 @@ files:
|
|
257
257
|
- lib/skull_island/exceptions/invalid_where_query.rb
|
258
258
|
- lib/skull_island/exceptions/new_instance_with_id.rb
|
259
259
|
- lib/skull_island/helpers/api_client.rb
|
260
|
+
- lib/skull_island/helpers/cli_erb.rb
|
260
261
|
- lib/skull_island/helpers/meta.rb
|
261
262
|
- lib/skull_island/helpers/migration.rb
|
262
263
|
- lib/skull_island/helpers/resource.rb
|
@@ -266,6 +267,7 @@ files:
|
|
266
267
|
- lib/skull_island/resource_collection.rb
|
267
268
|
- lib/skull_island/resources/access_control_list.rb
|
268
269
|
- lib/skull_island/resources/basicauth_credential.rb
|
270
|
+
- lib/skull_island/resources/ca_certificate.rb
|
269
271
|
- lib/skull_island/resources/certificate.rb
|
270
272
|
- lib/skull_island/resources/consumer.rb
|
271
273
|
- lib/skull_island/resources/jwt_credential.rb
|