3scale_toolbox 0.4.0 → 0.5.0

Sign up to get free protection for your applications and to get access to all the features.
data/exe/3scale-update DELETED
@@ -1,270 +0,0 @@
1
- #!/usr/bin/env ruby
2
-
3
- require '3scale_toolbox/cli'
4
- require 'optparse'
5
- require '3scale/api'
6
- require 'uri'
7
-
8
- options = {}
9
-
10
- parser = OptionParser.new do |parser|
11
- parser.banner = '3scale update <command> [options]'
12
-
13
- parser.on('-s', '--source SOURCE', "Source") do |domain|
14
- options[:source] = domain
15
- end
16
-
17
- parser.on('-d', '--destination DESTINATION', "Destination") do |domain|
18
- options[:destination] = domain
19
- end
20
-
21
- parser.on('-f', '--force', 'Overwrites the mapping rules by deleting all rules from target service first') do
22
- options[:force] = true
23
- end
24
-
25
- # TODO: parametrize what parts of service need to be copied
26
- parser.on('-r', '--rules-only', 'Updates only the mapping rules') do
27
- options[:rules_only] = true
28
- end
29
-
30
- parser.on('-h', '--help', 'Prints this help') do
31
- puts parser
32
- puts
33
- puts 'Available Commands:', ['service <source_service_id> <destination_service_id>', 'help']
34
- exit
35
- end
36
- end
37
-
38
- print_help = ->(error = nil) do
39
- if error
40
- puts "Error: #{error}"
41
- puts
42
- end
43
- parser.parse(['--help'])
44
- end
45
-
46
- parser.parse!
47
-
48
- def fetch_option(options, key)
49
- options.fetch(key) { raise OptionParser::MissingArgument, key }
50
- end
51
-
52
- class ServiceUpdater
53
-
54
- attr_reader :source_client, :target_client, :source_service_id, :target_service_id
55
-
56
- def initialize (source, source_service_id, destination, target_service_id)
57
- @source_client = ThreeScale::API.new(
58
- endpoint: endpoint_from_url(source),
59
- provider_key: provider_key_from_url(source)
60
- )
61
- @target_client = ThreeScale::API.new(
62
- endpoint: endpoint_from_url(destination),
63
- provider_key: provider_key_from_url(destination)
64
- )
65
- @source_service_id = source_service_id
66
- @target_service_id = target_service_id
67
- end
68
-
69
- def compare_hashes(first, second, keys)
70
- keys.map{ |key| first.fetch(key) } == keys.map{ |key| second.fetch(key) }
71
- end
72
-
73
- def provider_key_from_url(url)
74
- URI(url).user
75
- end
76
-
77
- def endpoint_from_url(url)
78
- uri = URI(url)
79
- uri.user = nil
80
-
81
- uri.to_s
82
- end
83
-
84
- def target_service_params(source)
85
- # NOTE: backend_version and deployment_option are not yet returned by show_service method
86
- params = %w(name backend_version deployment_option end_user_registration_required)
87
- source.select { |k,v| params.include?(k) && v }
88
- end
89
-
90
- def source_metrics
91
- @source_metrics ||= source_client.list_metrics(source_service_id)
92
- end
93
-
94
- def metrics_mapping
95
- @metrics_mapping ||= target_client.list_metrics(target_service_id).map do |target|
96
- metric = source_metrics.find{|metric| metric.fetch('system_name') == target.fetch('system_name') }
97
- metric ||= {}
98
-
99
- [metric['id'], target['id']]
100
- end.to_h
101
- end
102
-
103
- def copy_service_settings
104
- source_service = source_client.show_service(source_service_id)
105
- puts "updating service settings for service id #{target_service_id}..."
106
- target_update_response = target_client.update_service(target_service_id, target_service_params(source_service))
107
- raise "Service has not been saved. Errors: #{target_update_response['errors']}" unless target_update_response['errors'].nil?
108
- end
109
-
110
- def copy_proxy_settings
111
- puts "updating proxy configuration for service id #{target_service_id}..."
112
- proxy = source_client.show_proxy(source_service_id)
113
- target_client.update_proxy(target_service_id, proxy)
114
- puts "updated proxy of #{target_service_id} to match the source #{source_service_id}"
115
- end
116
-
117
- def copy_metrics_and_methods
118
- target_metrics = target_client.list_metrics(target_service_id)
119
-
120
- source_hits = source_metrics.find{ |metric| metric['system_name'] == 'hits' } or raise 'missing hits metric'
121
- target_hits = target_metrics.find{ |metric| metric['system_name'] == 'hits' } or raise 'missing hits metric'
122
-
123
- source_methods = source_client.list_methods(source_service_id, source_hits['id'])
124
- target_methods = target_client.list_methods(target_service_id, target_hits['id'])
125
-
126
- puts "source service hits metric #{source_hits['id']} has #{source_methods.size} methods"
127
- puts "target service hits metric #{target_hits['id']} has #{target_methods.size} methods"
128
-
129
- missing_methods = source_methods.reject { |source_method| target_methods.find{|target_method| compare_hashes(source_method, target_method, ['system_name']) } }
130
-
131
- puts "creating #{missing_methods.size} missing methods on target service..."
132
- missing_methods.each do |method|
133
- target = { friendly_name: method['friendly_name'], system_name: method['system_name'] }
134
- target_client.create_method(target_service_id, target_hits['id'], target)
135
- end
136
-
137
- target_metrics = target_client.list_metrics(target_service_id)
138
-
139
- puts "source service has #{source_metrics.size} metrics"
140
- puts "target service has #{target_metrics.size} metrics"
141
-
142
- missing_metrics = source_metrics.reject { |source_metric| target_metrics.find{|target_metric| compare_hashes(source_metric, target_metric, ['system_name']) } }
143
-
144
- missing_metrics.map do |metric|
145
- metric.delete('links')
146
- target_client.create_metric(target_service_id, metric)
147
- end
148
-
149
- puts "created #{missing_metrics.size} metrics on the target service"
150
- end
151
-
152
- def copy_application_plans
153
- source_plans = source_client.list_service_application_plans(source_service_id)
154
- target_plans = target_client.list_service_application_plans(target_service_id)
155
-
156
- puts "source service has #{source_plans.size} application plans"
157
- puts "target service has #{target_plans.size} application plans"
158
-
159
- missing_application_plans = source_plans.reject { |source_plan| target_plans.find{|target_plan| source_plan.fetch('system_name') == target_plan.fetch('system_name') } }
160
-
161
- puts "creating #{missing_application_plans.size} missing application plans..."
162
-
163
- missing_application_plans.each do |plan|
164
- plan.delete('links')
165
- plan.delete('default') # TODO: handle default plans
166
-
167
- if plan.delete('custom') # TODO: what to do with custom plans?
168
- puts "skipping custom plan #{plan}"
169
- else
170
- target_client.create_application_plan(target_service_id, plan)
171
- end
172
- end
173
-
174
- puts "updating limits for application plans..."
175
-
176
- application_plan_mapping = target_client.list_service_application_plans(target_service_id).map do |plan_target|
177
- plan = source_plans.find{|plan| plan.fetch('system_name') == plan_target.fetch('system_name') }
178
- plan ||= {}
179
- [plan['id'], plan_target['id']]
180
- end.to_h.reject { |key, value| !key }
181
-
182
- application_plan_mapping.each do |source_id, target_id|
183
- source_limits = source_client.list_application_plan_limits(source_id)
184
- target_limits = target_client.list_application_plan_limits(target_id)
185
-
186
- missing_limits = source_limits.reject { |limit| target_limits.find{|limit_target| limit.fetch('period') == limit_target.fetch('period') } }
187
-
188
- puts "target application plan #{target_id} is missing #{missing_limits.size} from the source plan #{source_id}"
189
-
190
- missing_limits.each do |limit|
191
- limit.delete('links')
192
- target_client.create_application_plan_limit(target_id, metrics_mapping.fetch(limit.fetch('metric_id')), limit)
193
- end
194
-
195
- end
196
- end
197
-
198
- def copy_mapping_rules force_mapping_rules
199
- source_mapping_rules = source_client.list_mapping_rules(source_service_id)
200
- target_mapping_rules = target_client.list_mapping_rules(target_service_id)
201
-
202
- puts "the source service has #{source_mapping_rules.size} mapping rules"
203
- puts "the target has #{target_mapping_rules.size} mapping rules"
204
-
205
- if force_mapping_rules
206
- puts "force mode was chosen, deleting existing mapping rules on target service..."
207
- target_mapping_rules.each do |rule|
208
- target_client.delete_mapping_rule(target_service_id, rule['id'])
209
- end
210
- missing_mapping_rules = source_mapping_rules
211
- else
212
- unique_target_mapping_rules = target_mapping_rules.dup
213
-
214
- missing_mapping_rules = source_mapping_rules.reject do |mapping_rule|
215
- matching_metric = unique_target_mapping_rules.find do |target|
216
- compare_hashes(mapping_rule, target, %w(pattern http_method delta)) &&
217
- metrics_mapping.fetch(mapping_rule.fetch('metric_id')) == target.fetch('metric_id')
218
- end
219
-
220
- unique_target_mapping_rules.delete(matching_metric)
221
- end
222
- end
223
-
224
- puts "missing #{missing_mapping_rules.size} mapping rules"
225
-
226
- missing_mapping_rules.each do |mapping_rule|
227
- mapping_rule.delete('links')
228
- mapping_rule['metric_id'] = metrics_mapping.fetch(mapping_rule.delete('metric_id'))
229
- target_client.create_mapping_rule(target_service_id, mapping_rule)
230
- end
231
- puts "created #{missing_mapping_rules.size} mapping rules"
232
- end
233
-
234
- def update_service force_mapping_rules=false
235
- copy_service_settings
236
- copy_proxy_settings
237
- copy_metrics_and_methods
238
- copy_application_plans
239
- copy_mapping_rules force_mapping_rules
240
- end
241
- end
242
-
243
- case (command = ARGV.shift)
244
- when 'service'
245
- source = fetch_option options, :source
246
- destination = fetch_option options, :destination
247
-
248
- rules_only = options[:rules_only] == true
249
- force_update = options[:force] == true
250
-
251
- source_service_id = ARGV.shift or raise OptionParser::MissingArgument, 'source_service_id'
252
- target_service_id = ARGV.shift or raise OptionParser::MissingArgument, 'destination_service_id'
253
-
254
- updater = ServiceUpdater.new(source, source_service_id, destination, target_service_id)
255
-
256
- if rules_only
257
- updater.copy_mapping_rules force_update
258
- else
259
- updater.update_service force_update
260
- end
261
-
262
- when 'help'
263
- print_help.call
264
- when nil
265
- print_help.call("missing subcommand")
266
- exit 1
267
- else
268
- print_help.call("unknown command #{command}")
269
- exit 1
270
- end