3scale_toolbox 0.6.0 → 0.7.0

Sign up to get free protection for your applications and to get access to all the features.
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