foreman_openbolt 1.1.0 → 1.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (51) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +14 -252
  3. data/Rakefile +0 -0
  4. data/app/controllers/foreman_openbolt/task_controller.rb +4 -1
  5. data/lib/foreman_openbolt/engine.rb +128 -24
  6. data/lib/foreman_openbolt/version.rb +1 -1
  7. data/lib/proxy_api/openbolt.rb +13 -3
  8. data/package.json +1 -1
  9. data/test/acceptance/acceptance_helper.rb +146 -0
  10. data/test/acceptance/docker/docker-compose.yml +69 -0
  11. data/test/acceptance/docker/foreman/Dockerfile +45 -0
  12. data/test/acceptance/docker/foreman/entrypoint.sh +26 -0
  13. data/test/acceptance/docker/target/Dockerfile +29 -0
  14. data/test/acceptance/docker/target/entrypoint.sh +11 -0
  15. data/test/acceptance/fixtures/modules/acceptance/tasks/complex_params.json +30 -0
  16. data/test/acceptance/fixtures/modules/acceptance/tasks/complex_params.sh +16 -0
  17. data/test/acceptance/fixtures/modules/acceptance/tasks/echo.json +13 -0
  18. data/test/acceptance/fixtures/modules/acceptance/tasks/echo.sh +3 -0
  19. data/test/acceptance/fixtures/modules/acceptance/tasks/failing_task.json +8 -0
  20. data/test/acceptance/fixtures/modules/acceptance/tasks/failing_task.sh +3 -0
  21. data/test/acceptance/fixtures/modules/acceptance/tasks/noop_task.json +8 -0
  22. data/test/acceptance/fixtures/modules/acceptance/tasks/noop_task.sh +2 -0
  23. data/test/acceptance/fixtures/modules/acceptance/tasks/slow_task.json +14 -0
  24. data/test/acceptance/fixtures/modules/acceptance/tasks/slow_task.sh +3 -0
  25. data/test/acceptance/fixtures/modules/acceptance/tasks/target_conditional.json +13 -0
  26. data/test/acceptance/fixtures/modules/acceptance/tasks/target_conditional.sh +9 -0
  27. data/test/acceptance/fixtures/openbolt.yml +7 -0
  28. data/test/acceptance/tests/error_handling_test.rb +40 -0
  29. data/test/acceptance/tests/host_selector_test.rb +31 -0
  30. data/test/acceptance/tests/launch_task_test.rb +96 -0
  31. data/test/acceptance/tests/parameter_table_test.rb +61 -0
  32. data/test/acceptance/tests/settings_test.rb +95 -0
  33. data/test/acceptance/tests/ssh_options_test.rb +77 -0
  34. data/test/acceptance/tests/task_execution_test.rb +40 -0
  35. data/test/acceptance/tests/task_history_test.rb +84 -0
  36. data/test/acceptance/tests/transport_options_test.rb +161 -0
  37. data/test/test_plugin_helper.rb +17 -0
  38. data/test/unit/controllers/task_controller_test.rb +426 -0
  39. data/test/unit/docker/Dockerfile +47 -0
  40. data/test/unit/docker/docker-compose.yml +33 -0
  41. data/test/unit/docker/entrypoint.sh +4 -0
  42. data/test/unit/factories/foreman_openbolt_factories.rb +39 -0
  43. data/test/unit/lib/actions/cleanup_proxy_artifacts_test.rb +51 -0
  44. data/test/unit/lib/actions/poll_task_status_test.rb +141 -0
  45. data/test/unit/lib/proxy_api/openbolt_test.rb +174 -0
  46. data/test/unit/models/task_job_test.rb +278 -0
  47. data/webpack/src/Components/LaunchTask/__tests__/ParameterField.test.js +45 -0
  48. data/webpack/src/Components/LaunchTask/hooks/__tests__/useOpenBoltOptions.test.js +1 -0
  49. data/webpack/src/Components/TaskExecution/__tests__/LoadingIndicator.test.js +1 -1
  50. data/webpack/src/Components/TaskExecution/hooks/__tests__/useJobPolling.test.js +1 -1
  51. metadata +39 -1
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 19c30e74d249eacf814179dac70292c3e42182b39477cab06adf304885298587
4
- data.tar.gz: bbc28cd01be2a7f100d1ec015c92aff471584e7445468184e7ef1bd97c485b27
3
+ metadata.gz: b212e4874311ac07caa39290021ef940849d6a64c4e903f393497b2cf97654a5
4
+ data.tar.gz: e8658c692b134da9b542234b30064f6274bd0b1aed2ad4f25ef5397b015afeb8
5
5
  SHA512:
6
- metadata.gz: 2b40018885e22e7d3690b13c524787dadbf8ad2fe8fa5af2e82e5eb4fd99d65a56a7015cbd02717573c5cd12395d1a157130c16257fa94a5b3f28ef78470fd55
7
- data.tar.gz: 753476abd475f3de15ad928874048c9772d4a55534129f35b9d4c032beb5c0f787e8ba6aed271763bb59d66383986360cbf8d0438618aefdb9f2175790b959c7
6
+ metadata.gz: 8fcfe54eef80b1951fb8cc483659b6219ede35010b120670b2dab5de998787bcc965bc3b73756d2ba7c9a684cc75a4fb007c7bc85a619f42168d63982029f275
7
+ data.tar.gz: dac7ac671cfa773d0ec2a28fcb0562634b59a38d7eed754f3fde79172f3c3da381f70a9ed3ef8a9f19fc34fc0d033931a2fdd2fabc302f88e6208c40029b72cc
data/README.md CHANGED
@@ -23,14 +23,14 @@ A task is copied to N targets and executed there.
23
23
 
24
24
  ## Plans
25
25
 
26
- Plans provide complex logic options, written in Puppet DSL.
27
- Besides the usual Puppet DSL functions, it's also possible to execute tasks and evaluate their responses.
26
+ Plans provide complex logic options, written in the Puppet language.
27
+ Besides the usual Puppet language functions, it's also possible to execute tasks and evaluate their responses.
28
28
 
29
29
  ## OpenBolt in Foreman!
30
30
 
31
- OpenBolt is the Ansible counterpart and OpenBolt is Puppet "native".
32
- OpenBolt and Puppet integrate very well together and OpenBolt can reuse your existing Puppet code.
33
- Since OpenBolt is a CLI only application, and most Puppet users run Foreman anyways, it made sense to integrate OpenBolt into Foreman, instead of writing another web UI.
31
+ OpenBolt is the Ansible counterpart and OpenBolt is OpenVox/Puppet native.
32
+ OpenBolt and OpenVox/Puppet integrate very well together and OpenBolt can reuse your existing code.
33
+ Since OpenBolt is a CLI only application, and most OpenVox and Puppet users run Foreman anyways, it made sense to integrate OpenBolt into Foreman, instead of writing another web UI.
34
34
 
35
35
  ## Installation
36
36
 
@@ -49,7 +49,9 @@ The [theforeman/foreman_proxy](https://github.com/theforeman/puppet-foreman_prox
49
49
  The Foreman plugin provides UI elements to start Tasks on various nodes.
50
50
  Foreman then talks to a Smartproxy to run OpenBolt.
51
51
  The Smartproxy also establishes the connections to the various targets.
52
- This is usually a ssh or WinRM connection (and soon choria, see [the TODO section](#todo)).
52
+ This is usually a SSH, WinRM, or Choria connection. The Choria transport
53
+ requires OpenBolt 5.5 or later and is not available in Puppet Bolt.
54
+ SSH and WinRM transports work with any version.
53
55
 
54
56
  You need to have `bolt` in your `$PATH` on the Smartproxy.
55
57
  OpenBolt packages are available at [yum.voxpupuli.org](https://yum.voxpupuli.org/) & [apt.voxpupuli.org](https://apt.voxpupuli.org/) in the openvox8 repo.
@@ -57,172 +59,18 @@ You can also use the legacy Bolt packages from Perforce from the `puppet-tools`
57
59
 
58
60
  The integration is supported on Foreman 3.17 and all following versions, including development/nightly builds.
59
61
 
60
- OpenBolt relies on Tasks & Plans. They are distributed as puppet modules.
62
+ OpenBolt relies on Tasks & Plans. They are distributed as modules.
61
63
  The plugin assumes that you deployed your code.
62
64
  We recommend to use [r10k](https://github.com/puppetlabs/r10k?tab=readme-ov-file#r10k) or [g10k](https://github.com/xorpaul/g10k?tab=readme-ov-file#g10k) to deploy code, as you do it on your compilers.
63
65
 
64
66
  A handful of core/default Tasks & Plans are also included in the [OpenBolt rpm/deb packages](https://github.com/OpenVoxProject/openbolt/blob/main/Puppetfile).
65
67
 
66
- ## Usage
68
+ ## Documentation
67
69
 
68
- (all screenshots were taken on Foreman 3.17)
69
-
70
- After installation, you will see a new UI element
71
-
72
- ![foreman UI menu screenshot](./ext/foreman-ui-menu.png)
73
-
74
- The "Launch Task" option allows you to select any smartproxy with the `openbolt` feature (which is available when the OpenBolt Smartproxy plugin is installed).
75
- Afterwards you can select N targets to run the task and select an available task from the selected Smartproxy.
76
- On the right side you can configure OpenBolt connection settings.
77
-
78
- ![launch task detail view](./ext/foreman-launch-task.png)
79
-
80
- After selecting a task, the task metadata is fetched and shown.
81
- Additional input elements will appear, if the task support it.
82
-
83
- ![service task metadata](./ext/task-metadata-minimal.png)
84
-
85
- The metadata can contains a description and datatypes for tasks.
86
- Those information can be shown as well.
87
-
88
- ![service task detailed metadata](./ext/task-metadata.png)
89
-
90
- While the task is running, the UI polls the status from the smart proxy.
91
-
92
- ![task loading screen](./ext/task-running.png)
93
-
94
- After the task finished, it will display a success for failure page.
95
-
96
- ![failed task view](./ext/task-execution-details.png)
97
-
98
- You can also see the used parameters for a task.
99
-
100
- ![task used parameters](./ext/task-task-details.png)
101
-
102
- We also display the used OpenBolt command line, in case you want to manually run it or debug it.
103
-
104
- ![display used OpenBolt command](./ext/task-log-output.png)
105
-
106
- OpenBolt returns JSON for executed tasks.
107
- That's visible in the UI.
108
- For failed tasks but also for passed tasks.
109
-
110
- ![failed task output](./ext/task-result.png)
111
-
112
- ![service task passed on two nodes](./ext/task-successful-result.png)
113
-
114
- ## Development
115
-
116
- ### Linting
117
-
118
- ```bash
119
- bundle exec rake lint # Run all linters (rubocop, erb_lint, eslint)
120
- bundle exec rake lint:fix # Auto-fix where possible
121
- ```
122
-
123
- Ruby and ERB linters run directly. The JavaScript linter requires npm dependencies, so either install them locally (`npm install --legacy-peer-deps`) or run lint:js inside a container:
124
-
125
- ```bash
126
- CONTAINER=1 bundle exec rake lint:js
127
- ```
128
-
129
- ### Unit Tests
130
-
131
- Unit tests run inside Docker containers with a full Foreman installation. Requires Docker with compose support.
132
-
133
- ```bash
134
- bundle exec rake test:unit:up # Build image, start containers, install deps
135
- bundle exec rake test:unit:ruby # Run Ruby tests
136
- bundle exec rake test:unit:js # Run JavaScript tests
137
- bundle exec rake test:unit:all # Run all unit tests
138
- bundle exec rake test:unit:down # Stop and remove containers
139
- bundle exec rake test # Shortcut: up, test, down in one step
140
- ```
141
-
142
- Set `FOREMAN_VERSION` to test against a specific Foreman version (default: `3.18`):
143
-
144
- ```bash
145
- FOREMAN_VERSION=3.17 bundle exec rake test:unit:up
146
- ```
147
-
148
- ### Acceptance Tests
149
-
150
- Acceptance tests exercise the plugin through the browser using Capybara and Selenium. They build RPMs, start a multi-container environment (Foreman + OpenVox + SSH targets + Chromium), and run tests against the real UI.
151
-
152
- **Prerequisites:**
153
-
154
- ```bash
155
- bundle install --with acceptance
156
- ```
157
-
158
- The [smart_proxy_openbolt](https://github.com/overlookinfra/smart_proxy_openbolt) and [foreman-packaging](https://github.com/theforeman/foreman-packaging) repos are cloned automatically when needed.
159
-
160
- **Running:**
161
-
162
- ```bash
163
- bundle exec rake acceptance # Full cycle: up, run tests, down
164
- bundle exec rake acceptance:up # Build RPMs, start Foreman, configure everything
165
- bundle exec rake acceptance:run # Run tests (requires up first)
166
- bundle exec rake acceptance:down # Stop containers
167
- bundle exec rake acceptance:clean # Full reset: stop containers, remove images and artifacts
168
- ```
169
-
170
- The `acceptance:up` task is idempotent and can be re-run to pick up new RPM changes. It caches the Foreman Docker image per version so subsequent runs are faster.
171
-
172
- **Watching tests in the browser:**
173
-
174
- Set `HEADFUL=1` to disable headless mode, then open `http://localhost:7900` (password: `secret`) to watch the tests via noVNC:
175
-
176
- ```bash
177
- HEADFUL=1 bundle exec rake acceptance:run
178
- ```
179
-
180
- **Running a subset of tests:**
181
-
182
- `acceptance:run` accepts `TEST=<path>` to limit which test files are loaded, and `TESTOPTS=<opts>` to forward options (e.g. `--name=/pattern/`) to the Test::Unit autorunner. Both can be combined.
183
-
184
- ```bash
185
- # Run every test in one file
186
- bundle exec rake acceptance:run TEST=test/acceptance/tests/settings_test.rb
187
-
188
- # Run a single test by exact method name (any file)
189
- bundle exec rake acceptance:run TESTOPTS='--name=test_echo_task_succeeds_on_all_targets'
190
-
191
- # Run tests whose name matches a regex within one file
192
- bundle exec rake acceptance:run \
193
- TEST=test/acceptance/tests/settings_test.rb \
194
- TESTOPTS='--name=/host_key/'
195
- ```
196
-
197
- **Environment variables:**
198
-
199
- | Variable | Default | Description |
200
- |----------|---------|-------------|
201
- | `CHROMEDRIVER_URL` | `http://localhost:4444` | Selenium WebDriver endpoint |
202
- | `FOREMAN_BRANCH` | `<version>-stable` | Foreman git branch for unit test image (derived from `FOREMAN_VERSION`) |
203
- | `FOREMAN_PACKAGING_REPO` | `https://github.com/theforeman/foreman-packaging.git` | Git URL for foreman-packaging (cloned automatically for RPM builds) |
204
- | `FOREMAN_PASS` | `changeme` | Foreman login password |
205
- | `FOREMAN_URL` | `https://foreman` | Foreman URL as seen by Chrome. Override to run tests against a live instance |
206
- | `FOREMAN_USER` | `admin` | Foreman login username |
207
- | `FOREMAN_VERSION` | `3.18` | Foreman version to test against |
208
- | `HEADFUL` | unset | Set to `1` to show the browser in noVNC |
209
- | `SELENIUM_IMAGE` | auto-detected (ARM/x86) | Selenium container image (auto-selects `seleniarm/standalone-chromium` or `selenium/standalone-chrome`) |
210
- | `SMART_PROXY_OPENBOLT_REF` | `main` | Branch or tag to clone |
211
- | `SMART_PROXY_OPENBOLT_REPO` | `https://github.com/overlookinfra/smart_proxy_openbolt.git` | Git URL for smart_proxy_openbolt (cloned automatically for RPM builds) |
212
-
213
- ### Building Packages
214
-
215
- Build RPM or DEB packages locally using containers. The [foreman-packaging](https://github.com/theforeman/foreman-packaging) repo is cloned automatically:
216
-
217
- ```bash
218
- bundle exec rake build:rpm # Build RPM
219
- bundle exec rake build:deb # Build DEB
220
- ```
221
-
222
- ## TODO
223
-
224
- * Integrate plans into the web UI
225
- * Provide a choria transport plugin
70
+ - [Usage](docs/usage.md): screenshots and walkthrough of the UI
71
+ - [Development](docs/development.md): linting, unit tests, acceptance tests, building packages
72
+ - [Releasing](docs/releasing.md): version locations, release steps, RPM/DEB packaging
73
+ - [Choria Testing](docs/choria-testing.md): setting up Choria on a Foreman install for transport testing
226
74
 
227
75
  ## Contributing & support
228
76
 
@@ -247,89 +95,3 @@ GNU General Public License for more details.
247
95
 
248
96
  You should have received a copy of the GNU General Public License
249
97
  along with this program. If not, see <http://www.gnu.org/licenses/>.
250
-
251
- ## How to Release
252
-
253
- ### Version locations
254
-
255
- Update the version in these files:
256
-
257
- 1. `lib/foreman_openbolt/version.rb` -- the gem version (authoritative source)
258
- 2. `package.json` -- the npm package version (must match)
259
-
260
- If the minimum Foreman version changes, also update:
261
-
262
- 3. `lib/foreman_openbolt/engine.rb` -- `requires_foreman '>= X.Y.Z'`
263
- 4. `foreman_openbolt.spec.erb` -- `%global foreman_min_version X.Y.Z`
264
- 5. `.github/workflows/build.yml` -- default `foreman_version` and `foreman_packaging_ref` inputs
265
-
266
- ### Release steps
267
-
268
- 1. Bump the version in the two files listed above
269
- 2. Generate the changelog:
270
- ```bash
271
- CHANGELOG_GITHUB_TOKEN=github_pat_... bundle exec rake changelog
272
- ```
273
- 3. Create a PR with the version bump and changelog, get it reviewed and merged
274
- 4. Create and push a tag matching the version:
275
- ```bash
276
- git tag 1.1.0
277
- git push origin 1.1.0
278
- ```
279
- 5. The [release workflow](.github/workflows/release.yml) runs automatically on tag push and:
280
- - Builds the gem
281
- - Creates a GitHub Release with auto-generated notes and the gem attached
282
- - Publishes the gem to GitHub Packages
283
- - Publishes the gem to RubyGems.org (requires the `release` environment)
284
- - Verifies the gem is available on RubyGems.org
285
-
286
- ### RPM/DEB packaging
287
-
288
- After the gem is published to RubyGems, both RPM and DEB packages need to be updated in [theforeman/foreman-packaging](https://github.com/theforeman/foreman-packaging).
289
-
290
- A bot automatically creates PRs against the `rpm/develop` and `deb/develop` branches to pick up the new gem version. These PRs build packages for Foreman nightly.
291
-
292
- For stable Foreman releases (currently 3.17 and 3.18), cherry-pick the packaging commits from the develop branches into the corresponding stable branches. For each stable version you want to support:
293
-
294
- ```bash
295
- cd foreman-packaging
296
-
297
- # RPM: cherry-pick from rpm/develop into a branch off the stable target
298
- git checkout rpm/3.18
299
- git checkout -b cherry-pick/rubygem-foreman_openbolt-rpm-3.18
300
- git cherry-pick <commit-from-rpm/develop>
301
- # Push to your fork and open a PR targeting rpm/3.18
302
-
303
- # DEB: same approach for the deb side
304
- git checkout deb/3.18
305
- git checkout -b cherry-pick/rubygem-foreman-openbolt-deb-3.18
306
- git cherry-pick <commit-from-deb/develop>
307
- # Push to your fork and open a PR targeting deb/3.18
308
- ```
309
-
310
- PRs against stable branches should be labeled "Stable branch".
311
-
312
- **Alternative: manual version bump**
313
-
314
- If the cherry-pick doesn't apply cleanly, you can bump the version manually on the stable branch instead.
315
-
316
- *RPM:* Checkout the target branch and run `bump_rpm.sh`:
317
- ```bash
318
- cd foreman-packaging
319
- git checkout rpm/3.18
320
- git checkout -b bump_rpm/rubygem-foreman_openbolt
321
- ./bump_rpm.sh packages/plugins/rubygem-foreman_openbolt
322
- # Review changes, push to your fork, and open a PR targeting rpm/3.18
323
- ```
324
-
325
- *DEB:* Checkout the target branch and update these files:
326
- - `debian/gem.list` -- new gem filename
327
- - `foreman_openbolt.rb` -- new version
328
- - `debian/control` -- dependency versions (if changed)
329
- - `debian/changelog` -- add a new entry
330
-
331
- ```bash
332
- git checkout deb/3.18
333
- git checkout -b bump_deb/ruby-foreman-openbolt
334
- # Make the changes above, push to your fork, and open a PR targeting deb/3.18
335
- ```
data/Rakefile CHANGED
File without changes
@@ -53,7 +53,7 @@ module ForemanOpenbolt
53
53
  key = setting.name.sub(/^openbolt_/, '')
54
54
  if setting.encrypted?
55
55
  defaults[key] = ENCRYPTED_PLACEHOLDER unless setting.value.to_s.empty?
56
- else
56
+ elsif !setting.value.to_s.empty?
57
57
  defaults[key] = setting.value
58
58
  end
59
59
  end
@@ -136,6 +136,9 @@ module ForemanOpenbolt
136
136
  rescue ActiveRecord::RecordInvalid => e
137
137
  log_exception('launch_task', e)
138
138
  render_error("Database error: #{e.message}", :internal_server_error)
139
+ rescue ProxyAPI::ProxyException => e
140
+ log_exception('launch_task', e)
141
+ render_error("Smart Proxy error: #{e.message}", :bad_gateway)
139
142
  rescue StandardError => e
140
143
  log_exception('launch_task', e)
141
144
  render_error("Error launching task: #{e.message}", :internal_server_error)
@@ -35,6 +35,7 @@ module ForemanOpenbolt
35
35
  TRANSPORTS = {
36
36
  ssh: N_('SSH'),
37
37
  winrm: N_('WinRM'),
38
+ choria: N_('Choria'),
38
39
  }.freeze
39
40
  LOG_LEVELS = {
40
41
  error: N_('Error'),
@@ -43,28 +44,19 @@ module ForemanOpenbolt
43
44
  debug: N_('Debug'),
44
45
  trace: N_('Trace'),
45
46
  }.freeze
47
+ CHORIA_TASK_AGENTS = {
48
+ bolt_tasks: N_('Bolt Tasks'),
49
+ shell: N_('Shell'),
50
+ }.freeze
46
51
  # rubocop:enable Lint/ConstantDefinitionInBlock
47
52
 
48
- setting 'openbolt_transport',
49
- type: :string,
50
- default: 'ssh',
51
- full_name: N_('Transport'),
52
- description: N_('The transport method to use for connecting to target hosts'),
53
- collection: proc { TRANSPORTS }
53
+ # General (all transports)
54
54
  setting 'openbolt_log-level',
55
55
  type: :string,
56
56
  default: 'debug',
57
57
  full_name: N_('Log Level'),
58
58
  description: N_('Set the log level during OpenBolt execution'),
59
59
  collection: proc { LOG_LEVELS }
60
- setting 'openbolt_verbose',
61
- type: :boolean,
62
- default: false,
63
- full_name: N_('Verbose'),
64
- description: N_(
65
- 'Run the OpenBolt command with the --verbose flag. This prints additional information ' \
66
- 'during OpenBolt execution and will print any out::verbose plan statements.'
67
- )
68
60
  setting 'openbolt_noop',
69
61
  type: :boolean,
70
62
  default: false,
@@ -72,22 +64,132 @@ module ForemanOpenbolt
72
64
  description: N_(
73
65
  'Run the OpenBolt command with the --noop flag, which will make no changes to the target host'
74
66
  )
67
+ setting 'openbolt_password',
68
+ type: :string,
69
+ default: nil,
70
+ full_name: N_('Password'),
71
+ description: N_('Password used for SSH or WinRM authentication'),
72
+ encrypted: true
75
73
  setting 'openbolt_tmpdir',
76
74
  type: :string,
77
- default: '',
75
+ default: nil,
78
76
  full_name: N_('Temporary Directory'),
79
77
  description: N_('Directory to use for temporary files on target hosts during OpenBolt execution')
78
+ setting 'openbolt_transport',
79
+ type: :string,
80
+ default: 'ssh',
81
+ full_name: N_('Transport'),
82
+ description: N_('The transport method to use for connecting to target hosts'),
83
+ collection: proc { TRANSPORTS }
80
84
  setting 'openbolt_user',
81
85
  type: :string,
82
- default: '',
86
+ default: nil,
83
87
  full_name: N_('User'),
84
88
  description: N_('Username used for SSH or WinRM authentication')
85
- setting 'openbolt_password',
89
+ setting 'openbolt_verbose',
90
+ type: :boolean,
91
+ default: false,
92
+ full_name: N_('Verbose'),
93
+ description: N_(
94
+ 'Run the OpenBolt command with the --verbose flag. This prints additional information ' \
95
+ 'during OpenBolt execution and will print any out::verbose plan statements.'
96
+ )
97
+
98
+ # Choria
99
+ setting 'openbolt_choria-broker-timeout',
100
+ type: :integer,
101
+ default: nil,
102
+ full_name: N_('Choria Broker Timeout'),
103
+ description: N_('Time in seconds to wait when establishing a connection to a Choria broker.')
104
+ setting 'openbolt_choria-brokers',
86
105
  type: :string,
87
- default: '',
88
- full_name: N_('Password'),
89
- description: N_('Password used for SSH or WinRM authentication'),
90
- encrypted: true
106
+ default: nil,
107
+ full_name: N_('Choria Brokers'),
108
+ description: N_(
109
+ 'Comma-separated list of Choria broker addresses in host or host:port format ' \
110
+ '(e.g. broker1.example.com:4222,broker2.example.com:4222). Port defaults to 4222 if omitted. ' \
111
+ 'When not set, the Choria client checks the config file, then SRV records, then falls back to puppet:4222.'
112
+ )
113
+ setting 'openbolt_choria-collective',
114
+ type: :string,
115
+ default: nil,
116
+ full_name: N_('Choria Collective'),
117
+ description: N_('Choria collective to route messages through.')
118
+ setting 'openbolt_choria-command-timeout',
119
+ type: :integer,
120
+ default: nil,
121
+ full_name: N_('Choria Command Timeout'),
122
+ description: N_('Time in seconds to wait for command completion on target nodes.')
123
+ setting 'openbolt_choria-config-file',
124
+ type: :string,
125
+ default: nil,
126
+ full_name: N_('Choria Config File'),
127
+ description: N_(
128
+ 'Path on the smart proxy host to the Choria client configuration file. This file ' \
129
+ 'must be readable by the foreman-proxy user. When not set, the proxy uses a built-in default.'
130
+ )
131
+ setting 'openbolt_choria-mcollective-certname',
132
+ type: :string,
133
+ default: nil,
134
+ full_name: N_('Choria MCollective Certname'),
135
+ description: N_(
136
+ 'Override the MCollective certname for Choria client identity. When not set, the ' \
137
+ 'proxy derives this automatically from its SSL certificate.'
138
+ )
139
+ setting 'openbolt_choria-puppet-environment',
140
+ type: :string,
141
+ default: nil,
142
+ full_name: N_('Choria Puppet Environment'),
143
+ description: N_(
144
+ 'Puppet environment used by the Choria bolt_tasks agent to locate task files. ' \
145
+ "Only applies when the Choria Task Agent is 'bolt_tasks'. Defaults to " \
146
+ "'production' when not specified."
147
+ )
148
+ setting 'openbolt_choria-rpc-timeout',
149
+ type: :integer,
150
+ default: nil,
151
+ full_name: N_('Choria RPC Timeout'),
152
+ description: N_('Time in seconds to wait for RPC responses from target nodes.')
153
+ setting 'openbolt_choria-ssl-ca',
154
+ type: :string,
155
+ default: nil,
156
+ full_name: N_('Choria SSL CA'),
157
+ description: N_(
158
+ 'Path on the smart proxy host to the Choria CA certificate. This file must be ' \
159
+ 'readable by the foreman-proxy user.'
160
+ )
161
+ setting 'openbolt_choria-ssl-cert',
162
+ type: :string,
163
+ default: nil,
164
+ full_name: N_('Choria SSL Certificate'),
165
+ description: N_(
166
+ 'Path on the smart proxy host to the Choria client SSL certificate. This file ' \
167
+ 'must be readable by the foreman-proxy user.'
168
+ )
169
+ setting 'openbolt_choria-ssl-key',
170
+ type: :string,
171
+ default: nil,
172
+ full_name: N_('Choria SSL Key'),
173
+ description: N_(
174
+ 'Path on the smart proxy host to the Choria client SSL private key. This file ' \
175
+ 'must be readable by the foreman-proxy user.'
176
+ )
177
+ setting 'openbolt_choria-task-agent',
178
+ type: :string,
179
+ default: 'bolt_tasks',
180
+ full_name: N_('Choria Task Agent'),
181
+ description: N_(
182
+ 'Choria agent used to execute tasks on target nodes. Use the bolt_tasks agent for ' \
183
+ 'standard OpenBolt tasks, or the shell agent to run shell commands.'
184
+ ),
185
+ collection: proc { CHORIA_TASK_AGENTS }
186
+ setting 'openbolt_choria-task-timeout',
187
+ type: :integer,
188
+ default: nil,
189
+ full_name: N_('Choria Task Timeout'),
190
+ description: N_('Time in seconds to wait for task completion on target nodes.')
191
+
192
+ # SSH
91
193
  setting 'openbolt_host-key-check',
92
194
  type: :boolean,
93
195
  default: true,
@@ -95,7 +197,7 @@ module ForemanOpenbolt
95
197
  description: N_('Whether to perform host key verification when connecting to targets over SSH')
96
198
  setting 'openbolt_private-key',
97
199
  type: :string,
98
- default: '',
200
+ default: nil,
99
201
  full_name: N_('SSH Private Key'),
100
202
  description: N_(
101
203
  'Path on the smart proxy host to the private key used for SSH authentication. This key must be ' \
@@ -103,7 +205,7 @@ module ForemanOpenbolt
103
205
  )
104
206
  setting 'openbolt_run-as',
105
207
  type: :string,
106
- default: '',
208
+ default: nil,
107
209
  full_name: N_('SSH Run As User'),
108
210
  description: N_(
109
211
  'The user to run commands as on the target host. This requires that the user specified ' \
@@ -111,10 +213,12 @@ module ForemanOpenbolt
111
213
  )
112
214
  setting 'openbolt_sudo-password',
113
215
  type: :string,
114
- default: '',
216
+ default: nil,
115
217
  full_name: N_('SSH Sudo Password'),
116
218
  description: N_('Password used for privilege escalation when using SSH'),
117
219
  encrypted: true
220
+
221
+ # WinRM
118
222
  setting 'openbolt_ssl',
119
223
  type: :boolean,
120
224
  default: true,
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module ForemanOpenbolt
4
- VERSION = '1.1.0'
4
+ VERSION = '1.2.0'
5
5
  end
@@ -52,15 +52,25 @@ module ProxyAPI
52
52
  end
53
53
 
54
54
  def parse_response(response, operation)
55
- raise ProxyException.new(@url, nil, "No response from Smart Proxy during #{operation}") unless response
55
+ unless response
56
+ raise ProxyException.new(
57
+ @url, RuntimeError.new("No response from Smart Proxy during #{operation}"),
58
+ "No response from Smart Proxy during #{operation}"
59
+ )
60
+ end
56
61
 
57
62
  body = response.body
58
- raise ProxyException.new(@url, nil, "Empty response body from Smart Proxy during #{operation}") if body.nil?
63
+ if body.nil?
64
+ raise ProxyException.new(
65
+ @url, RuntimeError.new("Empty response body from Smart Proxy during #{operation}"),
66
+ "Empty response body from Smart Proxy during #{operation}"
67
+ )
68
+ end
59
69
 
60
70
  JSON.parse(body)
61
71
  rescue JSON::ParserError => e
62
72
  raise ProxyException.new(
63
- @url, nil,
73
+ @url, e,
64
74
  "Invalid JSON from Smart Proxy during #{operation}: #{e.message}. " \
65
75
  "Response body (first 500 chars): #{body.to_s[0..500]}"
66
76
  )
data/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "foreman_openbolt",
3
- "version": "1.1.0",
3
+ "version": "1.2.0",
4
4
  "description": "OpenBolt integration into Foreman",
5
5
  "main": "index.js",
6
6
  "scripts": {