Archive for » July, 2009 «

Thursday, July 30th, 2009 | Author:

-Post en anglais, pour une fois-

Everyone using puppet knows DavidS awesome git repository : git.black.co.at. Unfornately for me, his puppet infrastructure seems to be almost only linux based. I have different OS in mine, including FreeBSD & OpenSolaris. Looking at his module-munin I decided to reuse it (and not recreate the wheel) but he used a custom fact that needed some little work. So this is a FreeBSD & (Open)Solaris capable version, to know what network interfaces have link up

# return the set of active interfaces as an array
# taken from http://git.black.co.at
# modified by nico <nico@gcu.info> to add FreeBSD & Solaris support
 
Facter.add("munin_interfaces") do
 
	setcode do
		# linux
		if Facter.value('kernel') == "Linux" then
			`ip -o link show`.split(/\n/).collect do |line|
					value = nil
					matches = line.match(/^\d*: ([^:]*): <(.*,)?UP(,.*)?>/)
					if !matches.nil?
						value = matches[1]
						value.gsub!(/@.*/, '')
					end
					value
			end.compact.sort.join(" ")
		#end
 
		# freebsd
		elsif Facter.value('kernel') == "FreeBSD" then
			Facter.value('interfaces').split(/,/).collect do |interface|
				status = `ifconfig #{interface} | grep status`
				if status != "" then
					status=status.strip!.split(":")[1].strip!
					if status == "active" then # I CAN HAZ LINK ?
						interface.to_a
					end
				end
			end.compact.sort.join(" ")
		#end
 
		# solaris
		elsif Facter.value('kernel') == "SunOS" then
			Facter.value('interfaces').split(/,/).collect do |interface|
				if interface != "lo0" then # /dev/lo0 does not exists
					status = `ndd -get /dev/#{interface} link_status`.strip!
					if status == "1" # ndd returns 1 for link up, 0 for down
						interface.to_a
					end
				end
			end.compact.sort.join(" ")
		end
	end
end

Thanks to Volcane from IRC for helping me.

Category: BOFH Life, Code, Puppet, SysAdmin, Tech  | Tags: ,  | 74 Comments
Monday, July 06th, 2009 | Author:

Il y a des trucs, ça relève du bon sens mais on y pense pas toujours. Dans le monde des sysadmins, il y en a qui militent pour ce qu’on appelle “l’agilité”. C’est en fait appliquer certaines techniques à la base mises en place pour le développement au monde de l’administration système. Personnellement, je trouve que ce sont essentiellement des conseils de bon sens, l’expérience qui parle en somme.

Une de ces “bonnes pratiques” est que le code est la documentation, ce qui évite d’avoir à la réécrire – parce que c’est chiant avouons le – voire même d’oublier de l’écrire, ce qui arrive souvent.

Comme je suis en pleine frénésie puppet-ienne, j’écris des classes à tout va mais pas la doc qui va avec.. et ça PAS BIEN. Je me suis donc lancé dans un petit projet pour documenter mes classes puppet vite fait bien comme une loutre.

Il suffit d’ajouter au dessus de chaque classe (ou en dessous ou peu importe, le code est crade et ne fait pas la différence) des commentaires formattés comme suit :

# @name : debian
# @desc : classe de base pour debian
# @info : ne pas affecter, sera incluse automatiquement

Pour que le script sorte les données dans un tableau façon dokuwiki en 3 colonnes.

Le script va ensuite poster les infos dans le dokuwiki via XML-RPC dans la page indiquée par le script. Tout ce que contient la page sera écrasé, ce n’est pas de l'”append”.

Personnellement je conjugue ce script avec le plugin “include” de dokuwiki. J’ai donc la syntaxe suivante dans une des pages de mon wiki :

{{page>:auto_puppetclasses}}

Le XML-RPC est désactivé par défaut dans dokuwiki, pour l’activer ajoutez dans conf/local.php

$conf['xmlrpc'] = 1;

Et enfin, le script en ruby avec des bouts de XML-RPC dedans (dispo dans le package libruby sous debian). Warning, code sale.

#!/usr/bin/env ruby
#
# Automagicaly adds puppet classes in the dokuwiki corporate documentation
# For use with the "include" plugin
# By nico <nico@gcu.info>
 
require 'xmlrpc/client'
 
xmlrpc_url = "http://XXXXX/wiki/lib/exe/xmlrpc.php"
basedirs = [ "/home/nico/sysadmin/puppet/manifests/classes", "/home/nico/sysadmin/puppet/manifests/os"]
destination_page = "auto_puppetclasses"
 
server = XMLRPC::Client.new2(xmlrpc_url)
 
def doku_class(classfile, final_page)
	fp=File.open(classfile)
	fp.readlines().each { |line|
 
		line=line.gsub("n","")
 
		if line =~ /@name/
			final_page += "| " + line[10,line.length]
		end
 
		if line =~ /@desc/
			final_page += " | " + line[10,line.length] + " | "
		end
 
		if line =~ /@info/
			final_page += line[10,line.length] + " |n"
		end
	}
 
	return final_page
end
 
final_page=""
 
# output some dokuwiki thing
final_page += "===== Classes disponibles =====n"
final_page +=  "n"
final_page +=  "^ Nom de la classe ^ Description rapide ^ Infos supplémentaires ^n"
 
basedirs.each{ |basedir|
	Dir.new(basedir).entries.each { |entry|
		if File.file? basedir+"/"+entry then
			final_page=doku_class(basedir+"/"+entry,final_page)
		end
	}
}
 
server.call2("wiki.putPage", destination_page, final_page, "", 0)