From 9b801d3be8e0268994169729cf5d5dd4600367cb Mon Sep 17 00:00:00 2001 From: Stefan Wold Date: Sat, 22 Feb 2014 18:29:41 +0100 Subject: [PATCH] git tag gpg signature validation of puppet modules Before staging a puppet module for install the latest git tag is verified using the available gpg key identities. The git tag pattern can be overriden using a fourth argument in cosmos-modules.conf. --- global/post-tasks.d/018packages | 96 +++++++++++++++++++++++++++++---- 1 file changed, 85 insertions(+), 11 deletions(-) diff --git a/global/post-tasks.d/018packages b/global/post-tasks.d/018packages index 9e25e69..bf7bf64 100755 --- a/global/post-tasks.d/018packages +++ b/global/post-tasks.d/018packages @@ -1,16 +1,90 @@ -#!/bin/sh +#!/bin/bash + +CONFIG=${CONFIG:=/etc/puppet/cosmos-modules.conf} +CACHE_DIR=/var/cache/puppet-modules +MODULES_DIR=${MODULES_DIR:=/etc/puppet/cosmos-modules} +export GNUPGHOME=/etc/cosmos/gnupg python -c "import yaml" 2>/dev/null || apt-get -y install python-yaml -if [ -f /etc/puppet/cosmos-modules.conf ]; then - grep -E -v "^#" /etc/puppet/cosmos-modules.conf | ( - cd /etc/puppet/modules && while read module src update; do - if [ ! -d /etc/puppet/modules/$module ]; then - echo $src | grep -q "://" && git clone $src $module || puppet module install $src - else - if [ "x$update" = "xyes" ]; then - echo $src | grep -q "://" && (cd /etc/puppet/modules/$module && git pull -q) || puppet module upgrade $src + +stage_module() { + rm -rf $CACHE_DIR/staging/$1 + git archive --format=tar --prefix=$1/ $2 | (cd $CACHE_DIR/staging/ && tar xf -) +} + +if [ -f $CONFIG ]; then + if [ ! -d $MODULES_DIR ]; then + mkdir -p $MODULES_DIR + fi + if [ ! -d $CACHE_DIR ]; then + mkdir -p $CACHE_DIR/{scm,staging} + fi + + # First pass to clone any new modules, and update those marked for updating. + grep -E -v "^#" $CONFIG | ( + while read module src update pattern; do + # We only support git:// urls atm + if [ "${src:0:6}" = "git://" ]; then + if [ ! -d $CACHE_DIR/scm/$module ]; then + git clone -q $src $CACHE_DIR/scm/$module + elif [ -d $CACHE_DIR/scm/$module/.git ]; then + if [ "$update" = "yes" ]; then + cd $CACHE_DIR/scm/$module + git pull -q + else + continue fi - fi - done) + else + echo "ERROR: Ignoring non-git repository" + continue + fi + fi + done + ) + + # Second pass to verify the signatures on all modules and stage those that + # have good signatures. + grep -E -v "^#" $CONFIG | ( + while read module src update pattern; do + # We only support git:// urls atm + if [ "${src:0:6}" = "git://" ]; then + # Verify git tag + cd $CACHE_DIR/scm/$module + TAG=$(git tag -l "${pattern:-*}" | sort | tail -1) + if [ "$COSMOS_VERBOSE" = "y" ]; then + echo "" + echo "Checking signature on tag ${TAG} for puppet-module $module" + fi + if [ -z "$TAG" ]; then + echo "ERROR: No git tag found for pattern '${pattern:-*}' on puppet-module $module" + continue + fi + git tag -v $TAG &> /dev/null + if [ $? == 0 ]; then + if [ "$COSMOS_VERBOSE" = "y" ]; then + # short output on good signature + git tag -v $TAG 2>&1 | grep "gpg: Good signature" + fi + # Put archive in staging since tag verified OK + stage_module $module $TAG + else + echo "################################################################" + echo "FAILED signature check on puppet-module $module" + echo "################################################################" + git tag -v $TAG + fi + fi + done + ) + + # Cleanup removed puppet modules from CACHE_DIR + for MODULE in $(ls -1 $CACHE_DIR/staging/); do + if ! grep -E -q "^$MODULE\s+" $CONFIG; then + rm -rf $CACHE_DIR/{scm,staging}/$MODULE + fi + done + + # Installing verified puppet modules + rsync --archive --delete $CACHE_DIR/staging/ $MODULES_DIR/ fi