3scale_toolbox 0.15.0 → 0.18.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (151) hide show
  1. checksums.yaml +4 -4
  2. data/3scale_toolbox.gemspec +2 -2
  3. data/README.md +15 -9
  4. data/lib/3scale_toolbox.rb +3 -1
  5. data/lib/3scale_toolbox/3scale_client_factory.rb +3 -4
  6. data/lib/3scale_toolbox/cli.rb +4 -0
  7. data/lib/3scale_toolbox/cli/custom_table_printer.rb +32 -0
  8. data/lib/3scale_toolbox/cli/error_handler.rb +17 -14
  9. data/lib/3scale_toolbox/cli/json_printer.rb +13 -0
  10. data/lib/3scale_toolbox/cli/output_flag.rb +20 -0
  11. data/lib/3scale_toolbox/cli/yaml_printer.rb +13 -0
  12. data/lib/3scale_toolbox/commands.rb +7 -1
  13. data/lib/3scale_toolbox/commands/activedocs_command/apply_command.rb +33 -10
  14. data/lib/3scale_toolbox/commands/activedocs_command/create_command.rb +22 -7
  15. data/lib/3scale_toolbox/commands/activedocs_command/list_command.rb +10 -17
  16. data/lib/3scale_toolbox/commands/application_command/apply_command.rb +27 -4
  17. data/lib/3scale_toolbox/commands/application_command/create_command.rb +16 -1
  18. data/lib/3scale_toolbox/commands/application_command/list_command.rb +10 -13
  19. data/lib/3scale_toolbox/commands/application_command/show_command.rb +8 -14
  20. data/lib/3scale_toolbox/commands/backend_command.rb +22 -0
  21. data/lib/3scale_toolbox/commands/backend_command/copy_command.rb +65 -0
  22. data/lib/3scale_toolbox/commands/backend_command/copy_command/copy_mapping_rules_task.rb +36 -0
  23. data/lib/3scale_toolbox/commands/backend_command/copy_command/copy_methods_task.rb +35 -0
  24. data/lib/3scale_toolbox/commands/backend_command/copy_command/copy_metrics_task.rb +30 -0
  25. data/lib/3scale_toolbox/commands/backend_command/copy_command/create_or_update_target_backend_task.rb +46 -0
  26. data/lib/3scale_toolbox/commands/backend_command/copy_command/task.rb +67 -0
  27. data/lib/3scale_toolbox/commands/copy_command.rb +2 -2
  28. data/lib/3scale_toolbox/commands/copy_command/service_command.rb +40 -0
  29. data/lib/3scale_toolbox/commands/import_command/issuer_type_transformer.rb +16 -0
  30. data/lib/3scale_toolbox/commands/import_command/openapi.rb +6 -2
  31. data/lib/3scale_toolbox/commands/import_command/openapi/create_mapping_rule_step.rb +2 -1
  32. data/lib/3scale_toolbox/commands/import_command/openapi/create_method_step.rb +5 -14
  33. data/lib/3scale_toolbox/commands/import_command/openapi/step.rb +4 -0
  34. data/lib/3scale_toolbox/commands/import_command/openapi/update_service_proxy_step.rb +1 -0
  35. data/lib/3scale_toolbox/commands/methods_command/apply_command.rb +28 -8
  36. data/lib/3scale_toolbox/commands/methods_command/create_command.rb +23 -3
  37. data/lib/3scale_toolbox/commands/methods_command/delete_command.rb +1 -1
  38. data/lib/3scale_toolbox/commands/methods_command/list_command.rb +7 -13
  39. data/lib/3scale_toolbox/commands/metrics_command/apply_command.rb +26 -4
  40. data/lib/3scale_toolbox/commands/metrics_command/create_command.rb +23 -1
  41. data/lib/3scale_toolbox/commands/metrics_command/list_command.rb +7 -12
  42. data/lib/3scale_toolbox/commands/plans_command/apply_command.rb +36 -7
  43. data/lib/3scale_toolbox/commands/plans_command/create_command.rb +23 -1
  44. data/lib/3scale_toolbox/commands/plans_command/export/read_plan_limits_step.rb +1 -1
  45. data/lib/3scale_toolbox/commands/plans_command/export/read_plan_methods_step.rb +2 -2
  46. data/lib/3scale_toolbox/commands/plans_command/export/read_plan_metrics_step.rb +2 -2
  47. data/lib/3scale_toolbox/commands/plans_command/export/read_plan_pricing_rules_step.rb +1 -2
  48. data/lib/3scale_toolbox/commands/plans_command/export/step.rb +8 -20
  49. data/lib/3scale_toolbox/commands/plans_command/import/import_plan_limits_step.rb +12 -14
  50. data/lib/3scale_toolbox/commands/plans_command/import/import_plan_metrics_step.rb +6 -13
  51. data/lib/3scale_toolbox/commands/plans_command/import/import_plan_pricing_rules_step.rb +12 -20
  52. data/lib/3scale_toolbox/commands/plans_command/import/step.rb +2 -22
  53. data/lib/3scale_toolbox/commands/plans_command/list_command.rb +8 -13
  54. data/lib/3scale_toolbox/commands/plans_command/show_command.rb +7 -15
  55. data/lib/3scale_toolbox/commands/policies_command.rb +24 -0
  56. data/lib/3scale_toolbox/commands/policies_command/export_command.rb +98 -0
  57. data/lib/3scale_toolbox/commands/policies_command/import_command.rb +61 -0
  58. data/lib/3scale_toolbox/commands/product_command.rb +26 -0
  59. data/lib/3scale_toolbox/commands/product_command/copy_command.rb +82 -0
  60. data/lib/3scale_toolbox/commands/product_command/copy_command/copy_backends_task.rb +88 -0
  61. data/lib/3scale_toolbox/commands/product_command/copy_command/delete_target_backend_usages_task.rb +48 -0
  62. data/lib/3scale_toolbox/commands/product_command/export_command.rb +81 -0
  63. data/lib/3scale_toolbox/commands/product_command/import_command.rb +125 -0
  64. data/lib/3scale_toolbox/commands/proxy_config_command.rb +5 -0
  65. data/lib/3scale_toolbox/commands/proxy_config_command/deploy_command.rb +54 -0
  66. data/lib/3scale_toolbox/commands/proxy_config_command/export_command.rb +74 -0
  67. data/lib/3scale_toolbox/commands/proxy_config_command/helper.rb +15 -0
  68. data/lib/3scale_toolbox/commands/proxy_config_command/list_command.rb +13 -29
  69. data/lib/3scale_toolbox/commands/proxy_config_command/show_command.rb +20 -23
  70. data/lib/3scale_toolbox/commands/service_command.rb +7 -5
  71. data/lib/3scale_toolbox/commands/service_command/apply_command.rb +69 -58
  72. data/lib/3scale_toolbox/commands/service_command/copy_command.rb +95 -0
  73. data/lib/3scale_toolbox/commands/service_command/copy_command/bump_proxy_version_task.rb +36 -0
  74. data/lib/3scale_toolbox/commands/service_command/copy_command/copy_activedocs_task.rb +49 -0
  75. data/lib/3scale_toolbox/commands/service_command/copy_command/copy_app_plans_task.rb +35 -0
  76. data/lib/3scale_toolbox/commands/service_command/copy_command/copy_limits_task.rb +38 -0
  77. data/lib/3scale_toolbox/commands/service_command/copy_command/copy_mapping_rules_task.rb +35 -0
  78. data/lib/3scale_toolbox/commands/service_command/copy_command/copy_methods_task.rb +37 -0
  79. data/lib/3scale_toolbox/commands/service_command/copy_command/copy_metrics_task.rb +37 -0
  80. data/lib/3scale_toolbox/commands/service_command/copy_command/copy_policies_task.rb +17 -0
  81. data/lib/3scale_toolbox/commands/service_command/copy_command/copy_pricingrules_task.rb +41 -0
  82. data/lib/3scale_toolbox/commands/service_command/copy_command/copy_service_proxy_task.rb +32 -0
  83. data/lib/3scale_toolbox/commands/service_command/copy_command/create_or_update_service_task.rb +49 -0
  84. data/lib/3scale_toolbox/commands/service_command/copy_command/destroy_mapping_rules_task.rb +38 -0
  85. data/lib/3scale_toolbox/commands/service_command/copy_command/task.rb +85 -0
  86. data/lib/3scale_toolbox/commands/service_command/create_command.rb +58 -44
  87. data/lib/3scale_toolbox/commands/service_command/delete_command.rb +31 -33
  88. data/lib/3scale_toolbox/commands/service_command/list_command.rb +24 -34
  89. data/lib/3scale_toolbox/commands/service_command/show_command.rb +39 -44
  90. data/lib/3scale_toolbox/commands/update_command.rb +3 -3
  91. data/lib/3scale_toolbox/commands/update_command/{update_service.rb → service_command.rb} +22 -18
  92. data/lib/3scale_toolbox/commands/update_command/service_command/copy_service_settings_task.rb +35 -0
  93. data/lib/3scale_toolbox/commands/update_command/service_command/delete_activedocs_task.rb +24 -0
  94. data/lib/3scale_toolbox/crds.rb +16 -0
  95. data/lib/3scale_toolbox/crds/application_plan_dump.rb +19 -0
  96. data/lib/3scale_toolbox/crds/backend_dump.rb +39 -0
  97. data/lib/3scale_toolbox/crds/backend_mapping_rule_dump.rb +26 -0
  98. data/lib/3scale_toolbox/crds/backend_method_dump.rb +12 -0
  99. data/lib/3scale_toolbox/crds/backend_metric_dump.rb +13 -0
  100. data/lib/3scale_toolbox/crds/backend_parser.rb +55 -0
  101. data/lib/3scale_toolbox/crds/backend_usage_dump.rb +11 -0
  102. data/lib/3scale_toolbox/crds/limit_dump.rb +37 -0
  103. data/lib/3scale_toolbox/crds/mapping_rule_dump.rb +26 -0
  104. data/lib/3scale_toolbox/crds/method_dump.rb +12 -0
  105. data/lib/3scale_toolbox/crds/metric_dump.rb +13 -0
  106. data/lib/3scale_toolbox/crds/pricing_rule_dump.rb +38 -0
  107. data/lib/3scale_toolbox/crds/product_deployment_parser.rb +329 -0
  108. data/lib/3scale_toolbox/crds/product_dump.rb +157 -0
  109. data/lib/3scale_toolbox/crds/product_parser.rb +114 -0
  110. data/lib/3scale_toolbox/crds/remote.rb +682 -0
  111. data/lib/3scale_toolbox/entities.rb +8 -0
  112. data/lib/3scale_toolbox/entities/activedocs.rb +12 -0
  113. data/lib/3scale_toolbox/entities/application_plan.rb +74 -39
  114. data/lib/3scale_toolbox/entities/backend.rb +187 -0
  115. data/lib/3scale_toolbox/entities/backend_mapping_rule.rb +102 -0
  116. data/lib/3scale_toolbox/entities/backend_method.rb +99 -0
  117. data/lib/3scale_toolbox/entities/backend_metric.rb +98 -0
  118. data/lib/3scale_toolbox/entities/backend_usage.rb +105 -0
  119. data/lib/3scale_toolbox/entities/limit.rb +71 -0
  120. data/lib/3scale_toolbox/entities/mapping_rule.rb +90 -0
  121. data/lib/3scale_toolbox/entities/method.rb +33 -19
  122. data/lib/3scale_toolbox/entities/metric.rb +29 -18
  123. data/lib/3scale_toolbox/entities/pricing_rule.rb +63 -0
  124. data/lib/3scale_toolbox/entities/proxy_config.rb +0 -1
  125. data/lib/3scale_toolbox/entities/service.rb +166 -48
  126. data/lib/3scale_toolbox/error.rb +53 -0
  127. data/lib/3scale_toolbox/helper.rb +17 -0
  128. data/lib/3scale_toolbox/openapi/oas3.rb +1 -1
  129. data/lib/3scale_toolbox/proxy_logger.rb +5 -1
  130. data/lib/3scale_toolbox/remote_cache.rb +157 -0
  131. data/lib/3scale_toolbox/remotes.rb +2 -2
  132. data/lib/3scale_toolbox/version.rb +1 -1
  133. data/licenses.xml +113 -45
  134. metadata +75 -26
  135. data/lib/3scale_toolbox/commands/copy_command/copy_service.rb +0 -144
  136. data/lib/3scale_toolbox/tasks.rb +0 -15
  137. data/lib/3scale_toolbox/tasks/bump_proxy_version_task.rb +0 -32
  138. data/lib/3scale_toolbox/tasks/copy_activedocs_task.rb +0 -42
  139. data/lib/3scale_toolbox/tasks/copy_app_plans_task.rb +0 -31
  140. data/lib/3scale_toolbox/tasks/copy_limits_task.rb +0 -36
  141. data/lib/3scale_toolbox/tasks/copy_mapping_rules_task.rb +0 -32
  142. data/lib/3scale_toolbox/tasks/copy_methods_task.rb +0 -36
  143. data/lib/3scale_toolbox/tasks/copy_metrics_task.rb +0 -33
  144. data/lib/3scale_toolbox/tasks/copy_policies_task.rb +0 -13
  145. data/lib/3scale_toolbox/tasks/copy_pricingrules_task.rb +0 -41
  146. data/lib/3scale_toolbox/tasks/copy_service_proxy_task.rb +0 -13
  147. data/lib/3scale_toolbox/tasks/copy_service_settings_task.rb +0 -38
  148. data/lib/3scale_toolbox/tasks/copy_task.rb +0 -66
  149. data/lib/3scale_toolbox/tasks/delete_activedocs_task.rb +0 -22
  150. data/lib/3scale_toolbox/tasks/destroy_mapping_rules_task.rb +0 -22
  151. data/lib/3scale_toolbox/tasks/helper_task.rb +0 -25
@@ -1,38 +1,35 @@
1
1
  module ThreeScaleToolbox
2
2
  module Entities
3
3
  class Method
4
+ include CRD::MethodSerializer
5
+
4
6
  class << self
5
- def create(service:, parent_id:, attrs:)
6
- method = service.remote.create_method service.id, parent_id, attrs
7
- if (errors = method['errors'])
7
+ def create(service:, attrs:)
8
+ method_attrs = service.remote.create_method service.id, service.hits.id, attrs
9
+ if (errors = method_attrs['errors'])
8
10
  raise ThreeScaleToolbox::ThreeScaleApiError.new('Method has not been created', errors)
9
-
10
11
  end
11
12
 
12
- new(id: method.fetch('id'), parent_id: parent_id, service: service, attrs: method)
13
+ new(id: method_attrs.fetch('id'), service: service, attrs: method_attrs)
13
14
  end
14
15
 
15
16
  # ref can be system_name or method_id
16
- def find(service:, parent_id:, ref:)
17
- new(id: ref, parent_id: parent_id, service: service).tap(&:attrs)
17
+ def find(service:, ref:)
18
+ new(id: ref, service: service).tap(&:attrs)
18
19
  rescue ThreeScale::API::HttpClient::NotFoundError
19
- find_by_system_name(service: service, parent_id: parent_id, system_name: ref)
20
+ find_by_system_name(service: service, system_name: ref)
20
21
  end
21
22
 
22
- def find_by_system_name(service:, parent_id:, system_name:)
23
- method = service.methods(parent_id).find { |m| m['system_name'] == system_name }
24
- return if method.nil?
25
-
26
- new(id: method.fetch('id'), parent_id: parent_id, service: service, attrs: method)
23
+ def find_by_system_name(service:, system_name:)
24
+ service.methods.find { |m| m.system_name == system_name }
27
25
  end
28
26
  end
29
27
 
30
- attr_reader :id, :parent_id, :service, :remote
28
+ attr_reader :id, :service, :remote
31
29
 
32
- def initialize(id:, parent_id:, service:, attrs: nil)
30
+ def initialize(id:, service:, attrs: nil)
33
31
  @id = id.to_i
34
32
  @service = service
35
- @parent_id = parent_id
36
33
  @remote = service.remote
37
34
  @attrs = attrs
38
35
  end
@@ -41,6 +38,18 @@ module ThreeScaleToolbox
41
38
  @attrs ||= method_attrs
42
39
  end
43
40
 
41
+ def system_name
42
+ attrs['system_name']
43
+ end
44
+
45
+ def friendly_name
46
+ attrs['friendly_name']
47
+ end
48
+
49
+ def description
50
+ attrs['description']
51
+ end
52
+
44
53
  def disable
45
54
  Metric.new(id: id, service: service).disable
46
55
  end
@@ -50,7 +59,7 @@ module ThreeScaleToolbox
50
59
  end
51
60
 
52
61
  def update(m_attrs)
53
- new_attrs = remote.update_method(service.id, parent_id, id, m_attrs)
62
+ new_attrs = remote.update_method(service.id, hits_id, id, m_attrs)
54
63
  if (errors = new_attrs['errors'])
55
64
  raise ThreeScaleToolbox::ThreeScaleApiError.new('Method has not been updated', errors)
56
65
  end
@@ -62,13 +71,18 @@ module ThreeScaleToolbox
62
71
  end
63
72
 
64
73
  def delete
65
- remote.delete_method service.id, parent_id, id
74
+ remote.delete_method service.id, hits_id, id
66
75
  end
67
76
 
77
+
68
78
  private
69
79
 
80
+ def hits_id
81
+ service.hits.id
82
+ end
83
+
70
84
  def method_attrs
71
- method = remote.show_method service.id, parent_id, id
85
+ method = remote.show_method service.id, hits_id, id
72
86
  if (errors = method['errors'])
73
87
  raise ThreeScaleToolbox::ThreeScaleApiError.new('Method not read', errors)
74
88
  end
@@ -1,6 +1,8 @@
1
1
  module ThreeScaleToolbox
2
2
  module Entities
3
3
  class Metric
4
+ include CRD::MetricSerializer
5
+
4
6
  class << self
5
7
  def create(service:, attrs:)
6
8
  metric = service.remote.create_metric service.id, attrs
@@ -19,10 +21,7 @@ module ThreeScaleToolbox
19
21
  end
20
22
 
21
23
  def find_by_system_name(service:, system_name:)
22
- metric = service.metrics.find { |m| m['system_name'] == system_name }
23
- return if metric.nil?
24
-
25
- new(id: metric.fetch('id'), service: service, attrs: metric)
24
+ service.metrics.find { |m| m.system_name == system_name }
26
25
  end
27
26
  end
28
27
 
@@ -39,25 +38,41 @@ module ThreeScaleToolbox
39
38
  @attrs ||= metric_attrs
40
39
  end
41
40
 
41
+ def system_name
42
+ attrs['system_name']
43
+ end
44
+
45
+ def friendly_name
46
+ attrs['friendly_name']
47
+ end
48
+
49
+ def unit
50
+ attrs['unit']
51
+ end
52
+
53
+ def description
54
+ attrs['description']
55
+ end
56
+
42
57
  def disable
43
58
  # For each plan, get limits for the current metric
44
59
  # if already disabled -> NOOP
45
60
  # if non zero eternity limit exist, update
46
61
  # if non eternity limit exist, create
47
- service_plans.each do |plan|
62
+ service.plans.each do |plan|
48
63
  eternity_limit = plan_eternity_limit(plan)
49
64
  if eternity_limit.nil?
50
65
  plan.create_limit(id, zero_eternity_limit_attrs)
51
- elsif !eternity_limit.fetch('value').zero?
52
- plan.update_limit(id, eternity_limit.fetch('id'), zero_eternity_limit_attrs)
66
+ elsif !eternity_limit.value.zero?
67
+ eternity_limit.update(zero_eternity_limit_attrs)
53
68
  end
54
69
  end
55
70
  end
56
71
 
57
72
  def enable
58
- service_plans.each do |plan|
73
+ service.plans.each do |plan|
59
74
  limit = plan_zero_eternity_limit(plan)
60
- plan.delete_limit(id, limit.fetch('id')) unless limit.nil?
75
+ limit.delete unless limit.nil?
61
76
  end
62
77
  end
63
78
 
@@ -90,19 +105,15 @@ module ThreeScaleToolbox
90
105
 
91
106
  def plan_zero_eternity_limit(plan)
92
107
  # only one limit for eternity period is allowed per (plan_id, metric_id)
93
- plan.metric_limits(id).find { |limit| limit > zero_eternity_limit_attrs }
108
+ #plan.metric_limits(id).find { |limit| limit.attrs > zero_eternity_limit_attrs }
109
+ plan.metric_limits(id).find do |limit|
110
+ limit.attrs > zero_eternity_limit_attrs
111
+ end
94
112
  end
95
113
 
96
114
  def plan_eternity_limit(plan)
97
115
  # only one limit for eternity period is allowed per (plan_id, metric_id)
98
- plan.metric_limits(id).find { |limit| limit['period'] == 'eternity' }
99
- end
100
-
101
- def service_plans
102
- service.plans.map do |plan_attrs|
103
- ThreeScaleToolbox::Entities::ApplicationPlan.new(id: plan_attrs.fetch('id'),
104
- service: service)
105
- end
116
+ plan.metric_limits(id).find { |limit| limit.period == 'eternity' }
106
117
  end
107
118
 
108
119
  def zero_eternity_limit_attrs
@@ -0,0 +1,63 @@
1
+ module ThreeScaleToolbox
2
+ module Entities
3
+ class PricingRule
4
+ include CRD::PricingRuleSerializer
5
+
6
+ class << self
7
+ def create(plan:, metric_id:, attrs:)
8
+ resp_attrs = plan.remote.create_pricingrule plan.id, metric_id, attrs
9
+ if (errors = resp_attrs['errors'])
10
+ raise ThreeScaleToolbox::ThreeScaleApiError.new('Pricing rule has not been created', errors)
11
+ end
12
+
13
+ new(id: resp_attrs.fetch('id'), plan: plan, metric_id: metric_id, attrs: resp_attrs)
14
+ end
15
+ end
16
+
17
+ attr_reader :id, :plan, :remote, :attrs, :metric_id
18
+
19
+ def initialize(id:, plan:, metric_id:, attrs:)
20
+ @id = id.to_i
21
+ @plan = plan
22
+ @remote = plan.remote
23
+ @metric_id = metric_id
24
+ @attrs = attrs
25
+ end
26
+
27
+ def cost_per_unit
28
+ attrs['cost_per_unit'].to_f
29
+ end
30
+
31
+ def min
32
+ attrs['min']
33
+ end
34
+
35
+ def max
36
+ attrs['max']
37
+ end
38
+
39
+ def links
40
+ attrs['links'] || []
41
+ end
42
+
43
+ def metric_link
44
+ links.find { |link| link['rel'] == 'metric' }
45
+ end
46
+
47
+ def delete
48
+ remote.delete_application_plan_pricingrule plan.id, metric_id, id
49
+ end
50
+
51
+ private
52
+
53
+ # Used by CRD::PricingRule
54
+ # Returns the backend hosting the metric
55
+ def backend_from_metric
56
+ backend_id = Helper.backend_metric_link_parser(metric_link['href'] || '')
57
+ return if backend_id.nil?
58
+
59
+ Backend.new(id: backend_id.to_i, remote: remote)
60
+ end
61
+ end
62
+ end
63
+ end
@@ -52,7 +52,6 @@ module ThreeScaleToolbox
52
52
  end
53
53
  proxy_cfg
54
54
  end
55
-
56
55
  end
57
56
  end
58
57
  end
@@ -1,6 +1,8 @@
1
1
  module ThreeScaleToolbox
2
2
  module Entities
3
3
  class Service
4
+ include CRD::ProductSerializer
5
+
4
6
  VALID_PARAMS = %w[
5
7
  name backend_version deployment_option description
6
8
  system_name end_user_registration_required
@@ -24,21 +26,17 @@ module ThreeScaleToolbox
24
26
  # ref can be system_name or service_id
25
27
  def find(remote:, ref:)
26
28
  new(id: ref, remote: remote).tap(&:attrs)
27
- rescue ThreeScale::API::HttpClient::NotFoundError
29
+ rescue ThreeScaleToolbox::InvalidIdError, ThreeScale::API::HttpClient::NotFoundError
28
30
  find_by_system_name(remote: remote, system_name: ref)
29
31
  end
30
32
 
31
33
  def find_by_system_name(remote:, system_name:)
32
- service_list = remote.list_services
33
-
34
- if service_list.respond_to?(:has_key?) && (errors = service_list['errors'])
35
- raise ThreeScaleToolbox::ThreeScaleApiError.new('Service list not read', errors)
34
+ attrs = list_services(remote: remote).find do |svc|
35
+ svc['system_name'] == system_name
36
36
  end
37
+ return if attrs.nil?
37
38
 
38
- service_attrs = service_list.find { |svc| svc['system_name'] == system_name }
39
- return if service_attrs.nil?
40
-
41
- new(id: service_attrs.fetch('id'), remote: remote, attrs: service_attrs)
39
+ new(id: attrs.fetch('id'), remote: remote, attrs: attrs)
42
40
  end
43
41
 
44
42
  private
@@ -61,6 +59,36 @@ module ThreeScaleToolbox
61
59
  def filtered_service_params(original_params)
62
60
  Helper.filter_params(VALID_PARAMS, original_params)
63
61
  end
62
+
63
+ def list_services(remote:)
64
+ services_enum(remote: remote).reduce([], :concat)
65
+ end
66
+
67
+ def services_enum(remote:)
68
+ Enumerator.new do |yielder|
69
+ page = 1
70
+ loop do
71
+ list = remote.list_services(
72
+ page: page,
73
+ per_page: ThreeScale::API::MAX_SERVICES_PER_PAGE
74
+ )
75
+
76
+ if list.respond_to?(:has_key?) && (errors = list['errors'])
77
+ raise ThreeScaleToolbox::ThreeScaleApiError.new('Service list not read', errors)
78
+ end
79
+
80
+ break if list.nil?
81
+
82
+ yielder << list
83
+
84
+ # The API response does not tell how many pages there are available
85
+ # If one page is not fully filled, it means that it is the last page.
86
+ break if list.length < ThreeScale::API::MAX_SERVICES_PER_PAGE
87
+
88
+ page += 1
89
+ end
90
+ end
91
+ end
64
92
  end
65
93
 
66
94
  attr_reader :id, :remote
@@ -72,7 +100,27 @@ module ThreeScaleToolbox
72
100
  end
73
101
 
74
102
  def attrs
75
- @attrs ||= service_attrs
103
+ @attrs ||= fetch_attrs
104
+ end
105
+
106
+ def system_name
107
+ attrs['system_name']
108
+ end
109
+
110
+ def name
111
+ attrs['name']
112
+ end
113
+
114
+ def description
115
+ attrs['description']
116
+ end
117
+
118
+ def deployment_option
119
+ attrs['deployment_option']
120
+ end
121
+
122
+ def backend_version
123
+ attrs['backend_version']
76
124
  end
77
125
 
78
126
  def update_proxy(proxy)
@@ -94,37 +142,42 @@ module ThreeScaleToolbox
94
142
  proxy_attrs
95
143
  end
96
144
 
145
+ def cached_proxy
146
+ @cached_proxy ||= proxy
147
+ end
148
+
149
+ # @api public
150
+ # @return [List]
97
151
  def metrics
98
- # cache result to reuse
99
- metric_and_method_list = metrics_and_methods
100
- hits_metric_obj = hits_metric(metric_and_method_list)
101
- hits_id = hits_metric_obj.fetch('id')
152
+ metric_attr_list = metrics_and_methods.select { |metric_attrs| metric_attrs['parent_id'].nil? }
102
153
 
103
- ThreeScaleToolbox::Helper.array_difference(metric_and_method_list, methods(hits_id)) do |metric, method|
104
- ThreeScaleToolbox::Helper.compare_hashes(metric, method, %w[id])
154
+ metric_attr_list.map do |metric_attrs|
155
+ Metric.new(id: metric_attrs.fetch('id'), service: self, attrs: metric_attrs)
105
156
  end
106
157
  end
107
158
 
108
159
  def hits
109
- hits_metric(metrics_and_methods)
160
+ metric_list = metrics_and_methods.map do |metric_attrs|
161
+ Metric.new(id: metric_attrs.fetch('id'), service: self, attrs: metric_attrs)
162
+ end
163
+ metric_list.find { |metric| metric.system_name == 'hits' }.tap do |hits_metric|
164
+ raise ThreeScaleToolbox::Error, 'missing hits metric' if hits_metric.nil?
165
+ end
110
166
  end
111
167
 
112
- def methods(parent_metric_id)
113
- service_methods = remote.list_methods id, parent_metric_id
114
- if service_methods.respond_to?(:has_key?) && (errors = service_methods['errors'])
168
+ # @api public
169
+ # @return [List]
170
+ def methods
171
+ method_attr_list = remote.list_methods id, hits.id
172
+ if method_attr_list.respond_to?(:has_key?) && (errors = method_attr_list['errors'])
115
173
  raise ThreeScaleToolbox::ThreeScaleApiError.new('Service methods not read', errors)
116
174
  end
117
175
 
118
- service_methods
119
- end
120
-
121
- def metrics_and_methods
122
- m_m = remote.list_metrics id
123
- if m_m.respond_to?(:has_key?) && (errors = m_m['errors'])
124
- raise ThreeScaleToolbox::ThreeScaleApiError.new('Service metrics not read', errors)
176
+ method_attr_list.map do |method_attrs|
177
+ Method.new(id: method_attrs.fetch('id'),
178
+ service: self,
179
+ attrs: method_attrs)
125
180
  end
126
-
127
- m_m
128
181
  end
129
182
 
130
183
  def plans
@@ -133,19 +186,24 @@ module ThreeScaleToolbox
133
186
  raise ThreeScaleToolbox::ThreeScaleApiError.new('Service plans not read', errors)
134
187
  end
135
188
 
136
- service_plans
189
+ service_plans.map do |plan_attrs|
190
+ ApplicationPlan.new(id: plan_attrs.fetch('id'),
191
+ service: self,
192
+ attrs: plan_attrs)
193
+ end
137
194
  end
138
195
 
139
196
  def mapping_rules
140
- remote.list_mapping_rules id
141
- end
142
-
143
- def delete_mapping_rule(rule_id)
144
- remote.delete_mapping_rule(id, rule_id)
145
- end
197
+ mr_list = remote.list_mapping_rules id
198
+ if mr_list.respond_to?(:has_key?) && (errors = mr_list['errors'])
199
+ raise ThreeScaleToolbox::ThreeScaleApiError.new('Service mapping rules not read', errors)
200
+ end
146
201
 
147
- def create_mapping_rule(mapping_rule)
148
- remote.create_mapping_rule id, mapping_rule
202
+ mr_list.map do |mr_attrs|
203
+ MappingRule.new(id: mr_attrs.fetch('id'),
204
+ service: self,
205
+ attrs: mr_attrs)
206
+ end
149
207
  end
150
208
 
151
209
  def update(svc_attrs)
@@ -165,7 +223,12 @@ module ThreeScaleToolbox
165
223
  end
166
224
 
167
225
  def policies
168
- remote.show_policies id
226
+ policy_chain = remote.show_policies id
227
+ if policy_chain.respond_to?(:has_key?) && (errors = policy_chain['errors'])
228
+ raise ThreeScaleToolbox::ThreeScaleApiError.new('Service policies not read', errors)
229
+ end
230
+
231
+ policy_chain
169
232
  end
170
233
 
171
234
  def update_policies(params)
@@ -179,8 +242,12 @@ module ThreeScaleToolbox
179
242
  raise ThreeScaleToolbox::ThreeScaleApiError.new('Service activedocs not read', errors)
180
243
  end
181
244
 
182
- tenant_activedocs.select do |activedoc|
183
- activedoc['service_id'] == id
245
+ service_activedocs = tenant_activedocs.select do |activedoc_attrs|
246
+ activedoc_attrs['service_id'] == id
247
+ end
248
+
249
+ service_activedocs.map do |activedoc_attrs|
250
+ Entities::ActiveDocs.new(id: activedoc_attrs.fetch('id'), remote: remote, attrs: activedoc_attrs)
184
251
  end
185
252
  end
186
253
 
@@ -194,6 +261,10 @@ module ThreeScaleToolbox
194
261
  service_oidc
195
262
  end
196
263
 
264
+ def cached_oidc
265
+ @cached_oidc ||= oidc
266
+ end
267
+
197
268
  def update_oidc(oidc_settings)
198
269
  new_oidc = remote.update_oidc(id, oidc_settings)
199
270
 
@@ -249,20 +320,58 @@ module ThreeScaleToolbox
249
320
  end
250
321
  end
251
322
 
323
+ def backend_usage_list
324
+ resp = remote.list_backend_usages id
325
+ if resp.respond_to?(:has_key?) && (errors = resp['errors'])
326
+ raise ThreeScaleToolbox::ThreeScaleApiError.new('Product backend usage not read', errors)
327
+ end
328
+
329
+ resp.map do |backend_usage_attrs|
330
+ Entities::BackendUsage.new(id: backend_usage_attrs.fetch('id'),
331
+ product: self,
332
+ attrs: backend_usage_attrs)
333
+ end
334
+ end
335
+
336
+ def create_mapping_rule(mr_attrs)
337
+ Entities::MappingRule.create(service: self, attrs: mr_attrs)
338
+ end
339
+
340
+ def proxy_deploy
341
+ proxy_attrs = remote.proxy_deploy id
342
+ if proxy_attrs.respond_to?(:has_key?) && (errors = proxy_attrs['errors'])
343
+ raise ThreeScaleToolbox::ThreeScaleApiError.new('Proxy configuration not deployed', errors)
344
+ end
345
+
346
+ proxy_attrs
347
+ end
348
+
349
+ # Compute matrics mapping between products, including related backend metrics as well
350
+ def metrics_mapping(other)
351
+ mapping = (metrics + methods).product(other.metrics + other.methods).select do |m_a, m_b|
352
+ m_a.system_name == m_b.system_name
353
+ end.map { |m_a, m_b| [m_a.id, m_b.id] }.to_h
354
+
355
+ backend_pairs = backend_usage_list.map(&:backend).product(other.backend_usage_list.map(&:backend)).select do |b_a, b_b|
356
+ b_a.system_name == b_b.system_name
357
+ end
358
+
359
+ backend_pairs.each do |b_a, b_b|
360
+ mapping.merge!(b_a.metrics_mapping(b_b))
361
+ end
362
+
363
+ mapping
364
+ end
365
+
252
366
  def ==(other)
253
367
  remote.http_client.endpoint == other.remote.http_client.endpoint && id == other.id
254
368
  end
255
369
 
256
370
  private
257
371
 
258
- def hits_metric(metric_list)
259
- hits_metric = metric_list.find { |metric| metric['system_name'] == 'hits' }
260
- raise ThreeScaleToolbox::Error, 'missing hits metric' if hits_metric.nil?
261
-
262
- hits_metric
263
- end
372
+ def fetch_attrs
373
+ raise ThreeScaleToolbox::InvalidIdError if id.zero?
264
374
 
265
- def service_attrs
266
375
  svc = remote.show_service id
267
376
  if (errors = svc['errors'])
268
377
  raise ThreeScaleToolbox::ThreeScaleApiError.new('Service attrs not read', errors)
@@ -285,6 +394,15 @@ module ThreeScaleToolbox
285
394
 
286
395
  new_attrs
287
396
  end
397
+
398
+ def metrics_and_methods
399
+ m_m = remote.list_metrics id
400
+ if m_m.respond_to?(:has_key?) && (errors = m_m['errors'])
401
+ raise ThreeScaleToolbox::ThreeScaleApiError.new('Service metrics not read', errors)
402
+ end
403
+
404
+ m_m
405
+ end
288
406
  end
289
407
  end
290
408
  end