3scale_toolbox 0.19.2 → 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/lib/3scale_toolbox/commands/import_command/openapi/update_policies_step.rb +23 -10
- 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/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/remote_cache.rb +42 -1
- data/lib/3scale_toolbox/version.rb +1 -1
- data/licenses.xml +4 -4
- metadata +4 -10
- 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
|
@@ -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
|
@@ -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
|
|
@@ -18,7 +18,7 @@ module ThreeScaleToolbox
|
|
18
18
|
{ 'systemName' => method.system_name }
|
19
19
|
elsif (metric = plan.service.metrics.find { |m| m.id == metric_id })
|
20
20
|
{ 'systemName' => metric.system_name }
|
21
|
-
elsif (backend =
|
21
|
+
elsif (backend = backend_from_metric_link)
|
22
22
|
if (backend_metric = backend.metrics.find { |m| m.id == metric_id })
|
23
23
|
{ 'systemName' => backend_metric.system_name, 'backend' => backend.system_name }
|
24
24
|
elsif (backend_method = backend.methods.find { |m| m.id == metric_id })
|
@@ -19,7 +19,7 @@ module ThreeScaleToolbox
|
|
19
19
|
{ 'systemName' => method.system_name }
|
20
20
|
elsif (metric = plan.service.metrics.find { |m| m.id == metric_id })
|
21
21
|
{ 'systemName' => metric.system_name }
|
22
|
-
elsif (backend =
|
22
|
+
elsif (backend = backend_from_metric_link)
|
23
23
|
if (backend_metric = backend.metrics.find { |m| m.id == metric_id })
|
24
24
|
{ 'systemName' => backend_metric.system_name, 'backend' => backend.system_name }
|
25
25
|
elsif (backend_method = backend.methods.find { |m| m.id == metric_id })
|
@@ -3,6 +3,9 @@ module ThreeScaleToolbox
|
|
3
3
|
class ApplicationPlan
|
4
4
|
include CRD::ApplicationPlanSerializer
|
5
5
|
|
6
|
+
APP_PLANS_BLACKLIST = %w[id links default custom created_at updated_at].freeze
|
7
|
+
PLAN_FEATURE_BLACKLIST = %w[id links created_at updated_at].freeze
|
8
|
+
|
6
9
|
class << self
|
7
10
|
def create(service:, plan_attrs:)
|
8
11
|
plan = service.remote.create_application_plan service.id, create_plan_attrs(plan_attrs)
|
@@ -209,8 +212,69 @@ module ThreeScaleToolbox
|
|
209
212
|
attrs.fetch('cost_per_month', 0.0)
|
210
213
|
end
|
211
214
|
|
215
|
+
def to_hash
|
216
|
+
{
|
217
|
+
'plan' => attrs.reject { |key, _| APP_PLANS_BLACKLIST.include? key },
|
218
|
+
'limits' => limits.map(&:to_hash),
|
219
|
+
'pricingrules' => pricing_rules.map(&:to_hash),
|
220
|
+
'plan_features' => features.map do |feature|
|
221
|
+
feature.reject { |key, _| PLAN_FEATURE_BLACKLIST.include? key }
|
222
|
+
end,
|
223
|
+
'metrics' => uniq_metrics_to_hash,
|
224
|
+
'methods' => uniq_methods_to_hash,
|
225
|
+
}
|
226
|
+
end
|
227
|
+
|
212
228
|
private
|
213
229
|
|
230
|
+
def uniq_metrics_to_hash
|
231
|
+
limit_metrics = limits.flat_map do |limit|
|
232
|
+
# one of them (or both) could be nil
|
233
|
+
[
|
234
|
+
limit.product_metric, limit.backend_metric
|
235
|
+
]
|
236
|
+
end.compact
|
237
|
+
|
238
|
+
pr_metrics = pricing_rules.flat_map do |pr|
|
239
|
+
# one of them (or both) could be nil
|
240
|
+
[
|
241
|
+
pr.product_metric, pr.backend_metric
|
242
|
+
]
|
243
|
+
end.compact
|
244
|
+
|
245
|
+
# multiple limits can reference the same metric
|
246
|
+
# multiple pricing rules can reference the same metric
|
247
|
+
uniq_metrics = limit_metrics.concat(pr_metrics).each_with_object({}) do |metric, acc|
|
248
|
+
acc[metric.enriched_key] = metric
|
249
|
+
end.values
|
250
|
+
|
251
|
+
uniq_metrics.map { |metric| metric.to_hash }
|
252
|
+
end
|
253
|
+
|
254
|
+
def uniq_methods_to_hash
|
255
|
+
limit_methods = limits.flat_map do |limit|
|
256
|
+
# one of them (or both) could be nil
|
257
|
+
[
|
258
|
+
limit.product_method, limit.backend_method
|
259
|
+
]
|
260
|
+
end.compact
|
261
|
+
|
262
|
+
pr_methods = pricing_rules.flat_map do |pr|
|
263
|
+
# one of them (or both) could be nil
|
264
|
+
[
|
265
|
+
pr.product_method, pr.backend_method
|
266
|
+
]
|
267
|
+
end.compact
|
268
|
+
|
269
|
+
# multiple limits can reference the same method
|
270
|
+
# multiple pricing rules can reference the same method
|
271
|
+
uniq_methods = limit_methods.concat(pr_methods).each_with_object({}) do |method, acc|
|
272
|
+
acc[method.enriched_key] = method
|
273
|
+
end.values
|
274
|
+
|
275
|
+
uniq_methods.map { |method| method.to_hash }
|
276
|
+
end
|
277
|
+
|
214
278
|
def read_plan_attrs
|
215
279
|
raise ThreeScaleToolbox::InvalidIdError if id.zero?
|
216
280
|
|
@@ -161,6 +161,10 @@ module ThreeScaleToolbox
|
|
161
161
|
remote.http_client.endpoint == other.remote.http_client.endpoint && id == other.id
|
162
162
|
end
|
163
163
|
|
164
|
+
def find_metric_or_method(system_name)
|
165
|
+
(metrics + methods).find { |m| m.system_name == system_name }
|
166
|
+
end
|
167
|
+
|
164
168
|
private
|
165
169
|
|
166
170
|
def metrics_and_methods
|
@@ -6,6 +6,8 @@ module ThreeScaleToolbox
|
|
6
6
|
VALID_PARAMS = %w[friendly_name system_name description].freeze
|
7
7
|
public_constant :VALID_PARAMS
|
8
8
|
|
9
|
+
METHOD_BLACKLIST = %w[id links created_at updated_at parent_id].freeze
|
10
|
+
|
9
11
|
class << self
|
10
12
|
def create(backend:, attrs:)
|
11
13
|
method = backend.remote.create_backend_method(backend.id, backend.hits.id,
|
@@ -71,6 +73,20 @@ module ThreeScaleToolbox
|
|
71
73
|
remote.delete_backend_method backend.id, hits_id, id
|
72
74
|
end
|
73
75
|
|
76
|
+
# enriched_key returns a metric key that will be unique for all
|
77
|
+
# metrics/methods from products and backends
|
78
|
+
def enriched_key
|
79
|
+
"backend.#{backend.id}.#{id}"
|
80
|
+
end
|
81
|
+
|
82
|
+
def to_hash
|
83
|
+
extra_attrs = {
|
84
|
+
'backend_system_name' => backend.system_name
|
85
|
+
}
|
86
|
+
|
87
|
+
attrs.merge(extra_attrs).reject { |key, _| METHOD_BLACKLIST.include? key }
|
88
|
+
end
|
89
|
+
|
74
90
|
private
|
75
91
|
|
76
92
|
def hits_id
|
@@ -6,6 +6,8 @@ module ThreeScaleToolbox
|
|
6
6
|
VALID_PARAMS = %w[friendly_name system_name unit description].freeze
|
7
7
|
public_constant :VALID_PARAMS
|
8
8
|
|
9
|
+
METRIC_BLACKLIST = %w[id links created_at updated_at].freeze
|
10
|
+
|
9
11
|
class << self
|
10
12
|
def create(backend:, attrs:)
|
11
13
|
metric = backend.remote.create_backend_metric(backend.id,
|
@@ -74,6 +76,20 @@ module ThreeScaleToolbox
|
|
74
76
|
remote.delete_backend_metric backend.id, id
|
75
77
|
end
|
76
78
|
|
79
|
+
# enriched_key returns a metric key that will be unique for all
|
80
|
+
# metrics from products and backends
|
81
|
+
def enriched_key
|
82
|
+
"backend.#{backend.id}.#{id}"
|
83
|
+
end
|
84
|
+
|
85
|
+
def to_hash
|
86
|
+
extra_attrs = {
|
87
|
+
'backend_system_name' => backend.system_name
|
88
|
+
}
|
89
|
+
|
90
|
+
attrs.merge(extra_attrs).reject { |key, _| METRIC_BLACKLIST.include? key }
|
91
|
+
end
|
92
|
+
|
77
93
|
private
|
78
94
|
|
79
95
|
def process_attrs(metric_attrs)
|