hammer_cli 0.9.0 → 0.10.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (225) hide show
  1. checksums.yaml +4 -4
  2. data/bin/hammer +22 -1
  3. data/config/cli_config.template.yml +20 -0
  4. data/doc/release_notes.md +7 -0
  5. data/lib/hammer_cli/abstract.rb +12 -15
  6. data/lib/hammer_cli/apipie/api_connection.rb +3 -1
  7. data/lib/hammer_cli/ca_cert_fetcher.rb +67 -0
  8. data/lib/hammer_cli/defaults.rb +18 -10
  9. data/lib/hammer_cli/exception_handler.rb +44 -5
  10. data/lib/hammer_cli/main.rb +8 -0
  11. data/lib/hammer_cli/options/option_collector.rb +22 -0
  12. data/lib/hammer_cli/options/sources/command_line.rb +18 -0
  13. data/lib/hammer_cli/options/sources/saved_defaults.rb +31 -0
  14. data/lib/hammer_cli/output/adapter/table.rb +66 -87
  15. data/lib/hammer_cli/output/fields.rb +1 -1
  16. data/lib/hammer_cli/ssloptions.rb +65 -0
  17. data/lib/hammer_cli/version.rb +1 -1
  18. data/locale/ca/LC_MESSAGES/hammer-cli.mo +0 -0
  19. data/locale/de/LC_MESSAGES/hammer-cli.mo +0 -0
  20. data/locale/en/LC_MESSAGES/hammer-cli.mo +0 -0
  21. data/locale/en_GB/LC_MESSAGES/hammer-cli.mo +0 -0
  22. data/locale/es/LC_MESSAGES/hammer-cli.mo +0 -0
  23. data/locale/fr/LC_MESSAGES/hammer-cli.mo +0 -0
  24. data/locale/it/LC_MESSAGES/hammer-cli.mo +0 -0
  25. data/locale/ja/LC_MESSAGES/hammer-cli.mo +0 -0
  26. data/locale/ko/LC_MESSAGES/hammer-cli.mo +0 -0
  27. data/locale/pt_BR/LC_MESSAGES/hammer-cli.mo +0 -0
  28. data/locale/ru/LC_MESSAGES/hammer-cli.mo +0 -0
  29. data/locale/zh_CN/LC_MESSAGES/hammer-cli.mo +0 -0
  30. data/locale/zh_TW/LC_MESSAGES/hammer-cli.mo +0 -0
  31. data/man/hammer.1.gz +0 -0
  32. data/test/unit/abstract_test.rb +34 -0
  33. data/test/unit/apipie/api_connection_test.rb +3 -2
  34. data/test/unit/defaults_test.rb +15 -5
  35. data/test/unit/fixtures/defaults/defaults.yml +2 -0
  36. data/test/unit/options/option_collector_test.rb +29 -0
  37. data/test/unit/options/sources/command_line_test.rb +36 -0
  38. data/test/unit/options/sources/saved_defaults_test.rb +59 -0
  39. data/test/unit/output/adapter/table_test.rb +0 -27
  40. data/test/unit/{options → output}/field_filter_test.rb +0 -0
  41. data/test/unit/output/fields_test.rb +9 -6
  42. data/test/unit/validator_test.rb +0 -6
  43. metadata +60 -382
  44. data/lib/hammer_cli/table_print/column.rb +0 -19
  45. data/lib/hammer_cli/table_print/formatter.rb +0 -18
  46. data/locale/Makefile +0 -57
  47. data/locale/README.md +0 -18
  48. data/locale/ca/hammer-cli.edit.po +0 -445
  49. data/locale/ca/hammer-cli.po +0 -361
  50. data/locale/ca/hammer-cli.po.time_stamp +0 -0
  51. data/locale/de/hammer-cli.edit.po +0 -451
  52. data/locale/de/hammer-cli.po +0 -379
  53. data/locale/de/hammer-cli.po.time_stamp +0 -0
  54. data/locale/en/hammer-cli.edit.po +0 -443
  55. data/locale/en/hammer-cli.po +0 -355
  56. data/locale/en/hammer-cli.po.time_stamp +0 -0
  57. data/locale/en_GB/hammer-cli.edit.po +0 -445
  58. data/locale/en_GB/hammer-cli.po +0 -371
  59. data/locale/en_GB/hammer-cli.po.time_stamp +0 -0
  60. data/locale/es/hammer-cli.edit.po +0 -448
  61. data/locale/es/hammer-cli.po +0 -377
  62. data/locale/es/hammer-cli.po.time_stamp +0 -0
  63. data/locale/fr/hammer-cli.edit.po +0 -447
  64. data/locale/fr/hammer-cli.po +0 -374
  65. data/locale/fr/hammer-cli.po.time_stamp +0 -0
  66. data/locale/hammer-cli.pot +0 -461
  67. data/locale/it/hammer-cli.edit.po +0 -446
  68. data/locale/it/hammer-cli.po +0 -377
  69. data/locale/it/hammer-cli.po.time_stamp +0 -0
  70. data/locale/ja/hammer-cli.edit.po +0 -445
  71. data/locale/ja/hammer-cli.po +0 -363
  72. data/locale/ja/hammer-cli.po.time_stamp +0 -0
  73. data/locale/ko/hammer-cli.edit.po +0 -445
  74. data/locale/ko/hammer-cli.po +0 -364
  75. data/locale/ko/hammer-cli.po.time_stamp +0 -0
  76. data/locale/pt_BR/hammer-cli.edit.po +0 -449
  77. data/locale/pt_BR/hammer-cli.po +0 -374
  78. data/locale/pt_BR/hammer-cli.po.time_stamp +0 -0
  79. data/locale/ru/hammer-cli.edit.po +0 -448
  80. data/locale/ru/hammer-cli.po +0 -374
  81. data/locale/ru/hammer-cli.po.time_stamp +0 -0
  82. data/locale/zanata.xml +0 -28
  83. data/locale/zh_CN/hammer-cli.edit.po +0 -445
  84. data/locale/zh_CN/hammer-cli.po +0 -367
  85. data/locale/zh_CN/hammer-cli.po.time_stamp +0 -0
  86. data/locale/zh_TW/hammer-cli.edit.po +0 -445
  87. data/locale/zh_TW/hammer-cli.po +0 -364
  88. data/locale/zh_TW/hammer-cli.po.time_stamp +0 -0
  89. data/test/reports/TEST-Fields-ContainerField-display-.xml +0 -7
  90. data/test/reports/TEST-Fields-ContainerField-display-blank-is-allowed.xml +0 -15
  91. data/test/reports/TEST-Fields-ContainerField-display-blank-is-not-allowed.xml +0 -15
  92. data/test/reports/TEST-Fields-ContainerField.xml +0 -7
  93. data/test/reports/TEST-Fields-Field-display-.xml +0 -7
  94. data/test/reports/TEST-Fields-Field-display-blank-is-allowed.xml +0 -11
  95. data/test/reports/TEST-Fields-Field-display-blank-is-not-allowed.xml +0 -11
  96. data/test/reports/TEST-Fields-Field-hide-blank-.xml +0 -11
  97. data/test/reports/TEST-Fields-Field-parameters.xml +0 -9
  98. data/test/reports/TEST-Fields-Field.xml +0 -13
  99. data/test/reports/TEST-HammerCLI-AbstractCommand-build-options.xml +0 -15
  100. data/test/reports/TEST-HammerCLI-AbstractCommand-exception-handler.xml +0 -13
  101. data/test/reports/TEST-HammerCLI-AbstractCommand-logging.xml +0 -21
  102. data/test/reports/TEST-HammerCLI-AbstractCommand-option-builder.xml +0 -11
  103. data/test/reports/TEST-HammerCLI-AbstractCommand-options.xml +0 -11
  104. data/test/reports/TEST-HammerCLI-AbstractCommand-output.xml +0 -19
  105. data/test/reports/TEST-HammerCLI-AbstractCommand-subcommand-behavior-remove-subcommand.xml +0 -11
  106. data/test/reports/TEST-HammerCLI-AbstractCommand-subcommand-behavior-subcommand-.xml +0 -13
  107. data/test/reports/TEST-HammerCLI-AbstractCommand-subcommand-behavior-subcommand.xml +0 -11
  108. data/test/reports/TEST-HammerCLI-AbstractCommand-subcommand-behavior.xml +0 -7
  109. data/test/reports/TEST-HammerCLI-AbstractCommand.xml +0 -11
  110. data/test/reports/TEST-HammerCLI-Apipie-Command-options.xml +0 -11
  111. data/test/reports/TEST-HammerCLI-Apipie-Command-resource-defined.xml +0 -9
  112. data/test/reports/TEST-HammerCLI-Apipie-Command-setting-resources.xml +0 -19
  113. data/test/reports/TEST-HammerCLI-Apipie-Command.xml +0 -9
  114. data/test/reports/TEST-HammerCLI-Apipie-OptionBuilder-aliasing-resources.xml +0 -13
  115. data/test/reports/TEST-HammerCLI-Apipie-OptionBuilder-filtering-options.xml +0 -15
  116. data/test/reports/TEST-HammerCLI-Apipie-OptionBuilder-required-options.xml +0 -11
  117. data/test/reports/TEST-HammerCLI-Apipie-OptionBuilder-setting-correct-normalizers.xml +0 -9
  118. data/test/reports/TEST-HammerCLI-Apipie-OptionBuilder-with-hash-params.xml +0 -11
  119. data/test/reports/TEST-HammerCLI-Apipie-OptionBuilder-with-one-simple-param.xml +0 -15
  120. data/test/reports/TEST-HammerCLI-Apipie-OptionBuilder.xml +0 -7
  121. data/test/reports/TEST-HammerCLI-Completer-command-completion.xml +0 -29
  122. data/test/reports/TEST-HammerCLI-Completer-option-value-completion.xml +0 -17
  123. data/test/reports/TEST-HammerCLI-Completer-subcommand-completion.xml +0 -19
  124. data/test/reports/TEST-HammerCLI-Completer.xml +0 -7
  125. data/test/reports/TEST-HammerCLI-CompleterLine-line-complete.xml +0 -25
  126. data/test/reports/TEST-HammerCLI-CompleterLine-splitting-words.xml +0 -29
  127. data/test/reports/TEST-HammerCLI-CompleterLine.xml +0 -7
  128. data/test/reports/TEST-HammerCLI-CompleterWord-complete-.xml +0 -23
  129. data/test/reports/TEST-HammerCLI-CompleterWord-quote.xml +0 -15
  130. data/test/reports/TEST-HammerCLI-CompleterWord-quoted-.xml +0 -13
  131. data/test/reports/TEST-HammerCLI-CompleterWord.xml +0 -7
  132. data/test/reports/TEST-HammerCLI-Connection.xml +0 -21
  133. data/test/reports/TEST-HammerCLI-ExceptionHandler.xml +0 -21
  134. data/test/reports/TEST-HammerCLI-I18n.xml +0 -11
  135. data/test/reports/TEST-HammerCLI-MainCommand-loading-context-password.xml +0 -11
  136. data/test/reports/TEST-HammerCLI-MainCommand-loading-context-username.xml +0 -11
  137. data/test/reports/TEST-HammerCLI-MainCommand-loading-context-verbose.xml +0 -9
  138. data/test/reports/TEST-HammerCLI-MainCommand-loading-context.xml +0 -7
  139. data/test/reports/TEST-HammerCLI-MainCommand.xml +0 -7
  140. data/test/reports/TEST-HammerCLI-Modules-find-by-name.xml +0 -13
  141. data/test/reports/TEST-HammerCLI-Modules-load-a-module-module-not-found.xml +0 -13
  142. data/test/reports/TEST-HammerCLI-Modules-load-a-module-module-runtime-exception.xml +0 -13
  143. data/test/reports/TEST-HammerCLI-Modules-load-a-module-success.xml +0 -15
  144. data/test/reports/TEST-HammerCLI-Modules-load-a-module.xml +0 -7
  145. data/test/reports/TEST-HammerCLI-Modules-load-all-modules.xml +0 -9
  146. data/test/reports/TEST-HammerCLI-Modules-names.xml +0 -13
  147. data/test/reports/TEST-HammerCLI-Modules.xml +0 -7
  148. data/test/reports/TEST-HammerCLI-OptionBuilderContainer.0.xml +0 -7
  149. data/test/reports/TEST-HammerCLI-OptionBuilderContainer.xml +0 -11
  150. data/test/reports/TEST-HammerCLI-Options-Normalizers-abstract.xml +0 -9
  151. data/test/reports/TEST-HammerCLI-Options-Normalizers-bool.xml +0 -31
  152. data/test/reports/TEST-HammerCLI-Options-Normalizers-datetime.xml +0 -17
  153. data/test/reports/TEST-HammerCLI-Options-Normalizers-enum.xml +0 -15
  154. data/test/reports/TEST-HammerCLI-Options-Normalizers-enumlist.xml +0 -21
  155. data/test/reports/TEST-HammerCLI-Options-Normalizers-json-input.xml +0 -15
  156. data/test/reports/TEST-HammerCLI-Options-Normalizers-key-value-list.xml +0 -17
  157. data/test/reports/TEST-HammerCLI-Options-Normalizers-list.xml +0 -15
  158. data/test/reports/TEST-HammerCLI-Options-Normalizers.xml +0 -7
  159. data/test/reports/TEST-HammerCLI-Options-OptionDefinition-context.xml +0 -9
  160. data/test/reports/TEST-HammerCLI-Options-OptionDefinition-formatters.xml +0 -11
  161. data/test/reports/TEST-HammerCLI-Options-OptionDefinition.xml +0 -7
  162. data/test/reports/TEST-HammerCLI-Output-Adapter-Abstract-error-messages.xml +0 -15
  163. data/test/reports/TEST-HammerCLI-Output-Adapter-Abstract-messages.xml +0 -11
  164. data/test/reports/TEST-HammerCLI-Output-Adapter-Abstract-test-data-for-field.xml +0 -15
  165. data/test/reports/TEST-HammerCLI-Output-Adapter-Abstract.xml +0 -17
  166. data/test/reports/TEST-HammerCLI-Output-Adapter-Base-print-collection-show-ids.xml +0 -9
  167. data/test/reports/TEST-HammerCLI-Output-Adapter-Base-print-collection.xml +0 -27
  168. data/test/reports/TEST-HammerCLI-Output-Adapter-Base.xml +0 -7
  169. data/test/reports/TEST-HammerCLI-Output-Adapter-CSValues-print-collection-formatters.xml +0 -11
  170. data/test/reports/TEST-HammerCLI-Output-Adapter-CSValues-print-collection-handle-fields-with-collections.xml +0 -13
  171. data/test/reports/TEST-HammerCLI-Output-Adapter-CSValues-print-collection-handle-fields-with-containers.xml +0 -11
  172. data/test/reports/TEST-HammerCLI-Output-Adapter-CSValues-print-collection-handle-ids.xml +0 -11
  173. data/test/reports/TEST-HammerCLI-Output-Adapter-CSValues-print-collection.xml +0 -11
  174. data/test/reports/TEST-HammerCLI-Output-Adapter-CSValues-print-message.xml +0 -11
  175. data/test/reports/TEST-HammerCLI-Output-Adapter-CSValues.xml +0 -7
  176. data/test/reports/TEST-HammerCLI-Output-Adapter-Table-print-collection-column-width.xml +0 -15
  177. data/test/reports/TEST-HammerCLI-Output-Adapter-Table-print-collection-formatters.xml +0 -11
  178. data/test/reports/TEST-HammerCLI-Output-Adapter-Table-print-collection-handle-ids.xml +0 -11
  179. data/test/reports/TEST-HammerCLI-Output-Adapter-Table-print-collection-sort-columns.xml +0 -9
  180. data/test/reports/TEST-HammerCLI-Output-Adapter-Table-print-collection.xml +0 -11
  181. data/test/reports/TEST-HammerCLI-Output-Adapter-Table.xml +0 -7
  182. data/test/reports/TEST-HammerCLI-Output-Definition-empty-.xml +0 -11
  183. data/test/reports/TEST-HammerCLI-Output-Definition.xml +0 -11
  184. data/test/reports/TEST-HammerCLI-Output-Dsl-collection.xml +0 -13
  185. data/test/reports/TEST-HammerCLI-Output-Dsl-custom-fields.xml +0 -11
  186. data/test/reports/TEST-HammerCLI-Output-Dsl-fields.xml +0 -15
  187. data/test/reports/TEST-HammerCLI-Output-Dsl-label.xml +0 -13
  188. data/test/reports/TEST-HammerCLI-Output-Dsl-path-definition.xml +0 -13
  189. data/test/reports/TEST-HammerCLI-Output-Dsl.xml +0 -9
  190. data/test/reports/TEST-HammerCLI-Output-FieldFilter.xml +0 -13
  191. data/test/reports/TEST-HammerCLI-Output-Formatters-BooleanFormatter.xml +0 -11
  192. data/test/reports/TEST-HammerCLI-Output-Formatters-ColorFormatter.xml +0 -9
  193. data/test/reports/TEST-HammerCLI-Output-Formatters-DateFormatter.xml +0 -11
  194. data/test/reports/TEST-HammerCLI-Output-Formatters-FieldFormatter.xml +0 -13
  195. data/test/reports/TEST-HammerCLI-Output-Formatters-FormatterContainer.xml +0 -13
  196. data/test/reports/TEST-HammerCLI-Output-Formatters-FormatterLibrary.xml +0 -11
  197. data/test/reports/TEST-HammerCLI-Output-Formatters-KeyValueFormatter.xml +0 -13
  198. data/test/reports/TEST-HammerCLI-Output-Formatters-ListFormatter.xml +0 -13
  199. data/test/reports/TEST-HammerCLI-Output-Formatters-LongTextFormatter.xml +0 -13
  200. data/test/reports/TEST-HammerCLI-Output-Output-adapters.xml +0 -17
  201. data/test/reports/TEST-HammerCLI-Output-Output-data.xml +0 -15
  202. data/test/reports/TEST-HammerCLI-Output-Output-formatters.xml +0 -9
  203. data/test/reports/TEST-HammerCLI-Output-Output-messages.xml +0 -19
  204. data/test/reports/TEST-HammerCLI-Output-Output.xml +0 -7
  205. data/test/reports/TEST-HammerCLI-Output-RecordCollection.xml +0 -13
  206. data/test/reports/TEST-HammerCLI-Settings-load-from-paths.xml +0 -15
  207. data/test/reports/TEST-HammerCLI-Settings.xml +0 -25
  208. data/test/reports/TEST-HammerCLI-ShellHistory-loading-old-history.xml +0 -11
  209. data/test/reports/TEST-HammerCLI-ShellHistory-saving-history.xml +0 -15
  210. data/test/reports/TEST-HammerCLI-ShellHistory.xml +0 -7
  211. data/test/reports/TEST-MiniTest-Spec.xml +0 -7
  212. data/test/reports/TEST-String-camelize.xml +0 -11
  213. data/test/reports/TEST-String-formatting.xml +0 -17
  214. data/test/reports/TEST-String-indent.xml +0 -11
  215. data/test/reports/TEST-String-interactive-.xml +0 -13
  216. data/test/reports/TEST-String.xml +0 -7
  217. data/test/reports/TEST-constraints-HammerCLI-Validator-AllConstraint-exist-.xml +0 -13
  218. data/test/reports/TEST-constraints-HammerCLI-Validator-AllConstraint.xml +0 -7
  219. data/test/reports/TEST-constraints-HammerCLI-Validator-AnyConstraint-exist-.xml +0 -13
  220. data/test/reports/TEST-constraints-HammerCLI-Validator-AnyConstraint.xml +0 -7
  221. data/test/reports/TEST-constraints-HammerCLI-Validator-BaseConstraint-exist-.xml +0 -9
  222. data/test/reports/TEST-constraints-HammerCLI-Validator-BaseConstraint-rejected.xml +0 -13
  223. data/test/reports/TEST-constraints-HammerCLI-Validator-BaseConstraint-required.xml +0 -13
  224. data/test/reports/TEST-constraints-HammerCLI-Validator-BaseConstraint.xml +0 -7
  225. data/test/reports/TEST-constraints.xml +0 -7
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 9c28ad069fcd115c4b6f01ad2b5d0b2cdf8b3cbd
4
- data.tar.gz: 2f9a543685a78f837bd1d1b657702c745c2ae0ba
3
+ metadata.gz: ef7854e6b8f65d3432b1f748a1bd300d4ab2274e
4
+ data.tar.gz: 09a8c5faa16658f072ebde9a0ca6493e0044dc8b
5
5
  SHA512:
6
- metadata.gz: e641575e3077ce1a854ba6f6e7bfc96d9b03c634a56ee09dcb8d5d486db188aa2bd5f4e7856dcc4f30c08b9ab6630d73397e3a9726db833064d11fc8afdfeecb
7
- data.tar.gz: 287e3b3f607305f302ff58d6c74c6cc871b46d627fd32e0392a2443a2f516561934344419ab9333f3083804a15996c4d9f4695b0eeb32357b8fb022416fdb2e3
6
+ metadata.gz: 398fa3c73cab657f5fa0afb2b9a255427fc7bcbca0a2d7488d74ddc1daca9b93bf237173ce644358529b26caffe0577abff3a9f03567343b565d23026009bbeb
7
+ data.tar.gz: 302c34a77aa5cffbf6bee3d2975e393c9ba5afdd08f9e820ae30e354010f5495ee2316acfb1fd9534489e2f5af1b5854fb7501c747aa30fb5acc8621e0645bb2
data/bin/hammer CHANGED
@@ -31,6 +31,16 @@ class PreParser < Clamp::Command
31
31
  option ["--output"], "ADAPTER", "Set output format"
32
32
  option ["--csv-separator"], "SEPARATOR", "Character to separate the values"
33
33
  option ["--autocomplete"], "LINE", "Get list of possible endings"
34
+ option ["--verify-ssl"], "VERIFY_SSL", "Configure SSL verification of remote system" do |value|
35
+ bool_normalizer = HammerCLI::Options::Normalizers::Bool.new
36
+ bool_normalizer.format(value)
37
+ end
38
+ option ["--ssl-ca-file"], "CA_FILE", "Configure the file containing the CA certificates"
39
+ option ["--ssl-ca-path"], "CA_PATH", "Configure the directory containing the CA certificates"
40
+ option ["--ssl-client-cert"], "CERT_FILE", "Configure the client's public certificate"
41
+ option ["--ssl-client-key"], "KEY_FILE", "Configure the client's private key"
42
+ option ["--ssl-with-basic-auth"], :flag, "Use standard authentication in addition to client certificate authentication"
43
+ option ["--fetch-ca-cert"], "SERVER", "Fetch CA certificate from server and exit"
34
44
  end
35
45
 
36
46
  preparser = PreParser.new File.basename($0), {}
@@ -76,7 +86,13 @@ HammerCLI::Settings.load({
76
86
  :host => preparser.server,
77
87
  :interactive => preparser.interactive,
78
88
  :verbose => preparser.verbose? || preparser.debug?,
79
- :reload_cache => preparser.reload_cache?
89
+ :reload_cache => preparser.reload_cache?,
90
+ :verify_ssl => preparser.verify_ssl,
91
+ :ssl_ca_file => preparser.ssl_ca_file,
92
+ :ssl_ca_path => preparser.ssl_ca_path,
93
+ :ssl_client_cert => preparser.ssl_client_cert,
94
+ :ssl_client_key => preparser.ssl_client_key,
95
+ :ssl_with_basic_auth => preparser.ssl_with_basic_auth?
80
96
  }})
81
97
 
82
98
  if HammerCLI::Settings.get(:ui, :mark_translated)
@@ -107,6 +123,11 @@ end
107
123
  # load hammer core
108
124
  require 'hammer_cli'
109
125
 
126
+ if preparser.fetch_ca_cert
127
+ require 'hammer_cli/ca_cert_fetcher'
128
+ exit HammerCLI::CACertFetcher.fetch_ca_cert(preparser.fetch_ca_cert)
129
+ end
130
+
110
131
  # load modules set in config
111
132
  begin
112
133
  HammerCLI::Modules.load_all
@@ -31,3 +31,23 @@
31
31
  # Log record pattern (logging gem syntax)
32
32
  #:log_pattern: '[%5l %d %c] %m'
33
33
 
34
+
35
+ # SSL auth options
36
+ #:ssl:
37
+ # Path to a ca file
38
+ #:ssl_ca_file: '/path/to/ca_certificate.pem'
39
+
40
+ # Path to a direcotry with ca file
41
+ #:ssl_ca_path: '/path/to/ca/'
42
+
43
+ # Turn SSL verification on/off
44
+ #:verify_ssl: true
45
+
46
+ # Path to a client certificate
47
+ #:ssl_client_cert: '/path/to/cert.crt'
48
+
49
+ # Path to a client key
50
+ #:ssl_client_key: '/path/to/cert.key'
51
+
52
+ # Enable standard authentication in addition to client certificate authentication
53
+ #:ssl_with_basic_auth: true
data/doc/release_notes.md CHANGED
@@ -1,6 +1,13 @@
1
1
  Release notes
2
2
  =============
3
3
 
4
+ ### 0.10.0 (2017-03-28)
5
+ * Defaults match on option switch name (#233) ([#17920](http://projects.theforeman.org/issues/17920))
6
+ * Add support for client certificate authentication ([#12401](http://projects.theforeman.org/issues/12401))
7
+ * Only include .mo files below locale/ ([#18439](http://projects.theforeman.org/issues/18439))
8
+ * Hide label fields when the value is empty or nil ([#18446](http://projects.theforeman.org/issues/18446))
9
+ * Replacement for table_print gem ([#17740](http://projects.theforeman.org/issues/17740))
10
+
4
11
  ### 0.9.0 (2016-12-15)
5
12
  * Double quotes in list type params ([#17180](http://projects.theforeman.org/issues/17180))
6
13
  * API connection moved to context ([PR #227](https://github.com/theforeman/hammer-cli/pull/227)) ([#8016](http://projects.theforeman.org/issues/8016))
@@ -1,6 +1,9 @@
1
1
  require 'hammer_cli/exception_handler'
2
2
  require 'hammer_cli/logger_watch'
3
3
  require 'hammer_cli/options/option_definition'
4
+ require 'hammer_cli/options/option_collector'
5
+ require 'hammer_cli/options/sources/command_line'
6
+ require 'hammer_cli/options/sources/saved_defaults'
4
7
  require 'hammer_cli/clamp'
5
8
  require 'hammer_cli/subcommand'
6
9
  require 'hammer_cli/options/matcher'
@@ -224,28 +227,22 @@ module HammerCLI
224
227
  end
225
228
 
226
229
  def all_options
227
- @all_options ||= self.class.recognised_options.inject({}) do |hash, opt|
228
- hash[opt.attribute_name] = send(opt.read_method)
229
- hash[opt.attribute_name] = add_custom_defaults(opt.attribute_name) if hash[opt.attribute_name].nil?
230
- hash
231
- end
232
- @all_options
230
+ option_collector.all_options
233
231
  end
234
232
 
235
233
  def options
236
- all_options.reject {|key, value| value.nil? }
234
+ option_collector.options
237
235
  end
238
236
 
239
- private
240
-
241
- def add_custom_defaults(attr)
242
- if context[:defaults]
243
- value = context[:defaults].get_defaults(attr)
244
- logger.info("Custom default value #{value} was used for attribute #{attr}") if value
245
- value
246
- end
237
+ def option_collector
238
+ @option_collector ||= HammerCLI::Options::OptionCollector.new(self.class.recognised_options, [
239
+ HammerCLI::Options::Sources::CommandLine.new(self),
240
+ HammerCLI::Options::Sources::SavedDefaults.new(context[:defaults], logger)
241
+ ])
247
242
  end
248
243
 
244
+ private
245
+
249
246
  def self.inherited_output_definition
250
247
  od = nil
251
248
  if superclass.respond_to? :output_definition
@@ -1,11 +1,13 @@
1
1
  require 'apipie_bindings'
2
+ require 'hammer_cli/ssloptions'
3
+
2
4
  module HammerCLI::Apipie
3
5
  class ApiConnection < HammerCLI::AbstractConnector
4
6
  attr_reader :api
5
7
 
6
8
  def initialize(params, options = {})
7
9
  @logger = options[:logger]
8
- @api = ApipieBindings::API.new(params)
10
+ @api = ApipieBindings::API.new(params, HammerCLI::SSLOptions.get_options)
9
11
  if options[:reload_cache]
10
12
  @api.clean_cache
11
13
  @logger.debug 'Apipie cache was cleared' unless @logger.nil?
@@ -0,0 +1,67 @@
1
+ module HammerCLI
2
+ class CACertFetcher
3
+ def self.fetch_ca_cert(host)
4
+ CACertFetcher.new.fetch_ca_cert(host)
5
+ end
6
+
7
+ def fetch_ca_cert(host)
8
+ begin
9
+ uri = URI.parse(host)
10
+
11
+ hostname = uri.host
12
+ port = uri.port || 443
13
+
14
+ if hostname.nil?
15
+ $stderr.puts _("Couldn't parse URI '%s'.") % host
16
+ $stderr.puts scheme_error(uri)
17
+ return HammerCLI::EX_SOFTWARE
18
+ end
19
+
20
+ puts get_ca_cert(hostname, port)
21
+ return HammerCLI::EX_OK
22
+ rescue StandardError => e
23
+ msg = [_('Fetching the CA certificate failed:')]
24
+
25
+ if e.is_a?(OpenSSL::SSL::SSLError) && e.message.include?('unknown protocol')
26
+ msg << _('The service at the given URI does not accept SSL connections')
27
+ msg << scheme_error(uri) if uri.scheme == 'http'
28
+ else
29
+ msg << e.message
30
+ end
31
+ $stderr.puts msg.join("\n")
32
+ return HammerCLI::EX_SOFTWARE
33
+ end
34
+ end
35
+
36
+ protected
37
+
38
+ def scheme_error(uri)
39
+ _("Perhaps you meant to connect to '%s'?") % uri_to_https(uri)
40
+ end
41
+
42
+ def uri_to_https(uri)
43
+ https_uri = uri.to_s
44
+ if uri.scheme == 'http'
45
+ # Scheme is http, replace with https.
46
+ https_uri = https_uri.sub(/^http/, 'https')
47
+ elsif uri.scheme.nil? || !https_uri.match(/:\/\//)
48
+ # Scheme either wasn't recognized or host was parsed into scheme.
49
+ # That can happen when user enters '<host>:<port>' without scheme.
50
+ https_uri = "https://#{https_uri}"
51
+ end
52
+ https_uri
53
+ end
54
+
55
+ def get_ca_cert(hostname, port)
56
+ noverify_ssl_connection = OpenSSL::SSL::SSLSocket.new(TCPSocket.new(hostname, port), noverify_ssl_context)
57
+ noverify_ssl_connection.connect
58
+ noverify_ssl_connection.peer_cert_chain.last
59
+ end
60
+
61
+ def noverify_ssl_context
62
+ noverify_ssl_context = OpenSSL::SSL::SSLContext.new
63
+ noverify_ssl_context.verify_mode = OpenSSL::SSL::VERIFY_NONE
64
+ noverify_ssl_context
65
+ end
66
+ end
67
+ end
@@ -32,9 +32,9 @@ module HammerCLI
32
32
  create_default_file if defaults_settings.empty?
33
33
  update_defaults_file do |defaults|
34
34
  default_options.each do |key, value|
35
- key = key.to_sym
35
+ key = switch_to_name(key).to_sym
36
36
  defaults.delete_if { |k,| defaults_match?(k, key) }
37
- defaults[key] = (value ? {:value => value,} : {:provider => provider})
37
+ defaults[key] = (value ? {:value => value} : {:provider => provider})
38
38
  end
39
39
  end
40
40
  end
@@ -44,16 +44,16 @@ module HammerCLI
44
44
  end
45
45
 
46
46
  def get_defaults(opt)
47
- option = opt
48
- option = opt.gsub("option_",'') if opt.include? "option_"
49
47
  unless defaults_settings.nil?
50
- option_key = defaults_settings[option.to_sym].nil? ? option.gsub('_','-').to_sym : option.to_sym
51
- return nil if defaults_settings[option_key].nil?
48
+ option_key = normalize_option(opt)
49
+ settings_key = defaults_settings[option_key.to_sym].nil? ? option_key.gsub('_','-').to_sym : option_key.to_sym
52
50
 
53
- if defaults_settings[option_key][:provider]
54
- providers[defaults_settings[option_key][:provider]].get_defaults(option.to_sym)
51
+ return nil if defaults_settings[settings_key].nil?
52
+
53
+ if defaults_settings[settings_key][:provider]
54
+ providers[defaults_settings[settings_key][:provider]].get_defaults(option_key.to_sym)
55
55
  else
56
- defaults_settings[option_key][:value]
56
+ defaults_settings[settings_key][:value]
57
57
  end
58
58
  end
59
59
  end
@@ -89,7 +89,15 @@ module HammerCLI
89
89
  private
90
90
 
91
91
  def defaults_match?(default_a, default_b)
92
- default_a.to_s.gsub('-','_') == default_b.to_s.gsub('-','_')
92
+ normalize_option(default_a) == normalize_option(default_b)
93
+ end
94
+
95
+ def normalize_option(opt)
96
+ switch_to_name(opt).gsub(/^option_/,'').gsub('-','_')
97
+ end
98
+
99
+ def switch_to_name(opt)
100
+ opt.to_s.gsub(/^-[-]?/,'')
93
101
  end
94
102
  end
95
103
 
@@ -16,6 +16,8 @@ module HammerCLI
16
16
  [Clamp::UsageError, :handle_usage_exception],
17
17
  [RestClient::ResourceNotFound, :handle_not_found],
18
18
  [RestClient::Unauthorized, :handle_unauthorized],
19
+ [RestClient::SSLCertificateNotVerified, :handle_ssl_cert_not_verified],
20
+ [OpenSSL::SSL::SSLError, :handle_ssl_error],
19
21
  [ApipieBindings::DocLoadingError, :handle_apipie_docloading_error],
20
22
  [ApipieBindings::MissingArgumentsError, :handle_apipie_missing_arguments_error],
21
23
  [HammerCLI::ModuleDisabledButRequired, :handle_generic_config_error]
@@ -88,12 +90,49 @@ module HammerCLI
88
90
  HammerCLI::EX_UNAUTHORIZED
89
91
  end
90
92
 
93
+ def rake_command
94
+ "rake apipie:cache"
95
+ end
96
+
97
+ def handle_ssl_error(e)
98
+ print_error(_("SSL error") + ": #{e.message}")
99
+ log_full_error(e)
100
+ HammerCLI::EX_CONFIG
101
+ end
102
+
103
+ def handle_ssl_cert_not_verified(e)
104
+ print_error(ssl_cert_message)
105
+ log_full_error(e)
106
+ HammerCLI::EX_CONFIG
107
+ end
108
+
109
+ def ssl_cert_instructions
110
+ end
111
+
112
+ def ssl_cert_message
113
+ message = _("SSL certificate verification failed")
114
+ message += "\n#{ssl_cert_instructions}" if ssl_cert_instructions
115
+ message
116
+ end
117
+
91
118
  def handle_apipie_docloading_error(e)
92
- rake_command = "rake apipie:cache"
93
- print_error _("Could not load the API description from the server") + "\n - " +
94
- _("is the server down?") + "\n - " +
95
- _("was '%s' run on the server when using apipie cache? (typical production settings)") % rake_command
96
- log_full_error e
119
+ api_cache_instructions = "\n - " +
120
+ _("is the server down?") + "\n - " +
121
+ _("was '%s' run on the server when using apipie cache? (typical production settings)") % rake_command
122
+
123
+ message = _("Could not load the API description from the server") + ": "
124
+ if e.respond_to?(:original_error)
125
+ if e.original_error.is_a?(RestClient::SSLCertificateNotVerified)
126
+ message += ssl_cert_message + "\n\n"
127
+ else
128
+ message += "\n#{e.original_error.message}"
129
+ message += api_cache_instructions
130
+ end
131
+ else
132
+ message += api_cache_instructions
133
+ end
134
+ print_error(message)
135
+ log_full_error(e)
97
136
  HammerCLI::EX_CONFIG
98
137
  end
99
138
 
@@ -16,6 +16,14 @@ module HammerCLI
16
16
  :context_target => :password
17
17
  option ["-s", "--server"], "SERVER", _("remote system address"),
18
18
  :context_target => :uri
19
+ option ["--verify-ssl"], "VERIFY_SSL", _("Configure SSL verification of remote system"),
20
+ :format => HammerCLI::Options::Normalizers::Bool.new
21
+ option ["--ssl-ca-file"], "CA_FILE", _("Configure the file containing the CA certificates")
22
+ option ["--ssl-ca-path"], "CA_PATH", _("Configure the directory containing the CA certificates")
23
+ option ["--ssl-client-cert"], "CERT_FILE", _("Configure the client's public certificate")
24
+ option ["--ssl-client-key"], "KEY_FILE", _("Configure the client's private key")
25
+ option ["--ssl-with-basic-auth"], :flag, _("Use standard authentication in addition to client certificate authentication")
26
+ option ["--fetch-ca-cert"], "SERVER", _("Fetch CA certificate from server and exit")
19
27
 
20
28
  option "--version", :flag, _("show version") do
21
29
  puts "hammer (%s)" % HammerCLI.version
@@ -0,0 +1,22 @@
1
+ module HammerCLI
2
+ module Options
3
+ class OptionCollector
4
+ attr_accessor :option_sources
5
+
6
+ def initialize(recognised_options, option_sources)
7
+ @recognised_options = recognised_options
8
+ @option_sources = option_sources
9
+ end
10
+
11
+ def all_options
12
+ @all_options ||= @option_sources.inject({}) do |all_options, source|
13
+ source.get_options(@recognised_options, all_options)
14
+ end
15
+ end
16
+
17
+ def options
18
+ @options ||= all_options.reject {|key, value| value.nil? }
19
+ end
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,18 @@
1
+ module HammerCLI
2
+ module Options
3
+ module Sources
4
+ class CommandLine
5
+ def initialize(command)
6
+ @command = command
7
+ end
8
+
9
+ def get_options(defined_options, result)
10
+ defined_options.each do |opt|
11
+ result[opt.attribute_name] ||= @command.send(opt.read_method)
12
+ end
13
+ result
14
+ end
15
+ end
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,31 @@
1
+ module HammerCLI
2
+ module Options
3
+ module Sources
4
+ class SavedDefaults
5
+ def initialize(defaults, logger)
6
+ @defaults = defaults
7
+ @logger = logger
8
+ end
9
+
10
+ def get_options(defined_options, result)
11
+ defined_options.each do |opt|
12
+ result[opt.attribute_name] = add_custom_defaults(opt) if result[opt.attribute_name].nil?
13
+ end if @defaults
14
+ result
15
+ end
16
+
17
+ protected
18
+ def add_custom_defaults(opt)
19
+ opt.switches.each do |switch|
20
+ value = @defaults.get_defaults(switch)
21
+ if value
22
+ @logger.info("Custom default value #{value} was used for attribute #{switch}")
23
+ return value
24
+ end
25
+ end
26
+ nil
27
+ end
28
+ end
29
+ end
30
+ end
31
+ end
@@ -1,7 +1,5 @@
1
- require 'table_print'
2
1
  require File.join(File.dirname(__FILE__), 'wrapper_formatter')
3
- require 'hammer_cli/table_print/formatter'
4
- require 'hammer_cli/table_print/column'
2
+ require 'hammer_cli/output/utils'
5
3
 
6
4
  module HammerCLI::Output::Adapter
7
5
 
@@ -10,6 +8,10 @@ module HammerCLI::Output::Adapter
10
8
  MAX_COLUMN_WIDTH = 80
11
9
  MIN_COLUMN_WIDTH = 5
12
10
 
11
+ HLINE = '-'
12
+ LINE_SEPARATOR = '-|-'
13
+ COLUMN_SEPARATOR = ' | '
14
+
13
15
  def tags
14
16
  [:screen, :flat]
15
17
  end
@@ -21,44 +23,32 @@ module HammerCLI::Output::Adapter
21
23
  def print_collection(all_fields, collection)
22
24
  fields = field_filter.filter(all_fields)
23
25
 
24
- rows = collection.collect do |d|
25
- row = {}
26
- fields.each do |f|
27
- row[label_for(f)] = WrapperFormatter.new(
28
- @formatters.formatter_for_type(f.class), f.parameters).format(data_for_field(f, d) || "")
29
- end
30
- row
31
- end
32
-
33
- if rows.empty?
34
- keys = fields.map { |f| [label_for(f), ''] }
35
- rows = [Hash[keys]]
36
- @header_only = true
37
- end
26
+ formatted_collection = format_values(fields, collection)
27
+ # calculate hash of column widths (label -> width)
28
+ widths = calculate_widths(fields, formatted_collection)
38
29
 
39
- options = fields.collect do |f|
40
- { label_for(f) => {
41
- :width => max_width_for(f)
42
- }
43
- }
30
+ header_bits = []
31
+ hline_bits = []
32
+ fields.map do |f|
33
+ header_bits << normalize_column(widths[f.label], f.label.upcase)
34
+ hline_bits << HLINE * widths[f.label]
44
35
  end
45
36
 
46
- sort_order = fields.map { |f| f.label.upcase }
37
+ line = hline_bits.join(LINE_SEPARATOR)
47
38
 
48
- printer = TablePrint::Printer.new(rows, options)
49
- TablePrint::Config.max_width = MAX_COLUMN_WIDTH
50
- TablePrint::Config.multibyte = true
39
+ puts line
40
+ puts header_bits.join(COLUMN_SEPARATOR)
41
+ puts line
51
42
 
52
- output = sort_columns(printer.table_print, sort_order)
53
- dashes = /\n([-|]+)\n/.match(output)
54
-
55
- if @header_only
56
- output = output.lines.first
43
+ formatted_collection.collect do |row|
44
+ row_bits = fields.map do |f|
45
+ normalize_column(widths[f.label], row[f.label] || "")
46
+ end
47
+ puts row_bits.join(COLUMN_SEPARATOR)
57
48
  end
58
49
 
59
- puts dashes[1] if dashes
60
- puts output
61
- puts dashes[1] if dashes
50
+ # print closing line only when the table isn't empty
51
+ puts line unless formatted_collection.empty?
62
52
 
63
53
  if collection.meta.pagination_set? && collection.count < collection.meta.subtotal
64
54
  pages = (collection.meta.subtotal.to_f/collection.meta.per_page).ceil
@@ -68,73 +58,62 @@ module HammerCLI::Output::Adapter
68
58
 
69
59
  protected
70
60
 
71
- def field_filter
72
- filtered = [Fields::ContainerField]
73
- filtered << Fields::Id unless @context[:show_ids]
74
- HammerCLI::Output::FieldFilter.new(filtered)
75
- end
76
-
77
- private
78
-
79
- def label_for(field)
80
- width = width_for(field)
81
- if width
82
- "%-#{width}s" % field.label.to_s
61
+ def normalize_column(width, value)
62
+ value = value.to_s
63
+ padding = width - HammerCLI::Output::Utils.real_length(value)
64
+ if padding >= 0
65
+ value += (" " * padding)
83
66
  else
84
- field.label.to_s
67
+ value, real_length = HammerCLI::Output::Utils.real_truncate(value, width-3)
68
+ value += '...'
69
+ value += ' ' if real_length < (width - 3)
85
70
  end
71
+ value
86
72
  end
87
73
 
88
- def max_width_for(field)
89
- width = width_for(field)
90
- width ||= field.parameters[:max_width]
91
- width = MIN_COLUMN_WIDTH if width && width < MIN_COLUMN_WIDTH
92
- width
74
+ def format_values(fields, collection)
75
+ collection.collect do |d|
76
+ fields.inject({}) do |row, f|
77
+ formatter = WrapperFormatter.new(@formatters.formatter_for_type(f.class), f.parameters)
78
+ row.update(f.label => formatter.format(data_for_field(f, d) || "").to_s)
79
+ end
80
+ end
93
81
  end
94
82
 
95
- def width_for(field)
96
- width = field.parameters[:width]
97
- width = MIN_COLUMN_WIDTH if width && width < MIN_COLUMN_WIDTH
98
- width
83
+ def calculate_widths(fields, collection)
84
+ Hash[fields.map { |f| [f.label, calculate_column_width(f, collection)] }]
99
85
  end
100
86
 
87
+ def calculate_column_width(field, collection)
88
+ if field.parameters[:width]
89
+ return [field.parameters[:width], MIN_COLUMN_WIDTH].max
90
+ end
101
91
 
102
- def sort_columns(output, sort_order)
103
- return output if sort_order.length == 1 # don't sort one column
104
- delimiter = ' | '
105
- lines = output.split("\n")
106
- out = []
107
-
108
- headers = lines.first.split(delimiter).map(&:strip)
109
-
110
- # create mapping table for column indexes
111
- sort_map = []
112
- sort_order.each { |c| sort_map << headers.index(c) }
113
-
114
- lines.each do |line|
115
- columns = line.split(delimiter)
116
- if columns.length == 1 # dashes
117
- columns = columns.first.split('-|-')
118
- if columns.length == 1
119
- out << columns.first
120
- else # new style dashes
121
- new_row = []
122
- sort_map.each { |i| new_row << columns[i] }
123
- out << new_row.join('-|-')
124
- end
125
- else
126
- # reorder row
127
- new_row = []
128
- sort_map.each { |i| new_row << columns[i] }
129
- out << new_row.join(delimiter)
130
- end
92
+ width = HammerCLI::Output::Utils.real_length(field.label.to_s)
93
+ max_width = max_width_for(field)
94
+ collection.each do |item|
95
+ width = [HammerCLI::Output::Utils.real_length(item[field.label]), width].max
96
+ return max_width if width >= max_width
131
97
  end
98
+ width
99
+ end
132
100
 
133
- out.join("\n")
101
+ def field_filter
102
+ filtered = [Fields::ContainerField]
103
+ filtered << Fields::Id unless @context[:show_ids]
104
+ HammerCLI::Output::FieldFilter.new(filtered)
134
105
  end
135
106
 
107
+ private
108
+
109
+ def max_width_for(field)
110
+ if field.parameters[:max_width]
111
+ [field.parameters[:max_width], MAX_COLUMN_WIDTH].min
112
+ else
113
+ MAX_COLUMN_WIDTH
114
+ end
115
+ end
136
116
  end
137
117
 
138
118
  HammerCLI::Output::Output.register_adapter(:table, Table)
139
-
140
119
  end
@@ -85,7 +85,7 @@ module Fields
85
85
  def display?(value)
86
86
  return true if not hide_blank?
87
87
 
88
- fields.any? do |f|
88
+ !(value.nil? || value.empty?) && fields.any? do |f|
89
89
  f.display?(HammerCLI::Output::Adapter::Abstract.data_for_field(f, value))
90
90
  end
91
91
  end