Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Windows testing using kitchen-vagrant #112

Merged
merged 5 commits into from
Nov 5, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
myii marked this conversation as resolved.
Show resolved Hide resolved

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
myii marked this conversation as resolved.
Show resolved Hide resolved

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