Skip to content

Commit f6c4cde

Browse files
authored
Merge pull request #27 from voxpupuli/configure_openvox
Configure openvox
2 parents 4577518 + a0232ae commit f6c4cde

File tree

17 files changed

+988
-33
lines changed

17 files changed

+988
-33
lines changed
Lines changed: 175 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,175 @@
1+
---
2+
name: 'PR Testing the configure task'
3+
4+
on:
5+
push:
6+
branches:
7+
- main
8+
pull_request:
9+
branches:
10+
- main
11+
12+
env:
13+
# These openvox_bootstrap::configure parameters are used in both
14+
# the agent and server task runs, but puppet_conf will vary.
15+
COMMON_CONFIGURE_PARAMS: |-
16+
"csr_attributes": {
17+
"custom_attributes": {
18+
"1.2.840.113549.1.9.7": "password"
19+
},
20+
"extension_requests": {
21+
"pp_role": "tomato"
22+
}
23+
},
24+
"puppet_service_running": true,
25+
"puppet_service_enabled": false
26+
27+
jobs:
28+
test-configure-task:
29+
strategy:
30+
matrix:
31+
os:
32+
- [almalinux, '9']
33+
- [ubuntu, '24.04']
34+
runs-on: ubuntu-22.04
35+
steps:
36+
- uses: actions/checkout@v4
37+
- id: install-bolt
38+
uses: ./.github/actions/bolt
39+
with:
40+
os-codename: jammy
41+
- id: vm-cluster
42+
uses: jpartlow/nested_vms@v1
43+
with:
44+
os: ${{ matrix.os[0] }}
45+
os-version: ${{ matrix.os[1] }}
46+
os-arch: ${{ matrix.os[2] || 'x86_64' }}
47+
host-root-access: true
48+
ruby-version: '3.3'
49+
install-openvox: false
50+
vms: |-
51+
[
52+
{
53+
"role": "primary",
54+
"cpus": 4,
55+
"mem_mb": 8192,
56+
"cpu_mode": "host-model"
57+
},
58+
{
59+
"role": "agent",
60+
"cpus": 2,
61+
"mem_mb": 4096,
62+
"cpu_mode": "host-model"
63+
}
64+
]
65+
- name: Capture dereferenced inventory for use with openvox_bootstrap
66+
working-directory: kvm_automation_tooling
67+
run: |-
68+
bolt inventory --inventory terraform/instances/inventory.test.yaml show --format json --detail | \
69+
jq '.inventory | with_entries(select(.key == "targets")) | del(.targets[].groups)' | \
70+
yq -P > ../inventory.yaml
71+
cat ../inventory.yaml
72+
- name: Install openvox
73+
run: |-
74+
bolt task run openvox_bootstrap::install --inventory inventory.yaml --targets test-primary-1,test-agent-1
75+
- name: Install openvox-server
76+
run: |-
77+
bolt task run openvox_bootstrap::install --inventory inventory.yaml --targets test-primary-1 package=openvox-server
78+
- name: Disable agents to prevent background service runs
79+
run: |-
80+
bolt command run '/opt/puppetlabs/bin/puppet agent --disable "OpenVox PR testing"' --inventory inventory.yaml --targets test-agent-1,test-primary-1
81+
- name: Write server configure params
82+
run: |-
83+
cat > server-params.json <<EOF
84+
{
85+
"puppet_conf": {
86+
"main": {
87+
"server": "test-primary-1.vm"
88+
},
89+
"server": {
90+
"autosign": "/etc/puppetlabs/puppet/sign.sh"
91+
}
92+
},
93+
${COMMON_CONFIGURE_PARAMS}
94+
}
95+
EOF
96+
cat server-params.json
97+
- name: Run openvox_boostrap::configure task on the primary
98+
run: |-
99+
bolt task run openvox_bootstrap::configure --inventory inventory.yaml --targets test-primary-1 --params @server-params.json
100+
- name: Configure openvox-server
101+
env:
102+
PUPPET_CONF: |-
103+
SIGN_SH: |-
104+
run: |-
105+
cat > sign.sh <<'EOF'
106+
#!/bin/bash
107+
set -e
108+
csr_pem=$(cat)
109+
csr_text=$(openssl req -text <<<"$csr_pem")
110+
password=$(awk -F: -e '/challengePassword/ { print $2 }' <<<"$csr_text")
111+
[[ "${password}" == 'password' ]]
112+
EOF
113+
bolt file upload sign.sh /etc/puppetlabs/puppet/sign.sh --inventory inventory.yaml --targets test-primary-1
114+
115+
cat > standup.sh <<'EOF'
116+
#! /bin/bash
117+
set -e
118+
set -x
119+
120+
chmod 750 /etc/puppetlabs/puppet/sign.sh
121+
chown puppet:puppet /etc/puppetlabs/puppet/sign.sh
122+
123+
set +e
124+
systemctl start puppetserver
125+
if [ $? -ne 0 ]; then
126+
cat /var/log/puppetlabs/puppetserver/puppetserver.log
127+
exit 1
128+
fi
129+
EOF
130+
bolt script run standup.sh --inventory inventory.yaml --targets test-primary-1 --stream
131+
- name: Write agent configure params
132+
run: |-
133+
cat > agent-params.json <<EOF
134+
{
135+
"puppet_conf": {
136+
"main": {
137+
"server": "test-primary-1.vm"
138+
}
139+
},
140+
${COMMON_CONFIGURE_PARAMS}
141+
}
142+
EOF
143+
cat agent-params.json
144+
- name: Run openvox_bootstrap::configure task on the agent
145+
run: |-
146+
bolt task run openvox_bootstrap::configure --inventory inventory.yaml --targets test-agent-1 --params @agent-params.json
147+
- name: Validate agent run on the primary
148+
run: |-
149+
bolt command run '/opt/puppetlabs/bin/puppet agent --agent_disabled_lockfile=/tmp/not_locked.lock --test' --inventory inventory.yaml --targets test-primary-1 --stream
150+
- name: Validate agent run on the agent
151+
run: |-
152+
bolt command run '/opt/puppetlabs/bin/puppet agent --agent_disabled_lockfile=/tmp/not_locked.lock --test' --inventory inventory.yaml --targets test-agent-1 --stream
153+
- name: Validate certificate extensions
154+
run: |-
155+
cat > site.pp <<'EOF'
156+
node default {
157+
notify { "Trusted Facts":
158+
message => $trusted,
159+
}
160+
if $trusted.dig('extensions', 'pp_role') != 'tomato' {
161+
fail("Certificate extension 'pp_role' should be 'tomato'. trusted['extensions'] = ${trusted['extensions']}")
162+
}
163+
}
164+
EOF
165+
bolt file upload site.pp /etc/puppetlabs/code/environments/production/manifests/site.pp --inventory inventory.yaml --targets test-primary-1
166+
bolt command run '/opt/puppetlabs/bin/puppet agent --agent_disabled_lockfile=/tmp/not_locked.lock --onetime --verbose --no-daemonize' --inventory inventory.yaml --targets test-primary-1,test-agent-1 --stream
167+
- name: Validate service state
168+
run: |-
169+
cat > apply.sh <<'EOF'
170+
set -e
171+
/opt/puppetlabs/bin/puppet apply --test -e 'service { "puppet": ensure => running, enable => false }'
172+
EOF
173+
# Use script rather than bolt apply so that we trip if the
174+
# apply produces changes and returns an exitcode of 2.
175+
bolt script run apply.sh --inventory inventory.yaml --targets test-agent-1,test-primary-1 --stream

README.md

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,60 @@ bolt task run openvox_bootstrap::install_build_artifact \
7474
--run-as root
7575
```
7676

77+
### openvox_bootstrap::configure
78+
79+
The openvox_bootstrap::configure task can be used to provide very
80+
basic initial configuration for the openvox agent.
81+
82+
It does not install the agent. Run openvox_bootstrap::install first.
83+
Since the agent service is installed stopped, configuration can
84+
be laid down before the first run begins the certificate request
85+
process.
86+
87+
It provides the following support:
88+
89+
* laying down an initial puppet.conf (primary use case being to set
90+
the [server] parameter to point to the openvox-server).
91+
* creating a [csr_attributes.yaml] file for the agent to use when
92+
generating a CSR for use with autosigning scripts and to provide
93+
extension data to the generated certificate.
94+
* ensuring the `puppet` service is in a preferred state.
95+
96+
NOTE: the csr_attributes.yaml will overwrite any pre-existing files,
97+
but settings for puppet.conf will be merged into an existing file if
98+
present.
99+
100+
With an example params.json file like this:
101+
102+
```json
103+
{
104+
"puppet_conf": {
105+
"main": {
106+
"server": "puppetserver.foo"
107+
}
108+
},
109+
"csr_attributes": {
110+
"custom_attributes": {
111+
"1.2.840.113549.1.9.7": "password"
112+
},
113+
"extension_requests": {
114+
"pp_role": "thing1"
115+
}
116+
},
117+
"puppet_service_running": true,
118+
"puppet_service_enabled": true
119+
}
120+
```
121+
122+
You can run the task like this:
123+
124+
```sh
125+
bolt task run openvox_bootstrap::configure \
126+
--targets <target> \
127+
--params @params.json \
128+
--run-as root
129+
```
130+
77131
## Reference
78132

79133
See [REFERENCE.md](./REFERENCE.md) for the generated reference doc.
@@ -117,3 +171,5 @@ along with this program. If not, see <https://www.gnu.org/licenses/>.
117171
[puppet_agent::install tasks]: https://github.com/puppetlabs/puppetlabs-puppet_agent/tree/main?tab=readme-ov-file#puppet_agentinstall
118172
[apply_prep]: https://www.puppet.com/docs/bolt/latest/plan_functions#apply-prep
119173
[puppet_library]: https://www.puppet.com/docs/bolt/latest/using_plugins#puppet-library-plugins
174+
[server]: https://github.com/puppetlabs/puppet/blob/main/references/configuration.md#server
175+
[csr_attributes.yaml]: https://help.puppet.com/core/current/Content/PuppetCore/config_file_csr_attributes.htm

REFERENCE.md

Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,12 +4,61 @@
44

55
## Table of Contents
66

7+
### Data types
8+
9+
* [`Openvox_bootstrap::Cer_short_names`](#Openvox_bootstrap--Cer_short_names): Certificate extension request short names. These are the allowed short names documented for Puppet(TM) extension requests per [csr_attributes
10+
* [`Openvox_bootstrap::Csr_attributes`](#Openvox_bootstrap--Csr_attributes): [csr_attributes.yaml](https://help.puppet.com/core/current/Content/PuppetCore/config_file_csr_attributes.htm)
11+
* [`Openvox_bootstrap::Ini_file`](#Openvox_bootstrap--Ini_file): Simple type for data to be transformed to an INI file format.
12+
* [`Openvox_bootstrap::Oid`](#Openvox_bootstrap--Oid): Object Identifier per https://en.wikipedia.org/wiki/Object_identifier
13+
714
### Tasks
815

916
* [`check`](#check): Check whether a Puppet(tm) implementation is installed. Optionally checks the version.
17+
* [`configure`](#configure): Provides initial configuration for a freshly installed openvox-agent.
1018
* [`install`](#install): Installs an openvox package. By default, this will be the latest openvox-agent from the latest collection.
1119
* [`install_build_artifact`](#install_build_artifact): Downloads and installs a package directly from the openvox build artifact server.
1220

21+
## Data types
22+
23+
### <a name="Openvox_bootstrap--Cer_short_names"></a>`Openvox_bootstrap::Cer_short_names`
24+
25+
Certificate extension request short names.
26+
These are the allowed short names documented for Puppet(TM)
27+
extension requests per [csr_attributes.yaml](https://help.puppet.com/core/current/Content/PuppetCore/config_file_csr_attributes.htm)
28+
29+
Alias of `Enum['pp_uuid', 'pp_instance_id', 'pp_image_name', 'pp_preshared_key', 'pp_cost_center', 'pp_product', 'pp_project', 'pp_application', 'pp_service', 'pp_employee', 'pp_created_by', 'pp_environment', 'pp_role', 'pp_software_version', 'pp_department', 'pp_cluster', 'pp_provisioner', 'pp_region', 'pp_datacenter', 'pp_zone', 'pp_network', 'pp_securitypolicy', 'pp_cloudplatform', 'pp_apptier', 'pp_hostname', 'pp_authorization', 'pp_auth_role']`
30+
31+
### <a name="Openvox_bootstrap--Csr_attributes"></a>`Openvox_bootstrap::Csr_attributes`
32+
33+
[csr_attributes.yaml](https://help.puppet.com/core/current/Content/PuppetCore/config_file_csr_attributes.htm)
34+
35+
Alias of
36+
37+
```puppet
38+
Struct[{
39+
Optional['custom_attributes'] => Hash[
40+
Openvox_bootstrap::Oid,
41+
String
42+
],
43+
Optional['extension_requests'] => Hash[
44+
Variant[Openvox_bootstrap::Oid,Openvox_bootstrap::Cer_short_names],
45+
String
46+
],
47+
}]
48+
```
49+
50+
### <a name="Openvox_bootstrap--Ini_file"></a>`Openvox_bootstrap::Ini_file`
51+
52+
Simple type for data to be transformed to an INI file format.
53+
54+
Alias of `Hash[String, Hash[String, String]]`
55+
56+
### <a name="Openvox_bootstrap--Oid"></a>`Openvox_bootstrap::Oid`
57+
58+
Object Identifier per https://en.wikipedia.org/wiki/Object_identifier
59+
60+
Alias of `Pattern[/\d+(\.\d+)*/]`
61+
1362
## Tasks
1463

1564
### <a name="check"></a>`check`
@@ -32,6 +81,38 @@ Data type: `Enum['eq', 'lt', 'le', 'gt', 'ge']`
3281

3382
Version comparison operator.
3483

84+
### <a name="configure"></a>`configure`
85+
86+
Provides initial configuration for a freshly installed openvox-agent.
87+
88+
**Supports noop?** false
89+
90+
#### Parameters
91+
92+
##### `puppet_conf`
93+
94+
Data type: `Optional[Openvox_bootstrap::Ini_file]`
95+
96+
Hash of puppet configuration settings to add to the puppet.conf ini file. These will be merged into the existing puppet.conf, if any.
97+
98+
##### `csr_attributes`
99+
100+
Data type: `Optional[Openvox_bootstrap::Csr_attributes]`
101+
102+
Hash of CSR attributes (custom_attributes and extension_requests) to write to the csr_attributes.yaml file. NOTE: This will completely overwrite any pre-existing csr_attributes.yaml.
103+
104+
##### `puppet_service_running`
105+
106+
Data type: `Boolean`
107+
108+
Whether the Puppet service should be running after this task completes. Defaults to true.
109+
110+
##### `puppet_service_enabled`
111+
112+
Data type: `Boolean`
113+
114+
Whether the Puppet service should be enabled to start on boot after this task completes. Defaults to true.
115+
35116
### <a name="install"></a>`install`
36117

37118
Installs an openvox package. By default, this will be the latest openvox-agent from the latest collection.

lib/openvox_bootstrap/task.rb

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
# frozen_string_literal: true
2+
3+
require 'json'
4+
5+
module OpenvoxBootstrap
6+
# Base class for openvox_bootstrap Ruby tasks.
7+
class Task
8+
# Run the task and print the result as JSON.
9+
def self.run
10+
params = JSON.parse($stdin.read)
11+
raise(ArgumentError, <<~ERR) unless params.is_a?(Hash)
12+
Expected a Hash, got #{params.class}: #{params.inspect}
13+
ERR
14+
15+
params.transform_keys!(&:to_sym)
16+
# Clean out empty params so that task defaults are used.
17+
params.delete_if { |_, v| v.nil? || v == '' }
18+
19+
result = new.task(**params)
20+
puts JSON.pretty_generate(result)
21+
22+
result
23+
end
24+
end
25+
end

spec/bash_spec_helper.rb

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
# frozen_string_literal: true
22

3+
require 'json'
34
require 'tmpdir'
45
require 'rspec'
56
require 'lib/bash_rspec'

0 commit comments

Comments
 (0)