3scale_toolbox 0.6.0 → 0.7.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: ae4791c3e86318f973f54abefb9df823abc7efe7ede820ca736697b23cd10653
4
- data.tar.gz: 68cb54b32c6286593464dc1d7302343684cd4d2df043e18a5b3ff777e61f2920
3
+ metadata.gz: 3f412bd1eba1df7d510acff344fc72fca45f7aa94c9317e10fe2425b611276f5
4
+ data.tar.gz: a2bd5e4bfc83e1be12abdecbb636a18a43de81ed86594d590109e8734a59f6db
5
5
  SHA512:
6
- metadata.gz: f36923df1c9961cb9a209a6228ecc50cd5e00b8b1d853384e561b3280d59550125c1793124a95cc7a9553cc42bea4453e898de2135496858d11b200333811242
7
- data.tar.gz: 955e042f2a2b8cc62c56ce8bcedaa4de8a7800a16f39dbb83e37a6969a178b13ff4fdf94104d8240d2b402ab488ce7eb44400fceba0d58c8c7af5ef94a310ef3
6
+ metadata.gz: 8a72ea781cf845c49aeb2a6b45f3576bcd76d534b086f377afcedcab0ed956bdb74cfb01a24b7697f39b6fbeaad12290b362b75796feb9cf259ac4d14cc9fee9
7
+ data.tar.gz: 55c946b9199edaea9dcb0583d8b06ac5769641ab25ba646ca79c3cbb138f744177c4d2d75239d2daa482aaadf735f1906f71056c56bef91916bcade642529109
data/README.md CHANGED
@@ -52,7 +52,7 @@ OPTIONS
52
52
  ```
53
53
 
54
54
  ### Copy a service
55
- Will create a new service, copy existing proxy settings, metrics, methods, application plans and mapping rules.
55
+ Will create a new service, copy existing proxy settings, pricing rules, activedocs, metrics, methods, application plans and mapping rules.
56
56
 
57
57
  3scale instances can be either a [URL](docs/remotes.md#remote-urls) or the name of a [remote](docs/remotes.md).
58
58
 
@@ -69,14 +69,15 @@ USAGE
69
69
 
70
70
  DESCRIPTION
71
71
  Will create a new services, copy existing proxy settings, metrics,
72
- methods, application plans and mapping rules.
72
+ methods, policies, application plans and mapping rules.
73
73
 
74
74
  OPTIONS
75
75
  -d --destination=<value> 3scale target instance. Url or
76
76
  remote name
77
77
  -s --source=<value> 3scale source instance. Url or
78
78
  remote name
79
- -t --target_system_name=<value> Target system name
79
+ -t --target_system_name=<value> Target system name. Default to
80
+ source system name
80
81
 
81
82
  OPTIONS FOR COPY
82
83
  -h --help show help for this command
@@ -92,7 +93,7 @@ OPTIONS FOR COPY
92
93
 
93
94
  ### Update a service
94
95
 
95
- Will update existing service, update proxy settings, metrics, methods, application plans and mapping rules.
96
+ Will update existing service, update proxy settings, pricing rules, activedocs, metrics, methods, application plans and mapping rules.
96
97
 
97
98
  3scale instances can be either a [URL](docs/remotes.md#remote-urls) or the name of a [remote](docs/remotes.md).
98
99
 
@@ -108,7 +109,7 @@ USAGE
108
109
 
109
110
  DESCRIPTION
110
111
  Will update existing service, update proxy settings, metrics, methods,
111
- application plans and mapping rules.
112
+ application plans, policies and mapping rules.
112
113
 
113
114
  OPTIONS
114
115
  -d --destination=<value> 3scale target instance. Url or
@@ -16,7 +16,7 @@ module ThreeScaleToolbox
16
16
 
17
17
  option :s, :source, '3scale source instance. Url or remote name', argument: :required
18
18
  option :d, :destination, '3scale target instance. Url or remote name', argument: :required
19
- option :t, 'target_system_name', 'Target system name', argument: :required
19
+ option :t, 'target_system_name', 'Target system name. Default to source system name', argument: :required
20
20
  param :service_id
21
21
 
22
22
  runner CopyServiceSubcommand
@@ -26,11 +26,10 @@ module ThreeScaleToolbox
26
26
  def run
27
27
  source = fetch_required_option(:source)
28
28
  destination = fetch_required_option(:destination)
29
- system_name = fetch_required_option(:target_system_name)
30
29
 
31
30
  source_service = Entities::Service.new(id: arguments[:service_id],
32
31
  remote: threescale_client(source))
33
- target_service = create_new_service(source_service.show_service, destination, system_name)
32
+ target_service = create_new_service(source_service.show_service, destination)
34
33
  puts "new service id #{target_service.id}"
35
34
  context = create_context(source_service, target_service)
36
35
  tasks = [
@@ -40,7 +39,10 @@ module ThreeScaleToolbox
40
39
  Tasks::CopyApplicationPlansTask.new(context),
41
40
  Tasks::CopyLimitsTask.new(context),
42
41
  Tasks::DestroyMappingRulesTask.new(context),
43
- Tasks::CopyMappingRulesTask.new(context)
42
+ Tasks::CopyMappingRulesTask.new(context),
43
+ Tasks::CopyPoliciesTask.new(context),
44
+ Tasks::CopyPricingRulesTask.new(context),
45
+ Tasks::CopyActiveDocsTask.new(context),
44
46
  ]
45
47
  tasks.each(&:call)
46
48
  end
@@ -54,10 +56,10 @@ module ThreeScaleToolbox
54
56
  }
55
57
  end
56
58
 
57
- def create_new_service(service, destination, system_name)
59
+ def create_new_service(service, destination)
58
60
  Entities::Service.create(remote: threescale_client(destination),
59
61
  service: service,
60
- system_name: system_name)
62
+ system_name: options[:target_system_name] || service['system_name'])
61
63
  end
62
64
  end
63
65
  end
@@ -8,6 +8,7 @@ require '3scale_toolbox/commands/import_command/openapi/threescale_api_spec'
8
8
  require '3scale_toolbox/commands/import_command/openapi/create_method_step'
9
9
  require '3scale_toolbox/commands/import_command/openapi/create_mapping_rule_step'
10
10
  require '3scale_toolbox/commands/import_command/openapi/create_service_step'
11
+ require '3scale_toolbox/commands/import_command/openapi/create_activedocs_step'
11
12
 
12
13
  module ThreeScaleToolbox
13
14
  module Commands
@@ -33,13 +34,15 @@ module ThreeScaleToolbox
33
34
  end
34
35
 
35
36
  def run
36
- context = create_context
37
+ openapi_resource = load_resource(arguments[:openapi_resource])
38
+ context = create_context(openapi_resource)
37
39
 
38
40
  tasks = []
39
41
  tasks << CreateServiceStep.new(context)
40
42
  tasks << CreateMethodsStep.new(context)
41
43
  tasks << ThreeScaleToolbox::Tasks::DestroyMappingRulesTask.new(context)
42
44
  tasks << CreateMappingRulesStep.new(context)
45
+ tasks << CreateActiveDocsStep.new(context)
43
46
 
44
47
  # run tasks
45
48
  tasks.each(&:call)
@@ -47,16 +50,17 @@ module ThreeScaleToolbox
47
50
 
48
51
  private
49
52
 
50
- def create_context
53
+ def create_context(openapi_resource)
51
54
  {
52
- api_spec: ThreeScaleApiSpec.new(load_openapi),
55
+ api_spec_resource: openapi_resource,
56
+ api_spec: ThreeScaleApiSpec.new(load_openapi(openapi_resource)),
53
57
  threescale_client: threescale_client(fetch_required_option(:destination)),
54
58
  target_system_name: options[:target_system_name]
55
59
  }
56
60
  end
57
61
 
58
- def load_openapi
59
- Swagger.build(load_resource(arguments[:openapi_resource]))
62
+ def load_openapi(openapi_resource)
63
+ Swagger.build(openapi_resource)
60
64
  # Disable validation step because https://petstore.swagger.io/v2/swagger.json
61
65
  # does not pass validation. Maybe library's schema is outdated?
62
66
  # openapi.tap(&:validate)
@@ -0,0 +1,52 @@
1
+ module ThreeScaleToolbox
2
+ module Commands
3
+ module ImportCommand
4
+ module OpenAPI
5
+ class CreateActiveDocsStep
6
+ include Step
7
+
8
+ def call
9
+ active_doc = {
10
+ name: api_spec.title,
11
+ system_name: activedocs_system_name,
12
+ service_id: service.id,
13
+ body: resource.to_json,
14
+ description: api_spec.description
15
+ }
16
+
17
+ res = threescale_client.create_activedocs(active_doc)
18
+ # Make operation indempotent
19
+ if (errors = res['errors'])
20
+ raise ThreeScaleToolbox::Error, "ActiveDocs has not been created. #{errors}" \
21
+ unless system_name_already_taken_error? errors
22
+
23
+ # if activedocs system_name exists, ignore error, update activedocs
24
+ puts 'Activedocs exists, update!'
25
+ update_res = threescale_client.update_activedocs(find_activedocs_id, active_doc)
26
+ raise ThreeScaleToolbox::Error, "ActiveDocs has not been updated. #{update_res['errors']}" unless update_res['errors'].nil?
27
+ end
28
+ end
29
+
30
+ private
31
+
32
+ def activedocs_system_name
33
+ @activedocs_system_name ||= service.show_service['system_name']
34
+ end
35
+
36
+ def find_activedocs_id
37
+ activedocs = get_current_service_activedocs
38
+ raise ThreeScaleToolbox::Error, "Could not find activedocs with system_name: #{activedocs_system_name}" if activedocs.empty?
39
+
40
+ activedocs.dig(0, 'id')
41
+ end
42
+
43
+ def get_current_service_activedocs
44
+ threescale_client.list_activedocs.select do |activedoc|
45
+ activedoc['system_name'] == activedocs_system_name
46
+ end
47
+ end
48
+ end
49
+ end
50
+ end
51
+ end
52
+ end
@@ -12,13 +12,11 @@ module ThreeScaleToolbox
12
12
  metric_id = res['id']
13
13
  # if method system_name exists, ignore error and get metric_id
14
14
  # Make operation indempotent
15
- unless res['errors'].nil?
16
- if !res['errors']['system_name'].nil? \
17
- && res['errors']['system_name'][0] =~ /has already been taken/
18
- metric_id = method_id_by_system_name[op.method['system_name']]
19
- else
20
- raise Error, "Metohd has not been saved. Errors: #{res['errors']}"
21
- end
15
+ if (errors = res['errors'])
16
+ raise ThreeScaleToolbox::Error, "Metohd has not been saved. #{errors}" \
17
+ unless system_name_already_taken_error? errors
18
+
19
+ metric_id = method_id_by_system_name[op.method['system_name']]
22
20
  end
23
21
 
24
22
  op.set(:metric_id, metric_id)
@@ -12,12 +12,16 @@ module ThreeScaleToolbox
12
12
  end
13
13
 
14
14
  def friendly_name
15
- operation[:operationId]
15
+ operation[:operationId] || operation_id
16
16
  end
17
17
 
18
18
  def system_name
19
19
  friendly_name.downcase
20
20
  end
21
+
22
+ def operation_id
23
+ "#{operation[:verb]}#{operation[:path].gsub(/[^\w]/, '')}"
24
+ end
21
25
  end
22
26
  end
23
27
  end
@@ -38,6 +38,14 @@ module ThreeScaleToolbox
38
38
  # could be nil
39
39
  context[:target_system_name]
40
40
  end
41
+
42
+ def resource
43
+ context[:api_spec_resource]
44
+ end
45
+
46
+ def system_name_already_taken_error?(error)
47
+ Array(Hash(error)['system_name']).any? { |msg| msg.match(/has already been taken/) }
48
+ end
41
49
  end
42
50
  end
43
51
  end
@@ -46,6 +46,10 @@ module ThreeScaleToolbox
46
46
  tasks << Tasks::CopyMetricsTask.new(context)
47
47
  tasks << Tasks::CopyApplicationPlansTask.new(context)
48
48
  tasks << Tasks::CopyLimitsTask.new(context)
49
+ tasks << Tasks::CopyPoliciesTask.new(context)
50
+ tasks << Tasks::CopyPricingRulesTask.new(context)
51
+ tasks << Tasks::DeleteActiveDocsTask.new(context)
52
+ tasks << Tasks::CopyActiveDocsTask.new(context)
49
53
  end
50
54
  tasks << Tasks::DestroyMappingRulesTask.new(context) if options[:force]
51
55
  tasks << Tasks::CopyMappingRulesTask.new(context)
@@ -108,6 +108,22 @@ module ThreeScaleToolbox
108
108
  def delete_service
109
109
  remote.delete_service id
110
110
  end
111
+
112
+ def policies
113
+ remote.show_policies id
114
+ end
115
+
116
+ def update_policies(params)
117
+ remote.update_policies(id, params)
118
+ end
119
+
120
+ def list_activedocs
121
+ remote.list_activedocs.select do |activedoc|
122
+ # service_id is optional attr. It would return nil and would not match
123
+ # activedocs endpoints return service_id as integers
124
+ activedoc['service_id'] == id.to_i
125
+ end
126
+ end
111
127
  end
112
128
  end
113
129
  end
@@ -8,3 +8,7 @@ require '3scale_toolbox/tasks/copy_limits_task'
8
8
  require '3scale_toolbox/tasks/destroy_mapping_rules_task'
9
9
  require '3scale_toolbox/tasks/copy_mapping_rules_task'
10
10
  require '3scale_toolbox/tasks/update_service_settings_task'
11
+ require '3scale_toolbox/tasks/copy_policies_task'
12
+ require '3scale_toolbox/tasks/copy_pricingrules_task'
13
+ require '3scale_toolbox/tasks/delete_activedocs_task'
14
+ require '3scale_toolbox/tasks/copy_activedocs_task'
@@ -0,0 +1,24 @@
1
+ module ThreeScaleToolbox
2
+ module Tasks
3
+ class CopyActiveDocsTask
4
+ include CopyTask
5
+
6
+ def call
7
+ puts 'copying all service ActiveDocs'
8
+
9
+ target_activedocs = source.list_activedocs.map do |source_activedoc|
10
+ source_activedoc.clone.tap do |target_activedoc|
11
+ target_activedoc.delete('id')
12
+ target_activedoc['service_id'] = target.id
13
+ target_activedoc['system_name'] = "#{target_activedoc['system_name']}#{target.id}"
14
+ end
15
+ end
16
+
17
+ target_activedocs.each do |ad|
18
+ res = target.remote.create_activedocs(ad)
19
+ raise ThreeScaleToolbox::Error, "ActiveDocs has not been created. Errors: #{res['errors']}" unless res['errors'].nil?
20
+ end
21
+ end
22
+ end
23
+ end
24
+ end
@@ -19,8 +19,8 @@ module ThreeScaleToolbox
19
19
  limit
20
20
  )
21
21
  end
22
- puts "target application plan #{target_plan['id']} is missing" \
23
- " #{missing_limits.size} from the original plan #{plan_id}"
22
+ puts "Missing #{missing_limits.size} plan limits from target application plan " \
23
+ "#{target_plan['id']}. Source plan #{plan_id}"
24
24
  end
25
25
  end
26
26
 
@@ -0,0 +1,13 @@
1
+ module ThreeScaleToolbox
2
+ module Tasks
3
+ class CopyPoliciesTask
4
+ include CopyTask
5
+
6
+ def call
7
+ puts 'copy proxy policies'
8
+ source_policies = source.policies
9
+ target.update_policies('policies_config' => source_policies)
10
+ end
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,36 @@
1
+ module ThreeScaleToolbox
2
+ module Tasks
3
+ class CopyPricingRulesTask
4
+ include CopyTask
5
+ include Helper
6
+
7
+ def call
8
+ metrics_map = metrics_mapping(source.metrics, target.metrics)
9
+ plan_mapping = application_plan_mapping(source.plans, target.plans)
10
+ plan_mapping.each do |plan_id, target_plan|
11
+ pricing_rules_source = source.remote.list_pricingrules_per_application_plan(plan_id)
12
+ pricing_rules_target = target.remote.list_pricingrules_per_application_plan(target_plan['id'])
13
+ missing_pricing_rules = missing_pricing_rules(pricing_rules_source, pricing_rules_target)
14
+ missing_pricing_rules.each do |pricing_rule|
15
+ pricing_rule.delete('links')
16
+ target.remote.create_pricingrule(
17
+ target_plan['id'],
18
+ metrics_map.fetch(pricing_rule['metric_id']),
19
+ pricing_rule
20
+ )
21
+ end
22
+ puts "Missing #{missing_pricing_rules.size} pricing rules from target application plan " \
23
+ "#{target_plan['id']}. Source plan #{plan_id}"
24
+ end
25
+ end
26
+
27
+ private
28
+
29
+ def missing_pricing_rules(source_pricing_rules, target_pricing_rules)
30
+ ThreeScaleToolbox::Helper.array_difference(source_pricing_rules, target_pricing_rules) do |src, target|
31
+ ThreeScaleToolbox::Helper.compare_hashes(src, target, ['system_name'])
32
+ end
33
+ end
34
+ end
35
+ end
36
+ end
@@ -0,0 +1,22 @@
1
+ module ThreeScaleToolbox
2
+ module Tasks
3
+ class DeleteActiveDocsTask
4
+ attr_reader :context
5
+
6
+ def initialize(context)
7
+ @context = context
8
+ end
9
+
10
+ def call
11
+ puts 'deleting all target service ActiveDocs'
12
+ target.list_activedocs.each do |activedoc|
13
+ target.remote.delete_activedocs(activedoc['id'])
14
+ end
15
+ end
16
+
17
+ def target
18
+ context[:target]
19
+ end
20
+ end
21
+ end
22
+ end
@@ -12,7 +12,7 @@ module ThreeScaleToolbox
12
12
  def call
13
13
  source_obj = source.show_service
14
14
  response = target.update_service(target_service_params(source_obj))
15
- raise Error, "Service has not been saved. Errors: #{response['errors']}" unless response['errors'].nil?
15
+ raise ThreeScaleToolbox::Error, "Service has not been saved. Errors: #{response['errors']}" unless response['errors'].nil?
16
16
 
17
17
  puts "updated service settings for service id #{source.id}..."
18
18
  end
@@ -1,3 +1,3 @@
1
1
  module ThreeScaleToolbox
2
- VERSION = '0.6.0'
2
+ VERSION = '0.7.0'
3
3
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: 3scale_toolbox
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.6.0
4
+ version: 0.7.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Michal Cichra
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: exe
11
11
  cert_chain: []
12
- date: 2019-02-05 00:00:00.000000000 Z
12
+ date: 2019-03-08 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: bundler
@@ -87,14 +87,14 @@ dependencies:
87
87
  requirements:
88
88
  - - "~>"
89
89
  - !ruby/object:Gem::Version
90
- version: 0.1.7
90
+ version: 0.1.8
91
91
  type: :runtime
92
92
  prerelease: false
93
93
  version_requirements: !ruby/object:Gem::Requirement
94
94
  requirements:
95
95
  - - "~>"
96
96
  - !ruby/object:Gem::Version
97
- version: 0.1.7
97
+ version: 0.1.8
98
98
  - !ruby/object:Gem::Dependency
99
99
  name: cri
100
100
  requirement: !ruby/object:Gem::Requirement
@@ -147,6 +147,7 @@ files:
147
147
  - lib/3scale_toolbox/commands/import_command.rb
148
148
  - lib/3scale_toolbox/commands/import_command/import_csv.rb
149
149
  - lib/3scale_toolbox/commands/import_command/openapi.rb
150
+ - lib/3scale_toolbox/commands/import_command/openapi/create_activedocs_step.rb
150
151
  - lib/3scale_toolbox/commands/import_command/openapi/create_mapping_rule_step.rb
151
152
  - lib/3scale_toolbox/commands/import_command/openapi/create_method_step.rb
152
153
  - lib/3scale_toolbox/commands/import_command/openapi/create_service_step.rb
@@ -170,13 +171,17 @@ files:
170
171
  - lib/3scale_toolbox/helper.rb
171
172
  - lib/3scale_toolbox/remotes.rb
172
173
  - lib/3scale_toolbox/tasks.rb
174
+ - lib/3scale_toolbox/tasks/copy_activedocs_task.rb
173
175
  - lib/3scale_toolbox/tasks/copy_app_plans_task.rb
174
176
  - lib/3scale_toolbox/tasks/copy_limits_task.rb
175
177
  - lib/3scale_toolbox/tasks/copy_mapping_rules_task.rb
176
178
  - lib/3scale_toolbox/tasks/copy_methods_task.rb
177
179
  - lib/3scale_toolbox/tasks/copy_metrics_task.rb
180
+ - lib/3scale_toolbox/tasks/copy_policies_task.rb
181
+ - lib/3scale_toolbox/tasks/copy_pricingrules_task.rb
178
182
  - lib/3scale_toolbox/tasks/copy_service_proxy_task.rb
179
183
  - lib/3scale_toolbox/tasks/copy_task.rb
184
+ - lib/3scale_toolbox/tasks/delete_activedocs_task.rb
180
185
  - lib/3scale_toolbox/tasks/destroy_mapping_rules_task.rb
181
186
  - lib/3scale_toolbox/tasks/helper_task.rb
182
187
  - lib/3scale_toolbox/tasks/update_service_settings_task.rb