Skip to content

Commit

Permalink
rewrite libraries to lwrp
Browse files Browse the repository at this point in the history
  • Loading branch information
bugoff committed Sep 1, 2020
1 parent 82333d9 commit 1eff415
Show file tree
Hide file tree
Showing 86 changed files with 1,716 additions and 5,421 deletions.
26 changes: 22 additions & 4 deletions .kitchen.dokken.yml
Original file line number Diff line number Diff line change
Expand Up @@ -103,19 +103,37 @@ platforms:
- RUN yum install -y net-tools initscripts which

suites:
- name: chef12server
- name: chef13server
driver:
chef_version: 13
verifier:
inspec_tests:
- test/smoke/server
run_list:
- recipe[icinga2::default]
- recipe[icinga2-test::default]
- name: chef14server
driver:
chef_version: 12.21.4
chef_version: 14
verifier:
inspec_tests:
- test/smoke/server
run_list:
- recipe[icinga2::default]
- recipe[icinga2-test::default]

- name: chef13server
- name: chef15server
driver:
chef_version: 15
verifier:
inspec_tests:
- test/smoke/server
run_list:
- recipe[icinga2::default]
- recipe[icinga2-test::default]
- name: chef16server
driver:
chef_version: 13.3.42
chef_version: 16
verifier:
inspec_tests:
- test/smoke/server
Expand Down
20 changes: 10 additions & 10 deletions attributes/default.rb
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@

default['icinga2']['version'] = value_for_platform(
%w(centos redhat fedora amazon) => { 'default' => '2.10.1-1' },
%w(debian ubuntu raspbian) => { 'default' => '2.10.1-1' },
%w(debian ubuntu raspbian) => { 'default' => '2.12.0-1' },
%w(windows) => { 'default' => '2.10.1' }
)
default['icinga2']['ignore_version'] = false
Expand Down Expand Up @@ -52,8 +52,8 @@
default['icinga2']['features_enabled_dir'] = ::File.join(node['icinga2']['conf_dir'], 'features-enabled')
default['icinga2']['features_available_dir'] = ::File.join(node['icinga2']['conf_dir'], 'features-available')

default['icinga2']['cluster_attribute'] = nil
default['icinga2']['application_attribute'] = nil
default['icinga2']['cluster_attribute'] = '' # used to be nil
default['icinga2']['application_attribute'] = '' # used to be nil
default['icinga2']['enable_cluster_hostgroup'] = true
default['icinga2']['enable_application_hostgroup'] = true
default['icinga2']['enable_role_hostgroup'] = false
Expand Down Expand Up @@ -147,8 +147,8 @@
default['icinga2']['object']['global-templates'] = false
default['icinga2']['object']['host']['import'] = 'generic-host'
default['icinga2']['object']['host']['max_check_attempts'] = 3
default['icinga2']['object']['host']['check_period'] = nil
default['icinga2']['object']['host']['notification_period'] = nil
default['icinga2']['object']['host']['check_period'] = '' # used to be nil
default['icinga2']['object']['host']['notification_period'] = '' # used to be nil
default['icinga2']['object']['host']['check_interval'] = '1m'
default['icinga2']['object']['host']['retry_interval'] = '30s'
default['icinga2']['object']['host']['enable_notifications'] = true
Expand All @@ -157,9 +157,9 @@
default['icinga2']['object']['host']['enable_event_handler'] = true
default['icinga2']['object']['host']['enable_flapping'] = true
default['icinga2']['object']['host']['enable_perfdata'] = true
default['icinga2']['object']['host']['event_command'] = nil
default['icinga2']['object']['host']['flapping_threshold'] = nil
default['icinga2']['object']['host']['volatile'] = nil
default['icinga2']['object']['host']['event_command'] = '' # used to be nil
default['icinga2']['object']['host']['flapping_threshold'] = '' # used to be nil
default['icinga2']['object']['host']['volatile'] = '' # used to be nil
default['icinga2']['object']['host']['check_command'] = 'hostalive'
default['icinga2']['object']['host']['zone'] = nil
default['icinga2']['object']['host']['command_endpoint'] = nil
default['icinga2']['object']['host']['zone'] = '' # used to be nil
default['icinga2']['object']['host']['command_endpoint'] = '' # used to be nil
91 changes: 91 additions & 0 deletions libraries/environment.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@


def create_hostgroups(env_resources)
env_hostgroups = []

# environment hostgroups
env_hostgroups += env_resources['clusters'] if new_resource.enable_cluster_hostgroup && env_resources.key?('clusters') && env_resources['clusters'].is_a?(Array)

env_hostgroups += env_resources['applications'] if new_resource.enable_application_hostgroup && env_resources.key?('applications') && env_resources['applications'].is_a?(Array)

env_hostgroups += env_resources['roles'] if new_resource.enable_role_hostgroup && env_resources.key?('roles') && env_resources['roles'].is_a?(Array)

env_hostgroups.uniq!

hostgroup_template = icinga2_envhostgroup new_resource.environment do
groups env_hostgroups
zone new_resource.zone
end

hostgroup_template.updated?
end

def create_endpoints(env_resources)
nodes = env_resources['nodes']
env_endpoints = nodes.map { |n| n[1]['fqdn'] }

endpoint_template = icinga2_envendpoint new_resource.environment do
endpoints env_endpoints
port new_resource.endpoint_port
log_duration new_resource.endpoint_log_duration
zone new_resource.zone
end

endpoint_template.updated?
end

def create_zones(env_resources)
nodes = env_resources['nodes']
env_zones = nodes.map { |n| n[1]['fqdn'] }

zone_template = icinga2_envzone new_resource.environment do
zones env_zones
parent new_resource.zone_parent
zone new_resource.zone
end

zone_template.updated?
end

def create_pki_tickets(env_resources)
env = new_resource.environment
salt = new_resource.pki_ticket_salt
nodes = env_resources['nodes']
all_fqdns = nodes.map { |n| n[1]['fqdn'] }
tickets = {}

begin
databag_item = data_bag_item('icinga2', "#{env}-pki-tickets")
tickets = databag_item['tickets']

if tickets['salt'] != salt
uncreated_tickets_fqdns = all_fqdns
else
tickets_fqdns = tickets.map { |k, _v| k }
uncreated_tickets_fqdns = all_fqdns - tickets_fqdns
end
rescue
uncreated_tickets_fqdns = all_fqdns
end

unless uncreated_tickets_fqdns.empty?
uncreated_tickets_fqdns.each do |f|
ruby_block "Create PKI-Ticket #{f}" do
block do
ticket_bash = Mixlib::ShellOut.new("icinga2 pki ticket --cn #{f} --salt #{salt}")
ticket_bash.run_command
tickets[f] = ticket_bash.stdout.chomp
databag_item = Chef::DataBagItem.new
databag_item.data_bag('icinga2')
databag_item.raw_data = {
'id' => "#{env}-pki-tickets",
'tickets' => tickets,
'salt' => salt,
}
databag_item.save
end
action :create
end
end
end
end
169 changes: 169 additions & 0 deletions libraries/instance.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,169 @@
protected

# collect object defined resources
def object_resources
Chef.run_context.resource_collection.select do |resource|
case new_resource.resource_name
when :icinga2_apilistener
resource.is_a?(Chef::Resource::Icinga2Apilistener)
when :icinga2_apiuser
resource.is_a?(Chef::Resource::Icinga2Apiuser)
when :icinga2_applydependency
resource.is_a?(Chef::Resource::Icinga2Applydependency)
when :icinga2_applynotification
resource.is_a?(Chef::Resource::Icinga2Applynotification)
when :icinga2_applyservice
resource.is_a?(Chef::Resource::Icinga2Applyservice)
when :icinga2_checkcommand
resource.is_a?(Chef::Resource::Icinga2Checkcommand)
when :icinga2_endpoint
resource.is_a?(Chef::Resource::Icinga2Endpoint)
when :icinga2_eventcommand
resource.is_a?(Chef::Resource::Icinga2Eventcommand)
when :icinga2_host
resource.is_a?(Chef::Resource::Icinga2Host)
when :icinga2_hostgroup
resource.is_a?(Chef::Resource::Icinga2Hostgroup)
when :icinga2_notification
resource.is_a?(Chef::Resource::Icinga2Notification)
when :icinga2_notificationcommand
resource.is_a?(Chef::Resource::Icinga2Notificationcommand)
when :icinga2_scheduleddowntime
resource.is_a?(Chef::Resource::Icinga2Scheduleddowntime)
when :icinga2_service
resource.is_a?(Chef::Resource::Icinga2Service)
when :icinga2_servicegroup
resource.is_a?(Chef::Resource::Icinga2Servicegroup)
when :icinga2_timeperiod
resource.is_a?(Chef::Resource::Icinga2Timeperiod)
when :icinga2_user
resource.is_a?(Chef::Resource::Icinga2User)
when :icinga2_usergroup
resource.is_a?(Chef::Resource::Icinga2Usergroup)
when :icinga2_zone
resource.is_a?(Chef::Resource::Icinga2Zone)
else
raise "unknown resource type #{new_resource.resource_name}, submit a bug"
end
end
end

# the template icinga definition should be placed to a separate file with '_template' suffix in the filename
# in order to do that for objects assigned to a zone, this function separate the object into two hashes
def separate_zone_resources(zone_objects)
object_resources = {}
template_resources = {}

zone_objects.each do |resource_key, resource_object|
if resource_object['object_class'] == 'object'
object_resources[resource_key] = resource_object
elsif resource_object['object_class'] == 'template'
template_resources[resource_key] = resource_object
else
Chef::Application.fatal!("Unknown object_class (#{resource_object['object_class']}), resource_key=#{resource_key}, resource_object=#{resource_object}", 1)
end
end

[object_resources, template_resources]
end

def process_icinga2_resources(resource_name, resource_properties, template_support)
icinga2_objects = {}
# default value for a new key in the hash is an empty hash
# key is a zone name, the hash for the key keeps an object definitions, each unique, each is a hash again
icinga2_zoned_objects = Hash.new { |h, k| h[k] = {} }

object_resources.reduce({}) do |_hash, resource|
next nil if !icinga2_resource_create?(resource.action) || icinga2_objects.key?(resource.name)
resource_data = Hash[resource_properties.map { |x| [x, resource.send(x)] }]

# not all icinga object support templating
# the object_class have to be determined in any case
resource_data['object_class'] = if template_support && resource.send('template')
'template'
else
'object'
end

# TODO: check first is such an object/key exist already, print a warning if so
# if resource.send('template') && !icinga2_objects.key?(resource.name)
if resource_data['zone']
icinga2_zoned_objects[resource_data['zone']][resource.name] = resource_data
else
icinga2_objects[resource.name] = resource_data
end
end

# separate object and teplate icinga definitions
icinga2_objects_grouped = icinga2_objects.group_by { |_k, v| v['object_class'] }
# now, this might be better refactored into a simple function with a simple loop, because I don't think I'll be
# able to understand immediatelly after a halt year or so
# what is does, it just produces a hash, with two keys, 'object' and 'template', under a key is another hash with
# icinga object definitions, which are then processed by a template resource and ERB template file
icinga2_objects_dict = icinga2_objects_grouped.keys.each_with_object('object': {}, 'template': {}) { |str, hash| hash[str] = Hash[icinga2_objects_grouped[str]] }

ot = template "object_config_#{resource_name}_#{new_resource.name}" do
path ::File.join(node['icinga2']['objects_dir'], "#{resource_name}.conf")
cookbook new_resource.cookbook
source "object.#{resource_name}.conf.erb"
owner node['icinga2']['user']
group node['icinga2']['group']
variables objects: icinga2_objects_dict['object']
notifies platform?('windows') ? :restart : :reload, 'service[icinga2]'
only_if { !icinga2_objects_dict['object'].empty? }
end

te = template "object_template_#{resource_name}_#{new_resource.name}" do
path ::File.join(node['icinga2']['objects_dir'], "#{resource_name}_template.conf")
source "object.#{resource_name}.conf.erb"
cookbook new_resource.cookbook
owner node['icinga2']['user']
group node['icinga2']['group']
mode 0o640
variables objects: icinga2_objects_dict['template']
notifies platform?('windows') ? :restart : :reload, 'service[icinga2]'
only_if { !icinga2_objects_dict['template'].empty? }
end

zoned_objects_updated = false

icinga2_zoned_objects.each do |zone, zone_objects|
zone_dir = directory "zone_directory_#{resource_name}_#{zone}_#{new_resource.name}" do
path ::File.join(node['icinga2']['zones_dir'], zone)
owner node['icinga2']['user']
group node['icinga2']['group']
only_if { !zone_objects.empty? }
end
zone_dir.run_action :create

zoned_objects, zoned_templates = separate_zone_resources(zone_objects)

zoned_ot = template "zone_config_#{resource_name}_#{zone}_#{new_resource.name}" do
path ::File.join(node['icinga2']['zones_dir'], zone, "#{resource_name}.conf")
source "object.#{resource_name}.conf.erb"
cookbook new_resource.cookbook
owner node['icinga2']['user']
group node['icinga2']['group']
mode 0o640
variables objects: zoned_objects
notifies platform?('windows') ? :restart : :reload, 'service[icinga2]'
only_if { !zoned_objects.empty? }
end

zoned_te = template "zone_template_#{resource_name}_#{zone}_#{new_resource.name}" do
path ::File.join(node['icinga2']['zones_dir'], zone, "#{resource_name}_template.conf")
source "object.#{resource_name}.conf.erb"
cookbook new_resource.cookbook
owner node['icinga2']['user']
group node['icinga2']['group']
mode 0o640
variables objects: zoned_templates
notifies platform?('windows') ? :restart : :reload, 'service[icinga2]'
only_if { !zoned_templates.empty? }
end

zoned_objects_updated = true if zoned_ot.updated? || zoned_te.updated?
end

ot.updated? || te.updated? || zoned_objects_updated
end
Loading

0 comments on commit 1eff415

Please sign in to comment.