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.
Files changed (51) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +143 -23
  3. data/exe/3scale +10 -3
  4. data/lib/3scale_toolbox.rb +18 -0
  5. data/lib/3scale_toolbox/3scale_client_factory.rb +33 -0
  6. data/lib/3scale_toolbox/base_command.rb +52 -14
  7. data/lib/3scale_toolbox/cli.rb +26 -5
  8. data/lib/3scale_toolbox/cli/error_handler.rb +120 -0
  9. data/lib/3scale_toolbox/commands.rb +3 -9
  10. data/lib/3scale_toolbox/commands/3scale_command.rb +8 -6
  11. data/lib/3scale_toolbox/commands/copy_command.rb +4 -4
  12. data/lib/3scale_toolbox/commands/copy_command/copy_service.rb +40 -193
  13. data/lib/3scale_toolbox/commands/help_command.rb +1 -1
  14. data/lib/3scale_toolbox/commands/import_command.rb +6 -4
  15. data/lib/3scale_toolbox/commands/import_command/import_csv.rb +15 -41
  16. data/lib/3scale_toolbox/commands/import_command/openapi.rb +70 -0
  17. data/lib/3scale_toolbox/commands/import_command/openapi/create_mapping_rule_step.rb +18 -0
  18. data/lib/3scale_toolbox/commands/import_command/openapi/create_method_step.rb +39 -0
  19. data/lib/3scale_toolbox/commands/import_command/openapi/create_service_step.rb +69 -0
  20. data/lib/3scale_toolbox/commands/import_command/openapi/mapping_rule.rb +35 -0
  21. data/lib/3scale_toolbox/commands/import_command/openapi/method.rb +25 -0
  22. data/lib/3scale_toolbox/commands/import_command/openapi/operation.rb +22 -0
  23. data/lib/3scale_toolbox/commands/import_command/openapi/resource_reader.rb +49 -0
  24. data/lib/3scale_toolbox/commands/import_command/openapi/step.rb +45 -0
  25. data/lib/3scale_toolbox/commands/import_command/openapi/threescale_api_spec.rb +33 -0
  26. data/lib/3scale_toolbox/commands/remote_command.rb +36 -0
  27. data/lib/3scale_toolbox/commands/remote_command/remote_add.rb +47 -0
  28. data/lib/3scale_toolbox/commands/remote_command/remote_list.rb +29 -0
  29. data/lib/3scale_toolbox/commands/remote_command/remote_remove.rb +26 -0
  30. data/lib/3scale_toolbox/commands/remote_command/remote_rename.rb +42 -0
  31. data/lib/3scale_toolbox/commands/update_command.rb +4 -4
  32. data/lib/3scale_toolbox/commands/update_command/update_service.rb +45 -235
  33. data/lib/3scale_toolbox/configuration.rb +35 -0
  34. data/lib/3scale_toolbox/entities.rb +1 -0
  35. data/lib/3scale_toolbox/entities/service.rb +113 -0
  36. data/lib/3scale_toolbox/error.rb +8 -0
  37. data/lib/3scale_toolbox/helper.rb +37 -0
  38. data/lib/3scale_toolbox/remotes.rb +93 -0
  39. data/lib/3scale_toolbox/tasks.rb +10 -0
  40. data/lib/3scale_toolbox/tasks/copy_app_plans_task.rb +31 -0
  41. data/lib/3scale_toolbox/tasks/copy_limits_task.rb +36 -0
  42. data/lib/3scale_toolbox/tasks/copy_mapping_rules_task.rb +29 -0
  43. data/lib/3scale_toolbox/tasks/copy_methods_task.rb +29 -0
  44. data/lib/3scale_toolbox/tasks/copy_metrics_task.rb +33 -0
  45. data/lib/3scale_toolbox/tasks/copy_service_proxy_task.rb +12 -0
  46. data/lib/3scale_toolbox/tasks/copy_task.rb +26 -0
  47. data/lib/3scale_toolbox/tasks/destroy_mapping_rules_task.rb +22 -0
  48. data/lib/3scale_toolbox/tasks/helper_task.rb +25 -0
  49. data/lib/3scale_toolbox/tasks/update_service_settings_task.rb +32 -0
  50. data/lib/3scale_toolbox/version.rb +1 -1
  51. metadata +87 -11
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: c162adffa46adcb9b43e88642bf1de4daaed45ae9db6abcaa93b388e56f9159a
4
- data.tar.gz: 481d3485a91d038c6c7af04d7609f9a907d3e8e30e3264c4cb43b2e0f15f2b8c
3
+ metadata.gz: ae4791c3e86318f973f54abefb9df823abc7efe7ede820ca736697b23cd10653
4
+ data.tar.gz: 68cb54b32c6286593464dc1d7302343684cd4d2df043e18a5b3ff777e61f2920
5
5
  SHA512:
6
- metadata.gz: 7faf8d5012d24d978a70d357fc1ff5aa9327edb67f4dc307cf8e32bfb3143b3bebe460238b6580a34b82220c8ea590877f3cd5ddc92eaee052a1bf9ec3c0484e
7
- data.tar.gz: 44b6c5e32f13eb98c1d2494d6b198374567b9cc5d6e0cd1f3461a88270f10a699e9228d4a32cc1d095a1c195cac081e30a0117896c3e7cf0993120130bbf3393
6
+ metadata.gz: f36923df1c9961cb9a209a6228ecc50cd5e00b8b1d853384e561b3280d59550125c1793124a95cc7a9553cc42bea4453e898de2135496858d11b200333811242
7
+ data.tar.gz: 955e042f2a2b8cc62c56ce8bcedaa4de8a7800a16f39dbb83e37a6969a178b13ff4fdf94104d8240d2b402ab488ce7eb44400fceba0d58c8c7af5ef94a310ef3
data/README.md CHANGED
@@ -8,13 +8,17 @@
8
8
  * [Copy a service](#copy-a-service)
9
9
  * [Update a service](#update-a-service)
10
10
  * [Import from CSV](#import-from-csv)
11
+ * [Import from OpenAPI definition](#import-openapi)
12
+ * [Remotes](#remotes)
11
13
  * [Development](#development)
14
+ * [Testing](#testing)
15
+ * [Develop your own core command](#develop-core-command)
12
16
  * [Plugins](#plugins)
13
17
  * [Troubleshooting](#troubleshooting)
14
18
  * [Contributing](#contributing)
15
19
 
16
20
  ## Installation
17
- Install the CLI:
21
+ Install the toolbox:
18
22
 
19
23
  $ gem install 3scale_toolbox
20
24
 
@@ -23,28 +27,34 @@ Install the CLI:
23
27
  ```shell
24
28
  $ 3scale help
25
29
  NAME
26
- 3scale - 3scale CLI Toolbox
30
+ 3scale - 3scale toolbox
27
31
 
28
32
  USAGE
29
- 3scale <command> [options]
33
+ 3scale <sub-command> [options]
30
34
 
31
35
  DESCRIPTION
32
- 3scale CLI tools to manage your API from the terminal.
36
+ 3scale toolbox to manage your API from the terminal.
33
37
 
34
38
  COMMANDS
35
- copy 3scale copy command
39
+ copy copy super command
36
40
  help show help
37
- import 3scale import command
38
- update 3scale update command
41
+ import import super command
42
+ remote remotes super command
43
+ update update super command
39
44
 
40
45
  OPTIONS
41
- -k --insecure Proceed and operate even for server connections
42
- otherwise considered insecure
43
- -v --version Prints the version of this command
46
+ -c --config-file=<value> 3scale toolbox configuration file (default:
47
+ /home/eguzki/.3scalerc.yaml)
48
+ -h --help show help for this command
49
+ -k --insecure Proceed and operate even for server
50
+ connections otherwise considered insecure
51
+ -v --version Prints the version of this command
44
52
  ```
45
53
 
46
54
  ### Copy a service
47
- Will create a new services, copy existing proxy settings, metrics, methods, application plans and mapping rules.
55
+ Will create a new service, copy existing proxy settings, metrics, methods, application plans and mapping rules.
56
+
57
+ 3scale instances can be either a [URL](docs/remotes.md#remote-urls) or the name of a [remote](docs/remotes.md).
48
58
 
49
59
  Help message:
50
60
 
@@ -62,10 +72,10 @@ DESCRIPTION
62
72
  methods, application plans and mapping rules.
63
73
 
64
74
  OPTIONS
65
- -d --destination=<value> 3scale target instance. Format:
66
- "http[s]://<provider_key>@3scale_url"
67
- -s --source=<value> 3scale source instance. Format:
68
- "http[s]://<provider_key>@3scale_url"
75
+ -d --destination=<value> 3scale target instance. Url or
76
+ remote name
77
+ -s --source=<value> 3scale source instance. Url or
78
+ remote name
69
79
  -t --target_system_name=<value> Target system name
70
80
 
71
81
  OPTIONS FOR COPY
@@ -77,13 +87,15 @@ OPTIONS FOR COPY
77
87
  ```
78
88
 
79
89
  ```shell
80
- 3scale copy service NUMBER --source=https://provider_key@foo-admin.3scale.net --destination=https://provider_key@foo2-admin.3scale.net
90
+ 3scale copy service NUMBER --source=foo --destination=https://access_token@foo2-admin.3scale.net
81
91
  ```
82
92
 
83
93
  ### Update a service
84
94
 
85
95
  Will update existing service, update proxy settings, metrics, methods, application plans and mapping rules.
86
96
 
97
+ 3scale instances can be either a [URL](docs/remotes.md#remote-urls) or the name of a [remote](docs/remotes.md).
98
+
87
99
  Help message:
88
100
 
89
101
  ```shell
@@ -99,13 +111,13 @@ DESCRIPTION
99
111
  application plans and mapping rules.
100
112
 
101
113
  OPTIONS
102
- -d --destination=<value> 3scale target instance. Format:
103
- "http[s]://<provider_key>@3scale_url"
114
+ -d --destination=<value> 3scale target instance. Url or
115
+ remote name
104
116
  -f --force Overwrites the mapping rules by deleting
105
117
  all rules from target service first
106
118
  -r --rules-only Updates only the mapping rules
107
- -s --source=<value> 3scale source instance. Format:
108
- "http[s]://<provider_key>@3scale_url"
119
+ -s --source=<value> 3scale source instance. Url or
120
+ remote name
109
121
 
110
122
  OPTIONS FOR UPDATE
111
123
  -h --help show help for this command
@@ -117,13 +129,15 @@ OPTIONS FOR UPDATE
117
129
  Example:
118
130
 
119
131
  ```shell
120
- $ 3scale update service -s https://9874598743@source.example.com -d https://2342342342342@destination.example.com 3 2
132
+ $ 3scale update service -s https://9874598743@source.example.com -d foo 3 2
121
133
  ```
122
134
 
123
135
  ### Import from CSV
124
136
 
125
137
  Will create new services, metrics, methods, and mapping rules having as source comma separated values (CSV) formatted file.
126
138
 
139
+ 3scale instances can be either a [URL](docs/remotes.md#remote-urls) or the name of a [remote](docs/remotes.md).
140
+
127
141
  CSV header
128
142
 
129
143
  ```csv
@@ -153,8 +167,7 @@ DESCRIPTION
153
167
  formatted file
154
168
 
155
169
  OPTIONS
156
- -d --destination=<value> 3scale target instance. Format:
157
- "http[s]://<provider_key>@3scale_url"
170
+ -d --destination=<value> 3scale target instance. Url or remote name
158
171
  -f --file=<value> CSV formatted file
159
172
 
160
173
  OPTIONS FOR IMPORT
@@ -170,12 +183,119 @@ Example:
170
183
  3scale import csv --destination=https://provider_key@user-admin.3scale.net --file=examples/import_example.csv
171
184
  ```
172
185
 
186
+ ### Import OpenAPI
187
+
188
+ Using an API definition format like OpenAPI, import to your 3scale API
189
+
190
+ Currently, only OpenAPI __2.0__ specification (f.k.a. __swagger__) is supported.
191
+
192
+ [Import from OpenAPI](docs/openapi.md)
193
+
194
+ ### Remotes
195
+
196
+ Manage set of 3scale instances.
197
+
198
+ [Howto](docs/remotes.md)
199
+
173
200
  ## Development
174
201
 
175
202
  After checking out the repo, run `bin/setup` to install dependencies. You can also run `bin/console` for an interactive prompt that will allow you to experiment. Run `bundle exec 3scale` to use the gem in this directory, ignoring other installed copies of this gem.
176
203
 
177
204
  To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and tags, and push the `.gem` file to [rubygems.org](https://rubygems.org).
178
205
 
206
+ ### Testing
207
+
208
+ To run all tests run `rake`.
209
+
210
+ There are two kinds of tests:
211
+ * unit (see [spec/unit](spec/unit))
212
+ ```bash
213
+ rake spec:unit
214
+ ```
215
+
216
+ * integration (see [spec/integration](spec/integration)).
217
+ ```bash
218
+ rake spec:integration
219
+ ```
220
+
221
+ Integration tests can be run locally or against a real 3scale account.
222
+ When details of the account are set via environment variables,
223
+ integration tests are run agains given account.
224
+ Otherwise, tests are run locally with mocked 3scale clients.
225
+
226
+ The easiest way to set everything up is it to have a `.env` file in the root of the project with the following environment variables (set your own values):
227
+
228
+ ```
229
+ ENDPOINT=https://your-domain-admin.3scaledomain
230
+ PROVIDER_KEY=abc123
231
+ VERIFY_SSL=true (by default true)
232
+ ```
233
+ ### Develop Core Command
234
+
235
+ Very simple core command to list existing services.
236
+ Helps to illustrate basic command code structure and helper methods to deal with remotes.
237
+
238
+ ```
239
+ $ cat lib/3scale_toolbox/commands/service_list_command.rb
240
+ module ThreeScaleToolbox
241
+ module Commands
242
+ class ServiceListCommand < Cri::CommandRunner
243
+ include ThreeScaleToolbox::Command
244
+
245
+ def self.command
246
+ Cri::Command.define do
247
+ name 'service_list'
248
+ usage 'service_list <3scale_remote>'
249
+ summary 'service list'
250
+ description 'list available services'
251
+ param :remote
252
+ runner ServiceListCommand
253
+ end
254
+ end
255
+
256
+ def run
257
+ puts threescale_client(arguments[:remote]).list_services
258
+ end
259
+ end
260
+ end
261
+ end
262
+ ```
263
+ A few things worth highlighting:
264
+ - Your module must include the *ThreeScaleToolbox::Command* module. It allows your command to be added to the toobox command tree.
265
+ - You must implement the `command` module function and return an instance of `Cri::Command` from [cri](https://github.com/ddfreyne/cri)
266
+ - `threescale_client` helper method returns *3scale API* client instance. All the process remote parsing, fetching from remote list and client instantiation is done out of the box.
267
+
268
+ Then register the core command in `lib/3scale_toolbox/commands.rb`
269
+ ```
270
+ --- a/lib/3scale_toolbox/commands.rb
271
+ +++ b/lib/3scale_toolbox/commands.rb
272
+ @@ -4,6 +4,7 @@ require '3scale_toolbox/commands/copy_command'
273
+ require '3scale_toolbox/commands/import_command'
274
+ require '3scale_toolbox/commands/update_command'
275
+ require '3scale_toolbox/commands/remote_command'
276
+ +require '3scale_toolbox/commands/service_list_command'
277
+
278
+ module ThreeScaleToolbox
279
+ module Commands
280
+ @@ -12,7 +13,8 @@ module ThreeScaleToolbox
281
+ ThreeScaleToolbox::Commands::CopyCommand,
282
+ ThreeScaleToolbox::Commands::ImportCommand,
283
+ ThreeScaleToolbox::Commands::UpdateCommand,
284
+ - ThreeScaleToolbox::Commands::RemoteCommand::RemoteCommand
285
+ + ThreeScaleToolbox::Commands::RemoteCommand::RemoteCommand,
286
+ + ThreeScaleToolbox::Commands::ServiceListCommand
287
+ ].freeze
288
+ end
289
+ end
290
+ ```
291
+
292
+ Running the new core command:
293
+
294
+ ```shell
295
+ $ 3scale service_list my-3scale-instance
296
+ { ... }
297
+ ```
298
+
179
299
  ## Plugins
180
300
 
181
301
  As of 3scale Toolbox 0.5.0, 3scale Toolbox will load plugins installed in gems or $LOAD_PATH. Plugins are discovered via Gem::find_files then loaded.
data/exe/3scale CHANGED
@@ -1,8 +1,15 @@
1
1
  #!/usr/bin/env ruby
2
2
 
3
- require '3scale_toolbox'
4
- require '3scale_toolbox/cli'
3
+ def suppress_warnings
4
+ original_verbosity = $VERBOSE
5
+ $VERBOSE = nil
6
+ yield
7
+ ensure
8
+ $VERBOSE = original_verbosity
9
+ end
10
+
11
+ suppress_warnings { require '3scale_toolbox' }
5
12
 
6
13
  args = ARGV.clone
7
14
 
8
- ThreeScaleToolbox::CLI.run args
15
+ exit(ThreeScaleToolbox::CLI.run(args))
@@ -1,4 +1,17 @@
1
+ require '3scale_toolbox/version'
2
+ require '3scale_toolbox/helper'
3
+ require '3scale_toolbox/error'
4
+ require '3scale_toolbox/configuration'
5
+ require '3scale_toolbox/remotes'
6
+ require '3scale_toolbox/3scale_client_factory'
7
+ require '3scale_toolbox/entities'
8
+ require '3scale_toolbox/tasks'
9
+ require '3scale_toolbox/base_command'
10
+ require '3scale_toolbox/commands'
11
+ require '3scale_toolbox/cli'
12
+
1
13
  module ThreeScaleToolbox
14
+
2
15
  def self.load_plugins
3
16
  plugin_paths.each { |plugin_path| require plugin_path }
4
17
  end
@@ -6,4 +19,9 @@ module ThreeScaleToolbox
6
19
  def self.plugin_paths
7
20
  Gem.find_files('3scale_toolbox_plugin')
8
21
  end
22
+
23
+ def self.default_config_file
24
+ # THREESCALE_CLI_CONFIG env var has priority over $HOME/.3scalerc.yaml file
25
+ ENV['THREESCALE_CLI_CONFIG'] || File.join(Gem.user_home, '.3scalerc.yaml')
26
+ end
9
27
  end
@@ -0,0 +1,33 @@
1
+ module ThreeScaleToolbox
2
+ class ThreeScaleClientFactory
3
+ class << self
4
+ def get(remotes, remote_str, verify_ssl)
5
+ new(remotes, remote_str, verify_ssl).call
6
+ end
7
+ end
8
+
9
+ attr_reader :remotes, :remote_str, :verify_ssl
10
+
11
+ def initialize(remotes, remote_str, verify_ssl)
12
+ @remotes = remotes
13
+ @remote_str = remote_str
14
+ @verify_ssl = verify_ssl
15
+ end
16
+
17
+ def call
18
+ begin
19
+ remote = Remotes.from_uri(remote_str)
20
+ rescue InvalidUrlError
21
+ remote = remotes.fetch(remote_str)
22
+ end
23
+
24
+ remote_client(remote.merge(verify_ssl: verify_ssl))
25
+ end
26
+
27
+ private
28
+
29
+ def remote_client(endpoint:, authentication:, verify_ssl:)
30
+ ThreeScale::API.new(endpoint: endpoint, provider_key: authentication, verify_ssl: verify_ssl)
31
+ end
32
+ end
33
+ end
@@ -1,28 +1,66 @@
1
1
 
2
2
  module ThreeScaleToolbox
3
3
  module Command
4
- def subcommands
5
- @subcommands ||= []
4
+ def self.included(base)
5
+ base.extend(ClassMethods)
6
6
  end
7
7
 
8
- def add_subcommand(command)
9
- subcommands << command
8
+ module ClassMethods
9
+ def subcommands
10
+ @subcommands ||= []
11
+ end
12
+
13
+ def add_subcommand(command)
14
+ subcommands << command
15
+ end
16
+
17
+ ##
18
+ # Override to command
19
+ #
20
+ def command
21
+ raise Exception, 'base command has no command definition'
22
+ end
23
+
24
+ ##
25
+ # Iterate recursively over command tree
26
+ #
27
+ def build_command
28
+ subcommands.each_with_object(command) do |subcommand, root_command|
29
+ root_command.add_command(subcommand.build_command)
30
+ end
31
+ end
10
32
  end
11
33
 
12
- ##
13
- # Override to command
14
- #
15
- def command
16
- raise Exception, 'base command has no command definition'
34
+ def config
35
+ @config ||= ThreeScaleToolbox::Configuration.new(config_file)
36
+ end
37
+
38
+ def config_file
39
+ options[:'config-file']
40
+ end
41
+
42
+ def remotes
43
+ @remotes ||= Remotes.new(config)
17
44
  end
18
45
 
19
46
  ##
20
- # Iterate recursively over command tree
47
+ # Input param can be endpoint url or remote name
21
48
  #
22
- def build_command
23
- subcommands.each_with_object(command) do |subcommand, root_command|
24
- root_command.add_command(subcommand.build_command)
25
- end
49
+ def threescale_client(str)
50
+ ThreeScaleClientFactory.get(remotes, str, verify_ssl)
51
+ end
52
+
53
+ def verify_ssl
54
+ # this is flag. It is either true or false. Cannot be nil
55
+ !options[:insecure]
56
+ end
57
+
58
+ def exit_with_message(message)
59
+ raise ThreeScaleToolbox::Error, message
60
+ end
61
+
62
+ def fetch_required_option(key)
63
+ options.fetch(key) { exit_with_message "error: Missing argument #{key}" }
26
64
  end
27
65
  end
28
66
  end
@@ -1,5 +1,4 @@
1
- require '3scale_toolbox'
2
- require '3scale_toolbox/commands'
1
+ require '3scale_toolbox/cli/error_handler'
3
2
 
4
3
  module ThreeScaleToolbox::CLI
5
4
  def self.root_command
@@ -14,9 +13,31 @@ module ThreeScaleToolbox::CLI
14
13
  ThreeScaleToolbox::Commands::BUILTIN_COMMANDS.each(&method(:add_command))
15
14
  end
16
15
 
16
+ def self.install_signal_handlers
17
+ # Set exit handler
18
+ %w[INT TERM].each do |signal|
19
+ Signal.trap(signal) do
20
+ puts
21
+ exit!(0)
22
+ end
23
+ end
24
+
25
+ # Set stack trace dump handler
26
+ if !defined?(RUBY_ENGINE) || RUBY_ENGINE != 'jruby'
27
+ Signal.trap('USR1') do
28
+ puts 'Caught USR1; dumping a stack trace'
29
+ puts caller.map { |i| " #{i}" }.join("\n")
30
+ end
31
+ end
32
+ end
33
+
17
34
  def self.run(args)
18
- load_builtin_commands
19
- ThreeScaleToolbox.load_plugins
20
- root_command.build_command.run args
35
+ install_signal_handlers
36
+ err = ErrorHandler.error_watchdog do
37
+ load_builtin_commands
38
+ ThreeScaleToolbox.load_plugins
39
+ root_command.build_command.run args
40
+ end
41
+ err.nil? ? 0 : 1
21
42
  end
22
43
  end