3scale_toolbox 0.10.0 → 0.11.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.
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,50 @@
1
+ module ThreeScaleToolbox
2
+ module Commands
3
+ module ServiceCommand
4
+ module List
5
+ class ListSubcommand < Cri::CommandRunner
6
+ include ThreeScaleToolbox::Command
7
+
8
+ def self.command
9
+ Cri::Command.define do
10
+ name 'list'
11
+ usage 'list <remote>'
12
+ summary 'List all services'
13
+ description 'List all services'
14
+ runner ListSubcommand
15
+
16
+ param :remote
17
+ end
18
+ end
19
+
20
+ def run
21
+ print_header
22
+ print_data
23
+ end
24
+
25
+ private
26
+
27
+ SERVICE_FIELDS_TO_SHOW = %w[id name system_name]
28
+
29
+ def services
30
+ @services ||= remote.list_services()
31
+ end
32
+
33
+ def remote
34
+ @remote ||= threescale_client(arguments[:remote])
35
+ end
36
+
37
+ def print_header
38
+ puts SERVICE_FIELDS_TO_SHOW.map { |e| e.upcase }.join("\t")
39
+ end
40
+
41
+ def print_data
42
+ services.each do |service|
43
+ puts SERVICE_FIELDS_TO_SHOW.map { |field| service.fetch(field, '(empty)') }.join("\t")
44
+ end
45
+ end
46
+ end
47
+ end
48
+ end
49
+ end
50
+ end
@@ -0,0 +1,63 @@
1
+ module ThreeScaleToolbox
2
+ module Commands
3
+ module ServiceCommand
4
+ module Show
5
+ class ShowSubcommand < Cri::CommandRunner
6
+ include ThreeScaleToolbox::Command
7
+
8
+ def self.command
9
+ Cri::Command.define do
10
+ name 'show'
11
+ usage 'show <remote> <service-id_or_system-name>'
12
+ summary 'Show the information of a service'
13
+ description "Show the information of a service"
14
+ runner ShowSubcommand
15
+
16
+ param :remote
17
+ param :service_id_or_system_name
18
+ end
19
+ end
20
+
21
+ def run
22
+ print_header
23
+ print_data
24
+ end
25
+
26
+ private
27
+
28
+ SERVICE_FIELDS_TO_SHOW = %w[
29
+ id name state system_name end_user_registration_required
30
+ backend_version deployment_option support_email description
31
+ created_at updated_at
32
+ ]
33
+
34
+ def remote
35
+ @remote ||= threescale_client(arguments[:remote])
36
+ end
37
+
38
+ def ref
39
+ @ref ||= arguments[:service_id_or_system_name]
40
+ end
41
+
42
+ def service
43
+ @service ||= find_service
44
+ end
45
+
46
+ def find_service
47
+ Entities::Service::find(remote: remote, ref: ref).tap do |svc|
48
+ raise ThreeScaleToolbox::Error, "Service #{ref} does not exist" if svc.nil?
49
+ end
50
+ end
51
+
52
+ def print_header
53
+ puts SERVICE_FIELDS_TO_SHOW.map { |e| e.upcase }.join("\t")
54
+ end
55
+
56
+ def print_data
57
+ puts SERVICE_FIELDS_TO_SHOW.map { |field| service.attrs.fetch(field, '(empty)') }.join("\t")
58
+ end
59
+ end
60
+ end
61
+ end
62
+ end
63
+ end
@@ -8,8 +8,11 @@ module ThreeScaleToolbox
8
8
  Cri::Command.define do
9
9
  name 'service'
10
10
  usage 'service [opts] -s <src> -d <dst> <src_service_id> <dst_service_id>'
11
- summary 'update service'
12
- description 'Update existing service, update proxy settings, metrics, methods, application plans and mapping rules.'
11
+ summary '[DEPRECTATED] update service'
12
+ description <<-HEREDOC
13
+ This command has been deprecated. Use '3scale copy service' instead.
14
+ \n Update existing service, update proxy settings, metrics, methods, application plans and mapping rules.'
15
+ HEREDOC
13
16
 
14
17
  option :s, :source, '3scale source instance. Url or remote name', argument: :required
15
18
  option :d, :destination, '3scale target instance. Url or remote name', argument: :required
@@ -37,7 +40,7 @@ module ThreeScaleToolbox
37
40
 
38
41
  tasks = []
39
42
  unless options[:'rules-only']
40
- tasks << Tasks::UpdateServiceSettingsTask.new(context.merge(target_name: system_name))
43
+ tasks << Tasks::CopyServiceSettingsTask.new(context)
41
44
  tasks << Tasks::CopyMethodsTask.new(context)
42
45
  tasks << Tasks::CopyMetricsTask.new(context)
43
46
  tasks << Tasks::CopyApplicationPlansTask.new(context)
@@ -2,3 +2,7 @@ require '3scale_toolbox/entities/service'
2
2
  require '3scale_toolbox/entities/application_plan'
3
3
  require '3scale_toolbox/entities/metric'
4
4
  require '3scale_toolbox/entities/method'
5
+ require '3scale_toolbox/entities/activedocs'
6
+ require '3scale_toolbox/entities/account'
7
+ require '3scale_toolbox/entities/proxy_config'
8
+ require '3scale_toolbox/entities/application'
@@ -0,0 +1,63 @@
1
+ require '3scale_toolbox/entities/base_entity'
2
+
3
+ module ThreeScaleToolbox
4
+ module Entities
5
+ class Account
6
+ include ThreeScaleToolbox::Entities::Entity
7
+ PRINTABLE_VARS = %w[id org_name].freeze
8
+ VERBOSE_PRINTABLE_VARS = %w[
9
+ id org_name created_at updated_at admin_domain domain from_email
10
+ support_email finance_support_email monthly_billing_enabled
11
+ monthly_charging_enabled
12
+ ].freeze
13
+ public_constant :PRINTABLE_VARS
14
+ public_constant :VERBOSE_PRINTABLE_VARS
15
+
16
+ class << self
17
+ def find(remote:, ref:)
18
+ new(id: ref, remote: remote).tap(&:attrs)
19
+ rescue ThreeScale::API::HttpClient::NotFoundError
20
+ find_by_text(ref, remote)
21
+ end
22
+
23
+ def find_by_text(text, client)
24
+ account = client.find_account(email: text, buyer_provider_key: text,
25
+ buyer_service_token: text)
26
+ if (errors = account['errors'])
27
+ raise ThreeScaleToolbox::ThreeScaleApiError.new(
28
+ 'Account find returned errors', errors
29
+ )
30
+ end
31
+ new(id: account['id'], remote: client, attrs: account)
32
+ rescue ThreeScale::API::HttpClient::NotFoundError
33
+ nil
34
+ end
35
+ end
36
+
37
+ def attrs
38
+ @attrs ||= account_attrs
39
+ end
40
+
41
+ def applications
42
+ app_attrs_list = remote.list_account_applications(id)
43
+ if app_attrs_list.respond_to?(:has_key?) && (errors = app_attrs_list['errors'])
44
+ raise ThreeScaleToolbox::ThreeScaleApiError.new('Account applications not read', errors)
45
+ end
46
+
47
+ app_attrs_list.map do |app_attrs|
48
+ Entities::Application.new(id: app_attrs.fetch('id'), remote: remote, attrs: app_attrs)
49
+ end
50
+ end
51
+
52
+ private
53
+
54
+ def account_attrs
55
+ remote.show_account(id).tap do |account|
56
+ if (errors = account['errors'])
57
+ raise ThreeScaleToolbox::ThreeScaleApiError.new('Account attrs not read', errors)
58
+ end
59
+ end
60
+ end
61
+ end
62
+ end
63
+ end
@@ -0,0 +1,88 @@
1
+ module ThreeScaleToolbox
2
+ module Entities
3
+ class ActiveDocs
4
+ class << self
5
+ def create(remote:, attrs:)
6
+ activedocs_res = create_activedocs(remote: remote, attrs: attrs)
7
+ new(id: activedocs_res.fetch('id'), remote: remote, attrs: activedocs_res)
8
+ end
9
+
10
+ # ref can be system_name or activedocs_id
11
+ def find(remote:, ref:)
12
+ new(id: ref, remote: remote).tap(&:attrs)
13
+ rescue ThreeScaleToolbox::ActiveDocsNotFoundError
14
+ find_by_system_name(remote: remote, system_name: ref)
15
+ end
16
+
17
+ def find_by_system_name(remote:, system_name:)
18
+ activedocs_list = remote.list_activedocs
19
+
20
+ if activedocs_list.respond_to?(:has_key?) && (errors = activedocs_list['errors'])
21
+ raise ThreeScaleToolbox::ThreeScaleApiError.new('ActiveDocs list not read', errors)
22
+ end
23
+
24
+ res_attrs = activedocs_list.find { |svc| svc['system_name'] == system_name }
25
+ return if res_attrs.nil?
26
+
27
+ new(id: res_attrs.fetch('id'), remote: remote, attrs: res_attrs)
28
+ end
29
+
30
+ private
31
+
32
+ def create_activedocs(remote:, attrs:)
33
+ activedocs_res = remote.create_activedocs(attrs)
34
+ if (errors = activedocs_res['errors'])
35
+ raise ThreeScaleToolbox::ThreeScaleApiError.new('ActiveDocs has not been created', errors)
36
+ end
37
+
38
+ activedocs_res
39
+ end
40
+ end
41
+
42
+ attr_reader :id, :remote
43
+
44
+ def initialize(id:, remote:, attrs: nil)
45
+ @id = id
46
+ @remote = remote
47
+ @attrs = attrs
48
+ end
49
+
50
+ def attrs
51
+ @attrs ||= activedoc_attrs
52
+ end
53
+
54
+ def delete
55
+ remote.delete_activedocs id
56
+ end
57
+
58
+ def update(a_attrs)
59
+ new_attrs = remote.update_activedocs(id, a_attrs)
60
+ if (errors = new_attrs['errors'])
61
+ raise ThreeScaleToolbox::ThreeScaleApiError.new('ActiveDocs has not been updated', errors)
62
+ end
63
+
64
+ # update current attrs
65
+ @attrs = new_attrs
66
+
67
+ new_attrs
68
+ end
69
+
70
+ private
71
+
72
+ def activedoc_attrs
73
+ activedocs_list = remote.list_activedocs
74
+
75
+ if activedocs_list.respond_to?(:has_key?) && (errors = activedocs_list['errors'])
76
+ raise ThreeScaleToolbox::ThreeScaleApiError.new('ActiveDocs list not read', errors)
77
+ end
78
+
79
+ res_attrs = activedocs_list.find { |adocs| adocs.fetch('id') == id }
80
+ if res_attrs.nil?
81
+ raise ThreeScaleToolbox::ActiveDocsNotFoundError.new(id)
82
+ end
83
+
84
+ res_attrs
85
+ end
86
+ end
87
+ end
88
+ end
@@ -0,0 +1,124 @@
1
+ module ThreeScaleToolbox
2
+ module Entities
3
+ class Application
4
+ class << self
5
+ def create(remote:, account_id:, plan_id:, app_attrs: nil)
6
+ attrs = remote.create_application(account_id, app_attrs, plan_id: plan_id)
7
+ if (errors = attrs['errors'])
8
+ raise ThreeScaleToolbox::ThreeScaleApiError.new('Application has not been created', errors)
9
+ end
10
+
11
+ new(id: attrs.fetch('id'), remote: remote, attrs: attrs)
12
+ end
13
+
14
+ # ref can be
15
+ # * Application internal id
16
+ # * User_key (API key)
17
+ # * App_id (from app_id/app_key pair)
18
+ # * Client ID (for OAuth and OpenID Connect authentication modes)
19
+ def find(remote:, ref:)
20
+ app = find_by_user_key(remote, ref)
21
+ return app unless app.nil?
22
+
23
+ app = find_by_app_id(remote, ref)
24
+ return app unless app.nil?
25
+
26
+ app = find_by_id(remote, ref)
27
+ return app unless app.nil?
28
+
29
+ nil
30
+ end
31
+
32
+ def find_by_id(remote, id)
33
+ generic_find(remote, :id, id)
34
+ end
35
+
36
+ def find_by_user_key(remote, user_key)
37
+ generic_find(remote, :user_key, user_key)
38
+ end
39
+
40
+ def find_by_app_id(remote, app_id)
41
+ generic_find(remote, :application_id, app_id)
42
+ end
43
+
44
+ private
45
+
46
+ def generic_find(remote, type, ref)
47
+ # find_application criteria only accepts one parameter.
48
+ # Otherwise unexpected behavior
49
+ attrs = remote.find_application(type => ref)
50
+ if (errors = attrs['errors'])
51
+ raise ThreeScaleToolbox::ThreeScaleApiError.new('Application find error', errors)
52
+ end
53
+
54
+ new(id: attrs.fetch('id'), remote: remote, attrs: attrs)
55
+ rescue ThreeScale::API::HttpClient::NotFoundError
56
+ nil
57
+ end
58
+ end
59
+
60
+ attr_reader :id, :remote
61
+
62
+ def initialize(id:, remote:, attrs: nil)
63
+ @id = id
64
+ @remote = remote
65
+ @attrs = attrs
66
+ end
67
+
68
+ def attrs
69
+ @attrs ||= application_attrs
70
+ end
71
+
72
+ def update(app_attrs)
73
+ new_attrs = remote.update_application(account_id, id, app_attrs)
74
+ if (errors = new_attrs['errors'])
75
+ raise ThreeScaleToolbox::ThreeScaleApiError.new('Application has not been updated', errors)
76
+ end
77
+
78
+ @attrs = new_attrs
79
+
80
+ new_attrs
81
+ end
82
+
83
+ def resume
84
+ new_attrs = remote.resume_application(account_id, id)
85
+ if (errors = new_attrs['errors'])
86
+ raise ThreeScaleToolbox::ThreeScaleApiError.new('Application has not been resumed', errors)
87
+ end
88
+
89
+ @attrs = new_attrs
90
+
91
+ new_attrs
92
+ end
93
+
94
+ def suspend
95
+ new_attrs = remote.suspend_application(account_id, id)
96
+ if (errors = new_attrs['errors'])
97
+ raise ThreeScaleToolbox::ThreeScaleApiError.new('Application has not been suspended', errors)
98
+ end
99
+
100
+ @attrs = new_attrs
101
+
102
+ new_attrs
103
+ end
104
+
105
+ def delete
106
+ remote.delete_application account_id, id
107
+ end
108
+
109
+ private
110
+
111
+ def account_id
112
+ attrs.fetch('account_id')
113
+ end
114
+
115
+ def application_attrs
116
+ remote.show_application(id).tap do |application|
117
+ if (errors = application['errors'])
118
+ raise ThreeScaleToolbox::ThreeScaleApiError.new('Application attrs not read', errors)
119
+ end
120
+ end
121
+ end
122
+ end
123
+ end
124
+ end
@@ -3,7 +3,7 @@ module ThreeScaleToolbox
3
3
  class ApplicationPlan
4
4
  class << self
5
5
  def create(service:, plan_attrs:)
6
- plan = service.remote.create_application_plan service.id, build_plan_attrs(plan_attrs)
6
+ plan = service.remote.create_application_plan service.id, create_plan_attrs(plan_attrs)
7
7
  if (errors = plan['errors'])
8
8
  raise ThreeScaleToolbox::ThreeScaleApiError.new('Application plan has not been created', errors)
9
9
  end
@@ -25,14 +25,13 @@ module ThreeScaleToolbox
25
25
  new(id: plan.fetch('id'), service: service, attrs: plan)
26
26
  end
27
27
 
28
- def build_plan_attrs(source_attrs)
28
+ def create_plan_attrs(source_attrs)
29
29
  # shallow copy is enough
30
30
  source_attrs.clone.tap do |new_plan_attrs|
31
31
  # plans are created by default in hidden state
32
32
  # If published is required, 'state_event' attr has to be added
33
33
  state = new_plan_attrs.delete('state')
34
34
  new_plan_attrs['state_event'] = 'publish' if state == 'published'
35
- new_plan_attrs['state_event'] = 'hide' if state == 'hidden'
36
35
  end
37
36
  end
38
37
  end
@@ -52,7 +51,7 @@ module ThreeScaleToolbox
52
51
 
53
52
  def update(plan_attrs)
54
53
  new_attrs = remote.update_application_plan(service.id, id,
55
- self.class.build_plan_attrs(plan_attrs))
54
+ update_plan_attrs(plan_attrs))
56
55
  if (errors = new_attrs['errors'])
57
56
  raise ThreeScaleToolbox::ThreeScaleApiError.new('Application plan has not been updated', errors)
58
57
  end
@@ -160,6 +159,17 @@ module ThreeScaleToolbox
160
159
  remote.delete_application_plan service.id, id
161
160
  end
162
161
 
162
+ def applications
163
+ app_attrs_list = remote.list_applications(service_id: service.id, plan_id: id)
164
+ if app_attrs_list.respond_to?(:has_key?) && (errors = app_attrs_list['errors'])
165
+ raise ThreeScaleToolbox::ThreeScaleApiError.new('Plan applications not read', errors)
166
+ end
167
+
168
+ app_attrs_list.map do |app_attrs|
169
+ Entities::Application.new(id: app_attrs.fetch('id'), remote: remote, attrs: app_attrs)
170
+ end
171
+ end
172
+
163
173
  private
164
174
 
165
175
  def read_plan_attrs
@@ -171,6 +181,20 @@ module ThreeScaleToolbox
171
181
  plan_attrs
172
182
  end
173
183
 
184
+ def update_plan_attrs(source_attrs)
185
+ # shallow copy is enough
186
+ source_attrs.clone.tap do |new_plan_attrs|
187
+ new_plan_attrs.delete('id')
188
+ new_plan_attrs.delete('links')
189
+ new_plan_attrs.delete('system_name')
190
+ # plans are created by default in hidden state
191
+ # If published is required, 'state_event' attr has to be added
192
+ state = new_plan_attrs.delete('state')
193
+ new_plan_attrs['state_event'] = 'publish' if state == 'published'
194
+ new_plan_attrs['state_event'] = 'hide' if state == 'hidden'
195
+ end
196
+ end
197
+
174
198
  def eternity_zero_limits
175
199
  limits.select { |limit| zero_eternity_limit_attrs < limit }
176
200
  end