3scale_toolbox 0.5.1 → 0.6.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 +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
|