hammer_cli 0.9.0 → 0.10.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 (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