Développement des modules

Bases

Langage

Un module peut être développé dans n'importe quel langage de programmation : scripts shell, perl, C, ...

Règles

Les règles sont passées aux modules par l'intermédiaire de variables d'environnement. Les langages de programmation avancés peut faire usage de valeurs de variables complexes sous forme de dictionnaires sérialisés par JSON ou XML.

Paramètres

Un module ne doit supporter qu'un seul paramètre. Sa valeur peut être

Argument Description
check

Vérifier que les règles sont correctement appliquées sur le noeud ou le service.

fixable

Vérifier que le module est capable d'assurer les corrections sur le service ou le noeud.

fix

Appliquer les règles au noeud ou au service

Code retour

Un module doit renvoyer une de ces trois valeurs

Argument Description
0

Les vérifications et les corrections de conformité ont réussi

1

Les vérifications et les corrections de conformité ont échoué

2

Les vérifications et les corrections de conformité ne sont pas applicables. Par exemple parcequ'aucune des règles attendues par le module ne sont exportées.

Emplacement

Modules are installed in <OSVCVAR>/compliance.

Convention de nommage des fichiers

A module can be either a file or a directory tree. The top-level file or directory name must comply to the naming convention:

[S][0-9]+[-]modname

If the module top-level object is a directory, the file tree under it must be either:

[S][0-9]+[-]modname/main

or:

[S][0-9]+[-]modname/scripts/main

Objets de conformité

OpenSVC distribue un ensemble d'objets de conformité, implémentées sous forme de classes python exécutables, afin de faciliter le développement des modules. Ils implémentent des fonctions de vérification et de correction pour les besoins de base. Les squelettes présentés ci-bas utilisent ces objets.

Les objets utilisent des règles complexes sous forme de dictionnaire sérialisés, et le collecteur dispose de formulaires pour créer facilement ces règles.

Les modules appelants doit spécifier aux objets deux informations :

  • The called action : fix, fixable or check
  • Le préfixe du nom des variables que l'objet doit prendre en considération. L'objet cherchera dans l'environnement toutes les variables correspondantes à ce préfixe.

Auto-modules

A module embedded in a moduleset, with no deployed script by that name, is an auto-module.

The agent loops over each variable provided with the moduleset. If the variable class matches a deployed compliance object, it executes this compliance object with the variable name as the scope argument.

Squelette d'un module

Script shell

#!/bin/bash

PATH_SCRIPT="$(cd $(/usr/bin/dirname $(type -p -- $0 || echo $0));pwd)"
PATH_LIB=$PATH_SCRIPT/com.opensvc
PREFIX=OSVC_COMP_FOO

typeset -i r=0

case $1 in
check)
        $PATH_LIB/files.py ${PREFIX}_FILES check
        [ $? -eq 1 ] && r=1
        $PATH_LIB/packages.py ${PREFIX}_PKG check
        [ $? -eq 1 ] && r=1
        exit $r
        ;;
fix)
        $PATH_LIB/files.py ${PREFIX}_FILES check
        [ $? -eq 1 ] && exit 1
        $PATH_LIB/packages.py ${PREFIX}_PKG check
        [ $? -eq 1 ] && exit 1
        ;;
fixable)
        exit 2
        ;;
esac

Scripts python

#!/usr/bin/env python

import os
import sys

sys.path.append(os.path.join(os.path.dirname(__file__), 'com.opensvc'))

from comp import *

import files
import packages

syntax = """syntax: %s check|fixable|fix"""%sys.argv[0]

if len(sys.argv) != 2:
    print >>sys.stderr, "wrong number of arguments"
    print >>sys.stderr, syntax
    sys.exit(RET_ERR)

objs = []

try:
    o = packages.CompPackages(prefix='OSVC_COMP_BDC_DHCPD_PACKAGE')
    objs.append(o)
except NotApplicable:
    pass

try:
    o = files.CompFiles(prefix='OSVC_COMP_BDC_DHCPD_FILE')
    objs.append(o)
except NotApplicable:
    pass

def check():
    r = 0
    for o in objs:
        r |= o.check()
    return r

def fixable():
    return RET_NA

def fix():
    r = 0
    for o in objs:
        r |= o.fix()
    return r

try:
    if sys.argv[1] == 'check':
        RET = check()
    elif sys.argv[1] == 'fix':
        RET = fix()
    elif sys.argv[1] == 'fixable':
        RET = fixable()
    else:
        print >>sys.stderr, "unsupported argument '%s'"%sys.argv[1]
        print >>sys.stderr, syntax
        RET = RET_ERR
except NotApplicable:
    sys.exit(RET_NA)
except:
    import traceback
    traceback.print_exc()
    sys.exit(RET_ERR)

sys.exit(RET)