3scale_toolbox 0.15.0 → 0.16.0

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.
Files changed (97) hide show
  1. checksums.yaml +4 -4
  2. data/3scale_toolbox.gemspec +1 -1
  3. data/README.md +4 -1
  4. data/lib/3scale_toolbox.rb +0 -1
  5. data/lib/3scale_toolbox/cli.rb +4 -0
  6. data/lib/3scale_toolbox/cli/custom_table_printer.rb +32 -0
  7. data/lib/3scale_toolbox/cli/json_printer.rb +13 -0
  8. data/lib/3scale_toolbox/cli/output_flag.rb +20 -0
  9. data/lib/3scale_toolbox/cli/yaml_printer.rb +13 -0
  10. data/lib/3scale_toolbox/commands.rb +5 -1
  11. data/lib/3scale_toolbox/commands/activedocs_command/apply_command.rb +33 -10
  12. data/lib/3scale_toolbox/commands/activedocs_command/create_command.rb +22 -7
  13. data/lib/3scale_toolbox/commands/activedocs_command/list_command.rb +10 -17
  14. data/lib/3scale_toolbox/commands/application_command/apply_command.rb +27 -4
  15. data/lib/3scale_toolbox/commands/application_command/create_command.rb +16 -1
  16. data/lib/3scale_toolbox/commands/application_command/list_command.rb +10 -13
  17. data/lib/3scale_toolbox/commands/application_command/show_command.rb +8 -14
  18. data/lib/3scale_toolbox/commands/backend_command.rb +22 -0
  19. data/lib/3scale_toolbox/commands/backend_command/copy_command.rb +65 -0
  20. data/lib/3scale_toolbox/commands/backend_command/copy_command/copy_mapping_rules_task.rb +52 -0
  21. data/lib/3scale_toolbox/commands/backend_command/copy_command/copy_methods_task.rb +40 -0
  22. data/lib/3scale_toolbox/commands/backend_command/copy_command/copy_metrics_task.rb +30 -0
  23. data/lib/3scale_toolbox/commands/backend_command/copy_command/create_or_update_target_backend_task.rb +45 -0
  24. data/lib/3scale_toolbox/commands/backend_command/copy_command/task.rb +89 -0
  25. data/lib/3scale_toolbox/commands/copy_command.rb +2 -2
  26. data/lib/3scale_toolbox/commands/copy_command/service_command.rb +40 -0
  27. data/lib/3scale_toolbox/commands/import_command/openapi.rb +3 -2
  28. data/lib/3scale_toolbox/commands/methods_command/apply_command.rb +26 -4
  29. data/lib/3scale_toolbox/commands/methods_command/create_command.rb +23 -1
  30. data/lib/3scale_toolbox/commands/methods_command/list_command.rb +11 -9
  31. data/lib/3scale_toolbox/commands/metrics_command/apply_command.rb +26 -4
  32. data/lib/3scale_toolbox/commands/metrics_command/create_command.rb +23 -1
  33. data/lib/3scale_toolbox/commands/metrics_command/list_command.rb +7 -12
  34. data/lib/3scale_toolbox/commands/plans_command/apply_command.rb +36 -7
  35. data/lib/3scale_toolbox/commands/plans_command/create_command.rb +23 -1
  36. data/lib/3scale_toolbox/commands/plans_command/list_command.rb +8 -13
  37. data/lib/3scale_toolbox/commands/plans_command/show_command.rb +6 -14
  38. data/lib/3scale_toolbox/commands/product_command.rb +22 -0
  39. data/lib/3scale_toolbox/commands/product_command/copy_command.rb +78 -0
  40. data/lib/3scale_toolbox/commands/product_command/copy_command/copy_backends_task.rb +71 -0
  41. data/lib/3scale_toolbox/commands/product_command/copy_command/delete_target_backend_usages_task.rb +48 -0
  42. data/lib/3scale_toolbox/commands/proxy_config_command/list_command.rb +13 -29
  43. data/lib/3scale_toolbox/commands/proxy_config_command/show_command.rb +20 -23
  44. data/lib/3scale_toolbox/commands/service_command.rb +7 -5
  45. data/lib/3scale_toolbox/commands/service_command/apply_command.rb +69 -58
  46. data/lib/3scale_toolbox/commands/service_command/copy_command.rb +95 -0
  47. data/lib/3scale_toolbox/commands/service_command/copy_command/bump_proxy_version_task.rb +36 -0
  48. data/lib/3scale_toolbox/commands/service_command/copy_command/copy_activedocs_task.rb +46 -0
  49. data/lib/3scale_toolbox/commands/service_command/copy_command/copy_app_plans_task.rb +35 -0
  50. data/lib/3scale_toolbox/commands/service_command/copy_command/copy_limits_task.rb +39 -0
  51. data/lib/3scale_toolbox/commands/service_command/copy_command/copy_mapping_rules_task.rb +35 -0
  52. data/lib/3scale_toolbox/commands/service_command/copy_command/copy_methods_task.rb +40 -0
  53. data/lib/3scale_toolbox/commands/service_command/copy_command/copy_metrics_task.rb +37 -0
  54. data/lib/3scale_toolbox/commands/service_command/copy_command/copy_policies_task.rb +17 -0
  55. data/lib/3scale_toolbox/commands/service_command/copy_command/copy_pricingrules_task.rb +44 -0
  56. data/lib/3scale_toolbox/commands/service_command/copy_command/copy_service_proxy_task.rb +17 -0
  57. data/lib/3scale_toolbox/commands/service_command/copy_command/create_or_update_service_task.rb +48 -0
  58. data/lib/3scale_toolbox/commands/service_command/copy_command/destroy_mapping_rules_task.rb +34 -0
  59. data/lib/3scale_toolbox/commands/service_command/copy_command/task.rb +99 -0
  60. data/lib/3scale_toolbox/commands/service_command/create_command.rb +58 -44
  61. data/lib/3scale_toolbox/commands/service_command/delete_command.rb +31 -33
  62. data/lib/3scale_toolbox/commands/service_command/list_command.rb +24 -34
  63. data/lib/3scale_toolbox/commands/service_command/show_command.rb +39 -44
  64. data/lib/3scale_toolbox/commands/update_command.rb +2 -2
  65. data/lib/3scale_toolbox/commands/update_command/{update_service.rb → service_command.rb} +19 -16
  66. data/lib/3scale_toolbox/commands/update_command/service_command/copy_service_settings_task.rb +35 -0
  67. data/lib/3scale_toolbox/commands/update_command/service_command/delete_activedocs_task.rb +26 -0
  68. data/lib/3scale_toolbox/entities.rb +5 -0
  69. data/lib/3scale_toolbox/entities/backend.rb +152 -0
  70. data/lib/3scale_toolbox/entities/backend_mapping_rule.rb +76 -0
  71. data/lib/3scale_toolbox/entities/backend_method.rb +90 -0
  72. data/lib/3scale_toolbox/entities/backend_metric.rb +88 -0
  73. data/lib/3scale_toolbox/entities/backend_usage.rb +99 -0
  74. data/lib/3scale_toolbox/entities/service.rb +18 -3
  75. data/lib/3scale_toolbox/error.rb +3 -0
  76. data/lib/3scale_toolbox/helper.rb +20 -0
  77. data/lib/3scale_toolbox/proxy_logger.rb +1 -1
  78. data/lib/3scale_toolbox/version.rb +1 -1
  79. data/licenses.xml +3 -3
  80. metadata +42 -22
  81. data/lib/3scale_toolbox/commands/copy_command/copy_service.rb +0 -144
  82. data/lib/3scale_toolbox/tasks.rb +0 -15
  83. data/lib/3scale_toolbox/tasks/bump_proxy_version_task.rb +0 -32
  84. data/lib/3scale_toolbox/tasks/copy_activedocs_task.rb +0 -42
  85. data/lib/3scale_toolbox/tasks/copy_app_plans_task.rb +0 -31
  86. data/lib/3scale_toolbox/tasks/copy_limits_task.rb +0 -36
  87. data/lib/3scale_toolbox/tasks/copy_mapping_rules_task.rb +0 -32
  88. data/lib/3scale_toolbox/tasks/copy_methods_task.rb +0 -36
  89. data/lib/3scale_toolbox/tasks/copy_metrics_task.rb +0 -33
  90. data/lib/3scale_toolbox/tasks/copy_policies_task.rb +0 -13
  91. data/lib/3scale_toolbox/tasks/copy_pricingrules_task.rb +0 -41
  92. data/lib/3scale_toolbox/tasks/copy_service_proxy_task.rb +0 -13
  93. data/lib/3scale_toolbox/tasks/copy_service_settings_task.rb +0 -38
  94. data/lib/3scale_toolbox/tasks/copy_task.rb +0 -66
  95. data/lib/3scale_toolbox/tasks/delete_activedocs_task.rb +0 -22
  96. data/lib/3scale_toolbox/tasks/destroy_mapping_rules_task.rb +0 -22
  97. data/lib/3scale_toolbox/tasks/helper_task.rb +0 -25
@@ -14,10 +14,12 @@ module ThreeScaleToolbox
14
14
  summary 'list applications'
15
15
  description 'List applications'
16
16
 
17
- param :remote
18
17
  option nil, :account, 'Filter by account', argument: :required
19
18
  option nil, :service, 'Filter by service', argument: :required
20
19
  option nil, :plan, 'Filter by application plan. Service option required', argument: :required
20
+ ThreeScaleToolbox::CLI.output_flag(self)
21
+
22
+ param :remote
21
23
 
22
24
  runner ListSubcommand
23
25
  end
@@ -35,8 +37,8 @@ module ThreeScaleToolbox
35
37
  else
36
38
  provider_account_applications
37
39
  end
38
- print_header
39
- print_data(applications)
40
+
41
+ printer.print_collection applications.map(&:attrs)
40
42
  end
41
43
 
42
44
  private
@@ -72,16 +74,6 @@ module ThreeScaleToolbox
72
74
  options[:plan]
73
75
  end
74
76
 
75
- def print_header
76
- puts FIELDS_TO_SHOW.map(&:upcase).join("\t")
77
- end
78
-
79
- def print_data(applications)
80
- applications.each do |app|
81
- puts FIELDS_TO_SHOW.map { |field| app.attrs.fetch(field, '(empty)') }.join("\t")
82
- end
83
- end
84
-
85
77
  def service
86
78
  @service ||= find_service
87
79
  end
@@ -117,6 +109,11 @@ module ThreeScaleToolbox
117
109
  def remote
118
110
  @remote ||= threescale_client(arguments[:remote])
119
111
  end
112
+
113
+ def printer
114
+ # keep backwards compatibility
115
+ options.fetch(:output, CLI::CustomTablePrinter.new(FIELDS_TO_SHOW))
116
+ end
120
117
  end
121
118
  end
122
119
  end
@@ -21,6 +21,8 @@ module ThreeScaleToolbox
21
21
  \n * Application internal id
22
22
  HEREDOC
23
23
 
24
+ ThreeScaleToolbox::CLI.output_flag(self)
25
+
24
26
  param :remote
25
27
  param :application
26
28
 
@@ -29,24 +31,11 @@ module ThreeScaleToolbox
29
31
  end
30
32
 
31
33
  def run
32
- print_header
33
- print_data
34
+ printer.print_record application.attrs
34
35
  end
35
36
 
36
37
  private
37
38
 
38
- def print_header
39
- puts FIELDS_TO_SHOW.map(&:upcase).join("\t")
40
- end
41
-
42
- def print_data
43
- puts FIELDS_TO_SHOW.map { |field| app_attrs.fetch(field, '(empty)') }.join("\t")
44
- end
45
-
46
- def app_attrs
47
- @app_attrs ||= application.attrs
48
- end
49
-
50
39
  def application
51
40
  @application ||= find_application
52
41
  end
@@ -64,6 +53,11 @@ module ThreeScaleToolbox
64
53
  def remote
65
54
  @remote ||= threescale_client(arguments[:remote])
66
55
  end
56
+
57
+ def printer
58
+ # keep backwards compatibility
59
+ options.fetch(:output, CLI::CustomTablePrinter.new(FIELDS_TO_SHOW))
60
+ end
67
61
  end
68
62
  end
69
63
  end
@@ -0,0 +1,22 @@
1
+ require '3scale_toolbox/commands/backend_command/copy_command'
2
+
3
+ module ThreeScaleToolbox
4
+ module Commands
5
+ module BackendCommand
6
+ include ThreeScaleToolbox::Command
7
+ def self.command
8
+ Cri::Command.define do
9
+ name 'backend'
10
+ usage 'backend <sub-command> [options]'
11
+ summary 'backend super command'
12
+ description 'Backend commands'
13
+
14
+ run do |_opts, _args, cmd|
15
+ puts cmd.help
16
+ end
17
+ end
18
+ end
19
+ add_subcommand(CopySubcommand)
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,65 @@
1
+ require '3scale_toolbox/commands/backend_command/copy_command/task'
2
+ require '3scale_toolbox/commands/backend_command/copy_command/create_or_update_target_backend_task'
3
+ require '3scale_toolbox/commands/backend_command/copy_command/copy_metrics_task'
4
+ require '3scale_toolbox/commands/backend_command/copy_command/copy_methods_task'
5
+ require '3scale_toolbox/commands/backend_command/copy_command/copy_mapping_rules_task'
6
+
7
+ module ThreeScaleToolbox
8
+ module Commands
9
+ module BackendCommand
10
+ class CopySubcommand < Cri::CommandRunner
11
+ include ThreeScaleToolbox::Command
12
+
13
+ def self.command
14
+ Cri::Command.define do
15
+ name 'copy'
16
+ usage 'copy [opts] -s <source-remote> -d <target-remote> <source-backend>'
17
+ summary 'Copy backend'
18
+ description <<-HEREDOC
19
+ This command makes a copy of the referenced backend.
20
+ Target backend will be searched by source backend system name. System name can be overriden with `--target-system-name` option.
21
+ If a backend with the selected `system-name` is not found, it will be created.
22
+ \n Components of the backend being copied:
23
+ \nmetrics
24
+ \nmethods
25
+ \nmapping rules
26
+ \n\n If a backend with the selected `system-name` is found, it will be updated. Only missing metrics, methods and mapping rules will be created.
27
+ HEREDOC
28
+
29
+ option :s, :source, '3scale source instance. Url or remote name', argument: :required
30
+ option :d, :destination, '3scale target instance. Url or remote name', argument: :required
31
+ option :t, 'target-system-name', 'Target system name. Default to source system name', argument: :required
32
+ param :source_backend
33
+
34
+ runner CopySubcommand
35
+ end
36
+ end
37
+
38
+ def run
39
+ tasks = []
40
+ tasks << CopyCommand::CreateOrUpdateTargetBackendTask.new(context)
41
+ # First metrics as methods need 'hits' metric in target backend
42
+ tasks << CopyCommand::CopyMetricsTask.new(context)
43
+ tasks << CopyCommand::CopyMethodsTask.new(context)
44
+ tasks << CopyCommand::CopyMappingRulesTask.new(context)
45
+ tasks.each(&:call)
46
+ end
47
+
48
+ private
49
+
50
+ def context
51
+ @context ||= create_context
52
+ end
53
+
54
+ def create_context
55
+ {
56
+ source_remote: threescale_client(fetch_required_option(:source)),
57
+ target_remote: threescale_client(fetch_required_option(:destination)),
58
+ source_backend_ref: arguments[:source_backend],
59
+ option_target_system_name: options[:'target-system-name']
60
+ }
61
+ end
62
+ end
63
+ end
64
+ end
65
+ end
@@ -0,0 +1,52 @@
1
+ module ThreeScaleToolbox
2
+ module Commands
3
+ module BackendCommand
4
+ module CopyCommand
5
+ class CopyMappingRulesTask
6
+ include Task
7
+
8
+ # entrypoint
9
+ def run
10
+ missing_rules = missing_mapping_rules(source_backend.mapping_rules,
11
+ target_backend.mapping_rules, metrics_map)
12
+ missing_rules.each do |mapping_rule|
13
+ mapping_rule.metric_id = metrics_map.fetch(mapping_rule.metric_id)
14
+ Entities::BackendMappingRule.create(backend: target_backend,
15
+ attrs: mapping_rule.attrs)
16
+ end
17
+ puts "created #{missing_rules.size} mapping rules"
18
+ end
19
+
20
+ private
21
+
22
+ def metrics_map
23
+ @metrics_map ||= build_metrics_mapping
24
+ end
25
+
26
+ def build_metrics_mapping
27
+ target_mm = target_metrics + target_methods
28
+ source_mm = source_metrics + source_methods
29
+ target_mm.map do |target|
30
+ source = source_mm.find do |m|
31
+ m.system_name == target.system_name
32
+ end
33
+ next if source.nil?
34
+
35
+ [source.id, target.id]
36
+ end.compact.to_h
37
+ end
38
+
39
+ def missing_mapping_rules(source_rules, target_rules, metrics_map)
40
+ ThreeScaleToolbox::Helper.array_difference(source_rules, target_rules) do |source, target|
41
+ # map metric_id to the target backend domain
42
+ source_attrs = source.attrs.merge('metric_id' => metrics_map.fetch(source.metric_id))
43
+ ThreeScaleToolbox::Helper.compare_hashes(source_attrs,
44
+ target.attrs,
45
+ %w[pattern http_method delta metric_id])
46
+ end
47
+ end
48
+ end
49
+ end
50
+ end
51
+ end
52
+ end
@@ -0,0 +1,40 @@
1
+ module ThreeScaleToolbox
2
+ module Commands
3
+ module BackendCommand
4
+ module CopyCommand
5
+ class CopyMethodsTask
6
+ include Task
7
+
8
+ # entrypoint
9
+ def run
10
+ missing_methods.each(&method(:create_method))
11
+ puts "created #{missing_methods.size} missing methods"
12
+ invalidate_target_methods if missing_methods.size.positive?
13
+ end
14
+
15
+ private
16
+
17
+ def create_method(method)
18
+ # return silently if target metric hits does not exist
19
+ return if target_hits.nil?
20
+
21
+ Entities::BackendMethod.create(backend: target_backend,
22
+ parent_id: target_hits.id,
23
+ attrs: method.attrs)
24
+ rescue ThreeScaleToolbox::ThreeScaleApiError => e
25
+ raise e unless ThreeScaleToolbox::Helper.system_name_already_taken_error?(e.apierrors)
26
+
27
+ warn "[WARN] backend method #{method.attrs.fetch('system_name')} not created. " \
28
+ 'Backend metric with the same system_name exists.'
29
+ end
30
+
31
+ def missing_methods
32
+ @missing_methods ||= ThreeScaleToolbox::Helper.array_difference(source_methods, target_methods) do |source, target|
33
+ source.system_name == target.system_name
34
+ end
35
+ end
36
+ end
37
+ end
38
+ end
39
+ end
40
+ end
@@ -0,0 +1,30 @@
1
+ module ThreeScaleToolbox
2
+ module Commands
3
+ module BackendCommand
4
+ module CopyCommand
5
+ class CopyMetricsTask
6
+ include Task
7
+
8
+ # entrypoint
9
+ def run
10
+ missing_metrics.each(&method(:create_metric))
11
+ puts "created #{missing_metrics.size} missing metrics"
12
+ invalidate_target_metrics if missing_metrics.size.positive?
13
+ end
14
+
15
+ private
16
+
17
+ def create_metric(metric)
18
+ Entities::BackendMetric.create(backend: target_backend, attrs: metric.attrs)
19
+ end
20
+
21
+ def missing_metrics
22
+ @missing_metrics ||= ThreeScaleToolbox::Helper.array_difference(source_metrics, target_metrics) do |source, target|
23
+ source.system_name == target.system_name
24
+ end
25
+ end
26
+ end
27
+ end
28
+ end
29
+ end
30
+ end
@@ -0,0 +1,45 @@
1
+ module ThreeScaleToolbox
2
+ module Commands
3
+ module BackendCommand
4
+ module CopyCommand
5
+ class CreateOrUpdateTargetBackendTask
6
+ include Task
7
+
8
+ # entrypoint
9
+ def run
10
+ backend = Entities::Backend.find(remote: target_remote, ref: target_backend_ref)
11
+
12
+ if backend.nil?
13
+ backend = Entities::Backend.create(remote: target_remote,
14
+ attrs: create_attrs)
15
+ elsif backend == source_backend
16
+ message = 'source and destination backends are the same: ' \
17
+ "ID: #{source_backend.id} system_name: #{source_backend.attrs['system_name']}"
18
+ warn "\e[1m\e[31mWarning: #{message}\e[0m"
19
+ else
20
+ backend.update update_attrs
21
+ end
22
+
23
+ # assign target backend for other tasks to have it available
24
+ self.target_backend = backend
25
+
26
+ puts "source backend ID: #{source_backend.id} system_name: #{source_backend.attrs['system_name']}"
27
+ puts "target backend ID: #{target_backend.id} system_name: #{target_backend.attrs['system_name']}"
28
+ end
29
+
30
+ def create_attrs
31
+ source_backend.attrs.merge('system_name' => target_backend_ref)
32
+ end
33
+
34
+ def update_attrs
35
+ source_backend.attrs.merge('system_name' => target_backend_ref)
36
+ end
37
+
38
+ def target_backend_ref
39
+ option_target_system_name || source_backend.attrs.fetch('system_name')
40
+ end
41
+ end
42
+ end
43
+ end
44
+ end
45
+ end
@@ -0,0 +1,89 @@
1
+ module ThreeScaleToolbox
2
+ module Commands
3
+ module BackendCommand
4
+ module CopyCommand
5
+ module Task
6
+ attr_reader :context
7
+
8
+ def initialize(context)
9
+ @context = context
10
+ end
11
+
12
+ def call
13
+ run
14
+ end
15
+
16
+ def target_backend=(target)
17
+ context[:target_backend] = target
18
+ end
19
+
20
+ def target_backend
21
+ context[:target_backend] ||= raise ThreeScaleToolbox::Error, 'Unexpected error. ' \
22
+ 'Target backend should have been created or updated'
23
+ end
24
+
25
+ def source_backend
26
+ context[:source_backend] ||= find_source_backend
27
+ end
28
+
29
+ def source_methods
30
+ context[:source_methods] ||= source_backend.methods(source_hits)
31
+ end
32
+
33
+ def source_hits
34
+ context[:source_hits] ||= source_backend.hits
35
+ end
36
+
37
+ def source_metrics
38
+ context[:source_metrics] ||= source_backend.metrics
39
+ end
40
+
41
+ def target_metrics
42
+ context[:target_metrics] ||= target_backend.metrics
43
+ end
44
+
45
+ def target_hits
46
+ context[:target_hits] ||= target_backend.hits
47
+ end
48
+
49
+ def target_methods
50
+ context[:target_methods] ||= target_backend.methods(target_hits)
51
+ end
52
+
53
+ def invalidate_target_methods
54
+ context[:target_methods] = nil
55
+ end
56
+
57
+ def invalidate_target_metrics
58
+ context[:target_metrics] = nil
59
+ end
60
+
61
+ def source_remote
62
+ context[:source_remote]
63
+ end
64
+
65
+ def target_remote
66
+ context[:target_remote]
67
+ end
68
+
69
+ def source_backend_ref
70
+ context[:source_backend_ref] ||= raise ThreeScaleToolbox::Error, 'Unexpected error. ' \
71
+ 'source_backend_ref not found'
72
+ end
73
+
74
+ def option_target_system_name
75
+ context[:option_target_system_name]
76
+ end
77
+
78
+ private
79
+
80
+ def find_source_backend
81
+ Entities::Backend.find(remote: source_remote, ref: source_backend_ref).tap do |backend|
82
+ raise ThreeScaleToolbox::Error, "Backend #{source_backend_ref} does not exist" if backend.nil?
83
+ end
84
+ end
85
+ end
86
+ end
87
+ end
88
+ end
89
+ end