9 changes: 9 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,14 @@
# Change Log

## [v3.10.0](https://github.com/sensu/sensu-puppet/tree/v3.10.0) (2019-10-31)
[Full Changelog](https://github.com/sensu/sensu-puppet/compare/v3.9.0...v3.10.0)

**Merged pull requests:**

- Initial work at design document [\#1161](https://github.com/sensu/sensu-puppet/pull/1161) ([treydock](https://github.com/treydock))
- Add bolt tasks [\#1153](https://github.com/sensu/sensu-puppet/pull/1153) ([treydock](https://github.com/treydock))
- Deprecate defining single asset builds [\#1140](https://github.com/sensu/sensu-puppet/pull/1140) ([treydock](https://github.com/treydock))

## [v3.9.0](https://github.com/sensu/sensu-puppet/tree/v3.9.0) (2019-10-10)
[Full Changelog](https://github.com/sensu/sensu-puppet/compare/v3.8.0...v3.9.0)

Expand Down
84 changes: 84 additions & 0 deletions DESIGN.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
# Module Design

## Classes

There are four main public classes and other can be added if they need to be managed separately than the existing classes:

* sensu - Resources shared by all other public classes such as agent and backend
* sensu::agent - Sensu Agent
* sensu::backend - Sensu Backend
* sensu::plugins - Sensu plugins

Subclasses to the above hold resources for that resources to keep the logic in the main public class shorter. So `sensu::backend::default_resources` is a private classes that adds functionality to `sensu::backend`. There are also some shared classes like `sensu::ssl` that are private and have resources shared by other public classes.

If a parameter is used by both agent and backend, it belongs in `sensu` class. All other parameters should be added to the appropriate public class.

## Types/Provides

### Sensuctl types

The types to `sensuctl` resources are designed to closely match the resource specifications from Sensu Go. For example the Sensu Go `check` resource property of `interval` would map directly to the `sensu_check` type property of `interval`.

Keys in the Sensu Go specification under `spec` should have a 1-to-1 mapping with Puppet type properties.

The exception to the 1-to-1 mapping is Sensu Go resource `metadata`. The values for `metadata` keys of `name`, `namespace`, `labels`, and `annotations` are pulled out into Puppet type properties. The metadata exception is to properly handle resource names and namespaces and relationships as well as the composite names used by namespace capable resources.

### All other types/providers

Other types and providers are added where possible to avoid the use of complex Exec resources in the manifest code.
One example is `sensu_plugin` which manages Sensu Go plugins that does not use `sensuctl`.

The use of Exec is acceptable for simple cases like adding the license file where the Exec can be triggered when a file changes.

### Helper functions for types

The helper code for types is found in `lib/puppet_x/sensu`. The following currently exist as helper classes for type properties:

* `array_of_hashes_property.rb` - Parent class for properties that are an Array of Hashes
* `array_property.rb` - Parent class for properties that are an Array
* `hash_property.rb` - Parent class for properties that are a Hash
* `integer_property.rb` - Parent class for properties that are an Integer

The module defined in `lib/puppet_x/sensu/type.rb` is included by all custom types of this module and provides functions that can be used to provide common logic:

* `add_autorequires` - Adds autorequires common between all types.
* `validate_namespace` - Helper function to be used in `pre_run_check` to validate a type's namespace.
* `error_prefix` - Helper function to produce meaning full string used with error messages in this module's types.

## Unit tests

The unit tests are designed to check Puppet catalog behavior without ensuring the functionality on a running system.

Test locations:

* `spec/classes` - Theses for each class in `manifests` directory.
* `spec/unit/*_spec.rb` - These are tests for the types defined in `lib/puppet/types`
* `spec/unit/provider/**/*_spec.rb` - These are tests for the providers defined in `lib/puppet/providers`
* `spec/unit/facter/*_spec.rb` - These are tests for custom facts that must be tested for both Linux and Windows
* `spec/type_aliases/*_spec.rb` - These are tests for manifest type aliases in `types` directory

The unit tests for providers rely on fixtures in `spec/fixtures/unit` and the path matters in order for fixtures to be loaded.

For types the simple properties can be added to appropariate array for testing behavior of the property. Any properties with extra validations or munging will require their own context and tests.

Each class, type, provider, and fact gets its own spec file for testing.

Unit tests use [rspec-puppet](https://rspec-puppet.com/) to test Puppet catalog resources using RSpec. The facts to simulate different operating systems are provided by [facterdb](https://github.com/camptocamp/facterdb).

## Acceptance tests

The acceptance tests functional tests to ensure this module's behavior on a running system.

Test locations:

* `spec/acceptance/*_spec.rb`

The class tests are ordered with numeric prefixes to control the order they run. The custom type tests are not ordered but all come after the class tests.

The type of `sensu_check` will have its tests in `sensu_check_spec.rb`. The tests to run are adding resources, updating resources, and deleting resources. Some extra test cases should be added based on any complexities of a given type.

Technologies for acceptance testing:

* Docker - provides running system where configurations can be made and tests can be executed
* [serverspec](https://serverspec.org/) - Ability to test system configurations of running systems
* [beaker](https://github.com/puppetlabs/beaker) - Handles the test system setup and interfacing with Docker and serverspec
29 changes: 29 additions & 0 deletions Vagrantfile
Original file line number Diff line number Diff line change
Expand Up @@ -164,6 +164,20 @@ Vagrant.configure(VAGRANTFILE_API_VERSION) do |config|
agent.vm.provision :shell, :inline => 'iex "facter --custom-dir=C:\vagrant\lib\facter sensu_agent"'
end

config.vm.define "win2012r2-agent-bolt", autostart: false do |agent|
agent.vm.box = "opentable/win-2012r2-standard-amd64-nocm"
agent.vm.provider :virtualbox do |vb|
vb.customize ["modifyvm", :id, "--memory", "2048"]
vb.customize ["modifyvm", :id, "--cpus", "1"]
end
agent.vm.hostname = 'win2012r2-agent'
agent.vm.network :private_network, ip: "192.168.52.29"
agent.vm.network "forwarded_port", host: 3389, guest: 3389, auto_correct: true
agent.vm.provision :shell, :path => "tests/provision_basic_win.ps1"
agent.vm.provision :shell, :path => "tests/test_bolt_win.ps1"
agent.vm.provision :shell, :inline => 'iex "facter --custom-dir=C:\vagrant\lib\facter sensu_agent"'
end

config.vm.define "win2016-agent", autostart: false do |agent|
agent.vm.box = "mwrock/Windows2016"
agent.vm.provider :virtualbox do |vb|
Expand All @@ -178,4 +192,19 @@ Vagrant.configure(VAGRANTFILE_API_VERSION) do |config|
agent.vm.provision :shell, :inline => 'iex "puppet apply -v C:/vagrant/tests/sensu-agent.pp"'
agent.vm.provision :shell, :inline => 'iex "facter --custom-dir=C:\vagrant\lib\facter sensu_agent"'
end

config.vm.define "win2016-agent-bolt", autostart: false do |agent|
agent.vm.box = "mwrock/Windows2016"
agent.vm.provider :virtualbox do |vb|
vb.customize ["modifyvm", :id, "--memory", "2048"]
vb.customize ["modifyvm", :id, "--cpus", "1"]
vb.gui = false
end
agent.vm.hostname = 'win2016-agent-bolt'
agent.vm.network :private_network, ip: "192.168.52.28"
agent.vm.network "forwarded_port", host: 3391, guest: 3389, auto_correct: true
agent.vm.provision :shell, :path => "tests/provision_basic_win.ps1"
agent.vm.provision :shell, :path => "tests/test_bolt_win.ps1"
agent.vm.provision :shell, :inline => 'iex "facter --custom-dir=C:\vagrant\lib\facter sensu_agent"'
end
end
14 changes: 9 additions & 5 deletions appveyor.yml
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,6 @@ branches:
only:
- master
- /^v\d/
cache:
- C:\downloads
- C:\vendor\bundle
init:
- ps: $env:GEM_SOURCE = "http://rubygems.org"
install:
Expand All @@ -28,6 +25,7 @@ install:
- ps: Copy-Item -Path $ENV:APPVEYOR_BUILD_FOLDER -Destination C:/ProgramData/PuppetLabs/code/environments/production/modules/sensu -Recurse
- ps: Copy-Item -Path "${ENV:APPVEYOR_BUILD_FOLDER}/tests/ssl" -Destination C:/ProgramData/PuppetLabs/puppet/etc/ssl -Recurse
- ps: Copy-Item -Path "${ENV:APPVEYOR_BUILD_FOLDER}/lib/facter" -Destination C:/ProgramData/PuppetLabs/puppet/cache/lib/facter -Recurse
- choco install puppet-bolt
- set PATH=C:\Program Files\Puppet Labs\Puppet\bin;%PATH%
- puppet --version
- puppet module install puppetlabs-stdlib
Expand All @@ -36,12 +34,18 @@ install:
- puppet config set --section main certname sensu_agent
- facter -p --debug
- ruby -v
- gem update --system 2.7.9
- gem -v
- bundle -v
- bundle install --jobs 4 --retry 2 --path C:\vendor\bundle
test_script:
- bundle exec rake acceptance:windows
- '"C:\\Program Files\\sensu\\sensu-agent\\bin\\sensu-agent.exe" service uninstall'
- 'puppet resource package "Sensu Agent" ensure=absent'
- rmdir C:\\ProgramData\\PuppetLabs\\code\\environments\\production\\modules /s /q
- ps: Copy-Item -Path $ENV:APPVEYOR_BUILD_FOLDER -Destination C:/ProgramData/PuppetLabs/code/environments/production/modules/sensu -Recurse
- set BEAKER_skip_apply=yes
- '"C:\Program Files\Puppet Labs\Bolt\bin\bolt" task show'
- '"C:\Program Files\Puppet Labs\Bolt\bin\bolt" --debug task run sensu::install_agent backend=sensu_backend:8081 subscription=windows output=true --nodes localhost'
- bundle exec rake acceptance:windows
image:
# Windows 2012 R2
- Visual Studio 2015
Expand Down
39 changes: 21 additions & 18 deletions lib/puppet/type/sensu_asset.rb
Original file line number Diff line number Diff line change
Expand Up @@ -7,21 +7,6 @@
Puppet::Type.newtype(:sensu_asset) do
desc <<-DESC
@summary Manages Sensu assets
@example Create an asset
sensu_asset { 'test':
ensure => 'present',
url => 'http://example.com/asset/example.tar',
sha512 => '4f926bf4328fbad2b9cac873d117f771914f4b837c9c85584c38ccf55a3ef3c2e8d154812246e5dda4a87450576b2c58ad9ab40c9e2edc31b288d066b195b21b',
filters => ["entity.system.os == 'linux'"],
}
@example Create an asset with namespace `dev` in the name
sensu_asset { 'test in dev':
ensure => 'present',
url => 'http://example.com/asset/example.tar',
sha512 => '4f926bf4328fbad2b9cac873d117f771914f4b837c9c85584c38ccf55a3ef3c2e8d154812246e5dda4a87450576b2c58ad9ab40c9e2edc31b288d066b195b21b',
filters => ["entity.system.os == 'linux'"],
}
@example Create an asset with multiple builds
sensu_asset { 'test':
Expand All @@ -33,7 +18,11 @@
"filters" => [
"entity.system.os == 'linux'",
"entity.system.arch == 'amd64'"
]
],
"headers" => {
"Authorization" => "Bearer $TOKEN",
"X-Forwarded-For" => "client1, proxy1, proxy2",
}
},
{
"url" => "https://assets.bonsai.sensu.io/981307deb10ebf1f1433a80da5504c3c53d5c44f/sensu-go-cpu-check_0.0.3_linux_armv7.tar.gz",
Expand All @@ -42,15 +31,23 @@
"entity.system.os == 'linux'",
"entity.system.arch == 'arm'",
"entity.system.arm_version == 7"
]
],
"headers" => {
"Authorization" => "Bearer $TOKEN",
"X-Forwarded-For" => "client1, proxy1, proxy2",
}
},
{
"url" => "https://assets.bonsai.sensu.io/981307deb10ebf1f1433a80da5504c3c53d5c44f/sensu-go-cpu-check_0.0.3_windows_amd64.tar.gz",
"sha512" => "10d6411e5c8bd61349897cf8868087189e9ba59c3c206257e1ebc1300706539cf37524ac976d0ed9c8099bdddc50efadacf4f3c89b04a1a8bf5db581f19c157f",
"filters" => [
"entity.system.os == 'windows'",
"entity.system.arch == 'amd64'"
]
],
"headers" => {
"Authorization" => "Bearer $TOKEN",
"X-Forwarded-For" => "client1, proxy1, proxy2",
}
}
],
}
Expand Down Expand Up @@ -203,6 +200,12 @@ def pre_run_check
end
end
end
if self[:url] || self[:sha512] || self[:filters] || self[:headers]
Puppet.warning("#{PuppetX::Sensu::Type.error_prefix(self)} Using url, sha512, filters, or headers properties for single build is deprecated, use builds property")
if self[:builds]
fail "Defining builds with url, sha512, or filters is not suppoed, they are mutually exclusive. Use only builds property"
end
end
PuppetX::Sensu::Type.validate_namespace(self)
end
end
6 changes: 6 additions & 0 deletions lib/puppet_x/sensu/type.rb
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,12 @@ def self.validate_namespace(resource)
raise Puppet::Error, "Sensu namespace '#{resource[:namespace]}' must be defined or exist"
end
end

# Used to take type class name and name to generate friendly error prefix
# Puppet::Type::Sensu_asset[test] becomes Sensu_asset[test]
def self.error_prefix(s)
"#{s.class.to_s.split(':').last}[#{s[:name]}]:"
end
end
end
end
2 changes: 1 addition & 1 deletion metadata.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "sensu-sensu",
"version": "3.9.0",
"version": "3.10.0",
"author": "sensu",
"summary": "A module to install the Sensu monitoring framework",
"license": "MIT",
Expand Down
Loading