3scale_toolbox 0.10.0 → 0.11.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (61) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +21 -144
  3. data/lib/3scale_toolbox.rb +0 -1
  4. data/lib/3scale_toolbox/commands.rb +12 -0
  5. data/lib/3scale_toolbox/commands/3scale_command.rb +1 -1
  6. data/lib/3scale_toolbox/commands/account_command.rb +23 -0
  7. data/lib/3scale_toolbox/commands/account_command/find_command.rb +41 -0
  8. data/lib/3scale_toolbox/commands/activedocs_command.rb +32 -0
  9. data/lib/3scale_toolbox/commands/activedocs_command/apply_command.rb +127 -0
  10. data/lib/3scale_toolbox/commands/activedocs_command/create_command.rb +65 -0
  11. data/lib/3scale_toolbox/commands/activedocs_command/delete_command.rb +49 -0
  12. data/lib/3scale_toolbox/commands/activedocs_command/list_command.rb +54 -0
  13. data/lib/3scale_toolbox/commands/application_command.rb +30 -0
  14. data/lib/3scale_toolbox/commands/application_command/apply_command.rb +179 -0
  15. data/lib/3scale_toolbox/commands/application_command/create_command.rb +110 -0
  16. data/lib/3scale_toolbox/commands/application_command/delete_command.rb +57 -0
  17. data/lib/3scale_toolbox/commands/application_command/list_command.rb +124 -0
  18. data/lib/3scale_toolbox/commands/application_command/show_command.rb +72 -0
  19. data/lib/3scale_toolbox/commands/copy_command/copy_service.rb +97 -28
  20. data/lib/3scale_toolbox/commands/import_command/import_csv.rb +16 -17
  21. data/lib/3scale_toolbox/commands/import_command/openapi.rb +14 -10
  22. data/lib/3scale_toolbox/commands/import_command/openapi/create_service_step.rb +3 -2
  23. data/lib/3scale_toolbox/commands/import_command/openapi/method.rb +0 -1
  24. data/lib/3scale_toolbox/commands/import_command/openapi/step.rb +8 -1
  25. data/lib/3scale_toolbox/commands/import_command/openapi/update_service_proxy_step.rb +17 -7
  26. data/lib/3scale_toolbox/commands/methods_command.rb +4 -4
  27. data/lib/3scale_toolbox/commands/methods_command/apply_command.rb +2 -2
  28. data/lib/3scale_toolbox/commands/methods_command/create_command.rb +1 -1
  29. data/lib/3scale_toolbox/commands/metrics_command.rb +4 -4
  30. data/lib/3scale_toolbox/commands/metrics_command/apply_command.rb +2 -2
  31. data/lib/3scale_toolbox/commands/metrics_command/create_command.rb +1 -1
  32. data/lib/3scale_toolbox/commands/plans_command/apply_command.rb +7 -7
  33. data/lib/3scale_toolbox/commands/plans_command/create_command.rb +5 -5
  34. data/lib/3scale_toolbox/commands/policy_registry_command.rb +22 -0
  35. data/lib/3scale_toolbox/commands/policy_registry_command/copy_command.rb +85 -0
  36. data/lib/3scale_toolbox/commands/proxy_config_command.rb +30 -0
  37. data/lib/3scale_toolbox/commands/proxy_config_command/list_command.rb +78 -0
  38. data/lib/3scale_toolbox/commands/proxy_config_command/promote_command.rb +68 -0
  39. data/lib/3scale_toolbox/commands/proxy_config_command/show_command.rb +88 -0
  40. data/lib/3scale_toolbox/commands/service_command.rb +34 -0
  41. data/lib/3scale_toolbox/commands/service_command/apply_command.rb +77 -0
  42. data/lib/3scale_toolbox/commands/service_command/create_command.rb +59 -0
  43. data/lib/3scale_toolbox/commands/service_command/delete_command.rb +49 -0
  44. data/lib/3scale_toolbox/commands/service_command/list_command.rb +50 -0
  45. data/lib/3scale_toolbox/commands/service_command/show_command.rb +63 -0
  46. data/lib/3scale_toolbox/commands/update_command/update_service.rb +6 -3
  47. data/lib/3scale_toolbox/entities.rb +4 -0
  48. data/lib/3scale_toolbox/entities/account.rb +63 -0
  49. data/lib/3scale_toolbox/entities/activedocs.rb +88 -0
  50. data/lib/3scale_toolbox/entities/application.rb +124 -0
  51. data/lib/3scale_toolbox/entities/application_plan.rb +28 -4
  52. data/lib/3scale_toolbox/entities/base_entity.rb +44 -0
  53. data/lib/3scale_toolbox/entities/proxy_config.rb +58 -0
  54. data/lib/3scale_toolbox/entities/service.rb +42 -8
  55. data/lib/3scale_toolbox/error.rb +8 -0
  56. data/lib/3scale_toolbox/tasks.rb +2 -1
  57. data/lib/3scale_toolbox/tasks/bump_proxy_version_task.rb +32 -0
  58. data/lib/3scale_toolbox/tasks/copy_service_settings_task.rb +38 -0
  59. data/lib/3scale_toolbox/version.rb +1 -1
  60. metadata +36 -5
  61. data/lib/3scale_toolbox/tasks/update_service_settings_task.rb +0 -49
@@ -0,0 +1,57 @@
1
+ module ThreeScaleToolbox
2
+ module Commands
3
+ module ApplicationCommand
4
+ module Delete
5
+ class DeleteSubcommand < Cri::CommandRunner
6
+ include ThreeScaleToolbox::Command
7
+
8
+ def self.command
9
+ Cri::Command.define do
10
+ name 'delete'
11
+ usage 'delete [opts] <remote> <application>'
12
+ summary 'delete application'
13
+ description <<-HEREDOC
14
+ Delete application'
15
+ \n Application param allows:
16
+ \n * Application internal id
17
+ \n * User_key (API key)
18
+ \n * App_id (from app_id/app_key pair)
19
+ \n * Client ID (for OAuth and OpenID Connect authentication modes)
20
+ HEREDOC
21
+
22
+ param :remote
23
+ param :application_ref
24
+
25
+ runner DeleteSubcommand
26
+ end
27
+ end
28
+
29
+ def run
30
+ application.delete
31
+ puts "Application id: #{application.id} deleted"
32
+ end
33
+
34
+ private
35
+
36
+ def application
37
+ @application ||= find_application
38
+ end
39
+
40
+ def find_application
41
+ Entities::Application.find(remote: remote, ref: application_ref).tap do |app|
42
+ raise ThreeScaleToolbox::Error, "Application #{application_ref} does not exist" if app.nil?
43
+ end
44
+ end
45
+
46
+ def remote
47
+ @remote ||= threescale_client(arguments[:remote])
48
+ end
49
+
50
+ def application_ref
51
+ arguments[:application_ref]
52
+ end
53
+ end
54
+ end
55
+ end
56
+ end
57
+ end
@@ -0,0 +1,124 @@
1
+ module ThreeScaleToolbox
2
+ module Commands
3
+ module ApplicationCommand
4
+ module List
5
+ class ListSubcommand < Cri::CommandRunner
6
+ include ThreeScaleToolbox::Command
7
+
8
+ FIELDS_TO_SHOW = %w[id name state enabled account_id service_id plan_id].freeze
9
+
10
+ def self.command
11
+ Cri::Command.define do
12
+ name 'list'
13
+ usage 'list [opts] <remote>'
14
+ summary 'list applications'
15
+ description 'List applications'
16
+
17
+ param :remote
18
+ option nil, :account, 'Filter by account', argument: :required
19
+ option nil, :service, 'Filter by service', argument: :required
20
+ option nil, :plan, 'Filter by application plan. Service option required', argument: :required
21
+
22
+ runner ListSubcommand
23
+ end
24
+ end
25
+
26
+ def run
27
+ validate_option_params
28
+
29
+ applications = if option_account
30
+ account.applications
31
+ elsif option_service && option_plan
32
+ plan.applications
33
+ elsif option_service
34
+ service.applications
35
+ else
36
+ provider_account_applications
37
+ end
38
+ print_header
39
+ print_data(applications)
40
+ end
41
+
42
+ private
43
+
44
+ def validate_option_params
45
+ raise ThreeScaleToolbox::Error, '--account and --service are mutually exclusive' \
46
+ if option_service && option_account
47
+
48
+ raise ThreeScaleToolbox::Error, '--plan requires --service option' \
49
+ if option_plan && option_service.nil?
50
+ end
51
+
52
+ def provider_account_applications
53
+ app_attrs_list = remote.list_applications
54
+ if app_attrs_list.respond_to?(:has_key?) && (errors = app_attrs_list['errors'])
55
+ raise ThreeScaleToolbox::ThreeScaleApiError.new('Provider account applications not read', errors)
56
+ end
57
+
58
+ app_attrs_list.map do |app_attrs|
59
+ Entities::Application.new(id: app_attrs.fetch('id'), remote: remote, attrs: app_attrs)
60
+ end
61
+ end
62
+
63
+ def option_service
64
+ options[:service]
65
+ end
66
+
67
+ def option_account
68
+ options[:account]
69
+ end
70
+
71
+ def option_plan
72
+ options[:plan]
73
+ end
74
+
75
+ def print_header
76
+ puts FIELDS_TO_SHOW.map(&:upcase).join("\t")
77
+ end
78
+
79
+ def print_data(applications)
80
+ applications.each do |app|
81
+ puts FIELDS_TO_SHOW.map { |field| app.attrs.fetch(field, '(empty)') }.join("\t")
82
+ end
83
+ end
84
+
85
+ def service
86
+ @service ||= find_service
87
+ end
88
+
89
+ def find_service
90
+ Entities::Service.find(remote: remote,
91
+ ref: option_service).tap do |svc|
92
+ raise ThreeScaleToolbox::Error, "Service #{option_service} does not exist" if svc.nil?
93
+ end
94
+ end
95
+
96
+ def account
97
+ @account ||= find_account
98
+ end
99
+
100
+ def find_account
101
+ Entities::Account.find(remote: remote,
102
+ ref: option_account).tap do |acc|
103
+ raise ThreeScaleToolbox::Error, "Account #{option_account} does not exist" if acc.nil?
104
+ end
105
+ end
106
+
107
+ def plan
108
+ @plan ||= find_plan
109
+ end
110
+
111
+ def find_plan
112
+ Entities::ApplicationPlan.find(service: service, ref: option_plan).tap do |plan|
113
+ raise ThreeScaleToolbox::Error, "Application plan #{option_plan} does not exist" if plan.nil?
114
+ end
115
+ end
116
+
117
+ def remote
118
+ @remote ||= threescale_client(arguments[:remote])
119
+ end
120
+ end
121
+ end
122
+ end
123
+ end
124
+ end
@@ -0,0 +1,72 @@
1
+ module ThreeScaleToolbox
2
+ module Commands
3
+ module ApplicationCommand
4
+ module Show
5
+ class ShowSubcommand < Cri::CommandRunner
6
+ include ThreeScaleToolbox::Command
7
+
8
+ FIELDS_TO_SHOW = %w[id name description state enabled account_id service_id plan_id
9
+ user_key application_id].freeze
10
+
11
+ def self.command
12
+ Cri::Command.define do
13
+ name 'show'
14
+ usage 'show [opts] <remote> <application>'
15
+ summary 'show application attributes'
16
+ description <<-HEREDOC
17
+ Show application attributes
18
+ \n Application param allows:
19
+ \n * Application internal id
20
+ \n * User_key (API key)
21
+ \n * App_id (from app_id/app_key pair)
22
+ \n * Client ID (for OAuth and OpenID Connect authentication modes)
23
+ HEREDOC
24
+
25
+ param :remote
26
+ param :application
27
+
28
+ runner ShowSubcommand
29
+ end
30
+ end
31
+
32
+ def run
33
+ print_header
34
+ print_data
35
+ end
36
+
37
+ private
38
+
39
+ def print_header
40
+ puts FIELDS_TO_SHOW.map(&:upcase).join("\t")
41
+ end
42
+
43
+ def print_data
44
+ puts FIELDS_TO_SHOW.map { |field| app_attrs.fetch(field, '(empty)') }.join("\t")
45
+ end
46
+
47
+ def app_attrs
48
+ @app_attrs ||= application.attrs
49
+ end
50
+
51
+ def application
52
+ @application ||= find_application
53
+ end
54
+
55
+ def find_application
56
+ Entities::Application.find(remote: remote, ref: application_ref).tap do |app|
57
+ raise ThreeScaleToolbox::Error, "Application #{application_ref} does not exist" if app.nil?
58
+ end
59
+ end
60
+
61
+ def application_ref
62
+ arguments[:application]
63
+ end
64
+
65
+ def remote
66
+ @remote ||= threescale_client(arguments[:remote])
67
+ end
68
+ end
69
+ end
70
+ end
71
+ end
72
+ end
@@ -7,45 +7,64 @@ module ThreeScaleToolbox
7
7
  def self.command
8
8
  Cri::Command.define do
9
9
  name 'service'
10
- usage 'service [opts] -s <src> -d <dst> <service_id>'
10
+ usage 'service [opts] -s <src> -d <dst> <source-service>'
11
11
  summary 'copy service'
12
- description 'will create a new services, copy existing proxy settings, metrics, methods, application plans and mapping rules.'
12
+ description <<-HEREDOC
13
+ This command makes a copy of the referenced service.
14
+ Target service will be searched by source service system name. System name can be overriden with `--target_system_name` option.
15
+ If a service with the selected `system_name` is not found, it will be created.
16
+ \n Components of the service being copied:
17
+ \nservice settings
18
+ \nproxy settings
19
+ \npricing rules
20
+ \nactivedocs
21
+ \nmetrics
22
+ \nmethods
23
+ \napplication plans
24
+ \nmapping rules
25
+ HEREDOC
13
26
 
14
27
  option :s, :source, '3scale source instance. Url or remote name', argument: :required
15
28
  option :d, :destination, '3scale target instance. Url or remote name', argument: :required
16
29
  option :t, 'target_system_name', 'Target system name. Default to source system name', argument: :required
17
- param :service_id
30
+ flag :f, :force, 'Overwrites the mapping rules by deleting all rules from target service first'
31
+ flag :r, 'rules-only', 'Only mapping rules are copied'
32
+ param :source_service
18
33
 
19
34
  runner CopyServiceSubcommand
20
35
  end
21
36
  end
22
37
 
23
38
  def run
24
- source = fetch_required_option(:source)
25
- destination = fetch_required_option(:destination)
39
+ target_service = Entities::Service.find(remote: target_remote,
40
+ ref: target_service_ref)
41
+ if target_service.nil?
42
+ target_service = Entities::Service.create(remote: target_remote,
43
+ service_params: create_service_attrs)
44
+ end
26
45
 
27
- source_service = Entities::Service.new(id: arguments[:service_id],
28
- remote: threescale_client(source))
29
- target_service = create_new_service(source_service.attrs, destination)
30
46
  puts "new service id #{target_service.id}"
47
+
31
48
  context = create_context(source_service, target_service)
32
- tasks = [
33
- Tasks::CopyMethodsTask.new(context),
34
- Tasks::CopyMetricsTask.new(context),
35
- Tasks::CopyApplicationPlansTask.new(context),
36
- Tasks::CopyLimitsTask.new(context),
37
- Tasks::DestroyMappingRulesTask.new(context),
38
- Tasks::CopyMappingRulesTask.new(context),
39
- Tasks::CopyPoliciesTask.new(context),
40
- Tasks::CopyPricingRulesTask.new(context),
41
- Tasks::CopyActiveDocsTask.new(context),
42
- # Copy proxy must be the last task
43
- # Proxy update is the mechanism to increase version of the proxy,
44
- # Hence propagating (mapping rules, poicies, oidc, auth) update to
45
- # latest proxy config, making available to gateway.
46
- Tasks::CopyServiceProxyTask.new(context),
47
- ]
49
+
50
+ tasks = []
51
+ unless option_rules_only
52
+ tasks << Tasks::CopyServiceSettingsTask.new(context)
53
+ tasks << Tasks::CopyServiceProxyTask.new(context)
54
+ tasks << Tasks::CopyMethodsTask.new(context)
55
+ tasks << Tasks::CopyMetricsTask.new(context)
56
+ tasks << Tasks::CopyApplicationPlansTask.new(context)
57
+ tasks << Tasks::CopyLimitsTask.new(context)
58
+ tasks << Tasks::CopyPoliciesTask.new(context)
59
+ tasks << Tasks::CopyPricingRulesTask.new(context)
60
+ tasks << Tasks::CopyActiveDocsTask.new(context)
61
+ end
62
+ tasks << Tasks::DestroyMappingRulesTask.new(context) if option_force
63
+ tasks << Tasks::CopyMappingRulesTask.new(context)
48
64
  tasks.each(&:call)
65
+
66
+ # This should be the last step
67
+ Tasks::BumpProxyVersionTask.new(service: target_service).call
49
68
  end
50
69
 
51
70
  private
@@ -57,10 +76,60 @@ module ThreeScaleToolbox
57
76
  }
58
77
  end
59
78
 
60
- def create_new_service(service, destination)
61
- Entities::Service.create(remote: threescale_client(destination),
62
- service: service,
63
- system_name: options[:target_system_name] || service['system_name'])
79
+ def option_rules_only
80
+ options[:'rules-only']
81
+ end
82
+
83
+ def option_force
84
+ options[:force]
85
+ end
86
+
87
+ def option_target_system_name
88
+ options[:target_system_name]
89
+ end
90
+
91
+ def create_service_attrs
92
+ # minimum required attrs.
93
+ # Service settings will be updated in later task
94
+ # These attrs are only when service is created
95
+ {
96
+ 'name' => source_service.attrs.fetch('name'),
97
+ 'system_name' => target_service_ref
98
+ }.compact
99
+ end
100
+
101
+ def source_service
102
+ @source_service ||= find_source_service
103
+ end
104
+
105
+ def find_source_service
106
+ Entities::Service.find(remote: source_remote, ref: source_service_ref).tap do |svc|
107
+ raise ThreeScaleToolbox::Error, "Service #{source_service_ref} does not exist" if svc.nil?
108
+ end
109
+ end
110
+
111
+ def source_remote
112
+ @source_remote ||= threescale_client(source)
113
+ end
114
+
115
+ def target_remote
116
+ @target_remote ||= threescale_client(target)
117
+ end
118
+
119
+ def source_service_ref
120
+ arguments[:source_service]
121
+ end
122
+
123
+ def target_service_ref
124
+ option_target_system_name || source_service.attrs.fetch('system_name')
125
+ end
126
+
127
+ def source
128
+ fetch_required_option(:source)
129
+ end
130
+
131
+ def target
132
+ fetch_required_option(:destination)
64
133
  end
65
134
  end
66
135
  end
@@ -35,7 +35,7 @@ module ThreeScaleToolbox
35
35
  data = CSV.read file_path
36
36
  headings = data.shift
37
37
  services = {}
38
- stats = { services: 0, metrics: 0, methods: 0 , mapping_rules: 0 }
38
+ stats = { services: 0, metrics: 0, methods: 0, mapping_rules: 0 }
39
39
 
40
40
  # prepare services data
41
41
  data.each do |row|
@@ -69,17 +69,16 @@ module ThreeScaleToolbox
69
69
  end
70
70
 
71
71
  services[service_name][:items].each do |item|
72
-
73
72
  metric, method = {}
74
73
 
75
74
  case item['type']
76
75
  # create a metric
77
76
  when 'metric'
78
77
  metric = client.create_metric(service['id'], {
79
- system_name: item['endpoint_system_name'],
80
- friendly_name: item['endpoint_name'],
81
- unit: 'unit'
82
- })
78
+ system_name: item['endpoint_system_name'],
79
+ friendly_name: item['endpoint_name'],
80
+ unit: 'unit'
81
+ })
83
82
 
84
83
  if metric['errors'].nil?
85
84
  stats[:metrics] += 1
@@ -90,10 +89,10 @@ module ThreeScaleToolbox
90
89
  # create a method
91
90
  when 'method'
92
91
  method = client.create_method(service['id'], hits_metric['id'], {
93
- system_name: item['endpoint_system_name'],
94
- friendly_name: item['endpoint_name'],
95
- unit: 'unit'
96
- })
92
+ system_name: item['endpoint_system_name'],
93
+ friendly_name: item['endpoint_name'],
94
+ unit: 'unit'
95
+ })
97
96
 
98
97
  if method['errors'].nil?
99
98
  stats[:methods] += 1
@@ -106,13 +105,13 @@ module ThreeScaleToolbox
106
105
  # create a mapping rule
107
106
  if (metric_id = metric['id'] || method['id'])
108
107
  mapping_rule = client.create_mapping_rule(service['id'], {
109
- metric_id: metric_id,
110
- pattern: item['endpoint_path'],
111
- http_method: item['endpoint_http_method'],
112
- metric_system_name: item['endpoint_system_name'],
113
- auth_app_key: auth_app_key_according_service(service),
114
- delta: 1
115
- })
108
+ metric_id: metric_id,
109
+ pattern: item['endpoint_path'],
110
+ http_method: item['endpoint_http_method'],
111
+ metric_system_name: item['endpoint_system_name'],
112
+ auth_app_key: auth_app_key_according_service(service),
113
+ delta: 1
114
+ })
116
115
 
117
116
  if mapping_rule['errors'].nil?
118
117
  stats[:mapping_rules] += 1