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