3scale_toolbox 0.15.0 → 0.18.2

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 (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
@@ -2,7 +2,15 @@ require '3scale_toolbox/entities/service'
2
2
  require '3scale_toolbox/entities/application_plan'
3
3
  require '3scale_toolbox/entities/metric'
4
4
  require '3scale_toolbox/entities/method'
5
+ require '3scale_toolbox/entities/mapping_rule'
6
+ require '3scale_toolbox/entities/limit'
7
+ require '3scale_toolbox/entities/pricing_rule'
5
8
  require '3scale_toolbox/entities/activedocs'
6
9
  require '3scale_toolbox/entities/account'
7
10
  require '3scale_toolbox/entities/proxy_config'
8
11
  require '3scale_toolbox/entities/application'
12
+ require '3scale_toolbox/entities/backend'
13
+ require '3scale_toolbox/entities/backend_method'
14
+ require '3scale_toolbox/entities/backend_metric'
15
+ require '3scale_toolbox/entities/backend_mapping_rule'
16
+ require '3scale_toolbox/entities/backend_usage'
@@ -51,6 +51,18 @@ module ThreeScaleToolbox
51
51
  @attrs ||= activedoc_attrs
52
52
  end
53
53
 
54
+ def system_name
55
+ attrs['system_name']
56
+ end
57
+
58
+ def body
59
+ attrs['body']
60
+ end
61
+
62
+ def name
63
+ attrs['name']
64
+ end
65
+
54
66
  def delete
55
67
  remote.delete_activedocs id
56
68
  end
@@ -1,6 +1,8 @@
1
1
  module ThreeScaleToolbox
2
2
  module Entities
3
3
  class ApplicationPlan
4
+ include CRD::ApplicationPlanSerializer
5
+
4
6
  class << self
5
7
  def create(service:, plan_attrs:)
6
8
  plan = service.remote.create_application_plan service.id, create_plan_attrs(plan_attrs)
@@ -14,15 +16,12 @@ module ThreeScaleToolbox
14
16
  # ref can be system_name or service_id
15
17
  def find(service:, ref:)
16
18
  new(id: ref, service: service).tap(&:attrs)
17
- rescue ThreeScale::API::HttpClient::NotFoundError
19
+ rescue ThreeScaleToolbox::InvalidIdError, ThreeScale::API::HttpClient::NotFoundError
18
20
  find_by_system_name(service: service, system_name: ref)
19
21
  end
20
22
 
21
23
  def find_by_system_name(service:, system_name:)
22
- plan = service.plans.find { |p| p['system_name'] == system_name }
23
- return if plan.nil?
24
-
25
- new(id: plan.fetch('id'), service: service, attrs: plan)
24
+ service.plans.find { |p| p.system_name == system_name }
26
25
  end
27
26
 
28
27
  def create_plan_attrs(source_attrs)
@@ -49,6 +48,22 @@ module ThreeScaleToolbox
49
48
  @attrs ||= read_plan_attrs
50
49
  end
51
50
 
51
+ def system_name
52
+ attrs['system_name']
53
+ end
54
+
55
+ def name
56
+ attrs['name']
57
+ end
58
+
59
+ def state
60
+ attrs['state']
61
+ end
62
+
63
+ def custom
64
+ attrs.fetch('custom', false)
65
+ end
66
+
52
67
  def update(plan_attrs)
53
68
  return attrs if update_plan_attrs(plan_attrs).empty?
54
69
 
@@ -78,9 +93,9 @@ module ThreeScaleToolbox
78
93
  # b) metrics having limits set with eternity period, but not zero value, must be updated
79
94
  # c) metrics not having limits set with eternity period, must be created
80
95
 
81
- eternity_limits = limits.select { |limit| limit.fetch('period') == 'eternity' }
82
- eternity_metric_ids = eternity_limits.map { |limit| limit.fetch('metric_id') }
83
- service_metric_ids = service.metrics.map { |metric| metric.fetch('id') }
96
+ eternity_limits = limits.select { |limit| limit.period == 'eternity' }
97
+ eternity_metric_ids = eternity_limits.map { |limit| limit.metric_id }
98
+ service_metric_ids = service.metrics.map { |metric| metric.id }
84
99
  metric_ids_without_eternity = service_metric_ids - eternity_metric_ids
85
100
 
86
101
  # create eternity zero limit for each metric without eternity limit set
@@ -89,16 +104,14 @@ module ThreeScaleToolbox
89
104
  end
90
105
 
91
106
  # update eternity zero limit those metrics already having eternity limit set
92
- not_zero_eternity_limits = eternity_limits.reject { |limit| limit.fetch('value').zero? }
107
+ not_zero_eternity_limits = eternity_limits.reject { |limit| limit.value.zero? }
93
108
  not_zero_eternity_limits.each do |limit|
94
- update_limit(limit.fetch('metric_id'), limit.fetch('id'), zero_eternity_limit_attrs)
109
+ limit.update(zero_eternity_limit_attrs)
95
110
  end
96
111
  end
97
112
 
98
113
  def enable
99
- eternity_zero_limits.each do |limit|
100
- delete_limit(limit.fetch('metric_id'), limit.fetch('id'))
101
- end
114
+ eternity_zero_limits.each(&:delete)
102
115
  end
103
116
 
104
117
  def limits
@@ -107,7 +120,9 @@ module ThreeScaleToolbox
107
120
  raise ThreeScaleToolbox::ThreeScaleApiError.new('Limits per application plan not read', errors)
108
121
  end
109
122
 
110
- plan_limits
123
+ plan_limits.map do |limit_attrs|
124
+ Limit.new(id: limit_attrs.fetch('id'), plan: self, metric_id: limit_attrs.fetch('metric_id'), attrs: limit_attrs)
125
+ end
111
126
  end
112
127
 
113
128
  def metric_limits(metric_id)
@@ -116,45 +131,47 @@ module ThreeScaleToolbox
116
131
  # Already reported. https://issues.jboss.org/browse/THREESCALE-2486
117
132
  # Meanwhile, the strategy will be to get all metrics from a given plan
118
133
  # and filter by metric_id
119
- limits.select { |limit| limit['metric_id'] == metric_id }
134
+ limits.select { |limit| limit.metric_id == metric_id }
120
135
  end
121
136
 
122
137
  def create_limit(metric_id, limit_attrs)
123
- limit = remote.create_application_plan_limit id, metric_id, limit_attrs
124
- if (errors = limit['errors'])
125
- raise ThreeScaleToolbox::ThreeScaleApiError.new('Limit has not been created', errors)
126
- end
127
-
128
- limit
129
- end
130
-
131
- def update_limit(metric_id, limit_id, limit_attrs)
132
- limit = remote.update_application_plan_limit id, metric_id, limit_id, limit_attrs
133
- if (errors = limit['errors'])
134
- raise ThreeScaleToolbox::ThreeScaleApiError.new('Limit not updated', errors)
135
- end
136
-
137
- limit
138
- end
139
-
140
- def delete_limit(metric_id, limit_id)
141
- remote.delete_application_plan_limit id, metric_id, limit_id
138
+ Limit.create(plan: self, metric_id: metric_id, attrs: limit_attrs)
142
139
  end
143
140
 
144
141
  def create_pricing_rule(metric_id, pr_attrs)
145
- remote.create_pricingrule id, metric_id, pr_attrs
142
+ PricingRule.create(plan: self, metric_id: metric_id, attrs: pr_attrs)
146
143
  end
147
144
 
148
145
  def pricing_rules
149
- remote.list_pricingrules_per_application_plan id
146
+ pr_list = remote.list_pricingrules_per_application_plan id
147
+
148
+ if pr_list.respond_to?(:has_key?) && (errors = pr_list['errors'])
149
+ raise ThreeScaleToolbox::ThreeScaleApiError.new('pricing rules not read', errors)
150
+ end
151
+
152
+ pr_list.map do |pr_attrs|
153
+ PricingRule.new(id: pr_attrs.fetch('id'), plan: self, metric_id: pr_attrs.fetch('metric_id'), attrs: pr_attrs)
154
+ end
150
155
  end
151
156
 
152
157
  def features
153
- remote.list_features_per_application_plan id
158
+ feature_list = remote.list_features_per_application_plan id
159
+
160
+ if feature_list.respond_to?(:has_key?) && (errors = feature_list['errors'])
161
+ raise ThreeScaleToolbox::ThreeScaleApiError.new('features not read', errors)
162
+ end
163
+
164
+ feature_list
154
165
  end
155
166
 
156
167
  def create_feature(feature_id)
157
- remote.create_application_plan_feature id, feature_id
168
+ feature = remote.create_application_plan_feature id, feature_id
169
+
170
+ if (errors = feature['errors'])
171
+ raise ThreeScaleToolbox::ThreeScaleApiError.new('feature not created', errors)
172
+ end
173
+
174
+ feature
158
175
  end
159
176
 
160
177
  def delete
@@ -176,9 +193,27 @@ module ThreeScaleToolbox
176
193
  attrs.fetch('state') == 'published'
177
194
  end
178
195
 
196
+ def approval_required?
197
+ attrs.fetch('approval_required', true)
198
+ end
199
+
200
+ def trial_period_days
201
+ attrs.fetch('trial_period_days', 0)
202
+ end
203
+
204
+ def setup_fee
205
+ attrs.fetch('setup_fee', 0.0)
206
+ end
207
+
208
+ def cost_per_month
209
+ attrs.fetch('cost_per_month', 0.0)
210
+ end
211
+
179
212
  private
180
213
 
181
214
  def read_plan_attrs
215
+ raise ThreeScaleToolbox::InvalidIdError if id.zero?
216
+
182
217
  plan_attrs = remote.show_application_plan service.id, id
183
218
  if (errors = plan_attrs['errors'])
184
219
  raise ThreeScaleToolbox::ThreeScaleApiError.new('Application plan not read', errors)
@@ -197,7 +232,7 @@ module ThreeScaleToolbox
197
232
  end
198
233
 
199
234
  def eternity_zero_limits
200
- limits.select { |limit| zero_eternity_limit_attrs < limit }
235
+ limits.select { |limit| zero_eternity_limit_attrs < limit.attrs }
201
236
  end
202
237
 
203
238
  def zero_eternity_limit_attrs
@@ -0,0 +1,187 @@
1
+ module ThreeScaleToolbox
2
+ module Entities
3
+ class Backend
4
+ include CRD::BackendSerializer
5
+
6
+ VALID_PARAMS = %w[name description system_name private_endpoint].freeze
7
+ public_constant :VALID_PARAMS
8
+
9
+ class << self
10
+ def create(remote:, attrs:)
11
+ b_attrs = remote.create_backend Helper.filter_params(VALID_PARAMS, attrs)
12
+ if (errors = b_attrs['errors'])
13
+ raise ThreeScaleToolbox::ThreeScaleApiError.new('Backend has not been created', errors)
14
+ end
15
+
16
+ new(id: b_attrs.fetch('id'), remote: remote, attrs: b_attrs)
17
+ end
18
+
19
+ # ref can be system_name or backend_id
20
+ def find(remote:, ref:)
21
+ new(id: ref, remote: remote).tap(&:attrs)
22
+ rescue ThreeScaleToolbox::InvalidIdError, ThreeScale::API::HttpClient::NotFoundError
23
+ find_by_system_name(remote: remote, system_name: ref)
24
+ end
25
+
26
+ def find_by_system_name(remote:, system_name:)
27
+ attrs = list_backends(remote: remote).find do |backend|
28
+ backend['system_name'] == system_name
29
+ end
30
+ return if attrs.nil?
31
+
32
+ new(id: attrs.fetch('id'), remote: remote, attrs: attrs)
33
+ end
34
+
35
+ private
36
+
37
+ def list_backends(remote:)
38
+ backends_enum(remote: remote).reduce([], :concat)
39
+ end
40
+
41
+ def backends_enum(remote:)
42
+ Enumerator.new do |yielder|
43
+ page = 1
44
+ loop do
45
+ list = remote.list_backends(
46
+ page: page,
47
+ per_page: ThreeScale::API::MAX_BACKENDS_PER_PAGE
48
+ )
49
+
50
+ if list.respond_to?(:has_key?) && (errors = list['errors'])
51
+ raise ThreeScaleToolbox::ThreeScaleApiError.new('Backend list not read', errors)
52
+ end
53
+
54
+ break if list.nil?
55
+
56
+ yielder << list
57
+
58
+ # The API response does not tell how many pages there are available
59
+ # If one page is not fully filled, it means that it is the last page.
60
+ break if list.length < ThreeScale::API::MAX_BACKENDS_PER_PAGE
61
+
62
+ page += 1
63
+ end
64
+ end
65
+ end
66
+ end
67
+
68
+ attr_reader :id, :remote
69
+
70
+ def initialize(id:, remote:, attrs: nil)
71
+ @id = id.to_i
72
+ @remote = remote
73
+ @attrs = attrs
74
+ end
75
+
76
+ def attrs
77
+ @attrs ||= fetch_backend_attrs
78
+ end
79
+
80
+ def system_name
81
+ attrs['system_name']
82
+ end
83
+
84
+ def description
85
+ attrs['description']
86
+ end
87
+
88
+ def name
89
+ attrs['name']
90
+ end
91
+
92
+ def private_endpoint
93
+ attrs['private_endpoint']
94
+ end
95
+
96
+ def metrics
97
+ metric_attr_list = metrics_and_methods.select { |metric_attrs| metric_attrs['parent_id'].nil? }
98
+
99
+ metric_attr_list.map do |metric_attrs|
100
+ BackendMetric.new(id: metric_attrs.fetch('id'), backend: self, attrs: metric_attrs)
101
+ end
102
+ end
103
+
104
+ def hits
105
+ metric_list = metrics_and_methods.map do |metric_attrs|
106
+ BackendMetric.new(id: metric_attrs.fetch('id'), backend: self, attrs: metric_attrs)
107
+ end
108
+ metric_list.find { |metric| metric.system_name == 'hits' }.tap do |hits_metric|
109
+ raise ThreeScaleToolbox::Error, 'missing hits metric' if hits_metric.nil?
110
+ end
111
+ end
112
+
113
+ # @api public
114
+ # @return [List]
115
+ def methods
116
+ method_attr_list = remote.list_backend_methods id, hits.id
117
+ if method_attr_list.respond_to?(:has_key?) && (errors = method_attr_list['errors'])
118
+ raise ThreeScaleToolbox::ThreeScaleApiError.new('Backend methods not read', errors)
119
+ end
120
+
121
+ method_attr_list.map do |method_attrs|
122
+ BackendMethod.new(id: method_attrs.fetch('id'), backend: self, attrs: method_attrs)
123
+ end
124
+ end
125
+
126
+ def mapping_rules
127
+ m_r = remote.list_backend_mapping_rules id
128
+ if m_r.respond_to?(:has_key?) && (errors = m_r['errors'])
129
+ raise ThreeScaleToolbox::ThreeScaleApiError.new('Backend mapping rules not read', errors)
130
+ end
131
+
132
+ m_r.map do |mr_attrs|
133
+ BackendMappingRule.new(id: mr_attrs.fetch('id'), backend: self, attrs: mr_attrs)
134
+ end
135
+ end
136
+
137
+ def update(b_attrs)
138
+ new_attrs = remote.update_backend id, Helper.filter_params(VALID_PARAMS, b_attrs)
139
+ if (errors = new_attrs['errors'])
140
+ raise ThreeScaleToolbox::ThreeScaleApiError.new('Backend not updated', errors)
141
+ end
142
+
143
+ # update current attrs
144
+ @attrs = new_attrs
145
+
146
+ new_attrs
147
+ end
148
+
149
+ def delete
150
+ remote.delete_backend id
151
+ end
152
+
153
+ # Compute matrics mapping
154
+ def metrics_mapping(other)
155
+ (metrics + methods).product(other.metrics + other.methods).select do |m_a, m_b|
156
+ m_a.system_name == m_b.system_name
157
+ end.map { |m_a, m_b| [m_a.id, m_b.id] }.to_h
158
+ end
159
+
160
+ def ==(other)
161
+ remote.http_client.endpoint == other.remote.http_client.endpoint && id == other.id
162
+ end
163
+
164
+ private
165
+
166
+ def metrics_and_methods
167
+ m_m = remote.list_backend_metrics id
168
+ if m_m.respond_to?(:has_key?) && (errors = m_m['errors'])
169
+ raise ThreeScaleToolbox::ThreeScaleApiError.new('Backend metrics not read', errors)
170
+ end
171
+
172
+ m_m
173
+ end
174
+
175
+ def fetch_backend_attrs
176
+ raise ThreeScaleToolbox::InvalidIdError if id.zero?
177
+
178
+ backend = remote.backend id
179
+ if (errors = backend['errors'])
180
+ raise ThreeScaleToolbox::ThreeScaleApiError.new('Backend attrs not read', errors)
181
+ end
182
+
183
+ backend
184
+ end
185
+ end
186
+ end
187
+ end
@@ -0,0 +1,102 @@
1
+ module ThreeScaleToolbox
2
+ module Entities
3
+ class BackendMappingRule
4
+ include CRD::BackendMappingRuleSerializer
5
+
6
+ VALID_PARAMS = %w[metric_id pattern http_method delta position last].freeze
7
+ public_constant :VALID_PARAMS
8
+
9
+ class << self
10
+ def create(backend:, attrs:)
11
+ mapping_rule = backend.remote.create_backend_mapping_rule(
12
+ backend.id,
13
+ Helper.filter_params(VALID_PARAMS, attrs)
14
+ )
15
+ if (errors = mapping_rule['errors'])
16
+ raise ThreeScaleToolbox::ThreeScaleApiError.new('Backend mapping rule has not been created',
17
+ errors)
18
+ end
19
+
20
+ new(id: mapping_rule.fetch('id'), backend: backend, attrs: mapping_rule)
21
+ end
22
+ end
23
+
24
+ attr_reader :id, :backend, :remote
25
+
26
+ def initialize(id:, backend:, attrs: nil)
27
+ @id = id.to_i
28
+ @backend = backend
29
+ @remote = backend.remote
30
+ @attrs = attrs
31
+ end
32
+
33
+ def attrs
34
+ @attrs ||= mapping_rule_attrs
35
+ end
36
+
37
+ def http_method
38
+ attrs['http_method']
39
+ end
40
+
41
+ def pattern
42
+ attrs['pattern']
43
+ end
44
+
45
+ def delta
46
+ attrs['delta']
47
+ end
48
+
49
+ def last
50
+ attrs['last']
51
+ end
52
+
53
+ def metric_id
54
+ attrs['metric_id']
55
+ end
56
+
57
+ def pattern
58
+ attrs['pattern']
59
+ end
60
+
61
+ def http_method
62
+ attrs['http_method']
63
+ end
64
+
65
+ def delta
66
+ attrs['delta']
67
+ end
68
+
69
+ def update(mr_attrs)
70
+ new_attrs = remote.update_backend_mapping_rule(
71
+ backend.id, id,
72
+ Helper.filter_params(VALID_PARAMS, mr_attrs)
73
+ )
74
+ if (errors = new_attrs['errors'])
75
+ raise ThreeScaleToolbox::ThreeScaleApiError.new('Backend mapping rule has not been updated', errors)
76
+ end
77
+
78
+ # update current attrs
79
+ @attrs = new_attrs
80
+
81
+ new_attrs
82
+ end
83
+
84
+ def delete
85
+ remote.delete_backend_mapping_rule backend.id, id
86
+ end
87
+
88
+ private
89
+
90
+ def mapping_rule_attrs
91
+ raise ThreeScaleToolbox::InvalidIdError if id.zero?
92
+
93
+ mapping_rule = remote.backend_mapping_rule backend.id, id
94
+ if (errors = mapping_rule['errors'])
95
+ raise ThreeScaleToolbox::ThreeScaleApiError.new('Backend mapping rule not read', errors)
96
+ end
97
+
98
+ mapping_rule
99
+ end
100
+ end
101
+ end
102
+ end