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

Add sensu_event type #920

Merged
merged 3 commits into from
Jul 6, 2018
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.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
83 changes: 83 additions & 0 deletions lib/puppet/provider/sensu_event/sensuctl.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
require File.expand_path(File.join(File.dirname(__FILE__), '..', 'sensuctl'))

Puppet::Type.type(:sensu_event).provide(:sensuctl, :parent => Puppet::Provider::Sensuctl) do
desc "Provider sensu_event using sensuctl"

mk_resource_methods

def self.instances
events = []

output = sensuctl_list('event')
Puppet.debug("sensu event: #{output}")
begin
data = JSON.parse(output)
rescue JSON::ParserError => e
Puppet.debug('Unable to parse output from sensuctl event list')
data = []
end

data.each do |d|
event = {}
event[:ensure] = :present
event[:entity] = d['entity']['id']
event[:check] = d['check']['name']
event[:name] = "#{event[:check]} for #{event[:entity]}"
if d['check']['status'] == 0
event[:ensure] = :resolve
end
events << new(event)
end
events
end

def self.prefetch(resources)
events = instances
resources.keys.each do |name|
if provider = events.find { |e|
e.check == resources[name][:check] &&
e.entity == resources[name][:entity]
}
resources[name].provider = provider
end
end
end

def exists?
@property_hash[:ensure] == :present || @property_hash[:ensure] == :resolve
end

def state
return @property_hash[:ensure]
end

def resolve
cmd = ['event', 'resolve']
cmd << resource[:entity]
cmd << resource[:check]
if resource[:organization]
cmd << '--organization'
cmd << resource[:organization]
end
if resource[:environment]
cmd << '--environment'
cmd << resource[:environment]
end
begin
sensuctl(cmd)
rescue Exception => e
raise Puppet::Error, "sensuctl event resolve #{resource[:entity]} #{resource[:check]} failed\nError message: #{e.message}"
end
@property_hash[:ensure] = :resolve
end

def destroy
begin
sensuctl(['event', 'delete', resource[:entity], resource[:check], '--skip-confirm'])
rescue Exception => e
raise Puppet::Error, "sensuctl delete event #{resource[:entity]} #{resource[:check]} failed\nError message: #{e.message}"
end
@property_hash.clear
end
end

87 changes: 87 additions & 0 deletions lib/puppet/type/sensu_event.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
require_relative '../../puppet_x/sensu/type'
require_relative '../../puppet_x/sensu/array_property'
require_relative '../../puppet_x/sensu/hash_property'
require_relative '../../puppet_x/sensu/integer_property'

Puppet::Type.newtype(:sensu_event) do
desc <<-DESC
Manages Sensu events
@example Resolve an event
sensu_event { 'test for sensu-agent':
ensure => 'resolve'
}

@example Delete an event
sensu_event { 'test for sensu-agent':
ensure => 'absent'
}
DESC

extend PuppetX::Sensu::Type
add_autorequires()

ensurable do
nodefault
newvalue(:present)
newvalue(:resolve) do
@resource.provider.resolve
end
newvalue(:absent) do
@resource.provider.destroy
end
aliasvalue(:delete, :absent)

def retrieve
@resource.provider.state || :absent
end
end

newparam(:name, :namevar => true) do
desc "Event name. Can take form of '<check> for <entity>'."
end

newparam(:entity, :namevar => true) do
desc "The name of the entity the event should match"
end

newparam(:check, :namevar => true) do
desc "The name of the check the event should match"
end

newparam(:organization) do
desc "The Sensu RBAC organization that this event belongs to."
defaultto 'default'
end

newparam(:environment) do
desc "The Sensu RBAC environment that this event belongs to."
defaultto 'default'
end

def self.title_patterns
[
[
/^((\S+) for (\S+))$/,
[
[:name],
[:check],
[:entity],
],
],
[
/(.*)/,
[
[:name],
],
],
]
end

validate do
if ! self[:entity] || ! self[:check]
fail "Must provide check and entity"
end
end

end

1 change: 1 addition & 0 deletions spec/acceptance/01_agent_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
pp = <<-EOS
class { '::sensu::agent':
config_hash => {
'id' => 'sensu_agent',
'backend-url' => 'ws://sensu_backend:8081',
}
}
Expand Down
41 changes: 41 additions & 0 deletions spec/acceptance/sensu_event_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
require 'spec_helper_acceptance'

describe 'sensu_event' do
node = only_host_with_role(hosts, 'sensu_backend')
context 'default' do
it 'should work without errors' do
pp = <<-EOS
include ::sensu::backend
sensu_event { 'keepalive for sensu_agent':
ensure => 'resolve',
}
EOS

# There should be no changes
apply_manifest_on(node, pp, :catch_changes => true)
end
end

context 'ensure => absent' do
it 'should remove without errors' do
# Stop sensu-agent on agent node to avoid re-creating event
apply_manifest_on(only_host_with_role(hosts, 'sensu_agent'),
"service { 'sensu-agent': ensure => 'stopped' }")
pp = <<-EOS
include ::sensu::backend
sensu_event { 'keepalive for sensu_agent':
ensure => 'absent',
}
EOS

# Run it twice and test for idempotency
apply_manifest_on(node, pp, :catch_failures => true)
apply_manifest_on(node, pp, :catch_changes => true)
end

describe command('sensuctl event info sensu_agent keepalive'), :node => node do
its(:exit_status) { should_not eq 0 }
end
end
end

97 changes: 97 additions & 0 deletions spec/fixtures/unit/provider/sensu_event/sensuctl/event_list.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
[
{
"timestamp": 1529875603,
"entity": {
"class": "agent",
"deregister": false,
"deregistration": {},
"environment": "default",
"id": "sensu-backend.example.com",
"keepalive_timeout": 120,
"last_seen": 1529875603,
"organization": "default",
"redact": [
"password",
"passwd",
"pass",
"api_key",
"api_token",
"access_key",
"secret_key",
"private_key",
"secret"
],
"subscriptions": [
"entity:sensu-backend.example.com"
],
"system": {
"hostname": "sensu-backend.example.com",
"os": "linux",
"platform": "centos",
"platform_family": "rhel",
"platform_version": "7.4.1708",
"network": {
"interfaces": [
{
"name": "lo",
"addresses": [
"127.0.0.1/8",
"::1/128"
]
},
{
"name": "eth0",
"mac": "52:54:00:da:a7:10",
"addresses": [
"10.0.2.15/24",
"fe80::5054:ff:feda:a710/64"
]
},
{
"name": "eth1",
"mac": "08:00:27:7a:3f:38",
"addresses": [
"192.168.52.10/24",
"fe80::a00:27ff:fe7a:3f38/64"
]
}
]
},
"arch": "amd64"
},
"user": "agent"
},
"check": {
"environment": "default",
"handlers": [
"keepalive"
],
"high_flap_threshold": 0,
"interval": 120,
"low_flap_threshold": 0,
"name": "keepalive",
"organization": "default",
"publish": false,
"runtime_assets": null,
"subscriptions": [],
"proxy_entity_id": "",
"check_hooks": null,
"stdin": false,
"subdue": null,
"ttl": 0,
"timeout": 0,
"round_robin": false,
"executed": 0,
"history": null,
"issued": 0,
"state": "passing",
"status": 0,
"total_state-change": 0,
"last_ok": 1529875603,
"occurrences": 1,
"occurrences_watermark": 1,
"output_metric_format": "",
"output_metric_handlers": null
}
}
]
45 changes: 45 additions & 0 deletions spec/unit/provider/sensu_event/sensuctl_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
require 'spec_helper'

describe Puppet::Type.type(:sensu_event).provider(:sensuctl) do
before(:each) do
@provider = described_class
@type = Puppet::Type.type(:sensu_event)
@resource = @type.new({
:name => 'keepalive for test'
})
end

describe 'self.instances' do
it 'should create instances' do
allow(@provider).to receive(:sensuctl_list).with('event').and_return(my_fixture_read('event_list.json'))
expect(@provider.instances.length).to eq(1)
end

it 'should return the resource for a event' do
allow(@provider).to receive(:sensuctl_list).with('event').and_return(my_fixture_read('event_list.json'))
property_hash = @provider.instances[0].instance_variable_get("@property_hash")
expect(property_hash[:name]).to eq('keepalive for sensu-backend.example.com')
expect(property_hash[:entity]).to eq('sensu-backend.example.com')
expect(property_hash[:check]).to eq('keepalive')
end
end

describe 'resolve' do
it 'should create a event' do
expect(@resource.provider).to receive(:sensuctl).with(['event', 'resolve', 'test', 'keepalive', '--organization', 'default', '--environment', 'default'])
@resource.provider.resolve
property_hash = @resource.provider.instance_variable_get("@property_hash")
expect(property_hash[:ensure]).to eq(:resolve)
end
end

describe 'destroy' do
it 'should delete a event' do
expect(@resource.provider).to receive(:sensuctl).with(['event', 'delete', 'test', 'keepalive', '--skip-confirm'])
@resource.provider.destroy
property_hash = @resource.provider.instance_variable_get("@property_hash")
expect(property_hash).to eq({})
end
end
end