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,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