3scale_toolbox 0.17.1 → 0.19.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 (99) hide show
  1. checksums.yaml +4 -4
  2. data/3scale_toolbox.gemspec +4 -4
  3. data/README.md +7 -5
  4. data/lib/3scale_toolbox.rb +3 -0
  5. data/lib/3scale_toolbox/3scale_client_factory.rb +3 -4
  6. data/lib/3scale_toolbox/commands.rb +2 -0
  7. data/lib/3scale_toolbox/commands/backend_command/copy_command.rb +3 -0
  8. data/lib/3scale_toolbox/commands/backend_command/copy_command/copy_mapping_rules_task.rb +11 -27
  9. data/lib/3scale_toolbox/commands/backend_command/copy_command/copy_methods_task.rb +5 -10
  10. data/lib/3scale_toolbox/commands/backend_command/copy_command/copy_metrics_task.rb +4 -4
  11. data/lib/3scale_toolbox/commands/backend_command/copy_command/create_or_update_target_backend_task.rb +3 -2
  12. data/lib/3scale_toolbox/commands/backend_command/copy_command/delete_mapping_rules_task.rb +18 -0
  13. data/lib/3scale_toolbox/commands/backend_command/copy_command/task.rb +14 -32
  14. data/lib/3scale_toolbox/commands/import_command/issuer_type_transformer.rb +16 -0
  15. data/lib/3scale_toolbox/commands/import_command/openapi.rb +5 -0
  16. data/lib/3scale_toolbox/commands/import_command/openapi/create_activedocs_step.rb +3 -2
  17. data/lib/3scale_toolbox/commands/import_command/openapi/create_mapping_rule_step.rb +2 -1
  18. data/lib/3scale_toolbox/commands/import_command/openapi/create_method_step.rb +5 -14
  19. data/lib/3scale_toolbox/commands/import_command/openapi/step.rb +4 -0
  20. data/lib/3scale_toolbox/commands/import_command/openapi/update_service_proxy_step.rb +1 -0
  21. data/lib/3scale_toolbox/commands/methods_command/apply_command.rb +2 -4
  22. data/lib/3scale_toolbox/commands/methods_command/create_command.rb +0 -2
  23. data/lib/3scale_toolbox/commands/methods_command/delete_command.rb +1 -1
  24. data/lib/3scale_toolbox/commands/methods_command/list_command.rb +1 -9
  25. data/lib/3scale_toolbox/commands/metrics_command/list_command.rb +1 -1
  26. data/lib/3scale_toolbox/commands/plans_command/export/read_plan_limits_step.rb +1 -1
  27. data/lib/3scale_toolbox/commands/plans_command/export/read_plan_methods_step.rb +2 -2
  28. data/lib/3scale_toolbox/commands/plans_command/export/read_plan_metrics_step.rb +2 -2
  29. data/lib/3scale_toolbox/commands/plans_command/export/read_plan_pricing_rules_step.rb +1 -2
  30. data/lib/3scale_toolbox/commands/plans_command/export/step.rb +8 -20
  31. data/lib/3scale_toolbox/commands/plans_command/import/import_plan_limits_step.rb +7 -8
  32. data/lib/3scale_toolbox/commands/plans_command/import/import_plan_metrics_step.rb +6 -13
  33. data/lib/3scale_toolbox/commands/plans_command/import/import_plan_pricing_rules_step.rb +8 -15
  34. data/lib/3scale_toolbox/commands/plans_command/import/step.rb +2 -22
  35. data/lib/3scale_toolbox/commands/plans_command/list_command.rb +1 -1
  36. data/lib/3scale_toolbox/commands/plans_command/show_command.rb +1 -1
  37. data/lib/3scale_toolbox/commands/policies_command.rb +24 -0
  38. data/lib/3scale_toolbox/commands/policies_command/export_command.rb +98 -0
  39. data/lib/3scale_toolbox/commands/policies_command/import_command.rb +61 -0
  40. data/lib/3scale_toolbox/commands/product_command.rb +4 -0
  41. data/lib/3scale_toolbox/commands/product_command/copy_command.rb +8 -3
  42. data/lib/3scale_toolbox/commands/product_command/copy_command/copy_backends_task.rb +28 -5
  43. data/lib/3scale_toolbox/commands/product_command/export_command.rb +81 -0
  44. data/lib/3scale_toolbox/commands/product_command/import_command.rb +126 -0
  45. data/lib/3scale_toolbox/commands/proxy_config_command.rb +2 -0
  46. data/lib/3scale_toolbox/commands/proxy_config_command/deploy_command.rb +54 -0
  47. data/lib/3scale_toolbox/commands/service_command/copy_command/copy_activedocs_task.rb +15 -12
  48. data/lib/3scale_toolbox/commands/service_command/copy_command/copy_app_plans_task.rb +15 -15
  49. data/lib/3scale_toolbox/commands/service_command/copy_command/copy_limits_task.rb +12 -13
  50. data/lib/3scale_toolbox/commands/service_command/copy_command/copy_mapping_rules_task.rb +11 -11
  51. data/lib/3scale_toolbox/commands/service_command/copy_command/copy_methods_task.rb +9 -12
  52. data/lib/3scale_toolbox/commands/service_command/copy_command/copy_metrics_task.rb +8 -8
  53. data/lib/3scale_toolbox/commands/service_command/copy_command/copy_policies_task.rb +1 -1
  54. data/lib/3scale_toolbox/commands/service_command/copy_command/copy_pricingrules_task.rb +15 -18
  55. data/lib/3scale_toolbox/commands/service_command/copy_command/copy_service_proxy_task.rb +2 -2
  56. data/lib/3scale_toolbox/commands/service_command/copy_command/create_or_update_service_task.rb +2 -1
  57. data/lib/3scale_toolbox/commands/service_command/copy_command/destroy_mapping_rules_task.rb +9 -5
  58. data/lib/3scale_toolbox/commands/service_command/copy_command/task.rb +20 -34
  59. data/lib/3scale_toolbox/commands/update_command/service_command/delete_activedocs_task.rb +1 -3
  60. data/lib/3scale_toolbox/crds.rb +16 -0
  61. data/lib/3scale_toolbox/crds/application_plan_dump.rb +19 -0
  62. data/lib/3scale_toolbox/crds/backend_dump.rb +39 -0
  63. data/lib/3scale_toolbox/crds/backend_mapping_rule_dump.rb +26 -0
  64. data/lib/3scale_toolbox/crds/backend_method_dump.rb +12 -0
  65. data/lib/3scale_toolbox/crds/backend_metric_dump.rb +13 -0
  66. data/lib/3scale_toolbox/crds/backend_parser.rb +55 -0
  67. data/lib/3scale_toolbox/crds/backend_usage_dump.rb +11 -0
  68. data/lib/3scale_toolbox/crds/limit_dump.rb +37 -0
  69. data/lib/3scale_toolbox/crds/mapping_rule_dump.rb +26 -0
  70. data/lib/3scale_toolbox/crds/method_dump.rb +12 -0
  71. data/lib/3scale_toolbox/crds/metric_dump.rb +13 -0
  72. data/lib/3scale_toolbox/crds/pricing_rule_dump.rb +38 -0
  73. data/lib/3scale_toolbox/crds/product_deployment_parser.rb +329 -0
  74. data/lib/3scale_toolbox/crds/product_dump.rb +157 -0
  75. data/lib/3scale_toolbox/crds/product_parser.rb +114 -0
  76. data/lib/3scale_toolbox/crds/remote.rb +682 -0
  77. data/lib/3scale_toolbox/entities.rb +3 -0
  78. data/lib/3scale_toolbox/entities/account.rb +1 -1
  79. data/lib/3scale_toolbox/entities/activedocs.rb +12 -0
  80. data/lib/3scale_toolbox/entities/application_plan.rb +54 -46
  81. data/lib/3scale_toolbox/entities/backend.rb +65 -30
  82. data/lib/3scale_toolbox/entities/backend_mapping_rule.rb +29 -3
  83. data/lib/3scale_toolbox/entities/backend_method.rb +25 -16
  84. data/lib/3scale_toolbox/entities/backend_metric.rb +12 -2
  85. data/lib/3scale_toolbox/entities/backend_usage.rb +7 -1
  86. data/lib/3scale_toolbox/entities/limit.rb +71 -0
  87. data/lib/3scale_toolbox/entities/mapping_rule.rb +90 -0
  88. data/lib/3scale_toolbox/entities/method.rb +33 -19
  89. data/lib/3scale_toolbox/entities/metric.rb +29 -18
  90. data/lib/3scale_toolbox/entities/pricing_rule.rb +63 -0
  91. data/lib/3scale_toolbox/entities/proxy_config.rb +0 -1
  92. data/lib/3scale_toolbox/entities/service.rb +149 -46
  93. data/lib/3scale_toolbox/helper.rb +13 -16
  94. data/lib/3scale_toolbox/proxy_logger.rb +4 -0
  95. data/lib/3scale_toolbox/remote_cache.rb +164 -0
  96. data/lib/3scale_toolbox/remotes.rb +2 -2
  97. data/lib/3scale_toolbox/version.rb +1 -1
  98. data/licenses.xml +98 -50
  99. metadata +37 -9
@@ -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 run
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
@@ -69,6 +73,7 @@ module ThreeScaleToolbox
69
73
  source_remote: threescale_client(fetch_required_option(:source)),
70
74
  target_remote: threescale_client(fetch_required_option(:destination)),
71
75
  source_service_ref: arguments[:source_product],
76
+ delete_mapping_rules: true,
72
77
  option_target_system_name: options[:'target-system-name']
73
78
  }
74
79
  end
@@ -13,32 +13,36 @@ module ThreeScaleToolbox
13
13
  def call
14
14
  backend_list = source.backend_usage_list
15
15
  backend_list.each(&method(:create_backend))
16
- puts "created/upated #{backend_list.size} backends"
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.system_name)
23
+ backend_context = create_backend_context(source_backend)
24
24
 
25
25
  tasks = []
26
26
  tasks << Commands::BackendCommand::CopyCommand::CreateOrUpdateTargetBackendTask.new(backend_context)
27
27
  # First metrics as methods need 'hits' metric in target backend
28
28
  tasks << Commands::BackendCommand::CopyCommand::CopyMetricsTask.new(backend_context)
29
29
  tasks << Commands::BackendCommand::CopyCommand::CopyMethodsTask.new(backend_context)
30
+ tasks << Commands::BackendCommand::CopyCommand::DeleteMappingRulesTask.new(backend_context)
30
31
  tasks << Commands::BackendCommand::CopyCommand::CopyMappingRulesTask.new(backend_context)
31
32
  tasks.each(&:call)
32
33
 
33
34
  # CreateOrUpdate task will keep reference of the target backend in
34
35
  # backend_context[:target_backend]
36
+ target_backend = backend_context[:target_backend]
35
37
  attrs = {
36
- 'backend_api_id' => backend_context[:target_backend].id,
38
+ 'backend_api_id' => target_backend.id,
37
39
  'path' => backend_usage.path
38
40
  }
39
41
  # It is assumed there is no target backend usage with this backend_source's path
40
42
  # DeleteExistingTargetBackendUsagesTask should provide that
41
43
  Entities::BackendUsage.create(product: target, attrs: attrs)
44
+
45
+ backends_report.merge!(target_backend.system_name => backend_context.fetch(:report))
42
46
  end
43
47
 
44
48
  def source
@@ -57,11 +61,30 @@ module ThreeScaleToolbox
57
61
  context[:target_remote]
58
62
  end
59
63
 
60
- def create_backend_context(source_backend_system_name)
64
+ def backends_report
65
+ report['backends'] ||= {}
66
+ end
67
+
68
+ def report
69
+ context.fetch(:report)
70
+ end
71
+
72
+ def logger
73
+ context.fetch(:logger)
74
+ end
75
+
76
+ def delete_mapping_rules
77
+ context.fetch(:delete_mapping_rules, false)
78
+ end
79
+
80
+ def create_backend_context(source_backend)
61
81
  {
62
82
  source_remote: source_remote,
63
83
  target_remote: target_remote,
64
- source_backend_ref: source_backend_system_name
84
+ source_backend: source_backend,
85
+ source_backend_ref: source_backend.id,
86
+ delete_mapping_rules: delete_mapping_rules,
87
+ logger: logger
65
88
  }
66
89
  end
67
90
  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,126 @@
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
+ delete_mapping_rules: true,
32
+ logger: Logger.new(File::NULL)
33
+ }
34
+
35
+ Commands::ProductCommand::CopySubcommand.workflow(context)
36
+
37
+ report[product.system_name] = context.fetch(:report)
38
+ end
39
+
40
+ printer.print_collection report
41
+ end
42
+
43
+ private
44
+
45
+ def crd_remote
46
+ @crd_remote ||= CRD::Remote.new(product_list, backend_list)
47
+ end
48
+
49
+ def product_list
50
+ @product_list ||= product_resources.map do |product_cr|
51
+ CRD::ProductParser.new product_cr
52
+ end
53
+ end
54
+
55
+ def backend_list
56
+ @backend_list ||= backend_resources.map do |backend_cr|
57
+ CRD::BackendParser.new backend_cr
58
+ end
59
+ end
60
+
61
+ def validate_artifacts_resource!
62
+ # TODO: Add openapiV3 validation
63
+ # https://github.com/3scale/3scale-operator/blob/3scale-2.10.0-CR2/deploy/crds/capabilities.3scale.net_backends_crd.yaml
64
+ # https://github.com/3scale/3scale-operator/blob/3scale-2.10.0-CR2/deploy/crds/capabilities.3scale.net_products_crd.yaml
65
+ validate_api_version!
66
+
67
+ validate_kind!
68
+ end
69
+
70
+ def validate_api_version!
71
+ artifacts_resource.fetch('apiVersion') do
72
+ raise ThreeScaleToolbox::Error, 'Invalid content. apiVersion not found'
73
+ end
74
+
75
+ raise ThreeScaleToolbox::Error, 'Invalid content. apiVersion wrong value ' unless artifacts_resource.fetch('apiVersion') == 'v1'
76
+ end
77
+
78
+ def validate_kind!
79
+ artifacts_resource.fetch('kind') do
80
+ raise ThreeScaleToolbox::Error, 'Invalid content. kind not found'
81
+ end
82
+
83
+ raise ThreeScaleToolbox::Error, 'Invalid content. kind wrong value ' unless artifacts_resource.fetch('kind') == 'List'
84
+ end
85
+
86
+ def artifacts_resource_items
87
+ artifacts_resource.fetch('items') do
88
+ raise ThreeScaleToolbox::Error, 'Invalid content. items not found'
89
+ end
90
+ end
91
+
92
+ def product_resources
93
+ artifacts_resource_items.select do |item|
94
+ item.respond_to?(:has_key?) &&
95
+ item.fetch('apiVersion', '').include?('capabilities.3scale.net') &&
96
+ item['kind'] == 'Product'
97
+ end
98
+ end
99
+
100
+ def backend_resources
101
+ artifacts_resource_items.select do |item|
102
+ item.respond_to?(:has_key?) &&
103
+ item.fetch('apiVersion', '').include?('capabilities.3scale.net') &&
104
+ item['kind'] == 'Backend'
105
+ end
106
+ end
107
+
108
+ def artifacts_resource
109
+ @artifacts_resource ||= load_resource(options[:file] || '-')
110
+ end
111
+
112
+ def report
113
+ @report ||= {}
114
+ end
115
+
116
+ def remote
117
+ @remote ||= threescale_client(arguments[:remote])
118
+ end
119
+
120
+ def printer
121
+ options.fetch(:output, CLI::JsonPrinter.new)
122
+ end
123
+ end
124
+ end
125
+ end
126
+ end
@@ -5,6 +5,7 @@ require '3scale_toolbox/commands/proxy_config_command/list_command'
5
5
  require '3scale_toolbox/commands/proxy_config_command/show_command'
6
6
  require '3scale_toolbox/commands/proxy_config_command/promote_command'
7
7
  require '3scale_toolbox/commands/proxy_config_command/export_command'
8
+ require '3scale_toolbox/commands/proxy_config_command/deploy_command'
8
9
 
9
10
  module ThreeScaleToolbox
10
11
  module Commands
@@ -28,6 +29,7 @@ module ThreeScaleToolbox
28
29
  add_subcommand(Show::ShowSubcommand)
29
30
  add_subcommand(Promote::PromoteSubcommand)
30
31
  add_subcommand(Export::ExportSubcommand)
32
+ add_subcommand(DeploySubcommand)
31
33
  end
32
34
  end
33
35
  end
@@ -0,0 +1,54 @@
1
+ module ThreeScaleToolbox
2
+ module Commands
3
+ module ProxyConfigCommand
4
+ class DeploySubcommand < Cri::CommandRunner
5
+ include ThreeScaleToolbox::Command
6
+
7
+ def self.command
8
+ Cri::Command.define do
9
+ name 'deploy'
10
+ usage 'deploy <remote> <service>'
11
+ summary 'Promotes the APIcast configuration to the Staging Environment'
12
+ description 'Promotes the APIcast configuration to the Staging Environment (Production Environment in case of Service Mesh).'
13
+
14
+ param :remote
15
+ param :service_ref
16
+
17
+ ThreeScaleToolbox::CLI.output_flag(self)
18
+
19
+ runner DeploySubcommand
20
+ end
21
+ end
22
+
23
+ def run
24
+ printer.print_record service.proxy_deploy
25
+ end
26
+
27
+ private
28
+
29
+ def remote
30
+ @remote ||= threescale_client(arguments[:remote])
31
+ end
32
+
33
+ def service_ref
34
+ arguments[:service_ref]
35
+ end
36
+
37
+ def find_service
38
+ Entities::Service.find(remote: remote,
39
+ ref: service_ref).tap do |svc|
40
+ raise ThreeScaleToolbox::Error, "Service #{service_ref} does not exist" if svc.nil?
41
+ end
42
+ end
43
+
44
+ def service
45
+ @service ||= find_service
46
+ end
47
+
48
+ def printer
49
+ options.fetch(:output, CLI::JsonPrinter.new)
50
+ end
51
+ end
52
+ end
53
+ end
54
+ end