Skip to content

Commit

Permalink
Merge pull request #112 from dafyddj/kitchen-vagrant
Browse files Browse the repository at this point in the history
Windows testing using kitchen-vagrant
  • Loading branch information
myii authored Nov 5, 2019
2 parents 06a09f2 + 0229d14 commit 5a263e0
Show file tree
Hide file tree
Showing 15 changed files with 183 additions and 111 deletions.
2 changes: 2 additions & 0 deletions .rubocop.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,3 +8,5 @@ Metrics/LineLength:
Max: 88

# Any offenses that should be fixed, e.g. collected via. `rubocop --auto-gen-config`
Metrics/BlockLength:
Max: 36
21 changes: 5 additions & 16 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -21,17 +21,14 @@ stages:
- name: release
if: branch = master AND type != pull_request
jobs:
allow_failures:
- env: Lint_rubocop
fast_finish: true
include:
## Define the test stage that runs the linters (and testing matrix, if applicable)

# Run all of the linters in a single job (except `rubocop`)
# Run all of the linters in a single job
- language: node_js
node_js: lts/*
env: Lint
name: 'Lint: salt-lint, yamllint & commitlint'
name: 'Lint: salt-lint, yamllint, rubocop & commitlint'
before_install: skip
script:
# Install and run `salt-lint`
Expand All @@ -42,21 +39,13 @@ jobs:
# Need at least `v1.17.0` for the `yaml-files` setting
- pip install --user yamllint>=1.17.0
- yamllint -s .
# Install and run `rubocop`
- gem install rubocop
- rubocop -d
# Install and run `commitlint`
- npm i -D @commitlint/config-conventional
@commitlint/travis-cli
- commitlint-travis
# Run the `rubocop` linter in a separate job that is allowed to fail
# Once these lint errors are fixed, this can be merged into a single job
- language: node_js
node_js: lts/*
env: Lint_rubocop
name: 'Lint: rubocop'
before_install: skip
script:
# Install and run `rubocop`
- gem install rubocop
- rubocop -d

## Define the rest of the matrix based on Kitchen testing
# Make sure the instances listed below match up with
Expand Down
1 change: 1 addition & 0 deletions .yamllint
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ ignore: |
node_modules/
test/**/states/**/*.sls
.kitchen/
test/salt/pillar/default.sls
yaml-files:
# Default settings
Expand Down
6 changes: 6 additions & 0 deletions Gemfile
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,12 @@

source 'https://rubygems.org'

gem 'inspec'
gem 'kitchen-docker', '>= 2.9'
gem 'kitchen-inspec', '>= 1.1'
gem 'kitchen-salt', '>= 0.6.0'
gem 'rspec-retry'

group :vagrant do
gem 'kitchen-vagrant'
end
62 changes: 62 additions & 0 deletions docs/README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -131,3 +131,65 @@ Runs all of the stages above in one go: i.e. ``destroy`` + ``converge`` + ``veri
^^^^^^^^^^^^^^^^^^^^^

Gives you SSH access to the instance for manual testing.

Testing with Vagrant
--------------------

Windows testing is done with ``kitchen-salt``.

Requirements
^^^^^^^^^^^^

* Ruby
* Virtualbox
* Vagrant

Setup
^^^^^

.. code-block:: bash
$ gem install bundler
$ bundle install --with=vagrant
$ bin/kitchen test [platform]
Where ``[platform]`` is the platform name defined in ``kitchen.yml``,
e.g. ``windows-81-2019-2-py3``.

Note
^^^^

When testing using Vagrant you must set the environment variable ``KITCHEN_LOCAL_YAML`` to ``kitchen.vagrant.yml``. For example:

.. code-block:: bash
$ KITCHEN_LOCAL_YAML=kitchen.vagrant.yml bin/kitchen test # Alternatively,
$ export KITCHEN_LOCAL_YAML=kitchen.vagrant.yml
$ bin/kitchen test
Then run the following commands as needed.

``bin/kitchen converge``
^^^^^^^^^^^^^^^^^^^^^^^^

Creates the Vagrant instance and runs the ``openvpn`` main state, ready for testing.

``bin/kitchen verify``
^^^^^^^^^^^^^^^^^^^^^^

Runs the ``inspec`` tests on the actual instance.

``bin/kitchen destroy``
^^^^^^^^^^^^^^^^^^^^^^^

Removes the Vagrant instance.

``bin/kitchen test``
^^^^^^^^^^^^^^^^^^^^

Runs all of the stages above in one go: i.e. ``destroy`` + ``converge`` + ``verify`` + ``destroy``.

``bin/kitchen login``
^^^^^^^^^^^^^^^^^^^^^

Gives you RDP access to the instance for manual testing.
18 changes: 18 additions & 0 deletions kitchen.vagrant.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
# -*- coding: utf-8 -*-
# vim: ft=yaml
---
driver:
name: vagrant

platforms:
- name: windows-81-2019-2-py3
driver:
box: techneg/win81x64-pro-salt
gui: false
linked_clone: true
provisioner:
init_environment: >
salt-call --local state.single file.managed
C:\Users\vagrant\AppData\Local\Temp\kitchen\srv\salt\win\repo-ng\openvpn.sls
source=https://github.com/saltstack/salt-winrepo-ng/raw/master/openvpn.sls
skip_verify=True makedirs=True
1 change: 1 addition & 0 deletions openvpn/defaults.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
# vim: ft=yaml
---
openvpn:
bin_dir: ~
conf_dir: /etc/openvpn
conf_ext: conf
dh_files: ['2048', '4096']
Expand Down
2 changes: 1 addition & 1 deletion openvpn/dhparams.sls
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
{%- set dh_file = config_dir ~ "/dh" ~ dh ~ ".pem" %}
openvpn_create_dh_{{ dh }}:
cmd.run:
- name: openssl dhparam {% if map.dsaparam %}-dsaparam {% endif %}-out {{ dh_file }} {{ dh }}
- name: '"{{ map.bin_dir | default('', true) }}openssl" dhparam {% if map.dsaparam %}-dsaparam {% endif %}-out "{{ dh_file }}" {{ dh }}'
- creates: {{ dh_file }}
- require:
- pkg: openvpn_pkgs
Expand Down
1 change: 1 addition & 0 deletions openvpn/init.sls
Original file line number Diff line number Diff line change
Expand Up @@ -3,5 +3,6 @@
include:
- openvpn.repo
- openvpn.install
- openvpn.adapters
- openvpn.dhparams
- openvpn.service
1 change: 1 addition & 0 deletions openvpn/osfamilymap.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ FreeBSD:
manage_user: false
manage_group: false
Windows:
bin_dir: C:\Program Files\OpenVPN\bin\
conf_dir: C:\Program Files\OpenVPN\config
conf_ext: ovpn
service: OpenVPNServiceInteractive
72 changes: 31 additions & 41 deletions test/integration/default/controls/config_spec.rb
Original file line number Diff line number Diff line change
@@ -1,55 +1,45 @@
# Overide by OS
# frozen_string_literal: true

if os[:family] == 'windows'
conf_dir = 'C:\\Program Files\\OpenVPN\\config'
conf_ext = 'ovpn'
else
conf_dir = '/etc/openvpn'
conf_ext = 'conf'
end

user = 'root'
group = 'openvpn'

control 'OpenVPN server configuration' do
title 'should match desired lines'

%w[server client].each do |role|
cfgfile =
case os[:name]
when 'debian'
'/etc/openvpn/server/myserver1.conf'
when 'fedora'
'/etc/openvpn/server/myserver1.conf'
when 'ubuntu'
'/etc/openvpn/server/myserver1.conf'
when 'debian', 'fedora', 'ubuntu'
"#{conf_dir}/#{role}/my#{role}1.#{conf_ext}"
else
'/etc/openvpn/myserver1.conf'
"#{conf_dir}/my#{role}1.#{conf_ext}"
end

describe file(cfgfile) do
it { should be_file }
it { should be_owned_by user }
it { should be_grouped_into group }
its('mode') { should cmp '0640' }
its('content') { should include '# OpenVPN server configuration' }
its('content') { should include '# Managed by Salt' }
its('content') { should include 'user' }
control "OpenVPN #{role} configuration" do
title 'should match desired lines'

describe file(cfgfile) do
it { should be_file }
its('content') { should include "# OpenVPN #{role} configuration" }
its('content') { should include '# Managed by Salt' }
its('content') { should include 'user' }
end
end
end

control 'OpenVPN client configuration' do
title 'should match desired lines'
control "OpenVPN #{role} configuration file permissions" do
title 'should be correct'

cfgfile =
case os[:name]
when 'debian'
'/etc/openvpn/client/myclient1.conf'
when 'fedora'
'/etc/openvpn/client/myclient1.conf'
when 'ubuntu'
'/etc/openvpn/client/myclient1.conf'
else
'/etc/openvpn/myclient1.conf'
end
only_if('Skip on Windows') { os[:family] != 'windows' }

describe file(cfgfile) do
it { should be_file }
it { should be_owned_by user }
it { should be_grouped_into group }
its('mode') { should cmp '0640' }
its('content') { should include '# OpenVPN client configuration' }
its('content') { should include '# Managed by Salt' }
its('content') { should include 'user' }
describe file(cfgfile) do
it { should be_owned_by user }
it { should be_grouped_into group }
its('mode') { should cmp '0640' }
end
end
end
2 changes: 2 additions & 0 deletions test/integration/default/controls/packages_spec.rb
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
# frozen_string_literal: true

control 'OpenVPN package' do
title 'should be installed'

Expand Down
50 changes: 26 additions & 24 deletions test/integration/default/controls/services_spec.rb
Original file line number Diff line number Diff line change
@@ -1,43 +1,45 @@
# frozen_string_literal: true

control 'OpenVPN service' do
impact 0.5
title 'should be running and enabled'

# single service
if os[:name] == 'centos' && os[:release].start_with?('6')
describe service("openvpn") do
it { should be_enabled }
it { should be_running }
end
require 'rspec/retry'

# multiple services
else
%w(server client).each do |role|
log_dir = '/var/log/openvpn/'

if os[:name] == 'centos' && os[:release].start_with?('6')
services = ['openvpn']
elsif os[:family] == 'windows'
log_dir = 'C:\\Program Files\\OpenVPN\\log\\'
services = ['OpenVPNService']
else
services = []
%w[server client].each do |role|
prefix =
case os[:name]
when 'debian'
"openvpn-#{role}"
when 'fedora'
"openvpn-#{role}"
when 'ubuntu'
when 'debian', 'fedora', 'ubuntu'
"openvpn-#{role}"
else
'openvpn'
end

describe service("#{prefix}@my#{role}1.service") do
it { should be_enabled }
it { should be_running }
end
services << "#{prefix}@my#{role}1.service"
end
end

%w(server client).each do |role|
logfile = "/var/log/openvpn/my#{role}1.log"
services.each do |service|
describe service(service) do
it { should be_enabled }
it { should be_running }
end
end

describe command("sh -c 'for i in $(seq 1 60); do if grep \"Initialization Sequence Completed\" #{logfile}; then exit 0; fi; echo -n '.'; sleep 1; done; cat #{logfile}; exit 1'") do
its('exit_status') { should be 0 }
its('stdout') { should include "Initialization Sequence Completed" }
%w[server client].each do |role|
logfile = "#{log_dir}my#{role}1.log"
describe 'Initialization' do
it 'should be completed', retry: 60, retry_wait: 1 do
expect(file(logfile).content).to include 'Initialization Sequence Completed'
end
end
end
end
1 change: 1 addition & 0 deletions test/integration/default/inspec.yml
Original file line number Diff line number Diff line change
Expand Up @@ -16,3 +16,4 @@ supports:
- platform-name: freebsd
- platform-name: amazon
- platform-name: arch
- platform: windows
Loading

0 comments on commit 5a263e0

Please sign in to comment.