Whopper Tacos

Ops, Security, Efficiency

Simple Puppet Function for Writing Out to Confluence

| Comments

A couple gigs ago we were an Atlassian shop and I am actually a big fan of Atlassian software, though it takes a lot of work up front to get it deployed in the way you like, but I’m not going to cover all that here. What I did though was I enabled the SOAP api for a user named Puppet, opened up the IT or Systems area so I could write something here:

1
http://confluence.yourorg.com/Systems/${fqdn}

Now that the thing that is phenomenal about this is that each page in Confluence has a comments section that you don’t deal with when comparing the data, to determine if an update is needed. Now what this means is that you can use the comments area as a server log. Everytime you do some work on a given server, you can log it right on the server’s page. So here is the function, which I will talk about a little bit more after the paste:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
# This file is managed by puppet. It's used to write node information to
# Atlassian Confluence wiki pages.
require 'erb'

module Puppet::Parser::Functions
   newfunction(:write_confluence_wiki) do |args|
      page_template = %{
{panel}
{color:#102051}This page is automagically generated and updated by a Puppet function.{color}
{panel}

h1. <%= lookupvar("::fqdn") %>
----

h2. Node Information
|| *Fact or Variable* \ || *Value* ||
| Architecture \ | <%= lookupvar("::hardwaremodel") %> \ |
| Core Count \ | <%= lookupvar("::processorcount") %> \ |
| CPU \ | <% if lookupvar("::kernel") == "OpenBSD" %><%= lookupvar("::hardwareisa") %><% else %><%= lookupvar("processor0") %><% end %> \ |
| Facter Version \ | <%= lookupvar("::facterversion") %> \ |
| Kernel \ | <%= lookupvar("::kernelrelease") %> \ |
| Location \ | <%= extlookup("address") %>, <%= extlookup("citystate") %> \ |
| OS \ | <% if lookupvar("::operatingsystem") == "OpenBSD" %>OpenBSD <%= lookupvar("::operatingsystemrelease") %><% else %><%= lookupvar("::lsbdistdescription") %><% end %> \ |
| Physical Processor Count \ | <%= lookupvar("::physicalprocessorcount") %> \ |
| Puppet Master \ | <%= extlookup("puppetserver") %> \ |
| RAID Type \ | <%= lookupvar("::raidtype") %> \ |
| Ruby Version \ | <%= lookupvar("::rubyversion") %> \ |
| Time Zone \ | <%= lookupvar("::timezone") %> \ |
| Virtual? \ | <% if lookupvar("::virtual") != "physical" %>Yes<% else %>No<% end %> \ |

h2. Firewall Information

*Note that this information is not accurate on OpenBSD routers and firewalls*

|| *Network Type* \ || *Networks* ||
| Node Networks \ | <%= extlookup("nodenets").to_a.join(',') %> \ |
| Trusted Networks \ | <%= extlookup("trustednets").to_a.join(',') %> \ |
| Blocked Machines/Networks \ | <%= extlookup("badactors").to_a.join(',') %> \ |

|| *Port Set* \ || *Ports* ||
| Restricted to Node Networks (TCP) \ | <%= lookupvar("restricted_to_node_nets_tcp_ports") %> \ |
| Restricted to Node Networks (UDP) \ | <%= lookupvar("restricted_to_node_nets_udp_ports") %> \ |
| Restricted to Trusted Networks (TCP) \ | <%= lookupvar("restricted_tcp_ports") %> \ |
| Restricted to Trusted Networks (UDP) \ | <%= lookupvar("restricted_udp_ports") %> \ |
| Fully Open to the World Ports (TCP) \ | <%= lookupvar("open_tcp_ports") %> \ |
| Fully Open to the World Ports (UDP) \ | <%= lookupvar("open_udp_ports") %> \ |

h2. NIC Information
|| *Interface* \ || *MAC Address* \ || *IP* \ || *Netmask* ||
<% lookupvar("::interfaces").split(',').each do |iface|
   ip   = "ipaddress_" + iface 
   mac  = "macaddress_" + iface
   mask = "netmask_" + iface
%>| <%= iface %> \ | <%= lookupvar(mac) %> \ | <%= lookupvar(ip) %> \ | <%= lookupvar(mask) %> \ |
<% end %>

h2. Contact Points
| Primary Admin | <%= extlookup("primary_nagios_contact") %> \ |
| Secondary Admin | <%= extlookup("secondary_nagios_contact") %> \ |
| Tertiary Admin | <%= extlookup("tertiary_nagios_contact") %> \ |

During non-emergency, please contact <%= lookupvar("admin_group_email") %>

More information such as what resources are managed on this node can be viewed [here|http://puppetdocs.<%= lookupvar("::domain") -%>/<%= lookupvar("::environment") -%>]
----

*Please use the comments for a server log.* 

{column}
{section}{section}
      }

      # Get current page to determine if there are no changed to be made
      current_confluence_page = `/usr/local/bin/confluence.sh --action getPageSource --title #{lookupvar("::fqdn")} --space IT`
      # Compile Confluence page with dynamic data populated
      new_confluence_page = ERB.new(page_template)

      # Now we will exit if there are no changes
      if current_confluence_page == new_confluence_page
         return 0
      end

      # Stuff changes into confluence
      output = `/usr/local/bin/confluence.sh --action storePage --title "#{lookupvar("::fqdn")}" --space IT --content '#{new_confluence_page.result(binding)}' 2>&1`

      if $? != 0
         raise Puppet::ParseError, output
      end

      return 0
   end
end

Please note this requires the shitty Java Confluence client, never had the chance to rewrite using native SOAP, but if you would, feel free to send me a patch!

This is also in production at one of my gigs on a 2.6.7 master, have yet to try on 2.7.9 which I am using at all my other gigs.

Comments