3scale_toolbox 0.16.0 → 0.18.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 +2 -2
- data/README.md +11 -8
- data/lib/3scale_toolbox.rb +3 -0
- data/lib/3scale_toolbox/3scale_client_factory.rb +3 -4
- data/lib/3scale_toolbox/cli/error_handler.rb +17 -14
- data/lib/3scale_toolbox/commands.rb +2 -0
- data/lib/3scale_toolbox/commands/backend_command/copy_command/copy_mapping_rules_task.rb +11 -27
- data/lib/3scale_toolbox/commands/backend_command/copy_command/copy_methods_task.rb +5 -10
- data/lib/3scale_toolbox/commands/backend_command/copy_command/copy_metrics_task.rb +4 -4
- data/lib/3scale_toolbox/commands/backend_command/copy_command/create_or_update_target_backend_task.rb +3 -2
- data/lib/3scale_toolbox/commands/backend_command/copy_command/task.rb +10 -32
- data/lib/3scale_toolbox/commands/import_command/issuer_type_transformer.rb +16 -0
- data/lib/3scale_toolbox/commands/import_command/openapi.rb +3 -0
- data/lib/3scale_toolbox/commands/import_command/openapi/create_activedocs_step.rb +3 -2
- data/lib/3scale_toolbox/commands/import_command/openapi/create_mapping_rule_step.rb +2 -1
- data/lib/3scale_toolbox/commands/import_command/openapi/create_method_step.rb +5 -14
- data/lib/3scale_toolbox/commands/import_command/openapi/step.rb +4 -0
- data/lib/3scale_toolbox/commands/import_command/openapi/update_service_proxy_step.rb +1 -0
- data/lib/3scale_toolbox/commands/methods_command/apply_command.rb +2 -4
- data/lib/3scale_toolbox/commands/methods_command/create_command.rb +0 -2
- data/lib/3scale_toolbox/commands/methods_command/delete_command.rb +1 -1
- data/lib/3scale_toolbox/commands/methods_command/list_command.rb +1 -9
- data/lib/3scale_toolbox/commands/metrics_command/list_command.rb +1 -1
- data/lib/3scale_toolbox/commands/plans_command/export/read_plan_limits_step.rb +1 -1
- data/lib/3scale_toolbox/commands/plans_command/export/read_plan_methods_step.rb +2 -2
- data/lib/3scale_toolbox/commands/plans_command/export/read_plan_metrics_step.rb +2 -2
- data/lib/3scale_toolbox/commands/plans_command/export/read_plan_pricing_rules_step.rb +1 -2
- data/lib/3scale_toolbox/commands/plans_command/export/step.rb +8 -20
- data/lib/3scale_toolbox/commands/plans_command/import/import_plan_limits_step.rb +12 -14
- data/lib/3scale_toolbox/commands/plans_command/import/import_plan_metrics_step.rb +6 -13
- data/lib/3scale_toolbox/commands/plans_command/import/import_plan_pricing_rules_step.rb +12 -20
- data/lib/3scale_toolbox/commands/plans_command/import/step.rb +2 -22
- data/lib/3scale_toolbox/commands/plans_command/list_command.rb +1 -1
- data/lib/3scale_toolbox/commands/plans_command/show_command.rb +1 -1
- data/lib/3scale_toolbox/commands/policies_command.rb +24 -0
- data/lib/3scale_toolbox/commands/policies_command/export_command.rb +98 -0
- data/lib/3scale_toolbox/commands/policies_command/import_command.rb +61 -0
- data/lib/3scale_toolbox/commands/product_command.rb +4 -0
- data/lib/3scale_toolbox/commands/product_command/copy_command.rb +7 -3
- data/lib/3scale_toolbox/commands/product_command/copy_command/copy_backends_task.rb +22 -5
- data/lib/3scale_toolbox/commands/product_command/export_command.rb +81 -0
- data/lib/3scale_toolbox/commands/product_command/import_command.rb +125 -0
- data/lib/3scale_toolbox/commands/proxy_config_command.rb +5 -0
- data/lib/3scale_toolbox/commands/proxy_config_command/deploy_command.rb +54 -0
- data/lib/3scale_toolbox/commands/proxy_config_command/export_command.rb +74 -0
- data/lib/3scale_toolbox/commands/proxy_config_command/helper.rb +15 -0
- data/lib/3scale_toolbox/commands/service_command/copy_command/copy_activedocs_task.rb +15 -12
- data/lib/3scale_toolbox/commands/service_command/copy_command/copy_app_plans_task.rb +15 -15
- data/lib/3scale_toolbox/commands/service_command/copy_command/copy_limits_task.rb +12 -13
- data/lib/3scale_toolbox/commands/service_command/copy_command/copy_mapping_rules_task.rb +11 -11
- data/lib/3scale_toolbox/commands/service_command/copy_command/copy_methods_task.rb +9 -12
- data/lib/3scale_toolbox/commands/service_command/copy_command/copy_metrics_task.rb +8 -8
- data/lib/3scale_toolbox/commands/service_command/copy_command/copy_policies_task.rb +1 -1
- data/lib/3scale_toolbox/commands/service_command/copy_command/copy_pricingrules_task.rb +15 -18
- data/lib/3scale_toolbox/commands/service_command/copy_command/copy_service_proxy_task.rb +17 -2
- data/lib/3scale_toolbox/commands/service_command/copy_command/create_or_update_service_task.rb +2 -1
- data/lib/3scale_toolbox/commands/service_command/copy_command/destroy_mapping_rules_task.rb +9 -5
- data/lib/3scale_toolbox/commands/service_command/copy_command/task.rb +20 -34
- data/lib/3scale_toolbox/commands/update_command.rb +1 -1
- data/lib/3scale_toolbox/commands/update_command/service_command.rb +3 -2
- data/lib/3scale_toolbox/commands/update_command/service_command/delete_activedocs_task.rb +1 -3
- data/lib/3scale_toolbox/crds.rb +16 -0
- data/lib/3scale_toolbox/crds/application_plan_dump.rb +19 -0
- data/lib/3scale_toolbox/crds/backend_dump.rb +39 -0
- data/lib/3scale_toolbox/crds/backend_mapping_rule_dump.rb +26 -0
- data/lib/3scale_toolbox/crds/backend_method_dump.rb +12 -0
- data/lib/3scale_toolbox/crds/backend_metric_dump.rb +13 -0
- data/lib/3scale_toolbox/crds/backend_parser.rb +55 -0
- data/lib/3scale_toolbox/crds/backend_usage_dump.rb +11 -0
- data/lib/3scale_toolbox/crds/limit_dump.rb +37 -0
- data/lib/3scale_toolbox/crds/mapping_rule_dump.rb +26 -0
- data/lib/3scale_toolbox/crds/method_dump.rb +12 -0
- data/lib/3scale_toolbox/crds/metric_dump.rb +13 -0
- data/lib/3scale_toolbox/crds/pricing_rule_dump.rb +38 -0
- data/lib/3scale_toolbox/crds/product_deployment_parser.rb +329 -0
- data/lib/3scale_toolbox/crds/product_dump.rb +157 -0
- data/lib/3scale_toolbox/crds/product_parser.rb +114 -0
- data/lib/3scale_toolbox/crds/remote.rb +682 -0
- data/lib/3scale_toolbox/entities.rb +3 -0
- data/lib/3scale_toolbox/entities/activedocs.rb +12 -0
- data/lib/3scale_toolbox/entities/application_plan.rb +74 -39
- data/lib/3scale_toolbox/entities/backend.rb +65 -30
- data/lib/3scale_toolbox/entities/backend_mapping_rule.rb +29 -3
- data/lib/3scale_toolbox/entities/backend_method.rb +25 -16
- data/lib/3scale_toolbox/entities/backend_metric.rb +12 -2
- data/lib/3scale_toolbox/entities/backend_usage.rb +7 -1
- data/lib/3scale_toolbox/entities/limit.rb +71 -0
- data/lib/3scale_toolbox/entities/mapping_rule.rb +90 -0
- data/lib/3scale_toolbox/entities/method.rb +33 -19
- data/lib/3scale_toolbox/entities/metric.rb +29 -18
- data/lib/3scale_toolbox/entities/pricing_rule.rb +63 -0
- data/lib/3scale_toolbox/entities/proxy_config.rb +0 -1
- data/lib/3scale_toolbox/entities/service.rb +149 -46
- data/lib/3scale_toolbox/error.rb +50 -0
- data/lib/3scale_toolbox/helper.rb +13 -16
- data/lib/3scale_toolbox/openapi/oas3.rb +1 -1
- data/lib/3scale_toolbox/proxy_logger.rb +4 -0
- data/lib/3scale_toolbox/remote_cache.rb +157 -0
- data/lib/3scale_toolbox/remotes.rb +2 -2
- data/lib/3scale_toolbox/version.rb +1 -1
- data/licenses.xml +113 -45
- metadata +37 -8
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
module ThreeScaleToolbox
|
|
2
|
+
module Commands
|
|
3
|
+
module PoliciesCommand
|
|
4
|
+
class ExportSubcommand < Cri::CommandRunner
|
|
5
|
+
include ThreeScaleToolbox::Command
|
|
6
|
+
|
|
7
|
+
class JSONSerializer
|
|
8
|
+
def call(object)
|
|
9
|
+
JSON.pretty_generate(object)
|
|
10
|
+
end
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
class YAMLSerializer
|
|
14
|
+
def call(object)
|
|
15
|
+
YAML.dump(object)
|
|
16
|
+
end
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
class SerializerTransformer
|
|
20
|
+
def call(output_format)
|
|
21
|
+
raise unless %w[yaml json].include?(output_format)
|
|
22
|
+
|
|
23
|
+
case output_format
|
|
24
|
+
when 'yaml'
|
|
25
|
+
YAMLSerializer.new
|
|
26
|
+
when 'json'
|
|
27
|
+
JSONSerializer.new
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
def self.command
|
|
33
|
+
Cri::Command.define do
|
|
34
|
+
name 'export'
|
|
35
|
+
usage 'export [opts] <remote> <product>'
|
|
36
|
+
summary 'export product policy chain'
|
|
37
|
+
description 'export product policy chain'
|
|
38
|
+
|
|
39
|
+
option :f, :file, 'Write to file instead of stdout', argument: :required
|
|
40
|
+
option :o, :output, 'Output format. One of: json|yaml', argument: :required, transform: SerializerTransformer.new
|
|
41
|
+
param :remote
|
|
42
|
+
param :service_ref
|
|
43
|
+
|
|
44
|
+
runner ExportSubcommand
|
|
45
|
+
end
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
def run
|
|
49
|
+
select_output do |output|
|
|
50
|
+
output.write(serializer.call(product.policies))
|
|
51
|
+
end
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
private
|
|
55
|
+
|
|
56
|
+
def remote
|
|
57
|
+
@remote ||= threescale_client(arguments[:remote])
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
def product
|
|
61
|
+
@product ||= find_product
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
def service_ref
|
|
65
|
+
arguments[:service_ref]
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
def find_product
|
|
69
|
+
Entities::Service.find(remote: remote,
|
|
70
|
+
ref: service_ref).tap do |svc|
|
|
71
|
+
raise ThreeScaleToolbox::Error, "Product #{service_ref} does not exist" if svc.nil?
|
|
72
|
+
end
|
|
73
|
+
end
|
|
74
|
+
|
|
75
|
+
def file
|
|
76
|
+
options[:file]
|
|
77
|
+
end
|
|
78
|
+
|
|
79
|
+
def select_output
|
|
80
|
+
ios = if file
|
|
81
|
+
File.open(file, 'w')
|
|
82
|
+
else
|
|
83
|
+
$stdout
|
|
84
|
+
end
|
|
85
|
+
begin
|
|
86
|
+
yield(ios)
|
|
87
|
+
ensure
|
|
88
|
+
ios.close
|
|
89
|
+
end
|
|
90
|
+
end
|
|
91
|
+
|
|
92
|
+
def serializer
|
|
93
|
+
options.fetch(:output, YAMLSerializer.new)
|
|
94
|
+
end
|
|
95
|
+
end
|
|
96
|
+
end
|
|
97
|
+
end
|
|
98
|
+
end
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
module ThreeScaleToolbox
|
|
2
|
+
module Commands
|
|
3
|
+
module PoliciesCommand
|
|
4
|
+
class ImportSubcommand < Cri::CommandRunner
|
|
5
|
+
include ThreeScaleToolbox::Command
|
|
6
|
+
include ThreeScaleToolbox::ResourceReader
|
|
7
|
+
|
|
8
|
+
def self.command
|
|
9
|
+
Cri::Command.define do
|
|
10
|
+
name 'import'
|
|
11
|
+
usage 'import [opts] <remote> <product>'
|
|
12
|
+
summary 'import product policy chain'
|
|
13
|
+
description 'import product policy chain'
|
|
14
|
+
|
|
15
|
+
option :f, :file, 'Read from file', argument: :required
|
|
16
|
+
option :u, :url, 'Read from url', argument: :required
|
|
17
|
+
param :remote
|
|
18
|
+
param :service_ref
|
|
19
|
+
|
|
20
|
+
runner ImportSubcommand
|
|
21
|
+
end
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
def run
|
|
25
|
+
res = product.update_policies('policies_config' => policies)
|
|
26
|
+
if res.is_a?(Hash) && (errors = res['errors'])
|
|
27
|
+
raise ThreeScaleToolbox::Error, "Product policies have not been imported. #{errors}"
|
|
28
|
+
end
|
|
29
|
+
if res.is_a?(Array) && (error_item = res.find { |i| i.key?('errors') })
|
|
30
|
+
raise ThreeScaleToolbox::Error, "Product policies have not been imported. #{error_item['errors']}"
|
|
31
|
+
end
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
private
|
|
35
|
+
|
|
36
|
+
def remote
|
|
37
|
+
@remote ||= threescale_client(arguments[:remote])
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
def service_ref
|
|
41
|
+
arguments[:service_ref]
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
def product
|
|
45
|
+
@product ||= find_product
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
def find_product
|
|
49
|
+
Entities::Service.find(remote: remote,
|
|
50
|
+
ref: service_ref).tap do |svc|
|
|
51
|
+
raise ThreeScaleToolbox::Error, "Product #{service_ref} does not exist" if svc.nil?
|
|
52
|
+
end
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
def policies
|
|
56
|
+
@policies ||= load_resource(options[:file] || options[:url] || '-')
|
|
57
|
+
end
|
|
58
|
+
end
|
|
59
|
+
end
|
|
60
|
+
end
|
|
61
|
+
end
|
|
@@ -1,4 +1,6 @@
|
|
|
1
1
|
require '3scale_toolbox/commands/product_command/copy_command'
|
|
2
|
+
require '3scale_toolbox/commands/product_command/export_command'
|
|
3
|
+
require '3scale_toolbox/commands/product_command/import_command'
|
|
2
4
|
|
|
3
5
|
module ThreeScaleToolbox
|
|
4
6
|
module Commands
|
|
@@ -17,6 +19,8 @@ module ThreeScaleToolbox
|
|
|
17
19
|
end
|
|
18
20
|
end
|
|
19
21
|
add_subcommand(CopySubcommand)
|
|
22
|
+
add_subcommand(ExportSubcommand)
|
|
23
|
+
add_subcommand(ImportSubcommand)
|
|
20
24
|
end
|
|
21
25
|
end
|
|
22
26
|
end
|
|
@@ -22,8 +22,8 @@ module ThreeScaleToolbox
|
|
|
22
22
|
\nproduct methods&metrics: Only missing metrics&methods will be created.
|
|
23
23
|
\nproduct mapping rules: Only missing mapping rules will be created.
|
|
24
24
|
\nproduct application plans & pricing rules & limits: Only missing application plans & pricing rules & limits will be created.
|
|
25
|
-
\nproduct application usage rules
|
|
26
|
-
\nproduct policies
|
|
25
|
+
\nproduct application usage rules
|
|
26
|
+
\nproduct policies
|
|
27
27
|
\nproduct backends: Only missing backends will be created.
|
|
28
28
|
\nproduct activedocs: Only missing activedocs will be created.
|
|
29
29
|
HEREDOC
|
|
@@ -37,7 +37,7 @@ module ThreeScaleToolbox
|
|
|
37
37
|
end
|
|
38
38
|
end
|
|
39
39
|
|
|
40
|
-
def
|
|
40
|
+
def self.workflow(context)
|
|
41
41
|
tasks = []
|
|
42
42
|
tasks << ThreeScaleToolbox::Commands::ServiceCommand::CopyCommand::CreateOrUpdateTargetServiceTask.new(context)
|
|
43
43
|
tasks << CopyCommand::DeleteExistingTargetBackendUsagesTask.new(context)
|
|
@@ -58,6 +58,10 @@ module ThreeScaleToolbox
|
|
|
58
58
|
ThreeScaleToolbox::Commands::ServiceCommand::CopyCommand::BumpProxyVersionTask.new(service: context[:target]).call
|
|
59
59
|
end
|
|
60
60
|
|
|
61
|
+
def run
|
|
62
|
+
self.class.workflow(context)
|
|
63
|
+
end
|
|
64
|
+
|
|
61
65
|
private
|
|
62
66
|
|
|
63
67
|
def context
|
|
@@ -13,14 +13,14 @@ module ThreeScaleToolbox
|
|
|
13
13
|
def call
|
|
14
14
|
backend_list = source.backend_usage_list
|
|
15
15
|
backend_list.each(&method(:create_backend))
|
|
16
|
-
|
|
16
|
+
logger.info "created/upated #{backend_list.size} backends"
|
|
17
17
|
end
|
|
18
18
|
|
|
19
19
|
private
|
|
20
20
|
|
|
21
21
|
def create_backend(backend_usage)
|
|
22
22
|
source_backend = Entities::Backend.new(id: backend_usage.backend_id, remote: source_remote)
|
|
23
|
-
backend_context = create_backend_context(source_backend
|
|
23
|
+
backend_context = create_backend_context(source_backend)
|
|
24
24
|
|
|
25
25
|
tasks = []
|
|
26
26
|
tasks << Commands::BackendCommand::CopyCommand::CreateOrUpdateTargetBackendTask.new(backend_context)
|
|
@@ -32,13 +32,16 @@ module ThreeScaleToolbox
|
|
|
32
32
|
|
|
33
33
|
# CreateOrUpdate task will keep reference of the target backend in
|
|
34
34
|
# backend_context[:target_backend]
|
|
35
|
+
target_backend = backend_context[:target_backend]
|
|
35
36
|
attrs = {
|
|
36
|
-
'backend_api_id' =>
|
|
37
|
+
'backend_api_id' => target_backend.id,
|
|
37
38
|
'path' => backend_usage.path
|
|
38
39
|
}
|
|
39
40
|
# It is assumed there is no target backend usage with this backend_source's path
|
|
40
41
|
# DeleteExistingTargetBackendUsagesTask should provide that
|
|
41
42
|
Entities::BackendUsage.create(product: target, attrs: attrs)
|
|
43
|
+
|
|
44
|
+
backends_report.merge!(target_backend.system_name => backend_context.fetch(:report))
|
|
42
45
|
end
|
|
43
46
|
|
|
44
47
|
def source
|
|
@@ -57,11 +60,25 @@ module ThreeScaleToolbox
|
|
|
57
60
|
context[:target_remote]
|
|
58
61
|
end
|
|
59
62
|
|
|
60
|
-
def
|
|
63
|
+
def backends_report
|
|
64
|
+
report['backends'] ||= {}
|
|
65
|
+
end
|
|
66
|
+
|
|
67
|
+
def report
|
|
68
|
+
context.fetch(:report)
|
|
69
|
+
end
|
|
70
|
+
|
|
71
|
+
def logger
|
|
72
|
+
context.fetch(:logger)
|
|
73
|
+
end
|
|
74
|
+
|
|
75
|
+
def create_backend_context(source_backend)
|
|
61
76
|
{
|
|
62
77
|
source_remote: source_remote,
|
|
63
78
|
target_remote: target_remote,
|
|
64
|
-
|
|
79
|
+
source_backend: source_backend,
|
|
80
|
+
source_backend_ref: source_backend.id,
|
|
81
|
+
logger: logger
|
|
65
82
|
}
|
|
66
83
|
end
|
|
67
84
|
end
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
module ThreeScaleToolbox
|
|
2
|
+
module Commands
|
|
3
|
+
module ProductCommand
|
|
4
|
+
class ExportSubcommand < Cri::CommandRunner
|
|
5
|
+
include ThreeScaleToolbox::Command
|
|
6
|
+
|
|
7
|
+
def self.command
|
|
8
|
+
Cri::Command.define do
|
|
9
|
+
name 'export'
|
|
10
|
+
usage 'export [opts] <remote> <product>'
|
|
11
|
+
summary 'Export product to serialized format'
|
|
12
|
+
description 'This command serializes the referenced product and associated backends into a yaml format'
|
|
13
|
+
|
|
14
|
+
option :f, :file, 'Write to file instead of stdout', argument: :required
|
|
15
|
+
param :remote
|
|
16
|
+
param :product_ref
|
|
17
|
+
|
|
18
|
+
runner ExportSubcommand
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
def run
|
|
23
|
+
select_output do |output|
|
|
24
|
+
output.write(serialized_object.to_yaml)
|
|
25
|
+
end
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
private
|
|
29
|
+
|
|
30
|
+
def remote
|
|
31
|
+
@remote ||= threescale_client(arguments[:remote])
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
def serialized_object
|
|
35
|
+
{
|
|
36
|
+
'apiVersion' => 'v1',
|
|
37
|
+
'kind' => 'List',
|
|
38
|
+
'items' => [product.to_cr] + product_backends.map(&:to_cr)
|
|
39
|
+
}
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
def select_output
|
|
43
|
+
ios = if file
|
|
44
|
+
File.open(file, 'w')
|
|
45
|
+
else
|
|
46
|
+
$stdout
|
|
47
|
+
end
|
|
48
|
+
begin
|
|
49
|
+
yield(ios)
|
|
50
|
+
ensure
|
|
51
|
+
ios.close
|
|
52
|
+
end
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
def product
|
|
56
|
+
@product ||= find_product
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
def product_backends
|
|
60
|
+
product.backend_usage_list.map do |backend_usage|
|
|
61
|
+
Entities::Backend.new(id: backend_usage.backend_id, remote: remote)
|
|
62
|
+
end
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
def product_ref
|
|
66
|
+
arguments[:product_ref]
|
|
67
|
+
end
|
|
68
|
+
|
|
69
|
+
def find_product
|
|
70
|
+
Entities::Service.find(remote: remote, ref: product_ref).tap do |prd|
|
|
71
|
+
raise ThreeScaleToolbox::Error, "Product #{product_ref} does not exist" if prd.nil?
|
|
72
|
+
end
|
|
73
|
+
end
|
|
74
|
+
|
|
75
|
+
def file
|
|
76
|
+
options[:file]
|
|
77
|
+
end
|
|
78
|
+
end
|
|
79
|
+
end
|
|
80
|
+
end
|
|
81
|
+
end
|
|
@@ -0,0 +1,125 @@
|
|
|
1
|
+
module ThreeScaleToolbox
|
|
2
|
+
module Commands
|
|
3
|
+
module ProductCommand
|
|
4
|
+
class ImportSubcommand < Cri::CommandRunner
|
|
5
|
+
include ThreeScaleToolbox::Command
|
|
6
|
+
include ThreeScaleToolbox::ResourceReader
|
|
7
|
+
|
|
8
|
+
def self.command
|
|
9
|
+
Cri::Command.define do
|
|
10
|
+
name 'import'
|
|
11
|
+
usage 'import [opts] <remote>'
|
|
12
|
+
summary 'Import product from serialized format'
|
|
13
|
+
description 'This command deserializes one product and associated backends'
|
|
14
|
+
|
|
15
|
+
option :f, :file, 'Read from file instead of stdin', argument: :required
|
|
16
|
+
ThreeScaleToolbox::CLI.output_flag(self)
|
|
17
|
+
param :remote
|
|
18
|
+
|
|
19
|
+
runner ImportSubcommand
|
|
20
|
+
end
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
def run
|
|
24
|
+
validate_artifacts_resource!
|
|
25
|
+
|
|
26
|
+
product_list.each do |product|
|
|
27
|
+
context = {
|
|
28
|
+
target_remote: remote,
|
|
29
|
+
source_remote: crd_remote,
|
|
30
|
+
source_service_ref: product.system_name,
|
|
31
|
+
logger: Logger.new(File::NULL)
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
Commands::ProductCommand::CopySubcommand.workflow(context)
|
|
35
|
+
|
|
36
|
+
report[product.system_name] = context.fetch(:report)
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
printer.print_collection report
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
private
|
|
43
|
+
|
|
44
|
+
def crd_remote
|
|
45
|
+
@crd_remote ||= CRD::Remote.new(product_list, backend_list)
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
def product_list
|
|
49
|
+
@product_list ||= product_resources.map do |product_cr|
|
|
50
|
+
CRD::ProductParser.new product_cr
|
|
51
|
+
end
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
def backend_list
|
|
55
|
+
@backend_list ||= backend_resources.map do |backend_cr|
|
|
56
|
+
CRD::BackendParser.new backend_cr
|
|
57
|
+
end
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
def validate_artifacts_resource!
|
|
61
|
+
# TODO: Add openapiV3 validation
|
|
62
|
+
# https://github.com/3scale/3scale-operator/blob/3scale-2.10.0-CR2/deploy/crds/capabilities.3scale.net_backends_crd.yaml
|
|
63
|
+
# https://github.com/3scale/3scale-operator/blob/3scale-2.10.0-CR2/deploy/crds/capabilities.3scale.net_products_crd.yaml
|
|
64
|
+
validate_api_version!
|
|
65
|
+
|
|
66
|
+
validate_kind!
|
|
67
|
+
end
|
|
68
|
+
|
|
69
|
+
def validate_api_version!
|
|
70
|
+
artifacts_resource.fetch('apiVersion') do
|
|
71
|
+
raise ThreeScaleToolbox::Error, 'Invalid content. apiVersion not found'
|
|
72
|
+
end
|
|
73
|
+
|
|
74
|
+
raise ThreeScaleToolbox::Error, 'Invalid content. apiVersion wrong value ' unless artifacts_resource.fetch('apiVersion') == 'v1'
|
|
75
|
+
end
|
|
76
|
+
|
|
77
|
+
def validate_kind!
|
|
78
|
+
artifacts_resource.fetch('kind') do
|
|
79
|
+
raise ThreeScaleToolbox::Error, 'Invalid content. kind not found'
|
|
80
|
+
end
|
|
81
|
+
|
|
82
|
+
raise ThreeScaleToolbox::Error, 'Invalid content. kind wrong value ' unless artifacts_resource.fetch('kind') == 'List'
|
|
83
|
+
end
|
|
84
|
+
|
|
85
|
+
def artifacts_resource_items
|
|
86
|
+
artifacts_resource.fetch('items') do
|
|
87
|
+
raise ThreeScaleToolbox::Error, 'Invalid content. items not found'
|
|
88
|
+
end
|
|
89
|
+
end
|
|
90
|
+
|
|
91
|
+
def product_resources
|
|
92
|
+
artifacts_resource_items.select do |item|
|
|
93
|
+
item.respond_to?(:has_key?) &&
|
|
94
|
+
item.fetch('apiVersion', '').include?('capabilities.3scale.net') &&
|
|
95
|
+
item['kind'] == 'Product'
|
|
96
|
+
end
|
|
97
|
+
end
|
|
98
|
+
|
|
99
|
+
def backend_resources
|
|
100
|
+
artifacts_resource_items.select do |item|
|
|
101
|
+
item.respond_to?(:has_key?) &&
|
|
102
|
+
item.fetch('apiVersion', '').include?('capabilities.3scale.net') &&
|
|
103
|
+
item['kind'] == 'Backend'
|
|
104
|
+
end
|
|
105
|
+
end
|
|
106
|
+
|
|
107
|
+
def artifacts_resource
|
|
108
|
+
@artifacts_resource ||= load_resource(options[:file] || '-')
|
|
109
|
+
end
|
|
110
|
+
|
|
111
|
+
def report
|
|
112
|
+
@report ||= {}
|
|
113
|
+
end
|
|
114
|
+
|
|
115
|
+
def remote
|
|
116
|
+
@remote ||= threescale_client(arguments[:remote])
|
|
117
|
+
end
|
|
118
|
+
|
|
119
|
+
def printer
|
|
120
|
+
options.fetch(:output, CLI::JsonPrinter.new)
|
|
121
|
+
end
|
|
122
|
+
end
|
|
123
|
+
end
|
|
124
|
+
end
|
|
125
|
+
end
|