3scale_toolbox 0.5.1 → 0.6.0

Sign up to get free protection for your applications and to get access to all the features.
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