hammer_cli 0.0.18 → 0.1.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 (66) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +3 -314
  3. data/bin/hammer +45 -6
  4. data/config/cli.modules.d/module_config_template.yml +4 -0
  5. data/config/cli_config.template.yml +9 -11
  6. data/doc/developer_docs.md +1 -0
  7. data/doc/i18n.md +85 -0
  8. data/doc/installation.md +321 -0
  9. data/lib/hammer_cli.rb +3 -0
  10. data/lib/hammer_cli/abstract.rb +15 -24
  11. data/lib/hammer_cli/apipie/command.rb +13 -7
  12. data/lib/hammer_cli/apipie/options.rb +14 -16
  13. data/lib/hammer_cli/apipie/read_command.rb +6 -1
  14. data/lib/hammer_cli/apipie/resource.rb +48 -58
  15. data/lib/hammer_cli/apipie/write_command.rb +5 -1
  16. data/lib/hammer_cli/completer.rb +77 -21
  17. data/lib/hammer_cli/connection.rb +44 -0
  18. data/lib/hammer_cli/exception_handler.rb +15 -4
  19. data/lib/hammer_cli/exceptions.rb +6 -0
  20. data/lib/hammer_cli/i18n.rb +95 -0
  21. data/lib/hammer_cli/logger.rb +3 -3
  22. data/lib/hammer_cli/main.rb +12 -11
  23. data/lib/hammer_cli/modules.rb +19 -6
  24. data/lib/hammer_cli/options/normalizers.rb +42 -7
  25. data/lib/hammer_cli/options/option_definition.rb +2 -2
  26. data/lib/hammer_cli/output.rb +1 -0
  27. data/lib/hammer_cli/output/adapter/abstract.rb +20 -0
  28. data/lib/hammer_cli/output/adapter/base.rb +49 -78
  29. data/lib/hammer_cli/output/adapter/csv.rb +5 -5
  30. data/lib/hammer_cli/output/adapter/table.rb +41 -10
  31. data/lib/hammer_cli/output/dsl.rb +1 -1
  32. data/lib/hammer_cli/output/field_filter.rb +21 -0
  33. data/lib/hammer_cli/output/fields.rb +44 -78
  34. data/lib/hammer_cli/output/formatters.rb +38 -0
  35. data/lib/hammer_cli/settings.rb +28 -6
  36. data/lib/hammer_cli/shell.rb +58 -57
  37. data/lib/hammer_cli/utils.rb +14 -0
  38. data/lib/hammer_cli/validator.rb +5 -5
  39. data/lib/hammer_cli/version.rb +1 -1
  40. data/locale/Makefile +64 -0
  41. data/locale/hammer-cli.pot +203 -0
  42. data/locale/zanata.xml +29 -0
  43. data/test/unit/apipie/command_test.rb +42 -25
  44. data/test/unit/apipie/read_command_test.rb +10 -7
  45. data/test/unit/apipie/write_command_test.rb +9 -8
  46. data/test/unit/completer_test.rb +206 -21
  47. data/test/unit/connection_test.rb +68 -0
  48. data/test/unit/fixtures/apipie/architectures.json +153 -0
  49. data/test/unit/fixtures/apipie/documented.json +79 -0
  50. data/test/unit/fixtures/json_input/invalid.json +12 -0
  51. data/test/unit/fixtures/json_input/valid.json +12 -0
  52. data/test/unit/history_test.rb +71 -0
  53. data/test/unit/main_test.rb +9 -0
  54. data/test/unit/modules_test.rb +22 -6
  55. data/test/unit/options/field_filter_test.rb +27 -0
  56. data/test/unit/options/normalizers_test.rb +53 -0
  57. data/test/unit/output/adapter/base_test.rb +162 -10
  58. data/test/unit/output/adapter/csv_test.rb +16 -3
  59. data/test/unit/output/adapter/table_test.rb +97 -13
  60. data/test/unit/output/dsl_test.rb +74 -6
  61. data/test/unit/output/fields_test.rb +93 -62
  62. data/test/unit/output/formatters_test.rb +47 -0
  63. data/test/unit/settings_test.rb +35 -4
  64. data/test/unit/utils_test.rb +45 -0
  65. metadata +85 -4
  66. data/test/unit/apipie/fake_api.rb +0 -101
@@ -11,3 +11,4 @@ Contents:
11
11
  - [Creating ApiPie commands](creating_apipie_commands.md#creating-commands-for-restful-api-with-apipie)
12
12
  - [Development tips](development_tips.md#development-tips)
13
13
  - [Option normalizers](option_normalizers.md#option-normalizers)
14
+ - [Internacionalization](i18n.md#internacionalization)
@@ -0,0 +1,85 @@
1
+ Internacionalization
2
+ --------------------
3
+
4
+ Hammer uses [fast gettext](https://github.com/grosser/fast_gettext) for string translations. Most of the localization magic
5
+ is done for you in hammer already. If you want your plugin to support i18n it needs to register it's translation domain
6
+ at hammer's i18n module:
7
+ ```ruby
8
+ require 'hammer_cli/i18n'
9
+
10
+ # namespace your i18n module
11
+ module HammerCLIAwesome
12
+ module I18n
13
+
14
+ # create a locale domain for your plugin
15
+ class LocaleDomain < HammerCLI::I18n::LocaleDomain
16
+
17
+ # lists all your source files that use _()
18
+ def translated_files
19
+ Dir.glob(File.join(File.dirname(__FILE__), '../**/*.rb'))
20
+ end
21
+
22
+ # returns path to your locale directory
23
+ # it's typically "locale" in the root of your plugin
24
+ def locale_dir
25
+ File.join(File.dirname(__FILE__), '../../locale')
26
+ end
27
+
28
+ # name for your language domain
29
+ def domain_name
30
+ 'hammer-cli-awesome'
31
+ end
32
+
33
+ # type of the translation files, 'mo' files are default
34
+ # you can also use 'po' and 'yaml' files for testing purposes
35
+ def type
36
+ :mo
37
+ end
38
+
39
+ end
40
+
41
+ end
42
+ end
43
+
44
+ # register the domain
45
+ HammerCLI::I18n.add_domain(HammerCLIAwesomePlugin::I18n::LocaleDomain.new)
46
+ ```
47
+
48
+ Then you have to export strings, translate them and place the files in a directory structure.
49
+ Inspiration on how to export the translations can be found in the hammer's [Rakefile](../Rakefile).
50
+
51
+ Typical directory structure for translation files look like this:
52
+ ```
53
+ locale
54
+ ├── de
55
+ │   ├── hammer-cli-awesome.po
56
+ │   └── LC_MESSAGES
57
+ │   └── hammer-cli-awesome.mo
58
+ ├── en
59
+ │   ├── hammer-cli-awesome.po
60
+ │   └── LC_MESSAGES
61
+ │   └── hammer-cli-awesome.mo
62
+ └── hammer-cli-awesome.pot
63
+ ```
64
+
65
+
66
+ ### Translation tips
67
+
68
+ When writing a code with translations make sure you keep two following rules:
69
+
70
+ 1) Don't use variables directly in the strings and make formatting substitutions outside the gettext function `_("...")`.
71
+ ```ruby
72
+ # WRONG
73
+ puts _("Hello #{name}")
74
+ puts _("Hello %s" % name)
75
+ # CORRECT
76
+ puts _("Hello %s") % name
77
+ ```
78
+
79
+ 2) Use named placeholders when there is more than one replacement. Languages differ in their word order.
80
+ ```ruby
81
+ # WRONG
82
+ puts _("Hello %s, it is %s" % [name, day])
83
+ # CORRECT
84
+ puts _("Hello %{name}, it is %{day}") % {:name => name, :day => day}
85
+ ```
@@ -0,0 +1,321 @@
1
+ Installation
2
+ ------------
3
+
4
+ Hammer CLI is packaged for the following RPM based distributions:
5
+
6
+ - RHEL and derivatives, version 6
7
+ - Fedora 18, 19
8
+ - Debian Wheezy, Squeezy
9
+ - Ubuntu Precise
10
+
11
+ ### Installation from RPMs
12
+
13
+ #### Step 1: setup yum repositories
14
+
15
+ For Foreman 1.3 stable the hammer packages are part of your installation repo and you can skip this step.
16
+
17
+ You can choose from stable or nightly repo. Nightly has more recent version of hammer packages, but it was subject to less testing so there is a higher risk of issues.
18
+ Add the Foreman yum repository to your yum repo files. For Fedora installations replace 'el6' with 'f18' or 'f19' as appropriate.
19
+
20
+
21
+ Using stable
22
+
23
+ ```bash
24
+ yum -y install http://yum.theforeman.org/releases/1.3/el6/x86_64/foreman-release.rpm
25
+ ```
26
+
27
+ or nightly
28
+
29
+ ```bash
30
+ cat > /etc/yum.repos.d/foreman.repo << EOF
31
+ [foreman]
32
+ name=Foreman Nightly
33
+ baseurl=http://yum.theforeman.org/nightly/el6/x86_64
34
+ gpgcheck=0
35
+ enabled=1
36
+ EOF
37
+ ```
38
+
39
+ On RHEL systems you will also have to add [EPEL repository](https://fedoraproject.org/wiki/EPEL) as it contains some of the required dependencies.
40
+
41
+
42
+ #### Step 2: install hammer core
43
+
44
+ ```bash
45
+ yum install rubygem-hammer_cli
46
+ ```
47
+
48
+ #### Step 3: install plugins
49
+ Currently, there are two plugins, both available as rpm packages.
50
+
51
+ - commands for managing foreman
52
+
53
+ ```bash
54
+ yum install rubygem-hammer_cli_foreman
55
+ ```
56
+
57
+ - commands for katello [katello cli](https://github.com/Katello/katello)
58
+
59
+ ```bash
60
+ yum install rubygem-hammer_cli_katello
61
+ ```
62
+
63
+ To install any other hammer plugin just make sure the appropriate gem is installed and follow with the configuration.
64
+
65
+
66
+ ### Installation from DEBs
67
+
68
+ #### Step 1: setup apt repositories
69
+
70
+ For Foreman 1.3 stable the hammer packages are part of your installation repo and you can skip this step.
71
+
72
+ You can choose from stable or nightly repo. Nightly has more recent version of hammer packages, but it was subject to less testing so there is a highr risk of issues.
73
+
74
+ Choose stable (don't forget to replace "squeeze" with version name of your system)
75
+
76
+ ```bash
77
+ echo "deb http://deb.theforeman.org/ squeeze stable" > /etc/apt/sources.list.d/foreman.list
78
+ ```
79
+
80
+ or nightly
81
+
82
+ ```bash
83
+ echo "deb http://deb.theforeman.org/ squeeze nightly" > /etc/apt/sources.list.d/foreman.list
84
+ ```
85
+
86
+ and update the keys
87
+
88
+ ```bash
89
+ wget -q http://deb.theforeman.org/foreman.asc -O- | apt-key add -
90
+ ```
91
+
92
+ #### Step 2: install hammer core
93
+
94
+ ```bash
95
+ apt-get update && apt-get install ruby-hammer-cli
96
+ ```
97
+
98
+ #### Step 3: install plugins
99
+ Currently, there are two plugins, both available as deb packages.
100
+
101
+ - commands for managing foreman
102
+
103
+ ```bash
104
+ $ apt-get install ruby-hammer-cli-foreman
105
+ ```
106
+
107
+ - 1:1 bridge to [katello cli](https://github.com/Katello/katello)
108
+
109
+ ```bash
110
+ $ apt-get install ruby-hammer-cli-katello
111
+ ```
112
+
113
+ To install any other hammer plugin just make sure the appropriate gem is installed and follow with the configuration.
114
+
115
+
116
+ ### Installation from GEMs
117
+
118
+ Make sure you have ```gem``` command installed on your system
119
+
120
+ #### Step 1: install hammer core
121
+
122
+ ```bash
123
+ $ gem install hammer_cli
124
+ ```
125
+
126
+ #### Step 2: install plugins
127
+ Currently, there are two plugins, both available on rubygems.org
128
+
129
+ - commands for managing foreman
130
+
131
+ ```bash
132
+ $ gem install hammer_cli_foreman
133
+ ```
134
+
135
+ - 1:1 bridge to [katello cli](https://github.com/Katello/katello)
136
+
137
+ ```bash
138
+ $ gem install hammer_cli_katello
139
+ ```
140
+
141
+ To install any other hammer plugin just install the appropriate gem and follow with the configuration.
142
+
143
+
144
+ ### Installation from SOURCE
145
+
146
+ If you can install hammer from git checkouts, you will just need ```rake``` installed on your system.
147
+ Clone and install CLI core
148
+
149
+ ```bash
150
+ $ git clone https://github.com/theforeman/hammer-cli.git
151
+ $ cd hammer-cli
152
+ $ rake install
153
+ $ cd ..
154
+ ```
155
+
156
+ clone plugin with foreman commands
157
+
158
+ ```bash
159
+ $ git clone https://github.com/theforeman/hammer-cli-foreman.git
160
+ $ cd hammer-cli-foreman
161
+ $ rake install
162
+ $ cd ..
163
+ ```
164
+
165
+ and optionally other plugins via any of the methods mentioned above.
166
+
167
+
168
+ Configuration
169
+ -------------
170
+
171
+ ### Locations
172
+
173
+ Configuration is by default looked for in the following directories, loaded in this order:
174
+
175
+ - ```RbConfig::CONFIG['sysconfdir']/hammer/``` (The actual value depends on your operatingsystem and ruby defaults.)
176
+ - ```/etc/hammer/```
177
+ - ```~/.hammer/```
178
+ - ```./config/``` (config dir in CWD)
179
+ - custom location (file or directory) specified on command line - ```-c CONF_FILE_PATH```
180
+
181
+ In each of these directories hammer is trying to load ```cli_config.yml``` and anything in
182
+ the ```cli.modules.d``` subdirectory which is place for specific configuration of hammer modules.
183
+
184
+ Later directories and files have precedence if they redefine the same option. Files from ```cli.modules.d```
185
+ are loaded in alphabetical order.
186
+
187
+ ### Format
188
+
189
+ Hammer uses yaml formatting for its configuration. The configuration templates are contained in the hammer_cli gem
190
+
191
+ ```bash
192
+ gem contents hammer_cli|grep template.yml
193
+ ```
194
+ and can be copied to one of the locations above and changed as needed. The packaged version of hammer copies the template to /etc for you.
195
+
196
+
197
+ ### Options
198
+
199
+ - ```:log_dir: <path>``` - directory where the logs are stored. The default is ```/var/log/hammer/``` and the log file is named ```hammer.log```
200
+ - ```:log_level: <level>``` - logging level. One of ```debug```, ```info```, ```warning```, ```error```, ```fatal```
201
+ - ```:log_owner: <owner>``` - logfile owner
202
+ - ```:log_group: <group>``` - logfile group
203
+ - ```:log_size: 1048576``` - size in bytes, when exceeded the log rotates. Default is 1MB
204
+ - ```:watch_plain: <bool>``` - turn on/off syntax highlighting of data being logged in debug mode
205
+ - ```:log_api_calls: <bool>``` - turn on logging of the communication with API (data sent and received)
206
+
207
+ In the ```:ui``` section there is
208
+
209
+ - ```:interactive: <bool>``` - whether to ask user for input (pagination, passwords)
210
+ - ```:per_page: <records>``` - number of records per page if server sends paginated data
211
+ - ```:history_file: <path>``` - file where the hammer shell store its history (default is ```~/.hammer_history```)
212
+
213
+
214
+ #### Sample config
215
+
216
+ ```yaml
217
+ :ui:
218
+ :interactive: true
219
+ :per_page: 20
220
+ :history_file: '~/.hammer/history'
221
+
222
+ :watch_plain: false
223
+
224
+ :log_dir: '~/.hammer/log'
225
+ :log_level: 'error'
226
+ :log_api_calls: false
227
+ ```
228
+
229
+ ### Plugins
230
+
231
+ Plugins are disabled by default. To enable plugin create configuration file in ```cli.modules.d``` and add```:enable_plugin: true``` in it. Plugin specific configuration should be nested under plugin's name (without the ```hammer_cli_``` prefix).
232
+
233
+ In the example we assume the gem ```hammer_cli_foreman``` with the Foreman plugin is installed. Then the plugin configuration
234
+ in ```~/.hammer/cli.plugins.d/foreman.yml``` should look as follows:
235
+
236
+ ```yaml
237
+ :foreman:
238
+ :enable_module: true
239
+ :host: 'https://localhost/'
240
+ :username: 'admin'
241
+ :password: 'changeme'
242
+ ```
243
+
244
+ Use the hammer
245
+ --------------
246
+
247
+ Confirm your setup by running ```$ hammer -h``` and check that the desired commands are listed.
248
+
249
+ ```
250
+ $ hammer -h
251
+ Usage:
252
+ hammer [OPTIONS] SUBCOMMAND [ARG] ...
253
+
254
+ Parameters:
255
+ SUBCOMMAND subcommand
256
+ [ARG] ... subcommand arguments
257
+
258
+ Subcommands:
259
+ activation-key Manipulate activation keys.
260
+ architecture Manipulate architectures.
261
+ compute_resource Manipulate compute resources.
262
+ domain Manipulate domains.
263
+ environment Manipulate environments.
264
+ fact Search facts.
265
+ global_parameter Manipulate global parameters.
266
+ gpg manipulate GPG Key actions on the server
267
+ host Manipulate hosts.
268
+ hostgroup Manipulate hostgroups.
269
+ lifecycle-environment manipulate lifecycle_environments on the server
270
+ location Manipulate locations.
271
+ medium Manipulate installation media.
272
+ model Manipulate hardware models.
273
+ organization Manipulate organizations
274
+ os Manipulate operating system.
275
+ partition_table Manipulate partition tables.
276
+ ping get the status of the server
277
+ product Manipulate products.
278
+ provider Manipulate providers
279
+ proxy Manipulate smart proxies.
280
+ puppet_class Search puppet modules.
281
+ report Browse and read reports.
282
+ repository Manipulate repositories
283
+ repository-set manipulate repository sets on the server
284
+ sc_param Manipulate smart class parameters.
285
+ shell Interactive shell
286
+ subnet Manipulate subnets.
287
+ subscription Manipulate subscriptions.
288
+ system manipulate systems on the server
289
+ systemgroup Manipulate system groups
290
+ task Tasks related actions.
291
+ template Manipulate config templates.
292
+ user Manipulate users.
293
+
294
+ Options:
295
+ --autocomplete LINE Get list of possible endings
296
+ --csv Output as CSV (same as --output=csv)
297
+ --csv-separator SEPARATOR Character to separate the values
298
+ --interactive INTERACTIVE Explicitly turn interactive mode on/off
299
+ One of true/false, yes/no, 1/0.
300
+ --output ADAPTER Set output format. One of [base, table, silent, csv]
301
+ --show-ids Show ids of associated resources
302
+ --version show version
303
+ -c, --config CFG_FILE path to custom config file
304
+ -h, --help print help
305
+ -p, --password PASSWORD password to access the remote system
306
+ -u, --username USERNAME username to access the remote system
307
+ -v, --verbose be verbose
308
+ ```
309
+
310
+
311
+ And you are Done. Your hammer client is configured and ready to use.
312
+
313
+
314
+ Autocompletion
315
+ --------------
316
+
317
+ It is necessary to copy the hammer_cli_complete script to the bash_completion.d directory.
318
+
319
+ $ sudo cp hammer-cli/hammer_cli_complete /etc/bash_completion.d/
320
+
321
+ Then after starting a new shell the completion should work.
@@ -1,8 +1,11 @@
1
+ require 'hammer_cli/i18n'
2
+ require 'hammer_cli/exceptions'
1
3
  require 'hammer_cli/utils'
2
4
  require 'hammer_cli/version'
3
5
  require 'hammer_cli/modules'
4
6
  require 'hammer_cli/exit_codes'
5
7
  require 'hammer_cli/settings'
8
+ require 'hammer_cli/connection'
6
9
  require 'hammer_cli/validator'
7
10
  require 'hammer_cli/output'
8
11
  require 'hammer_cli/options/normalizers'
@@ -87,6 +87,19 @@ module HammerCLI
87
87
  super
88
88
  end
89
89
 
90
+ class SortedBuilder < Clamp::Help::Builder
91
+ def add_list(heading, items)
92
+ items.sort! do |a, b|
93
+ a.help[0] <=> b.help[0]
94
+ end
95
+ super(heading, items)
96
+ end
97
+ end
98
+
99
+ def help
100
+ self.class.help(invocation_path, SortedBuilder.new)
101
+ end
102
+
90
103
  def self.output(definition=nil, &block)
91
104
  dsl = HammerCLI::Output::Dsl.new
92
105
  dsl.build &block if block_given?
@@ -116,35 +129,13 @@ module HammerCLI
116
129
  @output_definition
117
130
  end
118
131
 
119
- protected
120
132
 
121
133
  def interactive?
122
- if context[:interactive].nil?
123
- return STDOUT.tty? && (HammerCLI::Settings.get(:ui, :interactive) != false)
124
- else
125
- return context[:interactive]
126
- end
134
+ HammerCLI.interactive?
127
135
  end
128
136
 
129
- def ask_username
130
- ask("Username: ") if interactive?
131
- end
132
-
133
- def ask_password
134
- ask("Password for '%s': " % username) {|q| q.echo = false} if interactive?
135
- end
136
137
 
137
- def username(ask_interactively=true)
138
- context[:username] ||= ENV['FOREMAN_USERNAME'] || HammerCLI::Settings.get(:foreman, :username)
139
- context[:username] ||= ask_username if ask_interactively
140
- context[:username]
141
- end
142
-
143
- def password(ask_interactively=true)
144
- context[:password] ||= ENV['FOREMAN_PASSWORD'] || HammerCLI::Settings.get(:foreman, :password)
145
- context[:password] ||= ask_password if ask_interactively
146
- context[:password]
147
- end
138
+ protected
148
139
 
149
140
  def print_record(definition, record)
150
141
  output.print_record(definition, record)