Class: ThreeScaleToolbox::CRD::Remote

Inherits:
Object
  • Object
show all
Defined in:
lib/3scale_toolbox/crds/remote.rb

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(products, backends) ⇒ Remote

Returns a new instance of Remote.



124
125
126
127
128
129
130
131
132
# File 'lib/3scale_toolbox/crds/remote.rb', line 124

def initialize(products, backends)
  # Index of backends by id (by sequence order)
  @backend_index = backends.each_with_object({}) { |backend, hash| hash[new_index] = backend }

  # Index of products by id (by sequence order)
  @product_index = products.each_with_object({}) { |product, hash| hash[new_index] = product }

  validate!
end

Instance Attribute Details

#backend_indexObject (readonly)

Product CRD Format github.com/3scale/3scale-operator/blob/3scale-2.10.0-CR2/doc/product-reference.md

apiVersion: capabilities.3scale.net/v1beta1
kind: Product
metadata:
  annotations:
    3scale_toolbox_created_at: '2021-02-10T09:16:59Z'
    3scale_toolbox_version: 0.17.1
  name: api.vygczmih
spec:
  name: Default API
  systemName: api
  description: ''
  mappingRules:
  - httpMethod: GET
    pattern: "/v1"
    metricMethodRef: servicemethod01
    increment: 1
    last: false
  metrics:
    hits:
      friendlyName: Hits
      unit: hit
      description: Number of API hits
  methods:
    servicemethod01:
      friendlyName: servicemethod01
      description: ''
  policies:
  - name: apicast
    version: builtin
    configuration: {}
    enabled: true
  backendUsages:
    backend_01:
      path: "/v1/pets"
    backend_02:
      path: "/v1/cats"
  deployment:
    apicastSelfManaged:
      authentication:
        appKeyAppID:
          appID: app_id
          appKey: app_key
          credentials: query
          security:
            hostHeader: ''
            secretToken: some_secret
          gatewayResponse:
            errorStatusAuthFailed: 403
            errorHeadersAuthFailed: text/plain; charset=us-ascii
            errorAuthFailed: Authentication failed
            errorStatusAuthMissing: 403
            errorHeadersAuthMissing: text/plain; charset=us-ascii
            errorAuthMissing: Authentication parameters missing
            errorStatusNoMatch: 404
            errorHeadersNoMatch: text/plain; charset=us-ascii
            errorNoMatch: No Mapping Rule matched
            errorStatusLimitsExceeded: 429
            errorHeadersLimitsExceeded: text/plain; charset=us-ascii
            errorLimitsExceeded: Usage limit exceeded
      stagingPublicBaseURL: http://staging.example.com:80
      productionPublicBaseURL: http://example.com:80
  applicationPlans:
    basic:
      name: Basic
      appsRequireApproval: false
      trialPeriod: 0
      setupFee: 0.0
      custom: false
      state: published
      costMonth: 0.0
      pricingRules:
      - from: 1
        to: 1000
        pricePerUnit: 1.0
        metricMethodRef:
          systemName: hits
      limits:
      - period: eternity
        value: 10000
        metricMethodRef:
          systemName: hits

Backend CRD format github.com/3scale/3scale-operator/blob/3scale-2.10.0-CR2/doc/backend-reference.md

apiVersion: capabilities.3scale.net/v1beta1
kind: Backend
metadata:
  annotations:
    3scale_toolbox_created_at: '2021-02-10T09:17:12Z'
    3scale_toolbox_version: 0.17.1
  name: backend.01.rxoeasvk
spec:
  name: Backend 01
  systemName: backend_01
  privateBaseURL: https://echo-api.3scale.net:443
  description: new desc
  mappingRules:
  - httpMethod: GET
    pattern: "/v1/pets"
    metricMethodRef: mybackendmethod01
    increment: 1
    last: false
  metrics:
    hits:
      friendlyName: Hits
      unit: hit
      description: Number of API hits
  methods:
    mybackendmethod01:
      friendlyName: mybackendmethod01
      description: ''


122
123
124
# File 'lib/3scale_toolbox/crds/remote.rb', line 122

def backend_index
  @backend_index
end

#product_indexObject (readonly)

Product CRD Format github.com/3scale/3scale-operator/blob/3scale-2.10.0-CR2/doc/product-reference.md

apiVersion: capabilities.3scale.net/v1beta1
kind: Product
metadata:
  annotations:
    3scale_toolbox_created_at: '2021-02-10T09:16:59Z'
    3scale_toolbox_version: 0.17.1
  name: api.vygczmih
spec:
  name: Default API
  systemName: api
  description: ''
  mappingRules:
  - httpMethod: GET
    pattern: "/v1"
    metricMethodRef: servicemethod01
    increment: 1
    last: false
  metrics:
    hits:
      friendlyName: Hits
      unit: hit
      description: Number of API hits
  methods:
    servicemethod01:
      friendlyName: servicemethod01
      description: ''
  policies:
  - name: apicast
    version: builtin
    configuration: {}
    enabled: true
  backendUsages:
    backend_01:
      path: "/v1/pets"
    backend_02:
      path: "/v1/cats"
  deployment:
    apicastSelfManaged:
      authentication:
        appKeyAppID:
          appID: app_id
          appKey: app_key
          credentials: query
          security:
            hostHeader: ''
            secretToken: some_secret
          gatewayResponse:
            errorStatusAuthFailed: 403
            errorHeadersAuthFailed: text/plain; charset=us-ascii
            errorAuthFailed: Authentication failed
            errorStatusAuthMissing: 403
            errorHeadersAuthMissing: text/plain; charset=us-ascii
            errorAuthMissing: Authentication parameters missing
            errorStatusNoMatch: 404
            errorHeadersNoMatch: text/plain; charset=us-ascii
            errorNoMatch: No Mapping Rule matched
            errorStatusLimitsExceeded: 429
            errorHeadersLimitsExceeded: text/plain; charset=us-ascii
            errorLimitsExceeded: Usage limit exceeded
      stagingPublicBaseURL: http://staging.example.com:80
      productionPublicBaseURL: http://example.com:80
  applicationPlans:
    basic:
      name: Basic
      appsRequireApproval: false
      trialPeriod: 0
      setupFee: 0.0
      custom: false
      state: published
      costMonth: 0.0
      pricingRules:
      - from: 1
        to: 1000
        pricePerUnit: 1.0
        metricMethodRef:
          systemName: hits
      limits:
      - period: eternity
        value: 10000
        metricMethodRef:
          systemName: hits

Backend CRD format github.com/3scale/3scale-operator/blob/3scale-2.10.0-CR2/doc/backend-reference.md

apiVersion: capabilities.3scale.net/v1beta1
kind: Backend
metadata:
  annotations:
    3scale_toolbox_created_at: '2021-02-10T09:17:12Z'
    3scale_toolbox_version: 0.17.1
  name: backend.01.rxoeasvk
spec:
  name: Backend 01
  systemName: backend_01
  privateBaseURL: https://echo-api.3scale.net:443
  description: new desc
  mappingRules:
  - httpMethod: GET
    pattern: "/v1/pets"
    metricMethodRef: mybackendmethod01
    increment: 1
    last: false
  metrics:
    hits:
      friendlyName: Hits
      unit: hit
      description: Number of API hits
  methods:
    mybackendmethod01:
      friendlyName: mybackendmethod01
      description: ''


122
123
124
# File 'lib/3scale_toolbox/crds/remote.rb', line 122

def product_index
  @product_index
end

Instance Method Details

#backend(backend_id) ⇒ Object



154
155
156
157
158
159
160
161
162
163
# File 'lib/3scale_toolbox/crds/remote.rb', line 154

def backend(backend_id)
  b = backend_index.fetch(backend_id) { raise_backend_missing(backend_id) }
  {
    'id' => backend_id,
    'name' => b.name,
    'system_name' => b.system_name,
    'description' => b.description,
    'private_endpoint' => b.private_endpoint
  }
end

#delete_backend(id) ⇒ Object



404
405
406
# File 'lib/3scale_toolbox/crds/remote.rb', line 404

def delete_backend(id)
  true
end

#delete_backend_usage(product_id, id) ⇒ Object



408
409
410
# File 'lib/3scale_toolbox/crds/remote.rb', line 408

def delete_backend_usage(product_id, id)
  true
end

#delete_service(id) ⇒ Object



400
401
402
# File 'lib/3scale_toolbox/crds/remote.rb', line 400

def delete_service(id)
  true
end

#http_clientObject



134
135
136
# File 'lib/3scale_toolbox/crds/remote.rb', line 134

def http_client
  Struct.new(:endpoint).new('http://fromCR')
end

#list_activedocsObject



396
397
398
# File 'lib/3scale_toolbox/crds/remote.rb', line 396

def list_activedocs
  []
end

#list_application_plan_limits(plan_id) ⇒ Object



357
358
359
360
361
362
363
364
365
366
367
368
# File 'lib/3scale_toolbox/crds/remote.rb', line 357

def list_application_plan_limits(plan_id)
  plan = application_plan_index.fetch(plan_id) { raise_plan_missing(plan_id) }
  plan.limits.map do |limit|
    {
      'id' => 1, # should not be used
      'period' => limit.period,
      'value' => limit.value,
      'metric_id' => find_metric_id_from_ref(plan_id, limit.metric_system_name, limit.backend_system_name),
      'plan_id' => plan_id
    }
  end
end

#list_backend_mapping_rules(backend_id) ⇒ Object



221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
# File 'lib/3scale_toolbox/crds/remote.rb', line 221

def list_backend_mapping_rules(backend_id)
  metric_index = backend_metric_index.fetch(backend_id) { raise_backend_missing(backend_id) }

  backend_index.fetch(backend_id).mapping_rules.each_with_index.map do |mapping_rule, mapping_id|
    {
      # 0 is not valid id
      'id' => mapping_id + 1,
      'pattern' => mapping_rule.pattern,
      'http_method' => mapping_rule.http_method,
      'delta' => mapping_rule.delta,
      'last' => mapping_rule.last,
      # Previous validation assures mapping rule metric references are valid
      'metric_id' => metric_index.find { |_, metric| metric.system_name == mapping_rule.metric_ref }.first
    }
  end
end

#list_backend_methods(backend_id, _) ⇒ Object



200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
# File 'lib/3scale_toolbox/crds/remote.rb', line 200

def list_backend_methods(backend_id, _)
  metric_index = backend_metric_index.fetch(backend_id) { raise_backend_missing(backend_id) }

  backend_method_system_name_list = backend_index.fetch(backend_id).methods.map(&:system_name)

  # select only methods
  backend_method_index = metric_index.select do |_, metric|
    backend_method_system_name_list.include? metric.system_name
  end

  backend_method_index.map do |method_id, method|
    {
      'id' => method_id,
      'parent_id' => 1, # should not be used
      'friendly_name' => method.friendly_name,
      'system_name' => method.system_name,
      'description' => method.description
    }
  end
end

#list_backend_metrics(backend_id) ⇒ Object

return metrics and methods



178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
# File 'lib/3scale_toolbox/crds/remote.rb', line 178

def list_backend_metrics(backend_id)
  metric_index = backend_metric_index.fetch(backend_id) { raise_backend_missing(backend_id) }

  # only metrics, not methods
  backend_metric_system_name_list = backend_index.fetch(backend_id).metrics.map(&:system_name)

  # select only metrics
  backend_metric_only_index = metric_index.select do |_, metric|
    backend_metric_system_name_list.include? metric.system_name
  end

  backend_metric_only_index.map do |metric_id, metric|
    {
      'id' => metric_id,
      'friendly_name' => metric.friendly_name,
      'system_name' => metric.system_name,
      'description' => metric.description,
      'unit' => metric.unit
    }
  end + list_backend_methods(backend_id, 0)
end

#list_backend_usages(service_id) ⇒ Object



165
166
167
168
169
170
171
172
173
174
175
# File 'lib/3scale_toolbox/crds/remote.rb', line 165

def list_backend_usages(service_id)
  service = product_index.fetch(service_id) { raise_product_missing(service_id) }
  service.backend_usages.each_with_index.map do |backend_usage, idx|
    {
      'id' => idx + 1,
      'path' => backend_usage.path,
      'service_id' => service_id,
      'backend_id' => backend_index.find { |k, b| b.system_name == backend_usage.backend_system_name }.first
    }
  end
end

#list_mapping_rules(service_id) ⇒ Object



322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
# File 'lib/3scale_toolbox/crds/remote.rb', line 322

def list_mapping_rules(service_id)
  metric_index = product_metric_index.fetch(service_id) { raise_product_missing(service_id) }

  product_index.fetch(service_id).mapping_rules.each_with_index.map do |mapping_rule, mapping_id|
    {
      # 0 is not valid id
      'id' => mapping_id + 1,
      'pattern' => mapping_rule.pattern,
      'http_method' => mapping_rule.http_method,
      'delta' => mapping_rule.delta,
      'last' => mapping_rule.last,
      # Previous validation assures mapping rule metric references are valid
      'metric_id' => metric_index.find { |_, metric| metric.system_name == mapping_rule.metric_ref }.first
    }
  end
end

#list_methods(service_id, _) ⇒ Object



301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
# File 'lib/3scale_toolbox/crds/remote.rb', line 301

def list_methods(service_id, _)
  metric_index = product_metric_index.fetch(service_id) { raise_product_missing(service_id) }

  product_method_system_name_list = product_index.fetch(service_id).methods.map(&:system_name)

  # select only methods
  product_method_index = metric_index.select do |_, metric|
    product_method_system_name_list.include? metric.system_name
  end

  product_method_index.map do |method_id, method|
    {
      'id' => method_id,
      'parent_id' => 1, # should not be used
      'friendly_name' => method.friendly_name,
      'system_name' => method.system_name,
      'description' => method.description
    }
  end
end

#list_metrics(service_id) ⇒ Object



279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
# File 'lib/3scale_toolbox/crds/remote.rb', line 279

def list_metrics(service_id)
  metric_index = product_metric_index.fetch(service_id) { raise_product_missing(service_id) }

  # only metrics, not methods
  product_metric_system_name_list = product_index.fetch(service_id).metrics.map(&:system_name)

  # select only metrics
  product_metric_only_index = metric_index.select do |_, metric|
    product_metric_system_name_list.include? metric.system_name
  end

  product_metric_only_index.map do |metric_id, metric|
    {
      'id' => metric_id,
      'friendly_name' => metric.friendly_name,
      'system_name' => metric.system_name,
      'description' => metric.description,
      'unit' => metric.unit
    }
  end + list_methods(service_id, 0)
end

#list_pricingrules_per_application_plan(plan_id) ⇒ Object



382
383
384
385
386
387
388
389
390
391
392
393
394
# File 'lib/3scale_toolbox/crds/remote.rb', line 382

def list_pricingrules_per_application_plan(plan_id)
  plan = application_plan_index.fetch(plan_id) { raise_plan_missing(plan_id) }
  plan.pricing_rules.map do |pr|
    {
      'id' => 1, # should not be used
      'cost_per_unit' => pr.price_per_unit,
      'min' => pr.from,
      'max' => pr.to,
      'metric_id' => find_metric_id_from_ref(plan_id, pr.metric_system_name, pr.backend_system_name),
      'plan_id' => plan_id
    }
  end
end

#list_service_application_plans(service_id) ⇒ Object



339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
# File 'lib/3scale_toolbox/crds/remote.rb', line 339

def list_service_application_plans(service_id)
  plan_index = product_plan_index.fetch(service_id) { raise_product_missing(service_id) }

  plan_index.map do |plan_id, plan|
    {
      'id' => plan_id,
      'name' => plan.name,
      'setup_fee' => plan.setup_fee,
      'custom' => plan.custom,
      'state' => plan.state,
      'cost_per_month' => plan.cost_per_month,
      'trial_period_days' => plan.trial_period_days,
      'approval_required' => plan.approval_required,
      'system_name' => plan.system_name
    }
  end
end

#list_services(page:, per_page:) ⇒ Object



150
151
152
# File 'lib/3scale_toolbox/crds/remote.rb', line 150

def list_services(page:, per_page:)
  product_index.keys.map(&method(:show_service))
end

#show_oidc(service_id) ⇒ Object



268
269
270
271
272
273
274
275
276
277
# File 'lib/3scale_toolbox/crds/remote.rb', line 268

def show_oidc(service_id)
  service = product_index.fetch(service_id) { raise_product_missing(service_id) }
  {
    'id' => service_id, #should not be used
    'standard_flow_enabled' => service.standard_flow_enabled,
    'implicit_flow_enabled' => service.implicit_flow_enabled,
    'service_accounts_enabled' => service.service_accounts_enabled,
    'direct_access_grants_enabled' => service.direct_access_grants_enabled
  }
end

#show_policies(service_id) ⇒ Object



370
371
372
373
374
375
376
377
378
379
380
# File 'lib/3scale_toolbox/crds/remote.rb', line 370

def show_policies(service_id)
  service = product_index.fetch(service_id) { raise_product_missing(service_id) }
  service.policy_chain.map do |policy_chain_item|
    {
      'name' => policy_chain_item.name,
      'version' => policy_chain_item.version,
      'configuration' => policy_chain_item.configuration,
      'enabled' => policy_chain_item.enabled
    }
  end
end

#show_proxy(service_id) ⇒ Object



238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
# File 'lib/3scale_toolbox/crds/remote.rb', line 238

def show_proxy(service_id)
  service = product_index.fetch(service_id) { raise_product_missing(service_id) }
  {
    'endpoint' => service.endpoint,
    'credentials_location' => service.credentials_location,
    'auth_app_key' => service.auth_app_key,
    'auth_app_id' => service.auth_app_id,
    'auth_user_key' => service.auth_user_key,
    'error_auth_failed' => service.error_auth_failed,
    'error_auth_missing' => service.error_auth_missing,
    'error_status_auth_failed' => service.error_status_auth_failed,
    'error_headers_auth_failed' => service.error_headers_auth_failed,
    'error_status_auth_missing' => service.error_status_auth_missing,
    'error_headers_auth_missing' => service.error_headers_auth_missing,
    'error_no_match' => service.error_no_match,
    'error_status_no_match' => service.error_status_no_match,
    'error_headers_no_match' => service.error_headers_no_match,
    'error_limits_exceeded' => service.error_limits_exceeded,
    'error_status_limits_exceeded' => service.error_status_limits_exceeded,
    'error_headers_limits_exceeded' => service.error_headers_limits_exceeded,
    'secret_token' => service.secret_token,
    'hostname_rewrite' => service.hostname_rewrite,
    'sandbox_endpoint' => service.sandbox_endpoint,
    'oidc_issuer_endpoint' => service.oidc_issuer_endpoint,
    'oidc_issuer_type' => service.oidc_issuer_type,
    'jwt_claim_with_client_id' => service.jwt_claim_with_client_id,
    'jwt_claim_with_client_id_type' => service.jwt_claim_with_client_id_type
  }.delete_if { |k,v| v.nil? }
end

#show_service(service_id) ⇒ Object



138
139
140
141
142
143
144
145
146
147
148
# File 'lib/3scale_toolbox/crds/remote.rb', line 138

def show_service(service_id)
  service = product_index.fetch(service_id) { raise_product_missing(service_id) }
  {
    'id' => service_id,
    'name' => service.name,
    'system_name' => service.system_name,
    'description' => service.description,
    'deployment_option' => service.deployment_option,
    'backend_version' => service.backend_version
  }
end