3scale_toolbox 0.8.0 → 0.9.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/README.md +13 -1
- data/lib/3scale_toolbox/cli/error_handler.rb +0 -2
- data/lib/3scale_toolbox/commands/3scale_command.rb +0 -4
- data/lib/3scale_toolbox/commands/copy_command/copy_service.rb +5 -4
- data/lib/3scale_toolbox/commands/copy_command.rb +0 -2
- data/lib/3scale_toolbox/commands/help_command.rb +0 -3
- data/lib/3scale_toolbox/commands/import_command/import_csv.rb +0 -6
- data/lib/3scale_toolbox/commands/import_command/openapi/create_activedocs_step.rb +39 -2
- data/lib/3scale_toolbox/commands/import_command/openapi/create_method_step.rb +1 -1
- data/lib/3scale_toolbox/commands/import_command/openapi/create_service_step.rb +5 -16
- data/lib/3scale_toolbox/commands/import_command/openapi/mapping_rule.rb +11 -1
- data/lib/3scale_toolbox/commands/import_command/openapi/step.rb +4 -3
- data/lib/3scale_toolbox/commands/import_command/openapi/threescale_api_spec.rb +13 -2
- data/lib/3scale_toolbox/commands/import_command/openapi/update_policies_step.rb +63 -14
- data/lib/3scale_toolbox/commands/import_command/openapi/update_service_proxy_step.rb +6 -3
- data/lib/3scale_toolbox/commands/import_command/openapi.rb +11 -5
- data/lib/3scale_toolbox/commands/import_command.rb +0 -2
- data/lib/3scale_toolbox/commands/plans_command/apply_command.rb +136 -0
- data/lib/3scale_toolbox/commands/plans_command/create_command.rb +100 -0
- data/lib/3scale_toolbox/commands/plans_command/delete_command.rb +66 -0
- data/lib/3scale_toolbox/commands/plans_command/export/read_app_plan_step.rb +16 -0
- data/lib/3scale_toolbox/commands/plans_command/export/read_plan_features_step.rb +16 -0
- data/lib/3scale_toolbox/commands/plans_command/export/read_plan_limits_step.rb +19 -0
- data/lib/3scale_toolbox/commands/plans_command/export/read_plan_methods_step.rb +50 -0
- data/lib/3scale_toolbox/commands/plans_command/export/read_plan_metrics_step.rb +49 -0
- data/lib/3scale_toolbox/commands/plans_command/export/read_plan_pricing_rules_step.rb +19 -0
- data/lib/3scale_toolbox/commands/plans_command/export/step.rb +95 -0
- data/lib/3scale_toolbox/commands/plans_command/export/write_artifacts_file_step.rb +84 -0
- data/lib/3scale_toolbox/commands/plans_command/export_command.rb +65 -0
- data/lib/3scale_toolbox/commands/plans_command/import/create_or_update_app_plan_step.rb +33 -0
- data/lib/3scale_toolbox/commands/plans_command/import/import_plan_features_step.rb +45 -0
- data/lib/3scale_toolbox/commands/plans_command/import/import_plan_limits_step.rb +41 -0
- data/lib/3scale_toolbox/commands/plans_command/import/import_plan_metrics_step.rb +57 -0
- data/lib/3scale_toolbox/commands/plans_command/import/import_plan_pricing_rules_step.rb +39 -0
- data/lib/3scale_toolbox/commands/plans_command/import/step.rb +129 -0
- data/lib/3scale_toolbox/commands/plans_command/import_command.rb +62 -0
- data/lib/3scale_toolbox/commands/plans_command/list_command.rb +63 -0
- data/lib/3scale_toolbox/commands/plans_command/show_command.rb +81 -0
- data/lib/3scale_toolbox/commands/plans_command.rb +34 -0
- data/lib/3scale_toolbox/commands/remote_command.rb +0 -3
- data/lib/3scale_toolbox/commands/update_command/update_service.rb +5 -4
- data/lib/3scale_toolbox/commands/update_command.rb +0 -2
- data/lib/3scale_toolbox/commands.rb +3 -1
- data/lib/3scale_toolbox/entities/application_plan.rb +150 -0
- data/lib/3scale_toolbox/entities/service.rb +25 -12
- data/lib/3scale_toolbox/entities.rb +1 -0
- data/lib/3scale_toolbox/helper.rb +41 -0
- data/lib/3scale_toolbox/resource_reader.rb +42 -0
- data/lib/3scale_toolbox/tasks/copy_app_plans_task.rb +1 -1
- data/lib/3scale_toolbox/tasks/copy_limits_task.rb +8 -11
- data/lib/3scale_toolbox/tasks/copy_pricingrules_task.rb +5 -3
- data/lib/3scale_toolbox/version.rb +1 -1
- data/lib/3scale_toolbox.rb +10 -0
- metadata +28 -5
- data/lib/3scale_toolbox/commands/import_command/openapi/resource_reader.rb +0 -51
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: f2de44dc4f50140aaa326b714441c8590eb728f520835905091048911e2cd210
|
4
|
+
data.tar.gz: '008edc2978180ab0bda597b545b2c25f09712be036f1b372e6ae6f5c1c83df3e'
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 6db32b4a58ba23a8c0a1902ccf9002812effdefa6946e98883e748406e05c905a075ac13798fbed58461df834c419a4ad66b4c836edf02b510eb61cd8c7770fd
|
7
|
+
data.tar.gz: 3eba10df0a824a07d9edd63a88fa7896c1c5fcce7a43dc9e5aefcdb71d955053e858ef6f100319aea53c5a197b38ad0c047232e48c0e993b756ebca280894f08
|
data/README.md
CHANGED
@@ -15,6 +15,8 @@ See the LICENSE and NOTICE files that should have been provided along with this
|
|
15
15
|
* [Update a service](#update-a-service)
|
16
16
|
* [Import from CSV](#import-from-csv)
|
17
17
|
* [Import from OpenAPI definition](#import-openapi)
|
18
|
+
* [Export/Import Application Plan](#export-import-application-plan)
|
19
|
+
* Create, Apply, List, Show, Delete [Application plan](docs/app-plan.md)
|
18
20
|
* [Remotes](#remotes)
|
19
21
|
* [Development](#development)
|
20
22
|
* [Testing](#testing)
|
@@ -50,11 +52,12 @@ COMMANDS
|
|
50
52
|
|
51
53
|
OPTIONS
|
52
54
|
-c --config-file=<value> 3scale toolbox configuration file (default:
|
53
|
-
|
55
|
+
$HOME/.3scalerc.yaml)
|
54
56
|
-h --help show help for this command
|
55
57
|
-k --insecure Proceed and operate even for server
|
56
58
|
connections otherwise considered insecure
|
57
59
|
-v --version Prints the version of this command
|
60
|
+
--verbose Verbose mode
|
58
61
|
```
|
59
62
|
|
60
63
|
### Copy a service
|
@@ -91,6 +94,7 @@ OPTIONS FOR COPY
|
|
91
94
|
connections otherwise considered
|
92
95
|
insecure
|
93
96
|
-v --version Prints the version of this command
|
97
|
+
--verbose Verbose mode
|
94
98
|
```
|
95
99
|
|
96
100
|
```shell
|
@@ -131,6 +135,7 @@ OPTIONS FOR UPDATE
|
|
131
135
|
-k --insecure Proceed and operate even for server
|
132
136
|
connections otherwise considered insecure
|
133
137
|
-v --version Prints the version of this command
|
138
|
+
--verbose Verbose mode
|
134
139
|
```
|
135
140
|
|
136
141
|
Example:
|
@@ -182,6 +187,7 @@ OPTIONS FOR IMPORT
|
|
182
187
|
-k --insecure Proceed and operate even for server
|
183
188
|
connections otherwise considered insecure
|
184
189
|
-v --version Prints the version of this command
|
190
|
+
--verbose Verbose mode
|
185
191
|
```
|
186
192
|
|
187
193
|
Example:
|
@@ -198,6 +204,12 @@ Currently, only OpenAPI __2.0__ specification (f.k.a. __swagger__) is supported.
|
|
198
204
|
|
199
205
|
[Import from OpenAPI](docs/openapi.md)
|
200
206
|
|
207
|
+
### Export Import Application Plan
|
208
|
+
|
209
|
+
A single application plan can be exported/imported as `yaml` format.
|
210
|
+
|
211
|
+
[Export/Import Application Plan](docs/export-import-app-plan.md)
|
212
|
+
|
201
213
|
### Remotes
|
202
214
|
|
203
215
|
Manage set of 3scale instances.
|
@@ -1,6 +1,3 @@
|
|
1
|
-
require 'cri'
|
2
|
-
require '3scale_toolbox/base_command'
|
3
|
-
|
4
1
|
module ThreeScaleToolbox
|
5
2
|
module Commands
|
6
3
|
module CopyCommand
|
@@ -33,7 +30,6 @@ module ThreeScaleToolbox
|
|
33
30
|
puts "new service id #{target_service.id}"
|
34
31
|
context = create_context(source_service, target_service)
|
35
32
|
tasks = [
|
36
|
-
Tasks::CopyServiceProxyTask.new(context),
|
37
33
|
Tasks::CopyMethodsTask.new(context),
|
38
34
|
Tasks::CopyMetricsTask.new(context),
|
39
35
|
Tasks::CopyApplicationPlansTask.new(context),
|
@@ -43,6 +39,11 @@ module ThreeScaleToolbox
|
|
43
39
|
Tasks::CopyPoliciesTask.new(context),
|
44
40
|
Tasks::CopyPricingRulesTask.new(context),
|
45
41
|
Tasks::CopyActiveDocsTask.new(context),
|
42
|
+
# Copy proxy must be the last task
|
43
|
+
# Proxy update is the mechanism to increase version of the proxy,
|
44
|
+
# Hence propagating (mapping rules, poicies, oidc, auth) update to
|
45
|
+
# latest proxy config, making available to gateway.
|
46
|
+
Tasks::CopyServiceProxyTask.new(context),
|
46
47
|
]
|
47
48
|
tasks.each(&:call)
|
48
49
|
end
|
@@ -10,7 +10,7 @@ module ThreeScaleToolbox
|
|
10
10
|
name: api_spec.title,
|
11
11
|
system_name: activedocs_system_name,
|
12
12
|
service_id: service.id,
|
13
|
-
body: JSON.pretty_generate(
|
13
|
+
body: JSON.pretty_generate(rewritten_openapi),
|
14
14
|
description: api_spec.description,
|
15
15
|
published: context[:activedocs_published],
|
16
16
|
skip_swagger_validations: context[:skip_openapi_validation]
|
@@ -20,7 +20,7 @@ module ThreeScaleToolbox
|
|
20
20
|
# Make operation indempotent
|
21
21
|
if (errors = res['errors'])
|
22
22
|
raise ThreeScaleToolbox::Error, "ActiveDocs has not been created. #{errors}" \
|
23
|
-
unless system_name_already_taken_error? errors
|
23
|
+
unless ThreeScaleToolbox::Helper.system_name_already_taken_error? errors
|
24
24
|
|
25
25
|
# if activedocs system_name exists, ignore error, update activedocs
|
26
26
|
puts 'Activedocs exists, update!'
|
@@ -47,6 +47,43 @@ module ThreeScaleToolbox
|
|
47
47
|
activedoc['system_name'] == activedocs_system_name
|
48
48
|
end
|
49
49
|
end
|
50
|
+
|
51
|
+
def rewritten_openapi
|
52
|
+
# Updates on copy
|
53
|
+
# Other processing steps can work with original openapi spec
|
54
|
+
Helper.hash_deep_dup(resource).tap do |activedocs|
|
55
|
+
# public production base URL
|
56
|
+
URI(service.show_proxy.fetch('endpoint')).tap do |uri|
|
57
|
+
activedocs['host'] = "#{uri.host}:#{uri.port}"
|
58
|
+
activedocs['schemes'] = [uri.scheme]
|
59
|
+
end
|
60
|
+
|
61
|
+
# the basePath field is updated to a new value only when overriden by optional param
|
62
|
+
activedocs['basePath'] = api_spec.public_base_path
|
63
|
+
|
64
|
+
# security definitions
|
65
|
+
# just valid for oauth2 when oidc_issuer_endpoint is supplied
|
66
|
+
if !security.nil? && security.type == 'oauth2' && !oidc_issuer_endpoint.nil?
|
67
|
+
# authorizationURL
|
68
|
+
if %w[implicit accessCode].include?(security.flow)
|
69
|
+
activedocs['securityDefinitions'][security.id]['authorizationUrl'] = authorization_url
|
70
|
+
end
|
71
|
+
|
72
|
+
# tokenUrl
|
73
|
+
if %w[password application accessCode].include?(security.flow)
|
74
|
+
activedocs['securityDefinitions'][security.id]['tokenUrl'] = token_url
|
75
|
+
end
|
76
|
+
end
|
77
|
+
end
|
78
|
+
end
|
79
|
+
|
80
|
+
def authorization_url
|
81
|
+
"#{oidc_issuer_endpoint}/protocol/openid-connect/auth"
|
82
|
+
end
|
83
|
+
|
84
|
+
def token_url
|
85
|
+
"#{oidc_issuer_endpoint}/protocol/openid-connect/token"
|
86
|
+
end
|
50
87
|
end
|
51
88
|
end
|
52
89
|
end
|
@@ -14,7 +14,7 @@ module ThreeScaleToolbox
|
|
14
14
|
# Make operation indempotent
|
15
15
|
if (errors = res['errors'])
|
16
16
|
raise ThreeScaleToolbox::Error, "Metohd has not been saved. #{errors}" \
|
17
|
-
unless system_name_already_taken_error? errors
|
17
|
+
unless ThreeScaleToolbox::Helper.system_name_already_taken_error? errors
|
18
18
|
|
19
19
|
metric_id = method_id_by_system_name[op.method['system_name']]
|
20
20
|
end
|
@@ -18,7 +18,11 @@ module ThreeScaleToolbox
|
|
18
18
|
raise unless e.message =~ /"system_name"=>\["has already been taken"\]/
|
19
19
|
|
20
20
|
# Update service and update context
|
21
|
-
self.service = Entities::Service.
|
21
|
+
self.service = Entities::Service.find_by_system_name(remote: threescale_client,
|
22
|
+
system_name: service_system_name)
|
23
|
+
# It should exist
|
24
|
+
raise ThreeScaleToolbox::Error, "Service with system_name: #{service_system_name}, should exist" if service.nil?
|
25
|
+
|
22
26
|
service.update_service(service_settings)
|
23
27
|
puts "Updated service id: #{service.id}, name: #{service_name}"
|
24
28
|
end
|
@@ -29,21 +33,6 @@ module ThreeScaleToolbox
|
|
29
33
|
target_system_name || service_name.downcase.gsub(/[^\w]/, '_')
|
30
34
|
end
|
31
35
|
|
32
|
-
def service_id
|
33
|
-
@service_id ||= fetch_service_id
|
34
|
-
end
|
35
|
-
|
36
|
-
def fetch_service_id
|
37
|
-
# figure out service by system_name
|
38
|
-
service_found = threescale_client.list_services.find do |svc|
|
39
|
-
svc['system_name'] == service_system_name
|
40
|
-
end
|
41
|
-
# It should exist
|
42
|
-
raise ThreeScaleToolbox::Error, "Service with system_name: #{service_system_name}, should exist" if service_found.nil?
|
43
|
-
|
44
|
-
service_found['id']
|
45
|
-
end
|
46
|
-
|
47
36
|
def service_settings
|
48
37
|
default_service_settings.tap do |svc|
|
49
38
|
svc['name'] = service_name
|
@@ -18,7 +18,17 @@ module ThreeScaleToolbox
|
|
18
18
|
|
19
19
|
def pattern
|
20
20
|
# apply strict matching
|
21
|
-
|
21
|
+
"#{raw_pattern}$"
|
22
|
+
end
|
23
|
+
|
24
|
+
def raw_pattern
|
25
|
+
# According OAS 2.0: path MUST begin with a slash
|
26
|
+
"#{public_base_path}#{operation[:path]}"
|
27
|
+
end
|
28
|
+
|
29
|
+
def public_base_path
|
30
|
+
# remove the last slash of the basePath
|
31
|
+
operation[:public_base_path].gsub(%r{/$}, '')
|
22
32
|
end
|
23
33
|
|
24
34
|
def delta
|
@@ -43,9 +43,6 @@ module ThreeScaleToolbox
|
|
43
43
|
context[:api_spec_resource]
|
44
44
|
end
|
45
45
|
|
46
|
-
def system_name_already_taken_error?(error)
|
47
|
-
Array(Hash(error)['system_name']).any? { |msg| msg.match(/has already been taken/) }
|
48
|
-
end
|
49
46
|
|
50
47
|
def security
|
51
48
|
api_spec.security
|
@@ -58,6 +55,10 @@ module ThreeScaleToolbox
|
|
58
55
|
def default_credentials_userkey
|
59
56
|
context[:default_credentials_userkey]
|
60
57
|
end
|
58
|
+
|
59
|
+
def override_private_basepath
|
60
|
+
context[:override_private_basepath]
|
61
|
+
end
|
61
62
|
end
|
62
63
|
end
|
63
64
|
end
|
@@ -5,8 +5,9 @@ module ThreeScaleToolbox
|
|
5
5
|
class ThreeScaleApiSpec
|
6
6
|
attr_reader :openapi
|
7
7
|
|
8
|
-
def initialize(openapi)
|
8
|
+
def initialize(openapi, base_path = nil)
|
9
9
|
@openapi = openapi
|
10
|
+
@base_path = base_path
|
10
11
|
end
|
11
12
|
|
12
13
|
def title
|
@@ -46,13 +47,23 @@ module ThreeScaleToolbox
|
|
46
47
|
def operations
|
47
48
|
openapi.operations.map do |op|
|
48
49
|
Operation.new(
|
49
|
-
|
50
|
+
base_path: base_path,
|
51
|
+
public_base_path: public_base_path,
|
52
|
+
path: op.path,
|
50
53
|
verb: op.verb,
|
51
54
|
operationId: op.operation_id
|
52
55
|
)
|
53
56
|
end
|
54
57
|
end
|
55
58
|
|
59
|
+
def public_base_path
|
60
|
+
@base_path || base_path
|
61
|
+
end
|
62
|
+
|
63
|
+
def base_path
|
64
|
+
openapi.base_path || '/'
|
65
|
+
end
|
66
|
+
|
56
67
|
private
|
57
68
|
|
58
69
|
def parse_security
|
@@ -17,6 +17,7 @@ module ThreeScaleToolbox
|
|
17
17
|
|
18
18
|
add_anonymous_access_policy(policies_settings)
|
19
19
|
add_rh_sso_keycloak_role_check_policy(policies_settings)
|
20
|
+
add_url_rewritting_policy(policies_settings)
|
20
21
|
|
21
22
|
return if source_policies_settings == policies_settings
|
22
23
|
|
@@ -47,13 +48,13 @@ module ThreeScaleToolbox
|
|
47
48
|
if default_credentials_userkey.nil?
|
48
49
|
|
49
50
|
{
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
51
|
+
name: 'default_credentials',
|
52
|
+
version: 'builtin',
|
53
|
+
configuration: {
|
54
|
+
auth_type: 'user_key',
|
55
|
+
user_key: default_credentials_userkey
|
55
56
|
},
|
56
|
-
|
57
|
+
enabled: true
|
57
58
|
}
|
58
59
|
end
|
59
60
|
|
@@ -68,20 +69,68 @@ module ThreeScaleToolbox
|
|
68
69
|
|
69
70
|
def keycloak_policy
|
70
71
|
{
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
72
|
+
name: 'keycloak_role_check',
|
73
|
+
version: 'builtin',
|
74
|
+
configuration: {
|
75
|
+
type: 'whitelist',
|
76
|
+
scopes: [
|
76
77
|
{
|
77
|
-
|
78
|
-
|
78
|
+
realm_roles: [],
|
79
|
+
client_roles: security.scopes.map { |scope| { 'name': scope } }
|
79
80
|
}
|
80
81
|
]
|
81
82
|
},
|
82
|
-
|
83
|
+
enabled: true
|
83
84
|
}
|
84
85
|
end
|
86
|
+
|
87
|
+
def add_url_rewritting_policy(policies)
|
88
|
+
return if private_base_path == api_spec.public_base_path
|
89
|
+
|
90
|
+
url_rewritting_policy_idx = policies.find_index do |policy|
|
91
|
+
policy['name'] == 'url_rewriting'
|
92
|
+
end
|
93
|
+
|
94
|
+
if url_rewritting_policy_idx.nil?
|
95
|
+
policies << url_rewritting_policy
|
96
|
+
else
|
97
|
+
policies[url_rewritting_policy_idx] = url_rewritting_policy
|
98
|
+
end
|
99
|
+
end
|
100
|
+
|
101
|
+
def private_base_path
|
102
|
+
override_private_basepath || api_spec.base_path
|
103
|
+
end
|
104
|
+
|
105
|
+
def url_rewritting_policy
|
106
|
+
regex = url_rewritting_policy_regex
|
107
|
+
replace = url_rewritting_policy_replace
|
108
|
+
# If regex has a / at the end, replace must have a / at the end
|
109
|
+
replace.concat('/') if regex.end_with?('/') && !replace.end_with?('/')
|
110
|
+
|
111
|
+
{
|
112
|
+
name: 'url_rewriting',
|
113
|
+
version: 'builtin',
|
114
|
+
configuration: {
|
115
|
+
commands: [
|
116
|
+
{
|
117
|
+
op: 'sub',
|
118
|
+
regex: regex,
|
119
|
+
replace: replace
|
120
|
+
}
|
121
|
+
]
|
122
|
+
},
|
123
|
+
enabled: true
|
124
|
+
}
|
125
|
+
end
|
126
|
+
|
127
|
+
def url_rewritting_policy_regex
|
128
|
+
"^#{api_spec.public_base_path}"
|
129
|
+
end
|
130
|
+
|
131
|
+
def url_rewritting_policy_replace
|
132
|
+
"#{private_base_path}"
|
133
|
+
end
|
85
134
|
end
|
86
135
|
end
|
87
136
|
end
|
@@ -9,13 +9,16 @@ module ThreeScaleToolbox
|
|
9
9
|
# Updates Proxy config
|
10
10
|
def call
|
11
11
|
# setting required attrs, operation is idempotent
|
12
|
-
proxy_settings = {
|
12
|
+
proxy_settings = {
|
13
|
+
# Adding harmless attribute to avoid empty body
|
14
|
+
# update_proxy cannot be done with empty body
|
15
|
+
# and must be done to increase proxy version
|
16
|
+
service_id: service.id
|
17
|
+
}
|
13
18
|
|
14
19
|
add_api_backend_settings(proxy_settings)
|
15
20
|
add_security_proxy_settings(proxy_settings)
|
16
21
|
|
17
|
-
return unless proxy_settings.size.positive?
|
18
|
-
|
19
22
|
res = service.update_proxy proxy_settings
|
20
23
|
if (errors = res['errors'])
|
21
24
|
raise ThreeScaleToolbox::Error, "Service proxy has not been updated. #{errors}"
|
@@ -2,7 +2,6 @@ require '3scale_toolbox/commands/import_command/openapi/method'
|
|
2
2
|
require '3scale_toolbox/commands/import_command/openapi/mapping_rule'
|
3
3
|
require '3scale_toolbox/commands/import_command/openapi/operation'
|
4
4
|
require '3scale_toolbox/commands/import_command/openapi/step'
|
5
|
-
require '3scale_toolbox/commands/import_command/openapi/resource_reader'
|
6
5
|
require '3scale_toolbox/commands/import_command/openapi/threescale_api_spec'
|
7
6
|
require '3scale_toolbox/commands/import_command/openapi/create_method_step'
|
8
7
|
require '3scale_toolbox/commands/import_command/openapi/create_mapping_rule_step'
|
@@ -18,7 +17,7 @@ module ThreeScaleToolbox
|
|
18
17
|
module OpenAPI
|
19
18
|
class OpenAPISubcommand < Cri::CommandRunner
|
20
19
|
include ThreeScaleToolbox::Command
|
21
|
-
include ResourceReader
|
20
|
+
include ThreeScaleToolbox::ResourceReader
|
22
21
|
|
23
22
|
def self.command
|
24
23
|
Cri::Command.define do
|
@@ -33,6 +32,8 @@ module ThreeScaleToolbox
|
|
33
32
|
flag nil, 'skip-openapi-validation', 'Skip OpenAPI schema validation'
|
34
33
|
option nil, 'oidc-issuer-endpoint', 'OIDC Issuer Endpoint', argument: :required
|
35
34
|
option nil, 'default-credentials-userkey', 'Default credentials policy userkey', argument: :required
|
35
|
+
option nil, 'override-private-basepath', 'Override the basepath for the public URLs', argument: :required
|
36
|
+
option nil, 'override-public-basepath', 'Override the basepath for the private URLs', argument: :required
|
36
37
|
param :openapi_resource
|
37
38
|
|
38
39
|
runner OpenAPISubcommand
|
@@ -46,9 +47,13 @@ module ThreeScaleToolbox
|
|
46
47
|
tasks << ThreeScaleToolbox::Tasks::DestroyMappingRulesTask.new(context)
|
47
48
|
tasks << CreateMappingRulesStep.new(context)
|
48
49
|
tasks << CreateActiveDocsStep.new(context)
|
49
|
-
tasks << UpdateServiceProxyStep.new(context)
|
50
50
|
tasks << UpdateServiceOidcConfStep.new(context)
|
51
51
|
tasks << UpdatePoliciesStep.new(context)
|
52
|
+
# Update proxy must be the last step
|
53
|
+
# Proxy update is the mechanism to increase version of the proxy,
|
54
|
+
# Hence propagating (mapping rules, poicies, oidc, auth) update to
|
55
|
+
# latest proxy config, making available to gateway.
|
56
|
+
tasks << UpdateServiceProxyStep.new(context)
|
52
57
|
|
53
58
|
# run tasks
|
54
59
|
tasks.each(&:call)
|
@@ -64,13 +69,14 @@ module ThreeScaleToolbox
|
|
64
69
|
openapi_resource = load_resource(arguments[:openapi_resource])
|
65
70
|
{
|
66
71
|
api_spec_resource: openapi_resource,
|
67
|
-
api_spec: ThreeScaleApiSpec.new(load_openapi(openapi_resource)),
|
72
|
+
api_spec: ThreeScaleApiSpec.new(load_openapi(openapi_resource), options[:'override-public-basepath']),
|
68
73
|
threescale_client: threescale_client(fetch_required_option(:destination)),
|
69
74
|
target_system_name: options[:target_system_name],
|
70
75
|
activedocs_published: !options[:'activedocs-hidden'],
|
71
76
|
oidc_issuer_endpoint: options[:'oidc-issuer-endpoint'],
|
72
77
|
default_credentials_userkey: options[:'default-credentials-userkey'],
|
73
|
-
skip_openapi_validation: options[:'skip-openapi-validation']
|
78
|
+
skip_openapi_validation: options[:'skip-openapi-validation'],
|
79
|
+
override_private_basepath: options[:'override-private-basepath']
|
74
80
|
}
|
75
81
|
end
|
76
82
|
|
@@ -0,0 +1,136 @@
|
|
1
|
+
module ThreeScaleToolbox
|
2
|
+
module Commands
|
3
|
+
module PlansCommand
|
4
|
+
module Apply
|
5
|
+
class ApplySubcommand < Cri::CommandRunner
|
6
|
+
include ThreeScaleToolbox::Command
|
7
|
+
|
8
|
+
def self.command
|
9
|
+
Cri::Command.define do
|
10
|
+
name 'apply'
|
11
|
+
usage 'apply [opts] <remote> <service> <plan>'
|
12
|
+
summary 'Update application plan'
|
13
|
+
description 'Update (create if it does not exist) application plan'
|
14
|
+
|
15
|
+
option :n, :name, 'Plan name', argument: :required
|
16
|
+
flag nil, :default, 'Make default application plan'
|
17
|
+
flag nil, :disabled, 'Disables all methods and metrics in this application plan'
|
18
|
+
flag nil, :enabled, 'Enable application plan'
|
19
|
+
flag :p, :publish, 'Publish application plan'
|
20
|
+
flag nil, :hide, 'Hide application plan'
|
21
|
+
option nil, 'approval-required', 'Applications require approval. true or false', argument: :required, transform: ThreeScaleToolbox::Helper::BooleanTransformer.new
|
22
|
+
option nil, 'cost-per-month', 'Cost per month', argument: :required, transform: method(:Integer)
|
23
|
+
option nil, 'setup-fee', 'Setup fee', argument: :required, transform: method(:Integer)
|
24
|
+
option nil, 'trial-period-days', 'Trial period days', argument: :required, transform: method(:Integer)
|
25
|
+
option nil, 'end-user-required', 'End user required. true or false', argument: :required, transform: ThreeScaleToolbox::Helper::BooleanTransformer.new
|
26
|
+
param :remote
|
27
|
+
param :service_ref
|
28
|
+
param :plan_ref
|
29
|
+
|
30
|
+
runner ApplySubcommand
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
def run
|
35
|
+
validate_option_params
|
36
|
+
plan = Entities::ApplicationPlan.find(service: service, ref: plan_ref)
|
37
|
+
if plan.nil?
|
38
|
+
plan = Entities::ApplicationPlan.create(service: service,
|
39
|
+
plan_attrs: create_plan_attrs)
|
40
|
+
else
|
41
|
+
plan.update(plan_attrs) unless plan_attrs.empty?
|
42
|
+
end
|
43
|
+
|
44
|
+
plan.make_default if option_default
|
45
|
+
plan.disable if option_disabled
|
46
|
+
plan.enable if option_enabled
|
47
|
+
|
48
|
+
output_msg_array = ["Applied application plan id: #{plan.id}"]
|
49
|
+
output_msg_array << "Default: #{option_default}"
|
50
|
+
output_msg_array << 'Disabled' if option_disabled
|
51
|
+
output_msg_array << 'Enabled' if option_enabled
|
52
|
+
output_msg_array << 'Published' if option_publish
|
53
|
+
output_msg_array << 'Hidden' if option_hide
|
54
|
+
puts output_msg_array.join('; ')
|
55
|
+
end
|
56
|
+
|
57
|
+
private
|
58
|
+
|
59
|
+
def validate_option_params
|
60
|
+
raise ThreeScaleToolbox::Error, '--disabled and --enabled are mutually exclusive' \
|
61
|
+
if option_enabled && option_disabled
|
62
|
+
|
63
|
+
raise ThreeScaleToolbox::Error, '--publish and --hide are mutually exclusive' \
|
64
|
+
if option_publish && option_hide
|
65
|
+
end
|
66
|
+
|
67
|
+
def create_plan_attrs
|
68
|
+
plan_attrs.merge('system_name' => plan_ref,
|
69
|
+
'name' => plan_ref) { |_key, oldval, _newval| oldval }
|
70
|
+
end
|
71
|
+
|
72
|
+
def plan_attrs
|
73
|
+
plan_basic_attrs.tap do |params|
|
74
|
+
params['state'] = 'published' if option_publish
|
75
|
+
params['state'] = 'hidden' if option_hide
|
76
|
+
end
|
77
|
+
end
|
78
|
+
|
79
|
+
def plan_basic_attrs
|
80
|
+
{
|
81
|
+
'name' => options[:name],
|
82
|
+
'approval_required' => options[:'approval-required'],
|
83
|
+
'end_user_required' => options[:'end-user-required'],
|
84
|
+
'cost_per_month' => options[:'cost-per-month'],
|
85
|
+
'setup_fee' => options[:'setup-fee'],
|
86
|
+
'trial_period_days' => options[:'trial-period-days']
|
87
|
+
}.compact
|
88
|
+
end
|
89
|
+
|
90
|
+
def option_default
|
91
|
+
!options[:default].nil?
|
92
|
+
end
|
93
|
+
|
94
|
+
def option_enabled
|
95
|
+
!options[:enabled].nil?
|
96
|
+
end
|
97
|
+
|
98
|
+
def option_disabled
|
99
|
+
!options[:disabled].nil?
|
100
|
+
end
|
101
|
+
|
102
|
+
def option_publish
|
103
|
+
!options[:publish].nil?
|
104
|
+
end
|
105
|
+
|
106
|
+
def option_hide
|
107
|
+
!options[:hide].nil?
|
108
|
+
end
|
109
|
+
|
110
|
+
def service
|
111
|
+
@service ||= find_service
|
112
|
+
end
|
113
|
+
|
114
|
+
def find_service
|
115
|
+
Entities::Service.find(remote: remote,
|
116
|
+
ref: service_ref).tap do |svc|
|
117
|
+
raise ThreeScaleToolbox::Error, "Service #{service_ref} does not exist" if svc.nil?
|
118
|
+
end
|
119
|
+
end
|
120
|
+
|
121
|
+
def remote
|
122
|
+
@remote ||= threescale_client(arguments[:remote])
|
123
|
+
end
|
124
|
+
|
125
|
+
def service_ref
|
126
|
+
arguments[:service_ref]
|
127
|
+
end
|
128
|
+
|
129
|
+
def plan_ref
|
130
|
+
arguments[:plan_ref]
|
131
|
+
end
|
132
|
+
end
|
133
|
+
end
|
134
|
+
end
|
135
|
+
end
|
136
|
+
end
|