Skip to content

Commit

Permalink
(PUP-9212) Add acceptance tests
Browse files Browse the repository at this point in the history
The acceptance tests added in this are not compatible with the canned
beaker vagrant host files, but should use the supplied dockerfile found
in nodesets/docker/docker.yml. The acceptance rake task has been
hardcoded to the hostfile at spec/acceptance/nodesets/docker/docker.yml.

To execute the acceptance test, use `rake acceptance`. Please note that
`rake beaker` won't automatically use the supported hostfile.
  • Loading branch information
tvpartytonight authored and pcarlisle committed Oct 31, 2018
1 parent a5905ec commit 1ae0857
Show file tree
Hide file tree
Showing 9 changed files with 459 additions and 0 deletions.
2 changes: 2 additions & 0 deletions Rakefile
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,8 @@ end

desc 'Run acceptance tests'
RSpec::Core::RakeTask.new(:acceptance) do |t|
puts 'acceptance task is hard-coded to use spec/acceptance/nodesets/docker/docker.yml'
ENV['BEAKER_setfile'] = 'spec/acceptance/nodesets/docker/docker.yml'
t.pattern = 'spec/acceptance'
end

Expand Down
132 changes: 132 additions & 0 deletions spec/acceptance/fixtures/intermediate_ca_openssl.cnf
Original file line number Diff line number Diff line change
@@ -0,0 +1,132 @@
# OpenSSL intermediate CA configuration file.
# Copy to `/root/ca/intermediate/openssl.cnf`.

[ ca ]
# `man ca`
default_ca = CA_default

[ CA_default ]
# Directory and file locations.
dir = /root/ca/intermediate
certs = $dir/certs
crl_dir = $dir/crl
new_certs_dir = $dir/newcerts
database = $dir/index.txt
serial = $dir/serial
RANDFILE = $dir/private/.rand

# The root key and root certificate.
private_key = $dir/private/intermediate.key.pem
certificate = $dir/certs/intermediate.cert.pem

# For certificate revocation lists.
crlnumber = $dir/crlnumber
crl = $dir/crl/intermediate.crl.pem
crl_extensions = crl_ext
default_crl_days = 30

# SHA-1 is deprecated, so use SHA-2 instead.
default_md = sha256

name_opt = ca_default
cert_opt = ca_default
default_days = 375
preserve = no
policy = policy_loose

[ policy_strict ]
# The root CA should only sign intermediate certificates that match.
# See the POLICY FORMAT section of `man ca`.
countryName = match
stateOrProvinceName = match
organizationName = match
organizationalUnitName = optional
commonName = supplied
emailAddress = optional

[ policy_loose ]
# Allow the intermediate CA to sign a more diverse range of certificates.
# See the POLICY FORMAT section of the `ca` man page.
countryName = optional
stateOrProvinceName = optional
localityName = optional
organizationName = optional
organizationalUnitName = optional
commonName = supplied
emailAddress = optional

[ req ]
# Options for the `req` tool (`man req`).
default_bits = 2048
distinguished_name = req_distinguished_name
string_mask = utf8only

# SHA-1 is deprecated, so use SHA-2 instead.
default_md = sha256

# Extension to add when the -x509 option is used.
x509_extensions = v3_ca

[ req_distinguished_name ]
# See <https://en.wikipedia.org/wiki/Certificate_signing_request>.
countryName = Country Name (2 letter code)
stateOrProvinceName = State or Province Name
localityName = Locality Name
0.organizationName = Organization Name
organizationalUnitName = Organizational Unit Name
commonName = Common Name
emailAddress = Email Address

# Optionally, specify some defaults.
countryName_default = GB
stateOrProvinceName_default = England
localityName_default =
0.organizationName_default = Alice Ltd
organizationalUnitName_default =
emailAddress_default =

[ v3_ca ]
# Extensions for a typical CA (`man x509v3_config`).
subjectKeyIdentifier = hash
authorityKeyIdentifier = keyid:always,issuer
basicConstraints = critical, CA:true
keyUsage = critical, digitalSignature, cRLSign, keyCertSign

[ v3_intermediate_ca ]
# Extensions for a typical intermediate CA (`man x509v3_config`).
subjectKeyIdentifier = hash
authorityKeyIdentifier = keyid:always,issuer
basicConstraints = critical, CA:true, pathlen:0
keyUsage = critical, digitalSignature, cRLSign, keyCertSign

[ usr_cert ]
# Extensions for client certificates (`man x509v3_config`).
basicConstraints = CA:FALSE
nsCertType = client, email
nsComment = "OpenSSL Generated Client Certificate"
subjectKeyIdentifier = hash
authorityKeyIdentifier = keyid,issuer
keyUsage = critical, nonRepudiation, digitalSignature, keyEncipherment
extendedKeyUsage = clientAuth, emailProtection

[ server_cert ]
# Extensions for server certificates (`man x509v3_config`).
basicConstraints = CA:FALSE
nsCertType = server
nsComment = "OpenSSL Generated Server Certificate"
subjectKeyIdentifier = hash
authorityKeyIdentifier = keyid,issuer:always
keyUsage = critical, digitalSignature, keyEncipherment
extendedKeyUsage = serverAuth

[ crl_ext ]
# Extension for CRLs (`man x509v3_config`).
authorityKeyIdentifier=keyid:always

[ ocsp ]
# Extension for OCSP signing certificates (`man ocsp`).
basicConstraints = CA:FALSE
subjectKeyIdentifier = hash
authorityKeyIdentifier = keyid,issuer
keyUsage = critical, digitalSignature
extendedKeyUsage = critical, OCSPSigning
132 changes: 132 additions & 0 deletions spec/acceptance/fixtures/root_ca_openssl.cnf
Original file line number Diff line number Diff line change
@@ -0,0 +1,132 @@
# OpenSSL root CA configuration file.
# Copy to `/root/ca/openssl.cnf`.

[ ca ]
# `man ca`
default_ca = CA_default

[ CA_default ]
# Directory and file locations.
dir = /root/ca
certs = $dir/certs
crl_dir = $dir/crl
new_certs_dir = $dir/newcerts
database = $dir/index.txt
serial = $dir/serial
RANDFILE = $dir/private/.rand

# The root key and root certificate.
private_key = $dir/private/rootca.key.pem
certificate = $dir/certs/rootca.cert.pem

# For certificate revocation lists.
crlnumber = $dir/crlnumber
crl = $dir/crl/ca.crl.pem
crl_extensions = crl_ext
default_crl_days = 30

# SHA-1 is deprecated, so use SHA-2 instead.
default_md = sha256

name_opt = ca_default
cert_opt = ca_default
default_days = 375
preserve = no
policy = policy_strict

[ policy_strict ]
# The root CA should only sign intermediate certificates that match.
# See the POLICY FORMAT section of `man ca`.
countryName = optional
stateOrProvinceName = optional
organizationName = optional
organizationalUnitName = optional
commonName = supplied
emailAddress = optional

[ policy_loose ]
# Allow the intermediate CA to sign a more diverse range of certificates.
# See the POLICY FORMAT section of the `ca` man page.
countryName = optional
stateOrProvinceName = optional
localityName = optional
organizationName = optional
organizationalUnitName = optional
commonName = supplied
emailAddress = optional

[ req ]
# Options for the `req` tool (`man req`).
default_bits = 2048
distinguished_name = req_distinguished_name
string_mask = utf8only

# SHA-1 is deprecated, so use SHA-2 instead.
default_md = sha256

# Extension to add when the -x509 option is used.
x509_extensions = v3_ca

[ req_distinguished_name ]
# See <https://en.wikipedia.org/wiki/Certificate_signing_request>.
countryName = Country Name (2 letter code)
stateOrProvinceName = State or Province Name
localityName = Locality Name
0.organizationName = Organization Name
organizationalUnitName = Organizational Unit Name
commonName = Common Name
emailAddress = Email Address

# Optionally, specify some defaults.
countryName_default = GB
stateOrProvinceName_default = England
localityName_default =
0.organizationName_default = Alice Ltd
organizationalUnitName_default =
emailAddress_default =

[ v3_ca ]
# Extensions for a typical CA (`man x509v3_config`).
subjectKeyIdentifier = hash
authorityKeyIdentifier = keyid:always,issuer
basicConstraints = critical, CA:true
keyUsage = critical, digitalSignature, cRLSign, keyCertSign

[ v3_intermediate_ca ]
# Extensions for a typical intermediate CA (`man x509v3_config`).
subjectKeyIdentifier = hash
authorityKeyIdentifier = keyid:always,issuer
basicConstraints = critical, CA:true, pathlen:0
keyUsage = critical, digitalSignature, cRLSign, keyCertSign

[ usr_cert ]
# Extensions for client certificates (`man x509v3_config`).
basicConstraints = CA:FALSE
nsCertType = client, email
nsComment = "OpenSSL Generated Client Certificate"
subjectKeyIdentifier = hash
authorityKeyIdentifier = keyid,issuer
keyUsage = critical, nonRepudiation, digitalSignature, keyEncipherment
extendedKeyUsage = clientAuth, emailProtection

[ server_cert ]
# Extensions for server certificates (`man x509v3_config`).
basicConstraints = CA:FALSE
nsCertType = server
nsComment = "OpenSSL Generated Server Certificate"
subjectKeyIdentifier = hash
authorityKeyIdentifier = keyid,issuer:always
keyUsage = critical, digitalSignature, keyEncipherment
extendedKeyUsage = serverAuth

[ crl_ext ]
# Extension for CRLs (`man x509v3_config`).
authorityKeyIdentifier=keyid:always

[ ocsp ]
# Extension for OCSP signing certificates (`man ocsp`).
basicConstraints = CA:FALSE
subjectKeyIdentifier = hash
authorityKeyIdentifier = keyid,issuer
keyUsage = critical, digitalSignature
extendedKeyUsage = critical, OCSPSigning
7 changes: 7 additions & 0 deletions spec/acceptance/fixtures/site.pp
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
$d = Deferred('vault_lookup::lookup',["secret/test", 'https://vault.local:8200'])

node default {
notify { example :
message => $d
}
}
34 changes: 34 additions & 0 deletions spec/acceptance/fixtures/unseal.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
#!/bin/sh
set -e

export VAULT_ADDR=https://vault.local:8200
export VAULT_CLIENT_KEY=/vault/config/vault.key
export VAULT_CLIENT_CERT=/vault/config/vault.cert
export VAULT_CACERT=/vault/config/certbundle.pem
echo "Initialize Vault"
vault operator init -key-shares=1 -key-threshold=1 | tee vault.keys
VAULT_TOKEN=$(grep '^Initial' vault.keys | awk '{print $4}')
VAULT_KEY=$(grep '^Unseal Key 1:' vault.keys | awk '{print $4}')

export VAULT_TOKEN

vault operator unseal "$VAULT_KEY"

echo "Create secret_reader policy that can read from secret/*"

vault policy write secret_reader - <<EOF
path "secret/*" {
capabilities = ["read"]
}
EOF

echo "Enable cert auth and add puppet server CA for secret_reader"
echo "Adding cert auth paths."

vault auth enable cert

vault write auth/cert/certs/vault.docker display_name='puppet cert' certificate=@/vault/config/certbundle.pem policies=secret_reader

echo 'Write secret/test: foo=bar'

vault write secret/test foo=bar
14 changes: 14 additions & 0 deletions spec/acceptance/fixtures/vault_config.hcl
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
{
"backend": {
"file": {
"path": "/vault/file"
}
},
"listener": {
"tcp": {
"address": "0.0.0.0:8200",
"tls_key_file": "/vault/config/vault.key",
"tls_cert_file": "/vault/config/vault.cert"
}
}
}
47 changes: 47 additions & 0 deletions spec/acceptance/lookup_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
require 'beaker-rspec'
require 'beaker-rspec/spec_helper'
require 'beaker-puppet'
require 'beaker/puppet_install_helper'
require 'beaker/module_install_helper'

describe 'lookup with vault configured to accept certs from puppetserver' do
before(:all) do
# install here doesn't really install, it just moves the module over to
# the host machine; after install, the test needs to move it somewhere
# on the module path.
install_module_on(master)
on(master, 'mv /vault_lookup /etc/puppetlabs/code/environments/production/modules')
vault = find_host_with_role('vault')
scp_to(vault, 'spec/acceptance/fixtures/unseal.sh', '/root/unseal.sh')
on(vault, 'su root /root/unseal.sh')

# Move the PKI infrastructure created on the vault container onto puppetserver
tmpdir = Dir.mktmpdir
scp_from(vault, '/root/ca/intermediate/private/intermediate.key.pem', tmpdir)
scp_from(vault, '/vault/config/crlchain.pem', tmpdir)
scp_from(vault, '/vault/config/certbundle.pem', tmpdir)
scp_to(master, "#{tmpdir}/crlchain.pem", '/root/crlchain.pem')
scp_to(master, "#{tmpdir}/intermediate.key.pem", '/root/intermediate.key.pem')
scp_to(master, "#{tmpdir}/certbundle.pem", '/root/certbundle.pem')

# Something fails here with the find and delete file type, and the ca/infra_serials
# is often left behind or instantly regenerated after the delete; sleeping momentarily
# and then trying to ensure it is deleted has been successful...
on(master, 'find /etc/puppetlabs/puppet/ssl/ -type f -delete')
sleep 3
on(master, 'rm /etc/puppetlabs/puppet/ssl/ca/infra_serials', acceptable_exit_codes: [0, 1])

on(master, '/opt/puppetlabs/bin/puppetserver ca import --cert-bundle /root/certbundle.pem --crl-chain /root/crlchain.pem --private-key /root/intermediate.key.pem')
on(master, 'service puppetserver reload')
end

it 'retrieves a secret from vault during an agent run' do
scp_to(
master,
'spec/acceptance/fixtures/site.pp',
'/etc/puppetlabs/code/environments/production/manifests',
)
response = on(master, '/opt/puppetlabs/bin/puppet agent -t --server puppetserver.local', acceptable_exit_codes: [0, 2])
assert_match(%r{Notice.+foo.+bar}, response.stdout)
end
end
Loading

0 comments on commit 1ae0857

Please sign in to comment.