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
@@ -0,0 +1,100 @@
|
|
1
|
+
module ThreeScaleToolbox
|
2
|
+
module Commands
|
3
|
+
module PlansCommand
|
4
|
+
module Create
|
5
|
+
class CreateSubcommand < Cri::CommandRunner
|
6
|
+
include ThreeScaleToolbox::Command
|
7
|
+
|
8
|
+
def self.command
|
9
|
+
Cri::Command.define do
|
10
|
+
name 'create'
|
11
|
+
usage 'create [opts] <remote> <service> <plan_name>'
|
12
|
+
summary 'create application plan'
|
13
|
+
description 'Create application plan'
|
14
|
+
|
15
|
+
option :t, 'system-name', 'Application plan system 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 :p, :publish, 'Publish application plan'
|
19
|
+
option nil, 'approval-required', 'Applications require approval. true or false', argument: :required, transform: ThreeScaleToolbox::Helper::BooleanTransformer.new
|
20
|
+
option nil, 'cost-per-month', 'Cost per month', argument: :required, transform: method(:Integer)
|
21
|
+
option nil, 'setup-fee', 'Setup fee', argument: :required, transform: method(:Integer)
|
22
|
+
option nil, 'trial-period-days', 'Trial period days', argument: :required, transform: method(:Integer)
|
23
|
+
option nil, 'end-user-required', 'End user required. true or false', argument: :required, transform: ThreeScaleToolbox::Helper::BooleanTransformer.new
|
24
|
+
param :remote
|
25
|
+
param :service_ref
|
26
|
+
param :plan_name
|
27
|
+
|
28
|
+
runner CreateSubcommand
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
def run
|
33
|
+
plan = create_application_plan
|
34
|
+
plan.make_default if option_default
|
35
|
+
plan.disable if option_disabled
|
36
|
+
puts "Created application plan id: #{plan.id}. Default: #{option_default}; Disabled: #{option_disabled}"
|
37
|
+
end
|
38
|
+
|
39
|
+
private
|
40
|
+
|
41
|
+
def create_application_plan
|
42
|
+
ThreeScaleToolbox::Entities::ApplicationPlan.create(
|
43
|
+
service: service,
|
44
|
+
plan_attrs: plan_attrs
|
45
|
+
)
|
46
|
+
end
|
47
|
+
|
48
|
+
def plan_attrs
|
49
|
+
plan_basic_attrs.tap do |params|
|
50
|
+
params['state'] = 'published' if option_publish
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
def plan_basic_attrs
|
55
|
+
{
|
56
|
+
'name' => arguments[:plan_name],
|
57
|
+
'system_name' => options[:'system-name'],
|
58
|
+
'approval_required' => options[:'approval-required'],
|
59
|
+
'end_user_required' => options[:'end-user-required'],
|
60
|
+
'cost_per_month' => options[:'cost-per-month'],
|
61
|
+
'setup_fee' => options[:'setup-fee'],
|
62
|
+
'trial_period_days' => options[:'trial-period-days']
|
63
|
+
}.compact
|
64
|
+
end
|
65
|
+
|
66
|
+
def option_default
|
67
|
+
!options[:default].nil?
|
68
|
+
end
|
69
|
+
|
70
|
+
def option_disabled
|
71
|
+
!options[:disabled].nil?
|
72
|
+
end
|
73
|
+
|
74
|
+
def option_publish
|
75
|
+
!options[:publish].nil?
|
76
|
+
end
|
77
|
+
|
78
|
+
def service
|
79
|
+
@service ||= find_service
|
80
|
+
end
|
81
|
+
|
82
|
+
def find_service
|
83
|
+
Entities::Service.find(remote: remote,
|
84
|
+
ref: service_ref).tap do |svc|
|
85
|
+
raise ThreeScaleToolbox::Error, "Service #{service_ref} does not exist" if svc.nil?
|
86
|
+
end
|
87
|
+
end
|
88
|
+
|
89
|
+
def remote
|
90
|
+
@remote ||= threescale_client(arguments[:remote])
|
91
|
+
end
|
92
|
+
|
93
|
+
def service_ref
|
94
|
+
arguments[:service_ref]
|
95
|
+
end
|
96
|
+
end
|
97
|
+
end
|
98
|
+
end
|
99
|
+
end
|
100
|
+
end
|
@@ -0,0 +1,66 @@
|
|
1
|
+
module ThreeScaleToolbox
|
2
|
+
module Commands
|
3
|
+
module PlansCommand
|
4
|
+
module Delete
|
5
|
+
class DeleteSubcommand < Cri::CommandRunner
|
6
|
+
include ThreeScaleToolbox::Command
|
7
|
+
|
8
|
+
def self.command
|
9
|
+
Cri::Command.define do
|
10
|
+
name 'delete'
|
11
|
+
usage 'delete [opts] <remote> <service> <plan>'
|
12
|
+
summary 'delete application plan'
|
13
|
+
description 'Delete application plan'
|
14
|
+
|
15
|
+
param :remote
|
16
|
+
param :service_ref
|
17
|
+
param :plan_ref
|
18
|
+
|
19
|
+
runner DeleteSubcommand
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
def run
|
24
|
+
plan.delete
|
25
|
+
puts "Application plan id: #{plan.id} deleted"
|
26
|
+
end
|
27
|
+
|
28
|
+
private
|
29
|
+
|
30
|
+
def service
|
31
|
+
@service ||= find_service
|
32
|
+
end
|
33
|
+
|
34
|
+
def plan
|
35
|
+
@plan ||= find_plan
|
36
|
+
end
|
37
|
+
|
38
|
+
def find_service
|
39
|
+
Entities::Service.find(remote: remote,
|
40
|
+
ref: service_ref).tap do |svc|
|
41
|
+
raise ThreeScaleToolbox::Error, "Service #{service_ref} does not exist" if svc.nil?
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
def find_plan
|
46
|
+
Entities::ApplicationPlan.find(service: service, ref: plan_ref).tap do |p|
|
47
|
+
raise ThreeScaleToolbox::Error, "Application plan #{plan_ref} does not exist" if p.nil?
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
def remote
|
52
|
+
@remote ||= threescale_client(arguments[:remote])
|
53
|
+
end
|
54
|
+
|
55
|
+
def service_ref
|
56
|
+
arguments[:service_ref]
|
57
|
+
end
|
58
|
+
|
59
|
+
def plan_ref
|
60
|
+
arguments[:plan_ref]
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|
65
|
+
end
|
66
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
module ThreeScaleToolbox
|
2
|
+
module Commands
|
3
|
+
module PlansCommand
|
4
|
+
module Export
|
5
|
+
class ReadPlanFeaturesStep
|
6
|
+
include Step
|
7
|
+
##
|
8
|
+
# Reads Application Plan features
|
9
|
+
def call
|
10
|
+
result[:plan_features] = plan.features
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
module ThreeScaleToolbox
|
2
|
+
module Commands
|
3
|
+
module PlansCommand
|
4
|
+
module Export
|
5
|
+
class ReadPlanLimitsStep
|
6
|
+
include Step
|
7
|
+
##
|
8
|
+
# Reads Application Plan limits
|
9
|
+
# add metric system_name out of metric_id
|
10
|
+
def call
|
11
|
+
result[:limits] = plan.limits.map do |limit|
|
12
|
+
limit.tap { |l| l['metric'] = metric_info(l, 'Limit') }
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1,50 @@
|
|
1
|
+
module ThreeScaleToolbox
|
2
|
+
module Commands
|
3
|
+
module PlansCommand
|
4
|
+
module Export
|
5
|
+
class ReadPlanMethods
|
6
|
+
include Step
|
7
|
+
##
|
8
|
+
# Compute unique list of methods from limits and pricingrules
|
9
|
+
def call
|
10
|
+
methods = [
|
11
|
+
limit_methods,
|
12
|
+
pricingrule_methods
|
13
|
+
]
|
14
|
+
result[:plan_methods] = methods.each_with_object({}) { |elem, acc| acc.merge!(elem) }
|
15
|
+
end
|
16
|
+
|
17
|
+
private
|
18
|
+
|
19
|
+
def limit_methods
|
20
|
+
# multiple limits can reference the same method
|
21
|
+
filtered_limit_methods.each_with_object({}) do |elem, acc|
|
22
|
+
# find_method should not return nil.
|
23
|
+
# It is assumed that metric_id refers to existing element from previous steps
|
24
|
+
acc[elem['metric_id']] = find_method(elem['metric_id'])
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
def filtered_limit_methods
|
29
|
+
# has to be filtered this way
|
30
|
+
# looking up in metrics list does not work. Metric list includes methods and metrics
|
31
|
+
result[:limits].select { |limit| limit.dig('metric', 'type') == 'method' }
|
32
|
+
end
|
33
|
+
|
34
|
+
def pricingrule_methods
|
35
|
+
filtered_pricing_rule_methods.each_with_object({}) do |elem, acc|
|
36
|
+
# find_method should not return nil.
|
37
|
+
# It is assumed that metric_id refers to existing element from previous steps
|
38
|
+
acc[elem['metric_id']] = find_method(elem['metric_id'])
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
def filtered_pricing_rule_methods
|
43
|
+
# looking up in metrics list does not work. Metric list includes methods and metrics
|
44
|
+
result[:pricingrules].select { |limit| limit.dig('metric', 'type') == 'method' }
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
@@ -0,0 +1,49 @@
|
|
1
|
+
module ThreeScaleToolbox
|
2
|
+
module Commands
|
3
|
+
module PlansCommand
|
4
|
+
module Export
|
5
|
+
class ReadPlanMetrics
|
6
|
+
include Step
|
7
|
+
##
|
8
|
+
# Compute unique list of metrics limits and pricingrules
|
9
|
+
def call
|
10
|
+
all_metrics = [
|
11
|
+
limit_metrics,
|
12
|
+
pricingrule_metrics
|
13
|
+
]
|
14
|
+
result[:plan_metrics] = all_metrics.each_with_object({}) { |elem, acc| acc.merge!(elem) }
|
15
|
+
end
|
16
|
+
|
17
|
+
private
|
18
|
+
|
19
|
+
def limit_metrics
|
20
|
+
# multiple limits can reference the same metric
|
21
|
+
filtered_limit_metrics.each_with_object({}) do |elem, acc|
|
22
|
+
# find_metric should not return nil.
|
23
|
+
# It is assumed that metric_id refers to existing element from previous steps
|
24
|
+
acc[elem['metric_id']] = find_metric(elem['metric_id'])
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
def filtered_limit_metrics
|
29
|
+
# looking up in metrics list does not work. Metric list includes methods and metrics
|
30
|
+
result[:limits].select { |limit| limit.dig('metric', 'type') == 'metric' }
|
31
|
+
end
|
32
|
+
|
33
|
+
def pricingrule_metrics
|
34
|
+
filtered_pricing_rule_metrics.each_with_object({}) do |elem, acc|
|
35
|
+
# find_metric should not return nil.
|
36
|
+
# It is assumed that metric_id refers to existing element from previous steps
|
37
|
+
acc[elem['metric_id']] = find_metric(elem['metric_id'])
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
def filtered_pricing_rule_metrics
|
42
|
+
# looking up in metrics list does not work. Metric list includes methods and metrics
|
43
|
+
result[:pricingrules].select { |limit| limit.dig('metric', 'type') == 'metric' }
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
module ThreeScaleToolbox
|
2
|
+
module Commands
|
3
|
+
module PlansCommand
|
4
|
+
module Export
|
5
|
+
class ReadPlanPricingRulesStep
|
6
|
+
include Step
|
7
|
+
##
|
8
|
+
# Reads Application Plan pricing rules
|
9
|
+
# add metric system_name out of metric_id
|
10
|
+
def call
|
11
|
+
result[:pricingrules] = plan.pricing_rules.map do |pr|
|
12
|
+
pr.tap { |e| e['metric'] = metric_info(e, 'PricingRule') }
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1,95 @@
|
|
1
|
+
module ThreeScaleToolbox
|
2
|
+
module Commands
|
3
|
+
module PlansCommand
|
4
|
+
module Export
|
5
|
+
APP_PLANS_BLACKLIST = %w[id links default custom created_at updated_at].freeze
|
6
|
+
LIMITS_BLACKLIST = %w[id metric_id links created_at updated_at].freeze
|
7
|
+
PRICINGRULES_BLACKLIST = %w[id metric_id links created_at updated_at].freeze
|
8
|
+
PLAN_FEATURE_BLACKLIST = %w[id links created_at updated_at].freeze
|
9
|
+
METRIC_BLACKLIST = %w[id links created_at updated_at].freeze
|
10
|
+
|
11
|
+
module Step
|
12
|
+
attr_reader :context
|
13
|
+
|
14
|
+
def initialize(context)
|
15
|
+
@context = context
|
16
|
+
end
|
17
|
+
|
18
|
+
def service
|
19
|
+
context[:service] ||= find_service
|
20
|
+
end
|
21
|
+
|
22
|
+
def file
|
23
|
+
context[:file]
|
24
|
+
end
|
25
|
+
|
26
|
+
def threescale_client
|
27
|
+
context[:threescale_client]
|
28
|
+
end
|
29
|
+
|
30
|
+
# can be id or system_name
|
31
|
+
def service_system_name
|
32
|
+
context[:service_system_name]
|
33
|
+
end
|
34
|
+
|
35
|
+
# can be id or system_name
|
36
|
+
def plan_system_name
|
37
|
+
context[:plan_system_name]
|
38
|
+
end
|
39
|
+
|
40
|
+
def result
|
41
|
+
context[:result] ||= {}
|
42
|
+
end
|
43
|
+
|
44
|
+
def plan
|
45
|
+
context[:plan] ||= find_plan
|
46
|
+
end
|
47
|
+
|
48
|
+
def service_metrics
|
49
|
+
context[:service_metrics] ||= service.metrics
|
50
|
+
end
|
51
|
+
|
52
|
+
def service_methods
|
53
|
+
context[:service_methods] ||= service.methods
|
54
|
+
end
|
55
|
+
|
56
|
+
def metric_info(elem, elem_name)
|
57
|
+
# Methods are included in metrics.
|
58
|
+
# First methods must be checked, otherwise it could be considered as a false metric
|
59
|
+
if (method = find_method(elem.fetch('metric_id')))
|
60
|
+
{ 'type' => 'method', 'system_name' => method.fetch('system_name') }
|
61
|
+
elsif (metric = find_metric(elem.fetch('metric_id')))
|
62
|
+
{ 'type' => 'metric', 'system_name' => metric.fetch('system_name') }
|
63
|
+
else
|
64
|
+
raise ThreeScaleToolbox::Error, "Unexpected error. #{elem_name} #{elem['id']} " \
|
65
|
+
"referencing to metric id #{elem.fetch('metric_id')} which has not been found"
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
private
|
70
|
+
|
71
|
+
def find_service
|
72
|
+
Entities::Service.find(remote: threescale_client,
|
73
|
+
ref: service_system_name).tap do |svc|
|
74
|
+
raise ThreeScaleToolbox::Error, "Service #{service_system_name} does not exist" if svc.nil?
|
75
|
+
end
|
76
|
+
end
|
77
|
+
|
78
|
+
def find_plan
|
79
|
+
Entities::ApplicationPlan.find(service: service, ref: plan_system_name).tap do |p|
|
80
|
+
raise ThreeScaleToolbox::Error, "Application plan #{plan_system_name} does not exist" if p.nil?
|
81
|
+
end
|
82
|
+
end
|
83
|
+
|
84
|
+
def find_metric(id)
|
85
|
+
service_metrics.find { |metric| metric['id'] == id }
|
86
|
+
end
|
87
|
+
|
88
|
+
def find_method(id)
|
89
|
+
service_methods.find { |method| method['id'] == id }
|
90
|
+
end
|
91
|
+
end
|
92
|
+
end
|
93
|
+
end
|
94
|
+
end
|
95
|
+
end
|
@@ -0,0 +1,84 @@
|
|
1
|
+
module ThreeScaleToolbox
|
2
|
+
module Commands
|
3
|
+
module PlansCommand
|
4
|
+
module Export
|
5
|
+
class WriteArtifactsStep
|
6
|
+
include Step
|
7
|
+
##
|
8
|
+
# Serialization of Application Plan objects
|
9
|
+
def call
|
10
|
+
select_output do |output|
|
11
|
+
output.write(serialized_object.to_yaml)
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
private
|
16
|
+
|
17
|
+
def select_output
|
18
|
+
ios = if file
|
19
|
+
File.open(file, 'w')
|
20
|
+
else
|
21
|
+
$stdout
|
22
|
+
end
|
23
|
+
begin
|
24
|
+
yield(ios)
|
25
|
+
ensure
|
26
|
+
ios.close
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
def serialized_object
|
31
|
+
{
|
32
|
+
'plan' => serialized_plan,
|
33
|
+
'limits' => serialized_limits,
|
34
|
+
'pricingrules' => serialized_pricing_rules,
|
35
|
+
'plan_features' => serialized_plan_features,
|
36
|
+
'metrics' => serialized_metrics,
|
37
|
+
'methods' => serialized_methods,
|
38
|
+
'created_at' => Time.now.utc.iso8601,
|
39
|
+
'toolbox_version' => ThreeScaleToolbox::VERSION
|
40
|
+
}
|
41
|
+
end
|
42
|
+
|
43
|
+
def serialized_plan
|
44
|
+
result[:plan].reject { |key, _| APP_PLANS_BLACKLIST.include? key }
|
45
|
+
end
|
46
|
+
|
47
|
+
def serialized_limits
|
48
|
+
result[:limits].map do |limit|
|
49
|
+
metric = limit.delete('metric')
|
50
|
+
limit['metric_system_name'] = metric['system_name']
|
51
|
+
limit.reject { |key, _| LIMITS_BLACKLIST.include? key }
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
def serialized_pricing_rules
|
56
|
+
result[:pricingrules].map do |pr|
|
57
|
+
metric = pr.delete('metric')
|
58
|
+
pr['metric_system_name'] = metric['system_name']
|
59
|
+
pr.reject { |key, _| PRICINGRULES_BLACKLIST.include? key }
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
def serialized_plan_features
|
64
|
+
result[:plan_features].map do |pr|
|
65
|
+
pr.reject { |key, _| PLAN_FEATURE_BLACKLIST.include? key }
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
def serialized_metrics
|
70
|
+
result[:plan_metrics].values.map do |metric|
|
71
|
+
metric.reject { |key, _| METRIC_BLACKLIST.include? key }
|
72
|
+
end
|
73
|
+
end
|
74
|
+
|
75
|
+
def serialized_methods
|
76
|
+
result[:plan_methods].values.map do |method|
|
77
|
+
method.reject { |key, _| METRIC_BLACKLIST.include? key }
|
78
|
+
end
|
79
|
+
end
|
80
|
+
end
|
81
|
+
end
|
82
|
+
end
|
83
|
+
end
|
84
|
+
end
|
@@ -0,0 +1,65 @@
|
|
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
|
+
module ThreeScaleToolbox
|
11
|
+
module Commands
|
12
|
+
module PlansCommand
|
13
|
+
module Export
|
14
|
+
class ExportSubcommand < Cri::CommandRunner
|
15
|
+
include ThreeScaleToolbox::Command
|
16
|
+
|
17
|
+
def self.command
|
18
|
+
Cri::Command.define do
|
19
|
+
name 'export'
|
20
|
+
usage 'export [opts] <remote> <service_system_name> <plan_system_name>'
|
21
|
+
summary 'export application plan'
|
22
|
+
description 'Export application plan, limits, pricing rules and features'
|
23
|
+
|
24
|
+
option :f, :file, 'Write to file instead of stdout', argument: :required
|
25
|
+
param :remote
|
26
|
+
param :service_system_name
|
27
|
+
param :plan_system_name
|
28
|
+
|
29
|
+
runner ExportSubcommand
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
def run
|
34
|
+
tasks = []
|
35
|
+
tasks << ReadAppPlanStep.new(context)
|
36
|
+
tasks << ReadPlanLimitsStep.new(context)
|
37
|
+
tasks << ReadPlanPricingRulesStep.new(context)
|
38
|
+
tasks << ReadPlanFeaturesStep.new(context)
|
39
|
+
tasks << ReadPlanMethods.new(context)
|
40
|
+
tasks << ReadPlanMetrics.new(context)
|
41
|
+
tasks << WriteArtifactsStep.new(context)
|
42
|
+
|
43
|
+
# run tasks
|
44
|
+
tasks.each(&:call)
|
45
|
+
end
|
46
|
+
|
47
|
+
private
|
48
|
+
|
49
|
+
def context
|
50
|
+
@context ||= create_context
|
51
|
+
end
|
52
|
+
|
53
|
+
def create_context
|
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
|
+
}
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|
65
|
+
end
|
@@ -0,0 +1,33 @@
|
|
1
|
+
module ThreeScaleToolbox
|
2
|
+
module Commands
|
3
|
+
module PlansCommand
|
4
|
+
module Import
|
5
|
+
class CreateOrUpdateAppPlanStep
|
6
|
+
include Step
|
7
|
+
##
|
8
|
+
# Creates if it does not exist, updates otherwise
|
9
|
+
def call
|
10
|
+
plan_obj = Entities::ApplicationPlan.find(service: service, ref: plan_system_name)
|
11
|
+
if plan_obj.nil?
|
12
|
+
plan_obj = Entities::ApplicationPlan.create(service: service, plan_attrs: plan_attrs)
|
13
|
+
puts "Application plan created: #{plan_obj.id}"
|
14
|
+
else
|
15
|
+
res = plan_obj.update(plan_attrs)
|
16
|
+
if (errors = res['errors'])
|
17
|
+
raise ThreeScaleToolbox::Error, "Could not update application plan #{plan_system_name}. Errors: #{errors}"
|
18
|
+
end
|
19
|
+
|
20
|
+
puts "Application plan updated: #{plan_obj.id}"
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
private
|
25
|
+
|
26
|
+
def plan_attrs
|
27
|
+
resource_plan.merge('system_name' => plan_system_name)
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
@@ -0,0 +1,45 @@
|
|
1
|
+
module ThreeScaleToolbox
|
2
|
+
module Commands
|
3
|
+
module PlansCommand
|
4
|
+
module Import
|
5
|
+
class ImportPlanFeaturesStep
|
6
|
+
include Step
|
7
|
+
##
|
8
|
+
# Writes Plan features
|
9
|
+
def call
|
10
|
+
missing_features.each do |feature|
|
11
|
+
create_plan_feature(feature)
|
12
|
+
puts "Created plan feature: #{feature}"
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
private
|
17
|
+
|
18
|
+
def missing_features
|
19
|
+
ThreeScaleToolbox::Helper.array_difference(resource_features, plan.features) do |a, b|
|
20
|
+
ThreeScaleToolbox::Helper.compare_hashes(a, b, ['system_name'])
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
def create_plan_feature(feature_attrs)
|
25
|
+
feature = find_feature_by_system_name(feature_attrs['system_name']) || create_service_feature(feature_attrs)
|
26
|
+
|
27
|
+
plan.create_feature(feature['id']).tap do |resp|
|
28
|
+
if (errors = resp['errors'])
|
29
|
+
raise ThreeScaleToolbox::Error, "Plan feature has not been created. #{errors}"
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
def create_service_feature(feature_attrs)
|
35
|
+
service.create_feature(feature_attrs).tap do |resp|
|
36
|
+
if (errors = resp['errors'])
|
37
|
+
raise ThreeScaleToolbox::Error, "Service feature has not been created. #{errors}"
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|