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
@@ -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