-
Notifications
You must be signed in to change notification settings - Fork 56
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
86 changed files
with
1,716 additions
and
5,421 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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 |
Oops, something went wrong.