3scale_toolbox 0.18.3 → 0.19.3
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/3scale_toolbox.gemspec +3 -3
- data/README.md +1 -2
- data/lib/3scale_toolbox/commands/backend_command/copy_command/delete_mapping_rules_task.rb +18 -0
- data/lib/3scale_toolbox/commands/backend_command/copy_command/task.rb +4 -0
- data/lib/3scale_toolbox/commands/backend_command/copy_command.rb +4 -1
- data/lib/3scale_toolbox/commands/import_command/import_csv.rb +8 -8
- data/lib/3scale_toolbox/commands/import_command/openapi/create_activedocs_step.rb +1 -1
- data/lib/3scale_toolbox/commands/import_command/openapi/update_policies_step.rb +23 -10
- data/lib/3scale_toolbox/commands/import_command/openapi.rb +2 -0
- data/lib/3scale_toolbox/commands/plans_command/export_command.rb +52 -29
- data/lib/3scale_toolbox/commands/plans_command/import/import_backend_metrics_step.rb +37 -0
- data/lib/3scale_toolbox/commands/plans_command/import/import_plan_limits_step.rb +11 -2
- data/lib/3scale_toolbox/commands/plans_command/import/import_plan_metrics_step.rb +2 -2
- data/lib/3scale_toolbox/commands/plans_command/import/import_plan_pricing_rules_step.rb +12 -1
- data/lib/3scale_toolbox/commands/plans_command/import/step.rb +23 -8
- data/lib/3scale_toolbox/commands/plans_command/import/validate_plan_step.rb +126 -0
- data/lib/3scale_toolbox/commands/plans_command/import_command.rb +5 -1
- data/lib/3scale_toolbox/commands/product_command/copy_command/copy_backends_task.rb +6 -0
- data/lib/3scale_toolbox/commands/product_command/copy_command.rb +3 -2
- data/lib/3scale_toolbox/commands/product_command/import_command.rb +1 -0
- data/lib/3scale_toolbox/crds/limit_dump.rb +1 -1
- data/lib/3scale_toolbox/crds/pricing_rule_dump.rb +1 -1
- data/lib/3scale_toolbox/entities/application_plan.rb +64 -0
- data/lib/3scale_toolbox/entities/backend.rb +4 -0
- data/lib/3scale_toolbox/entities/backend_method.rb +16 -0
- data/lib/3scale_toolbox/entities/backend_metric.rb +16 -0
- data/lib/3scale_toolbox/entities/limit.rb +52 -7
- data/lib/3scale_toolbox/entities/method.rb +11 -0
- data/lib/3scale_toolbox/entities/metric.rb +12 -0
- data/lib/3scale_toolbox/entities/pricing_rule.rb +52 -7
- data/lib/3scale_toolbox/entities/service.rb +4 -0
- data/lib/3scale_toolbox/proxy_logger.rb +2 -0
- data/lib/3scale_toolbox/remote_cache.rb +49 -2
- data/lib/3scale_toolbox/version.rb +1 -1
- data/licenses.xml +15 -25
- metadata +8 -13
- data/lib/3scale_toolbox/commands/plans_command/export/read_app_plan_step.rb +0 -16
- data/lib/3scale_toolbox/commands/plans_command/export/read_plan_features_step.rb +0 -16
- data/lib/3scale_toolbox/commands/plans_command/export/read_plan_limits_step.rb +0 -19
- data/lib/3scale_toolbox/commands/plans_command/export/read_plan_methods_step.rb +0 -47
- data/lib/3scale_toolbox/commands/plans_command/export/read_plan_metrics_step.rb +0 -47
- data/lib/3scale_toolbox/commands/plans_command/export/read_plan_pricing_rules_step.rb +0 -19
- data/lib/3scale_toolbox/commands/plans_command/export/step.rb +0 -85
- data/lib/3scale_toolbox/commands/plans_command/export/write_artifacts_file_step.rb +0 -84
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: d2a44bdf128bf6f8d4d0a592a4eee49c82c34415017e03366ff2bcc241fe18c0
|
4
|
+
data.tar.gz: 0e94df4747331e9092ae0c961709cfcc334a553eb54209378941b8239307eceb
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 8dd7a6efc6567598d87e4ebbc18c486eba1ea9e6766ca6c0241f78e73a4287408d9e18ac838788e81a073c8f3a8fd93d299fac4ea9f21a42571e3cff68f2b0bb
|
7
|
+
data.tar.gz: c4ed75a0b46414606208a5fb6e1374e72d5fe06fbb5a237b3793bc2471d20667c489acace51cdf93d4971bfe59b42dc2919631b90074a8af72bac1668c663d01
|
data/3scale_toolbox.gemspec
CHANGED
@@ -8,8 +8,8 @@ Gem::Specification.new do |spec|
|
|
8
8
|
spec.name = '3scale_toolbox'
|
9
9
|
spec.version = ThreeScaleToolbox::VERSION
|
10
10
|
spec.licenses = ['MIT']
|
11
|
-
spec.authors = ['
|
12
|
-
spec.email = ['
|
11
|
+
spec.authors = ['Miguel Soriano', 'Eguzki Astiz Lezaun']
|
12
|
+
spec.email = ['msoriano@redhat.com', 'eastizle@redhat.com']
|
13
13
|
|
14
14
|
spec.summary = %q{3scale Toolbox.}
|
15
15
|
spec.description = %q{3scale tools to manage your API from the terminal.}
|
@@ -34,7 +34,7 @@ Gem::Specification.new do |spec|
|
|
34
34
|
spec.add_development_dependency 'rake', '~> 13.0'
|
35
35
|
spec.add_development_dependency 'rspec', '~> 3.8'
|
36
36
|
spec.add_development_dependency 'webmock', '~> 3.4'
|
37
|
-
spec.required_ruby_version = '>= 2.
|
37
|
+
spec.required_ruby_version = '>= 2.6'
|
38
38
|
|
39
39
|
spec.add_dependency '3scale-api', '~> 1.4'
|
40
40
|
spec.add_dependency 'cri', '~> 2.15'
|
data/README.md
CHANGED
@@ -39,7 +39,6 @@
|
|
39
39
|
## Requirements
|
40
40
|
Supported Ruby interpreters
|
41
41
|
|
42
|
-
* MRI 2.5
|
43
42
|
* MRI 2.6
|
44
43
|
* MRI 2.7
|
45
44
|
|
@@ -219,5 +218,5 @@ Install, uninstall and update plugins using tools like [RubyGems](https://guides
|
|
219
218
|
|
220
219
|
## Contributing
|
221
220
|
|
222
|
-
|
221
|
+
If you are interested in contributing to 3scale Toolbox, please refer to instructions available [here](docs/contributing.md)
|
223
222
|
|
@@ -0,0 +1,18 @@
|
|
1
|
+
module ThreeScaleToolbox
|
2
|
+
module Commands
|
3
|
+
module BackendCommand
|
4
|
+
module CopyCommand
|
5
|
+
class DeleteMappingRulesTask
|
6
|
+
include Task
|
7
|
+
|
8
|
+
# entrypoint
|
9
|
+
def run
|
10
|
+
return unless delete_mapping_rules
|
11
|
+
|
12
|
+
target_backend.mapping_rules.each(&:delete)
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
@@ -2,6 +2,7 @@ require '3scale_toolbox/commands/backend_command/copy_command/task'
|
|
2
2
|
require '3scale_toolbox/commands/backend_command/copy_command/create_or_update_target_backend_task'
|
3
3
|
require '3scale_toolbox/commands/backend_command/copy_command/copy_metrics_task'
|
4
4
|
require '3scale_toolbox/commands/backend_command/copy_command/copy_methods_task'
|
5
|
+
require '3scale_toolbox/commands/backend_command/copy_command/delete_mapping_rules_task'
|
5
6
|
require '3scale_toolbox/commands/backend_command/copy_command/copy_mapping_rules_task'
|
6
7
|
|
7
8
|
module ThreeScaleToolbox
|
@@ -17,7 +18,7 @@ module ThreeScaleToolbox
|
|
17
18
|
summary 'Copy backend'
|
18
19
|
description <<-HEREDOC
|
19
20
|
This command makes a copy of the referenced backend.
|
20
|
-
Target backend will be searched by source backend system name. System name can be
|
21
|
+
Target backend will be searched by the source backend system name. System name can be overridden with `--target-system-name` option.
|
21
22
|
If a backend with the selected `system-name` is not found, it will be created.
|
22
23
|
\n Components of the backend being copied:
|
23
24
|
\nmetrics
|
@@ -41,6 +42,7 @@ module ThreeScaleToolbox
|
|
41
42
|
# First metrics as methods need 'hits' metric in target backend
|
42
43
|
tasks << CopyCommand::CopyMetricsTask.new(context)
|
43
44
|
tasks << CopyCommand::CopyMethodsTask.new(context)
|
45
|
+
tasks << CopyCommand::DeleteMappingRulesTask.new(context)
|
44
46
|
tasks << CopyCommand::CopyMappingRulesTask.new(context)
|
45
47
|
tasks.each(&:call)
|
46
48
|
end
|
@@ -56,6 +58,7 @@ module ThreeScaleToolbox
|
|
56
58
|
source_remote: threescale_client(fetch_required_option(:source)),
|
57
59
|
target_remote: threescale_client(fetch_required_option(:destination)),
|
58
60
|
source_backend_ref: arguments[:source_backend],
|
61
|
+
delete_mapping_rules: true,
|
59
62
|
option_target_system_name: options[:'target-system-name']
|
60
63
|
}
|
61
64
|
end
|
@@ -104,14 +104,14 @@ module ThreeScaleToolbox
|
|
104
104
|
|
105
105
|
# create a mapping rule
|
106
106
|
if (metric_id = metric['id'] || method['id'])
|
107
|
-
mapping_rule = client.create_mapping_rule(service['id'],
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
107
|
+
mapping_rule = client.create_mapping_rule(service['id'],{
|
108
|
+
metric_id: metric_id,
|
109
|
+
pattern: item['endpoint_path'],
|
110
|
+
http_method: item['endpoint_http_method'],
|
111
|
+
metric_system_name: item['endpoint_system_name'],
|
112
|
+
auth_app_key: auth_app_key_according_service(service),
|
113
|
+
delta: 1
|
114
|
+
})
|
115
115
|
|
116
116
|
if mapping_rule['errors'].nil?
|
117
117
|
stats[:mapping_rules] += 1
|
@@ -53,7 +53,7 @@ module ThreeScaleToolbox
|
|
53
53
|
# Other processing steps can work with original openapi spec
|
54
54
|
Helper.hash_deep_dup(resource).tap do |activedocs|
|
55
55
|
# public production base URL
|
56
|
-
# the basePath field is updated to a new value only when
|
56
|
+
# the basePath field is updated to a new value only when overridden by optional param
|
57
57
|
unless service.proxy['endpoint'].nil?
|
58
58
|
api_spec.set_server_url(activedocs, URI.join(service.proxy.fetch('endpoint'), public_base_path))
|
59
59
|
end
|
@@ -15,7 +15,7 @@ module ThreeScaleToolbox
|
|
15
15
|
# do not update in-place, otherwise changes will not be detected
|
16
16
|
policies_settings = source_policies_settings.dup
|
17
17
|
|
18
|
-
|
18
|
+
reconcile_anonymous_access_policy(policies_settings)
|
19
19
|
add_rh_sso_keycloak_role_check_policy(policies_settings)
|
20
20
|
add_url_rewritting_policy(policies_settings)
|
21
21
|
|
@@ -31,15 +31,28 @@ module ThreeScaleToolbox
|
|
31
31
|
|
32
32
|
private
|
33
33
|
|
34
|
-
def
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
34
|
+
def reconcile_anonymous_access_policy(policies)
|
35
|
+
idx = policies.find_index { |p| p['name'] == 'default_credentials' }
|
36
|
+
|
37
|
+
if api_spec.security.nil?
|
38
|
+
# only on 'open api' security req
|
39
|
+
# Update anonymous policy if exists
|
40
|
+
#
|
41
|
+
if idx.nil?
|
42
|
+
# Anonymous policy should be before apicast policy
|
43
|
+
# hence, adding as a first element
|
44
|
+
policies.insert(0, anonymous_policy)
|
45
|
+
else
|
46
|
+
# only update if different
|
47
|
+
if policies[idx].dig('configuration', 'user_key') != anonymous_policy.dig(:configuration, :user_key)
|
48
|
+
policies[idx] = anonymous_policy
|
49
|
+
end
|
50
|
+
end
|
51
|
+
else
|
52
|
+
unless idx.nil?
|
53
|
+
policies.slice!(idx)
|
54
|
+
end
|
55
|
+
end
|
43
56
|
end
|
44
57
|
|
45
58
|
def anonymous_policy
|
@@ -108,6 +108,8 @@ module ThreeScaleToolbox
|
|
108
108
|
end
|
109
109
|
|
110
110
|
def openapi_parser
|
111
|
+
raise ThreeScaleToolbox::Error, 'only JSON/YAML format is supported' unless openapi_resource.is_a?(Hash)
|
112
|
+
|
111
113
|
if openapi_resource.key?('openapi')
|
112
114
|
ThreeScaleToolbox::OpenAPI::OAS3.build(openapi_path, openapi_resource, validate: validate)
|
113
115
|
else
|
@@ -1,12 +1,3 @@
|
|
1
|
-
require '3scale_toolbox/commands/plans_command/export/step'
|
2
|
-
require '3scale_toolbox/commands/plans_command/export/read_app_plan_step'
|
3
|
-
require '3scale_toolbox/commands/plans_command/export/read_plan_features_step'
|
4
|
-
require '3scale_toolbox/commands/plans_command/export/read_plan_limits_step'
|
5
|
-
require '3scale_toolbox/commands/plans_command/export/read_plan_pricing_rules_step'
|
6
|
-
require '3scale_toolbox/commands/plans_command/export/read_plan_methods_step'
|
7
|
-
require '3scale_toolbox/commands/plans_command/export/read_plan_metrics_step'
|
8
|
-
require '3scale_toolbox/commands/plans_command/export/write_artifacts_file_step'
|
9
|
-
|
10
1
|
module ThreeScaleToolbox
|
11
2
|
module Commands
|
12
3
|
module PlansCommand
|
@@ -31,32 +22,64 @@ module ThreeScaleToolbox
|
|
31
22
|
end
|
32
23
|
|
33
24
|
def run
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
tasks << WriteArtifactsStep.new(context)
|
42
|
-
|
43
|
-
# run tasks
|
44
|
-
tasks.each(&:call)
|
25
|
+
select_output do |output|
|
26
|
+
plan_object = application_plan.to_hash.merge(
|
27
|
+
'created_at' => Time.now.utc.iso8601,
|
28
|
+
'toolbox_version' => ThreeScaleToolbox::VERSION
|
29
|
+
)
|
30
|
+
output.write(plan_object.to_yaml)
|
31
|
+
end
|
45
32
|
end
|
46
33
|
|
47
34
|
private
|
48
35
|
|
49
|
-
def
|
50
|
-
@
|
36
|
+
def remote
|
37
|
+
@remote ||= threescale_client(arguments[:remote])
|
38
|
+
end
|
39
|
+
|
40
|
+
def select_output
|
41
|
+
ios = if file
|
42
|
+
File.open(file, 'w')
|
43
|
+
else
|
44
|
+
$stdout
|
45
|
+
end
|
46
|
+
begin
|
47
|
+
yield(ios)
|
48
|
+
ensure
|
49
|
+
ios.close
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
def application_plan
|
54
|
+
@application_plan ||= find_application_plan
|
55
|
+
end
|
56
|
+
|
57
|
+
def find_application_plan
|
58
|
+
Entities::ApplicationPlan.find(service: product, ref: plan_system_name).tap do |p|
|
59
|
+
raise ThreeScaleToolbox::Error, "Application plan #{plan_system_name} does not exist" if p.nil?
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
def product
|
64
|
+
@product ||= find_product
|
65
|
+
end
|
66
|
+
|
67
|
+
def product_ref
|
68
|
+
arguments[:service_system_name]
|
69
|
+
end
|
70
|
+
|
71
|
+
def plan_system_name
|
72
|
+
arguments[:plan_system_name]
|
73
|
+
end
|
74
|
+
|
75
|
+
def find_product
|
76
|
+
Entities::Service.find(remote: remote, ref: product_ref).tap do |prd|
|
77
|
+
raise ThreeScaleToolbox::Error, "Product #{product_ref} does not exist" if prd.nil?
|
78
|
+
end
|
51
79
|
end
|
52
80
|
|
53
|
-
def
|
54
|
-
|
55
|
-
file: options[:file],
|
56
|
-
threescale_client: threescale_client(arguments[:remote]),
|
57
|
-
service_system_name: arguments[:service_system_name],
|
58
|
-
plan_system_name: arguments[:plan_system_name],
|
59
|
-
}
|
81
|
+
def file
|
82
|
+
options[:file]
|
60
83
|
end
|
61
84
|
end
|
62
85
|
end
|
@@ -0,0 +1,37 @@
|
|
1
|
+
module ThreeScaleToolbox
|
2
|
+
module Commands
|
3
|
+
module PlansCommand
|
4
|
+
module Import
|
5
|
+
class ImportBackendMetricsStep
|
6
|
+
include Step
|
7
|
+
##
|
8
|
+
# Writes Plan metrics and methods
|
9
|
+
def call
|
10
|
+
resource_backend_metrics.each(&method(:create_metric))
|
11
|
+
resource_backend_methods.each(&method(:create_method))
|
12
|
+
end
|
13
|
+
|
14
|
+
private
|
15
|
+
|
16
|
+
def create_metric(metric_attrs)
|
17
|
+
backend = find_backend(metric_attrs.fetch('backend_system_name'))
|
18
|
+
|
19
|
+
unless backend.metrics.any? { |m| m.system_name == metric_attrs.fetch('system_name') }
|
20
|
+
Entities::BackendMetric.create(backend: backend, attrs: metric_attrs)
|
21
|
+
puts "Created backend metric: #{metric_attrs.fetch('system_name')}; backend: #{backend.system_name}"
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
def create_method(method_attrs)
|
26
|
+
backend = find_backend(method_attrs.fetch('backend_system_name'))
|
27
|
+
|
28
|
+
unless backend.methods.any? { |m| m.system_name == method_attrs.fetch('system_name') }
|
29
|
+
Entities::BackendMethod.create(backend: backend, attrs: method_attrs)
|
30
|
+
puts "Created backend method: #{method_attrs.fetch('system_name')}; backend: #{backend.system_name}"
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
@@ -2,7 +2,7 @@ module ThreeScaleToolbox
|
|
2
2
|
module Commands
|
3
3
|
module PlansCommand
|
4
4
|
module Import
|
5
|
-
class
|
5
|
+
class ImportLimitsStep
|
6
6
|
include Step
|
7
7
|
##
|
8
8
|
# Writes Plan limits
|
@@ -26,9 +26,18 @@ module ThreeScaleToolbox
|
|
26
26
|
|
27
27
|
def resource_limits_processed
|
28
28
|
resource_limits.map do |limit|
|
29
|
-
|
29
|
+
metric_system_name = limit.delete('metric_system_name')
|
30
|
+
backend_system_name = limit.delete('metric_backend_system_name')
|
31
|
+
metric_owner = if backend_system_name.nil?
|
32
|
+
service
|
33
|
+
else
|
34
|
+
find_backend(backend_system_name)
|
35
|
+
end
|
36
|
+
metric = metric_owner.find_metric_or_method(metric_system_name)
|
30
37
|
# this ImportMetricLimitsStep step is assuming all metrics/methods have been created
|
31
38
|
# in previous step, so finding metric should always succeed.
|
39
|
+
raise ThreeScaleToolbox::Error, "metric [#{metric_system_name}, #{backend_system_name}] not found" if metric.nil?
|
40
|
+
|
32
41
|
limit.merge('metric_id' => metric.id)
|
33
42
|
end
|
34
43
|
end
|
@@ -14,13 +14,13 @@ module ThreeScaleToolbox
|
|
14
14
|
private
|
15
15
|
|
16
16
|
def missing_metrics
|
17
|
-
ThreeScaleToolbox::Helper.array_difference(
|
17
|
+
ThreeScaleToolbox::Helper.array_difference(resource_product_metrics, service.metrics) do |a, b|
|
18
18
|
a['system_name'] == b.system_name
|
19
19
|
end
|
20
20
|
end
|
21
21
|
|
22
22
|
def missing_methods
|
23
|
-
ThreeScaleToolbox::Helper.array_difference(
|
23
|
+
ThreeScaleToolbox::Helper.array_difference(resource_product_methods, service.methods) do |a, b|
|
24
24
|
a['system_name'] == b.system_name
|
25
25
|
end
|
26
26
|
end
|
@@ -26,7 +26,18 @@ module ThreeScaleToolbox
|
|
26
26
|
|
27
27
|
def resource_pr_processed
|
28
28
|
resource_pricing_rules.map do |pr|
|
29
|
-
|
29
|
+
metric_system_name = pr.delete('metric_system_name')
|
30
|
+
backend_system_name = pr.delete('metric_backend_system_name')
|
31
|
+
metric_owner = if backend_system_name.nil?
|
32
|
+
service
|
33
|
+
else
|
34
|
+
find_backend(backend_system_name)
|
35
|
+
end
|
36
|
+
metric = metric_owner.find_metric_or_method(metric_system_name)
|
37
|
+
# this ImportMetricLimitsStep step is assuming all metrics/methods have been created
|
38
|
+
# in previous step, so finding metric should always succeed.
|
39
|
+
raise ThreeScaleToolbox::Error, "metric [#{metric_system_name}, #{backend_system_name}] not found" if metric.nil?
|
40
|
+
|
30
41
|
pr.merge('metric_id' => metric.id,
|
31
42
|
'cost_per_unit' => pr.fetch('cost_per_unit').to_f)
|
32
43
|
end
|
@@ -53,6 +53,22 @@ module ThreeScaleToolbox
|
|
53
53
|
artifacts_resource['methods'] || []
|
54
54
|
end
|
55
55
|
|
56
|
+
def resource_product_metrics
|
57
|
+
resource_metrics.reject{ |m| m.has_key? 'backend_system_name' }
|
58
|
+
end
|
59
|
+
|
60
|
+
def resource_product_methods
|
61
|
+
resource_methods.reject{ |mth| mth.has_key? 'backend_system_name' }
|
62
|
+
end
|
63
|
+
|
64
|
+
def resource_backend_metrics
|
65
|
+
resource_metrics.select{ |m| m.has_key? 'backend_system_name' }
|
66
|
+
end
|
67
|
+
|
68
|
+
def resource_backend_methods
|
69
|
+
resource_methods.select{ |mth| mth.has_key? 'backend_system_name' }
|
70
|
+
end
|
71
|
+
|
56
72
|
def resource_limits
|
57
73
|
artifacts_resource['limits'] || []
|
58
74
|
end
|
@@ -65,10 +81,6 @@ module ThreeScaleToolbox
|
|
65
81
|
artifacts_resource['plan_features'] || []
|
66
82
|
end
|
67
83
|
|
68
|
-
def service_metrics_and_methods
|
69
|
-
service.metrics + service.methods
|
70
|
-
end
|
71
|
-
|
72
84
|
def service_features
|
73
85
|
context[:service_features] ||= service.features
|
74
86
|
end
|
@@ -82,10 +94,6 @@ module ThreeScaleToolbox
|
|
82
94
|
service_features.find { |feature| feature['system_name'] == system_name }
|
83
95
|
end
|
84
96
|
|
85
|
-
def find_metric_by_system_name(system_name)
|
86
|
-
service_metrics_and_methods.find { |metric| metric.system_name == system_name }
|
87
|
-
end
|
88
|
-
|
89
97
|
private
|
90
98
|
|
91
99
|
def find_service
|
@@ -100,6 +108,13 @@ module ThreeScaleToolbox
|
|
100
108
|
raise ThreeScaleToolbox::Error, "Application plan #{plan_system_name} does not exist" if p.nil?
|
101
109
|
end
|
102
110
|
end
|
111
|
+
|
112
|
+
def find_backend(backend_system_name)
|
113
|
+
Entities::Backend.find_by_system_name(remote: threescale_client,
|
114
|
+
system_name: backend_system_name).tap do |backend|
|
115
|
+
raise ThreeScaleToolbox::Error, "Backend #{backend_system_name} does not exist" if backend.nil?
|
116
|
+
end
|
117
|
+
end
|
103
118
|
end
|
104
119
|
end
|
105
120
|
end
|
@@ -0,0 +1,126 @@
|
|
1
|
+
module ThreeScaleToolbox
|
2
|
+
module Commands
|
3
|
+
module PlansCommand
|
4
|
+
module Import
|
5
|
+
class ValidatePlanStep
|
6
|
+
include Step
|
7
|
+
##
|
8
|
+
# Creates if it does not exist, updates otherwise
|
9
|
+
def call
|
10
|
+
validate_product_metric_method_uniqueness!
|
11
|
+
|
12
|
+
validate_backend_metric_method_uniqueness!
|
13
|
+
|
14
|
+
validate_product_backend_usage_references!
|
15
|
+
|
16
|
+
validate_limit_backend_references!
|
17
|
+
|
18
|
+
validate_limit_product_references!
|
19
|
+
|
20
|
+
validate_pricingrule_backend_references!
|
21
|
+
|
22
|
+
validate_pricingrule_product_references!
|
23
|
+
end
|
24
|
+
|
25
|
+
private
|
26
|
+
|
27
|
+
def validate_product_metric_method_uniqueness!
|
28
|
+
system_name_list = (resource_product_metrics + resource_product_methods).map do |m|
|
29
|
+
m.fetch('system_name')
|
30
|
+
end
|
31
|
+
if system_name_list.length != system_name_list.uniq.length
|
32
|
+
raise ThreeScaleToolbox::Error, "Invalid content. " \
|
33
|
+
"Product metrics and method system names must be unique."
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
def validate_backend_metric_method_uniqueness!
|
38
|
+
metric_list = resource_backend_metrics + resource_backend_methods
|
39
|
+
backend_list = metric_list.map { |m| m.fetch('backend_system_name') }.uniq
|
40
|
+
backend_list.each do |backend_system_name|
|
41
|
+
backend_metric_list = metric_list.select do |m|
|
42
|
+
m.fetch('backend_system_name') == backend_system_name
|
43
|
+
end.map { |m| m.fetch('system_name') }
|
44
|
+
|
45
|
+
if backend_metric_list.length != backend_metric_list.uniq.length
|
46
|
+
raise ThreeScaleToolbox::Error, "Invalid content. " \
|
47
|
+
"Backend #{backend_system_name} contains metrics and method system names that are not unique"
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
def validate_product_backend_usage_references!
|
53
|
+
metric_list = resource_backend_metrics + resource_backend_methods
|
54
|
+
backend_list = metric_list.map { |m| m.fetch('backend_system_name') }.uniq
|
55
|
+
backend_usages_list = service.backend_usage_list.map(&:backend).map(&:system_name)
|
56
|
+
|
57
|
+
backend_list.each do |backend_system_name|
|
58
|
+
unless backend_usages_list.include?(backend_system_name)
|
59
|
+
raise ThreeScaleToolbox::Error, "Invalid content. " \
|
60
|
+
"Backend usage reference to backend #{backend_system_name} has not been found"
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
def validate_limit_backend_references!
|
66
|
+
metric_list = resource_backend_metrics + resource_backend_methods
|
67
|
+
limits_with_backend_ref = resource_limits.select{ |limit| limit.has_key? 'metric_backend_system_name'}
|
68
|
+
limits_with_backend_ref.each do |limit|
|
69
|
+
none = metric_list.none? do |m|
|
70
|
+
m.fetch('system_name') == limit.fetch('metric_system_name') &&
|
71
|
+
m.fetch('backend_system_name') == limit.fetch('metric_backend_system_name')
|
72
|
+
end
|
73
|
+
|
74
|
+
if none
|
75
|
+
raise ThreeScaleToolbox::Error, "Invalid content. " \
|
76
|
+
"Limit with backend metric [#{limit.fetch('metric_system_name')}, #{limit.fetch('metric_backend_system_name')}] " \
|
77
|
+
"has not been found in metric or method list"
|
78
|
+
end
|
79
|
+
end
|
80
|
+
end
|
81
|
+
|
82
|
+
def validate_limit_product_references!
|
83
|
+
metric_list = resource_product_metrics + resource_product_methods
|
84
|
+
limits = resource_limits.reject { |limit| limit.has_key? 'metric_backend_system_name'}
|
85
|
+
limits.each do |limit|
|
86
|
+
if metric_list.none? { |m| m.fetch('system_name') == limit.fetch('metric_system_name') }
|
87
|
+
raise ThreeScaleToolbox::Error, "Invalid content. " \
|
88
|
+
"Limit with product metric [#{limit.fetch('metric_system_name')}] " \
|
89
|
+
"has not been found in metric or method list"
|
90
|
+
end
|
91
|
+
end
|
92
|
+
end
|
93
|
+
|
94
|
+
def validate_pricingrule_backend_references!
|
95
|
+
metric_list = resource_backend_metrics + resource_backend_methods
|
96
|
+
pr_with_backend_ref = resource_pricing_rules.select{ |pr| pr.has_key? 'metric_backend_system_name'}
|
97
|
+
pr_with_backend_ref.each do |pr|
|
98
|
+
none = metric_list.none? do |m|
|
99
|
+
m.fetch('system_name') == pr.fetch('metric_system_name') &&
|
100
|
+
m.fetch('backend_system_name') == pr.fetch('metric_backend_system_name')
|
101
|
+
end
|
102
|
+
|
103
|
+
if none
|
104
|
+
raise ThreeScaleToolbox::Error, "Invalid content. " \
|
105
|
+
"PricingRule with backend metric [#{pr.fetch('metric_system_name')}, #{pr.fetch('metric_backend_system_name')}] " \
|
106
|
+
"has not been found in metric or method list"
|
107
|
+
end
|
108
|
+
end
|
109
|
+
end
|
110
|
+
|
111
|
+
def validate_pricingrule_product_references!
|
112
|
+
metric_list = resource_product_metrics + resource_product_methods
|
113
|
+
prs = resource_pricing_rules.reject { |pr| pr.has_key? 'metric_backend_system_name'}
|
114
|
+
prs.each do |pr|
|
115
|
+
if metric_list.none? { |m| m.fetch('system_name') == pr.fetch('metric_system_name') }
|
116
|
+
raise ThreeScaleToolbox::Error, "Invalid content. " \
|
117
|
+
"PricingRule with product metric [#{pr.fetch('metric_system_name')}] " \
|
118
|
+
"has not been found in metric or method list"
|
119
|
+
end
|
120
|
+
end
|
121
|
+
end
|
122
|
+
end
|
123
|
+
end
|
124
|
+
end
|
125
|
+
end
|
126
|
+
end
|
@@ -1,9 +1,11 @@
|
|
1
1
|
require '3scale_toolbox/commands/plans_command/import/step'
|
2
|
+
require '3scale_toolbox/commands/plans_command/import/validate_plan_step'
|
2
3
|
require '3scale_toolbox/commands/plans_command/import/create_or_update_app_plan_step'
|
3
4
|
require '3scale_toolbox/commands/plans_command/import/import_plan_features_step'
|
4
5
|
require '3scale_toolbox/commands/plans_command/import/import_plan_metrics_step'
|
5
6
|
require '3scale_toolbox/commands/plans_command/import/import_plan_limits_step'
|
6
7
|
require '3scale_toolbox/commands/plans_command/import/import_plan_pricing_rules_step'
|
8
|
+
require '3scale_toolbox/commands/plans_command/import/import_backend_metrics_step'
|
7
9
|
|
8
10
|
module ThreeScaleToolbox
|
9
11
|
module Commands
|
@@ -31,9 +33,11 @@ module ThreeScaleToolbox
|
|
31
33
|
|
32
34
|
def run
|
33
35
|
tasks = []
|
36
|
+
tasks << ValidatePlanStep.new(context)
|
34
37
|
tasks << CreateOrUpdateAppPlanStep.new(context)
|
35
38
|
tasks << ImportMetricsStep.new(context)
|
36
|
-
tasks <<
|
39
|
+
tasks << ImportBackendMetricsStep.new(context)
|
40
|
+
tasks << ImportLimitsStep.new(context)
|
37
41
|
tasks << ImportPricingRulesStep.new(context)
|
38
42
|
tasks << ImportPlanFeaturesStep.new(context)
|
39
43
|
|
@@ -27,6 +27,7 @@ module ThreeScaleToolbox
|
|
27
27
|
# First metrics as methods need 'hits' metric in target backend
|
28
28
|
tasks << Commands::BackendCommand::CopyCommand::CopyMetricsTask.new(backend_context)
|
29
29
|
tasks << Commands::BackendCommand::CopyCommand::CopyMethodsTask.new(backend_context)
|
30
|
+
tasks << Commands::BackendCommand::CopyCommand::DeleteMappingRulesTask.new(backend_context)
|
30
31
|
tasks << Commands::BackendCommand::CopyCommand::CopyMappingRulesTask.new(backend_context)
|
31
32
|
tasks.each(&:call)
|
32
33
|
|
@@ -72,12 +73,17 @@ module ThreeScaleToolbox
|
|
72
73
|
context.fetch(:logger)
|
73
74
|
end
|
74
75
|
|
76
|
+
def delete_mapping_rules
|
77
|
+
context.fetch(:delete_mapping_rules, false)
|
78
|
+
end
|
79
|
+
|
75
80
|
def create_backend_context(source_backend)
|
76
81
|
{
|
77
82
|
source_remote: source_remote,
|
78
83
|
target_remote: target_remote,
|
79
84
|
source_backend: source_backend,
|
80
85
|
source_backend_ref: source_backend.id,
|
86
|
+
delete_mapping_rules: delete_mapping_rules,
|
81
87
|
logger: logger
|
82
88
|
}
|
83
89
|
end
|