3scale_toolbox 0.5.1 → 0.6.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +143 -23
- data/exe/3scale +10 -3
- data/lib/3scale_toolbox.rb +18 -0
- data/lib/3scale_toolbox/3scale_client_factory.rb +33 -0
- data/lib/3scale_toolbox/base_command.rb +52 -14
- data/lib/3scale_toolbox/cli.rb +26 -5
- data/lib/3scale_toolbox/cli/error_handler.rb +120 -0
- data/lib/3scale_toolbox/commands.rb +3 -9
- data/lib/3scale_toolbox/commands/3scale_command.rb +8 -6
- data/lib/3scale_toolbox/commands/copy_command.rb +4 -4
- data/lib/3scale_toolbox/commands/copy_command/copy_service.rb +40 -193
- data/lib/3scale_toolbox/commands/help_command.rb +1 -1
- data/lib/3scale_toolbox/commands/import_command.rb +6 -4
- data/lib/3scale_toolbox/commands/import_command/import_csv.rb +15 -41
- data/lib/3scale_toolbox/commands/import_command/openapi.rb +70 -0
- data/lib/3scale_toolbox/commands/import_command/openapi/create_mapping_rule_step.rb +18 -0
- data/lib/3scale_toolbox/commands/import_command/openapi/create_method_step.rb +39 -0
- data/lib/3scale_toolbox/commands/import_command/openapi/create_service_step.rb +69 -0
- data/lib/3scale_toolbox/commands/import_command/openapi/mapping_rule.rb +35 -0
- data/lib/3scale_toolbox/commands/import_command/openapi/method.rb +25 -0
- data/lib/3scale_toolbox/commands/import_command/openapi/operation.rb +22 -0
- data/lib/3scale_toolbox/commands/import_command/openapi/resource_reader.rb +49 -0
- data/lib/3scale_toolbox/commands/import_command/openapi/step.rb +45 -0
- data/lib/3scale_toolbox/commands/import_command/openapi/threescale_api_spec.rb +33 -0
- data/lib/3scale_toolbox/commands/remote_command.rb +36 -0
- data/lib/3scale_toolbox/commands/remote_command/remote_add.rb +47 -0
- data/lib/3scale_toolbox/commands/remote_command/remote_list.rb +29 -0
- data/lib/3scale_toolbox/commands/remote_command/remote_remove.rb +26 -0
- data/lib/3scale_toolbox/commands/remote_command/remote_rename.rb +42 -0
- data/lib/3scale_toolbox/commands/update_command.rb +4 -4
- data/lib/3scale_toolbox/commands/update_command/update_service.rb +45 -235
- data/lib/3scale_toolbox/configuration.rb +35 -0
- data/lib/3scale_toolbox/entities.rb +1 -0
- data/lib/3scale_toolbox/entities/service.rb +113 -0
- data/lib/3scale_toolbox/error.rb +8 -0
- data/lib/3scale_toolbox/helper.rb +37 -0
- data/lib/3scale_toolbox/remotes.rb +93 -0
- data/lib/3scale_toolbox/tasks.rb +10 -0
- data/lib/3scale_toolbox/tasks/copy_app_plans_task.rb +31 -0
- data/lib/3scale_toolbox/tasks/copy_limits_task.rb +36 -0
- data/lib/3scale_toolbox/tasks/copy_mapping_rules_task.rb +29 -0
- data/lib/3scale_toolbox/tasks/copy_methods_task.rb +29 -0
- data/lib/3scale_toolbox/tasks/copy_metrics_task.rb +33 -0
- data/lib/3scale_toolbox/tasks/copy_service_proxy_task.rb +12 -0
- data/lib/3scale_toolbox/tasks/copy_task.rb +26 -0
- data/lib/3scale_toolbox/tasks/destroy_mapping_rules_task.rb +22 -0
- data/lib/3scale_toolbox/tasks/helper_task.rb +25 -0
- data/lib/3scale_toolbox/tasks/update_service_settings_task.rb +32 -0
- data/lib/3scale_toolbox/version.rb +1 -1
- metadata +87 -11
@@ -0,0 +1,45 @@
|
|
1
|
+
module ThreeScaleToolbox
|
2
|
+
module Commands
|
3
|
+
module ImportCommand
|
4
|
+
module OpenAPI
|
5
|
+
module Step
|
6
|
+
attr_reader :context
|
7
|
+
|
8
|
+
def initialize(context)
|
9
|
+
@context = context
|
10
|
+
end
|
11
|
+
|
12
|
+
# Can be nil on initialization time and not nil afterwards
|
13
|
+
# method to fetch from context required
|
14
|
+
def service
|
15
|
+
context[:target]
|
16
|
+
end
|
17
|
+
|
18
|
+
def service=(service)
|
19
|
+
context[:target] = service
|
20
|
+
end
|
21
|
+
|
22
|
+
def api_spec
|
23
|
+
context[:api_spec]
|
24
|
+
end
|
25
|
+
|
26
|
+
def threescale_client
|
27
|
+
context[:threescale_client]
|
28
|
+
end
|
29
|
+
|
30
|
+
def operations
|
31
|
+
# api_spec.operations are readonly
|
32
|
+
# store operations in context
|
33
|
+
# each operation can be extended with extra information to be used later
|
34
|
+
context[:operations] ||= api_spec.operations
|
35
|
+
end
|
36
|
+
|
37
|
+
def target_system_name
|
38
|
+
# could be nil
|
39
|
+
context[:target_system_name]
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
@@ -0,0 +1,33 @@
|
|
1
|
+
module ThreeScaleToolbox
|
2
|
+
module Commands
|
3
|
+
module ImportCommand
|
4
|
+
module OpenAPI
|
5
|
+
class ThreeScaleApiSpec
|
6
|
+
attr_reader :openapi
|
7
|
+
|
8
|
+
def initialize(openapi)
|
9
|
+
@openapi = openapi
|
10
|
+
end
|
11
|
+
|
12
|
+
def title
|
13
|
+
openapi.info.title
|
14
|
+
end
|
15
|
+
|
16
|
+
def description
|
17
|
+
openapi.info.description
|
18
|
+
end
|
19
|
+
|
20
|
+
def operations
|
21
|
+
openapi.operations.map do |op|
|
22
|
+
Operation.new(
|
23
|
+
path: "#{openapi.base_path}#{op.path}",
|
24
|
+
verb: op.verb,
|
25
|
+
operationId: op.operationId
|
26
|
+
)
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
@@ -0,0 +1,36 @@
|
|
1
|
+
require 'cri'
|
2
|
+
require '3scale_toolbox/base_command'
|
3
|
+
require '3scale_toolbox/remotes'
|
4
|
+
require '3scale_toolbox/commands/remote_command/remote_add'
|
5
|
+
require '3scale_toolbox/commands/remote_command/remote_remove'
|
6
|
+
require '3scale_toolbox/commands/remote_command/remote_rename'
|
7
|
+
require '3scale_toolbox/commands/remote_command/remote_list'
|
8
|
+
|
9
|
+
module ThreeScaleToolbox
|
10
|
+
module Commands
|
11
|
+
module RemoteCommand
|
12
|
+
class RemoteCommand < Cri::CommandRunner
|
13
|
+
include ThreeScaleToolbox::Command
|
14
|
+
|
15
|
+
def self.command
|
16
|
+
Cri::Command.define do
|
17
|
+
name 'remote'
|
18
|
+
usage 'remote <sub-command> [options]'
|
19
|
+
summary 'remotes super command'
|
20
|
+
description 'Manage your remotes'
|
21
|
+
runner RemoteCommand
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
def run
|
26
|
+
puts command.help
|
27
|
+
end
|
28
|
+
|
29
|
+
add_subcommand(RemoteAddSubcommand)
|
30
|
+
add_subcommand(RemoteRemoveSubcommand)
|
31
|
+
add_subcommand(RemoteRenameSubcommand)
|
32
|
+
add_subcommand(RemoteListSubcommand)
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
@@ -0,0 +1,47 @@
|
|
1
|
+
module ThreeScaleToolbox
|
2
|
+
module Commands
|
3
|
+
module RemoteCommand
|
4
|
+
class RemoteAddSubcommand < Cri::CommandRunner
|
5
|
+
include ThreeScaleToolbox::Command
|
6
|
+
|
7
|
+
def self.command
|
8
|
+
Cri::Command.define do
|
9
|
+
name 'add'
|
10
|
+
usage 'add <name> <url>'
|
11
|
+
summary 'remote add'
|
12
|
+
description 'Add new remote to the list'
|
13
|
+
param :remote_name
|
14
|
+
param :remote_url
|
15
|
+
runner RemoteAddSubcommand
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
def run
|
20
|
+
# 'arguments' cannot be converted to Hash
|
21
|
+
add_remote arguments[:remote_name], arguments[:remote_url]
|
22
|
+
end
|
23
|
+
|
24
|
+
private
|
25
|
+
|
26
|
+
def validate_remote_name(name)
|
27
|
+
raise ThreeScaleToolbox::Error, 'remote name already exists.' if remotes.all.key?(name)
|
28
|
+
end
|
29
|
+
|
30
|
+
def validate_remote(remote_url_str)
|
31
|
+
# parsing url before trying to create client
|
32
|
+
# raises Invalid URL when syntax is incorrect
|
33
|
+
ThreeScaleToolbox::Helper.parse_uri(remote_url_str)
|
34
|
+
threescale_client(remote_url_str).list_services
|
35
|
+
rescue ThreeScale::API::HttpClient::ForbiddenError
|
36
|
+
raise ThreeScaleToolbox::Error, 'remote not valid'
|
37
|
+
end
|
38
|
+
|
39
|
+
def add_remote(remote_name, remote_url)
|
40
|
+
validate_remote_name remote_name
|
41
|
+
validate_remote remote_url
|
42
|
+
remotes.add_uri(remote_name, remote_url)
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
module ThreeScaleToolbox
|
2
|
+
module Commands
|
3
|
+
module RemoteCommand
|
4
|
+
class RemoteListSubcommand < Cri::CommandRunner
|
5
|
+
include ThreeScaleToolbox::Command
|
6
|
+
|
7
|
+
def self.command
|
8
|
+
Cri::Command.define do
|
9
|
+
name 'list'
|
10
|
+
usage 'list'
|
11
|
+
summary 'remote list'
|
12
|
+
description 'List all defined remotes'
|
13
|
+
runner RemoteListSubcommand
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
def run
|
18
|
+
if remotes.all.empty?
|
19
|
+
puts 'Empty remote list.'
|
20
|
+
else
|
21
|
+
remotes.all.each do |name, remote|
|
22
|
+
puts "#{name} #{remote[:endpoint]} #{remote[:authentication]}"
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
module ThreeScaleToolbox
|
2
|
+
module Commands
|
3
|
+
module RemoteCommand
|
4
|
+
class RemoteRemoveSubcommand < Cri::CommandRunner
|
5
|
+
include ThreeScaleToolbox::Command
|
6
|
+
|
7
|
+
def self.command
|
8
|
+
Cri::Command.define do
|
9
|
+
name 'remove'
|
10
|
+
usage 'remove <name>'
|
11
|
+
summary 'remote remove'
|
12
|
+
description 'Remove remote from list'
|
13
|
+
param :remote_name
|
14
|
+
runner RemoteRemoveSubcommand
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
def run
|
19
|
+
remotes.delete(arguments[:remote_name]) do |el|
|
20
|
+
raise ThreeScaleToolbox::Error, "could not remove remote '#{el}'"
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
@@ -0,0 +1,42 @@
|
|
1
|
+
module ThreeScaleToolbox
|
2
|
+
module Commands
|
3
|
+
module RemoteCommand
|
4
|
+
class RemoteRenameSubcommand < Cri::CommandRunner
|
5
|
+
include ThreeScaleToolbox::Command
|
6
|
+
|
7
|
+
def self.command
|
8
|
+
Cri::Command.define do
|
9
|
+
name 'rename'
|
10
|
+
usage 'rename <old_name> <new_name>'
|
11
|
+
summary 'remote rename'
|
12
|
+
description 'Rename remote name'
|
13
|
+
param :remote_old_name
|
14
|
+
param :remote_new_name
|
15
|
+
runner RemoteRenameSubcommand
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
def run
|
20
|
+
# 'arguments' cannot be converted to Hash
|
21
|
+
rename_remote arguments[:remote_old_name], arguments[:remote_new_name]
|
22
|
+
end
|
23
|
+
|
24
|
+
private
|
25
|
+
|
26
|
+
def validate_remote_old_name(name)
|
27
|
+
raise ThreeScaleToolbox::Error, "Could not rename, old name '#{name}' does not exist." unless remotes.all.key?(name)
|
28
|
+
end
|
29
|
+
|
30
|
+
def validate_remote_new_name(name)
|
31
|
+
raise ThreeScaleToolbox::Error, "Could not rename, new name '#{name}' already exists." if remotes.all.key?(name)
|
32
|
+
end
|
33
|
+
|
34
|
+
def rename_remote(remote_old_name, remote_new_name)
|
35
|
+
validate_remote_old_name remote_old_name
|
36
|
+
validate_remote_new_name remote_new_name
|
37
|
+
remotes.add(remote_new_name, remotes.delete(remote_old_name))
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
@@ -5,13 +5,13 @@ require '3scale_toolbox/commands/update_command/update_service'
|
|
5
5
|
module ThreeScaleToolbox
|
6
6
|
module Commands
|
7
7
|
module UpdateCommand
|
8
|
-
|
8
|
+
include ThreeScaleToolbox::Command
|
9
9
|
def self.command
|
10
10
|
Cri::Command.define do
|
11
11
|
name 'update'
|
12
|
-
usage 'update <command> [options]'
|
13
|
-
summary '
|
14
|
-
description '3scale
|
12
|
+
usage 'update <sub-command> [options]'
|
13
|
+
summary 'update super command'
|
14
|
+
description 'Update 3scale entities between tenants'
|
15
15
|
end
|
16
16
|
end
|
17
17
|
add_subcommand(UpdateServiceSubcommand)
|
@@ -4,253 +4,63 @@ require '3scale_toolbox/base_command'
|
|
4
4
|
module ThreeScaleToolbox
|
5
5
|
module Commands
|
6
6
|
module UpdateCommand
|
7
|
-
|
8
|
-
|
7
|
+
class UpdateServiceSubcommand < Cri::CommandRunner
|
8
|
+
include ThreeScaleToolbox::Command
|
9
|
+
|
9
10
|
def self.command
|
10
11
|
Cri::Command.define do
|
11
12
|
name 'service'
|
12
13
|
usage 'service [opts] -s <src> -d <dst> <src_service_id> <dst_service_id>'
|
13
|
-
summary '
|
14
|
-
description '
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
option
|
19
|
-
flag
|
20
|
-
flag
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
14
|
+
summary 'update service'
|
15
|
+
description 'Update existing service, update proxy settings, metrics, methods, application plans and mapping rules.'
|
16
|
+
|
17
|
+
option :s, :source, '3scale source instance. Url or remote name', argument: :required
|
18
|
+
option :d, :destination, '3scale target instance. Url or remote name', argument: :required
|
19
|
+
option :t, 'target_system_name', 'Target system name', argument: :required
|
20
|
+
flag :f, :force, 'Overwrites the mapping rules by deleting all rules from target service first'
|
21
|
+
flag :r, 'rules-only', 'Updates only the mapping rules'
|
22
|
+
param :src_service_id
|
23
|
+
param :dst_service_id
|
24
|
+
|
25
|
+
runner UpdateServiceSubcommand
|
25
26
|
end
|
26
27
|
end
|
27
28
|
|
28
|
-
def
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
)
|
46
|
-
|
47
|
-
|
48
|
-
provider_key: provider_key_from_url(destination),
|
49
|
-
verify_ssl: !insecure
|
50
|
-
)
|
51
|
-
@source_service_id = source_service_id
|
52
|
-
@target_service_id = target_service_id
|
53
|
-
@target_system_name = system_name
|
54
|
-
end
|
55
|
-
|
56
|
-
def compare_hashes(first, second, keys)
|
57
|
-
keys.map{ |key| first.fetch(key) } == keys.map{ |key| second.fetch(key) }
|
58
|
-
end
|
59
|
-
|
60
|
-
def provider_key_from_url(url)
|
61
|
-
URI(url).user
|
62
|
-
end
|
63
|
-
|
64
|
-
def endpoint_from_url(url)
|
65
|
-
uri = URI(url)
|
66
|
-
uri.user = nil
|
67
|
-
|
68
|
-
uri.to_s
|
69
|
-
end
|
70
|
-
|
71
|
-
# system name only included when specified from options
|
72
|
-
def target_service_params(source)
|
73
|
-
target_service = source.select do |k, v|
|
74
|
-
Commands.service_valid_params.include?(k) \
|
75
|
-
&& k != 'system_name' \
|
76
|
-
&& v
|
77
|
-
end
|
78
|
-
target_service.tap do |hash|
|
79
|
-
hash['system_name'] = target_system_name unless target_system_name.nil?
|
80
|
-
end
|
81
|
-
end
|
82
|
-
|
83
|
-
def source_metrics
|
84
|
-
@source_metrics ||= source_client.list_metrics(source_service_id)
|
85
|
-
end
|
86
|
-
|
87
|
-
def metrics_mapping
|
88
|
-
@metrics_mapping ||= target_client.list_metrics(target_service_id).map do |target|
|
89
|
-
metric = source_metrics.find{|metric| metric.fetch('system_name') == target.fetch('system_name') }
|
90
|
-
metric ||= {}
|
91
|
-
|
92
|
-
[metric['id'], target['id']]
|
93
|
-
end.to_h
|
94
|
-
end
|
95
|
-
|
96
|
-
def copy_service_settings
|
97
|
-
source_service = source_client.show_service(source_service_id)
|
98
|
-
puts "updating service settings for service id #{target_service_id}..."
|
99
|
-
target_update_response = target_client.update_service(target_service_id, target_service_params(source_service))
|
100
|
-
raise "Service has not been saved. Errors: #{target_update_response['errors']}" unless target_update_response['errors'].nil?
|
101
|
-
end
|
102
|
-
|
103
|
-
def copy_proxy_settings
|
104
|
-
puts "updating proxy configuration for service id #{target_service_id}..."
|
105
|
-
proxy = source_client.show_proxy(source_service_id)
|
106
|
-
target_client.update_proxy(target_service_id, proxy)
|
107
|
-
puts "updated proxy of #{target_service_id} to match the source #{source_service_id}"
|
108
|
-
end
|
109
|
-
|
110
|
-
def copy_metrics_and_methods
|
111
|
-
target_metrics = target_client.list_metrics(target_service_id)
|
112
|
-
|
113
|
-
source_hits = source_metrics.find{ |metric| metric['system_name'] == 'hits' } or raise 'missing hits metric'
|
114
|
-
target_hits = target_metrics.find{ |metric| metric['system_name'] == 'hits' } or raise 'missing hits metric'
|
115
|
-
|
116
|
-
source_methods = source_client.list_methods(source_service_id, source_hits['id'])
|
117
|
-
target_methods = target_client.list_methods(target_service_id, target_hits['id'])
|
118
|
-
|
119
|
-
puts "source service hits metric #{source_hits['id']} has #{source_methods.size} methods"
|
120
|
-
puts "target service hits metric #{target_hits['id']} has #{target_methods.size} methods"
|
121
|
-
|
122
|
-
missing_methods = source_methods.reject { |source_method| target_methods.find{|target_method| compare_hashes(source_method, target_method, ['system_name']) } }
|
123
|
-
|
124
|
-
puts "creating #{missing_methods.size} missing methods on target service..."
|
125
|
-
missing_methods.each do |method|
|
126
|
-
target = { friendly_name: method['friendly_name'], system_name: method['system_name'] }
|
127
|
-
target_client.create_method(target_service_id, target_hits['id'], target)
|
128
|
-
end
|
129
|
-
|
130
|
-
target_metrics = target_client.list_metrics(target_service_id)
|
131
|
-
|
132
|
-
puts "source service has #{source_metrics.size} metrics"
|
133
|
-
puts "target service has #{target_metrics.size} metrics"
|
134
|
-
|
135
|
-
missing_metrics = source_metrics.reject { |source_metric| target_metrics.find{|target_metric| compare_hashes(source_metric, target_metric, ['system_name']) } }
|
136
|
-
|
137
|
-
missing_metrics.map do |metric|
|
138
|
-
metric.delete('links')
|
139
|
-
target_client.create_metric(target_service_id, metric)
|
140
|
-
end
|
141
|
-
|
142
|
-
puts "created #{missing_metrics.size} metrics on the target service"
|
29
|
+
def run
|
30
|
+
source_service = Entities::Service.new(
|
31
|
+
id: arguments[:src_service_id],
|
32
|
+
remote: threescale_client(fetch_required_option(:source))
|
33
|
+
)
|
34
|
+
update_service = Entities::Service.new(
|
35
|
+
id: arguments[:dst_service_id],
|
36
|
+
remote: threescale_client(fetch_required_option(:destination))
|
37
|
+
)
|
38
|
+
system_name = options[:target_system_name]
|
39
|
+
context = create_context(source_service, update_service)
|
40
|
+
|
41
|
+
tasks = []
|
42
|
+
unless options[:'rules-only']
|
43
|
+
tasks << Tasks::UpdateServiceSettingsTask.new(context.merge(target_name: system_name))
|
44
|
+
tasks << Tasks::CopyServiceProxyTask.new(context)
|
45
|
+
tasks << Tasks::CopyMethodsTask.new(context)
|
46
|
+
tasks << Tasks::CopyMetricsTask.new(context)
|
47
|
+
tasks << Tasks::CopyApplicationPlansTask.new(context)
|
48
|
+
tasks << Tasks::CopyLimitsTask.new(context)
|
143
49
|
end
|
50
|
+
tasks << Tasks::DestroyMappingRulesTask.new(context) if options[:force]
|
51
|
+
tasks << Tasks::CopyMappingRulesTask.new(context)
|
144
52
|
|
145
|
-
|
146
|
-
|
147
|
-
target_plans = target_client.list_service_application_plans(target_service_id)
|
148
|
-
|
149
|
-
puts "source service has #{source_plans.size} application plans"
|
150
|
-
puts "target service has #{target_plans.size} application plans"
|
151
|
-
|
152
|
-
missing_application_plans = source_plans.reject { |source_plan| target_plans.find{|target_plan| source_plan.fetch('system_name') == target_plan.fetch('system_name') } }
|
153
|
-
|
154
|
-
puts "creating #{missing_application_plans.size} missing application plans..."
|
155
|
-
|
156
|
-
missing_application_plans.each do |plan|
|
157
|
-
plan.delete('links')
|
158
|
-
plan.delete('default') # TODO: handle default plans
|
159
|
-
|
160
|
-
if plan.delete('custom') # TODO: what to do with custom plans?
|
161
|
-
puts "skipping custom plan #{plan}"
|
162
|
-
else
|
163
|
-
target_client.create_application_plan(target_service_id, plan)
|
164
|
-
end
|
165
|
-
end
|
166
|
-
|
167
|
-
puts "updating limits for application plans..."
|
168
|
-
|
169
|
-
application_plan_mapping = target_client.list_service_application_plans(target_service_id).map do |plan_target|
|
170
|
-
plan = source_plans.find{|plan| plan.fetch('system_name') == plan_target.fetch('system_name') }
|
171
|
-
plan ||= {}
|
172
|
-
[plan['id'], plan_target['id']]
|
173
|
-
end.to_h.reject { |key, value| !key }
|
174
|
-
|
175
|
-
application_plan_mapping.each do |source_id, target_id|
|
176
|
-
source_limits = source_client.list_application_plan_limits(source_id)
|
177
|
-
target_limits = target_client.list_application_plan_limits(target_id)
|
178
|
-
|
179
|
-
missing_limits = source_limits.reject { |limit| target_limits.find{|limit_target| limit.fetch('period') == limit_target.fetch('period') } }
|
180
|
-
|
181
|
-
puts "target application plan #{target_id} is missing #{missing_limits.size} from the source plan #{source_id}"
|
182
|
-
|
183
|
-
missing_limits.each do |limit|
|
184
|
-
limit.delete('links')
|
185
|
-
target_client.create_application_plan_limit(target_id, metrics_mapping.fetch(limit.fetch('metric_id')), limit)
|
186
|
-
end
|
187
|
-
|
188
|
-
end
|
189
|
-
end
|
190
|
-
|
191
|
-
def copy_mapping_rules force_mapping_rules
|
192
|
-
source_mapping_rules = source_client.list_mapping_rules(source_service_id)
|
193
|
-
target_mapping_rules = target_client.list_mapping_rules(target_service_id)
|
194
|
-
|
195
|
-
puts "the source service has #{source_mapping_rules.size} mapping rules"
|
196
|
-
puts "the target has #{target_mapping_rules.size} mapping rules"
|
197
|
-
|
198
|
-
if force_mapping_rules
|
199
|
-
puts "force mode was chosen, deleting existing mapping rules on target service..."
|
200
|
-
target_mapping_rules.each do |rule|
|
201
|
-
target_client.delete_mapping_rule(target_service_id, rule['id'])
|
202
|
-
end
|
203
|
-
missing_mapping_rules = source_mapping_rules
|
204
|
-
else
|
205
|
-
unique_target_mapping_rules = target_mapping_rules.dup
|
206
|
-
|
207
|
-
missing_mapping_rules = source_mapping_rules.reject do |mapping_rule|
|
208
|
-
matching_metric = unique_target_mapping_rules.find do |target|
|
209
|
-
compare_hashes(mapping_rule, target, %w(pattern http_method delta)) &&
|
210
|
-
metrics_mapping.fetch(mapping_rule.fetch('metric_id')) == target.fetch('metric_id')
|
211
|
-
end
|
212
|
-
|
213
|
-
unique_target_mapping_rules.delete(matching_metric)
|
214
|
-
end
|
215
|
-
end
|
216
|
-
|
217
|
-
puts "missing #{missing_mapping_rules.size} mapping rules"
|
218
|
-
|
219
|
-
missing_mapping_rules.each do |mapping_rule|
|
220
|
-
mapping_rule.delete('links')
|
221
|
-
mapping_rule['metric_id'] = metrics_mapping.fetch(mapping_rule.delete('metric_id'))
|
222
|
-
target_client.create_mapping_rule(target_service_id, mapping_rule)
|
223
|
-
end
|
224
|
-
puts "created #{missing_mapping_rules.size} mapping rules"
|
225
|
-
end
|
226
|
-
|
227
|
-
def update_service force_mapping_rules=false
|
228
|
-
copy_service_settings
|
229
|
-
copy_proxy_settings
|
230
|
-
copy_metrics_and_methods
|
231
|
-
copy_application_plans
|
232
|
-
copy_mapping_rules force_mapping_rules
|
233
|
-
end
|
53
|
+
# run tasks
|
54
|
+
tasks.each(&:call)
|
234
55
|
end
|
235
56
|
|
236
|
-
|
237
|
-
source = fetch_required_option(opts, :source)
|
238
|
-
destination = fetch_required_option(opts, :destination)
|
239
|
-
insecure = opts[:insecure] || false
|
240
|
-
exit_with_message 'error: missing source_service_id argument' if args.empty?
|
241
|
-
exit_with_message 'error: missing target_service_id argument' if args.size < 2
|
242
|
-
source_service_id = args[0]
|
243
|
-
target_service_id = args[1]
|
244
|
-
force_update = opts[:force] || false
|
245
|
-
rules_only = opts[:'rules-only'] || false
|
246
|
-
system_name = opts[:target_system_name]
|
247
|
-
updater = ServiceUpdater.new(source, source_service_id, destination, target_service_id, insecure, system_name)
|
57
|
+
private
|
248
58
|
|
249
|
-
|
250
|
-
|
251
|
-
|
252
|
-
|
253
|
-
|
59
|
+
def create_context(source, target)
|
60
|
+
{
|
61
|
+
source: source,
|
62
|
+
target: target
|
63
|
+
}
|
254
64
|
end
|
255
65
|
end
|
256
66
|
end
|