3scale_toolbox 0.8.0 → 0.9.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|