dhaivat home

I've been programming in one form or another for quite a bit, one control flow I've used more than anything else is loops - foreach, for and while (other than in school never used do..while) roughly in that order. Lately I've been using Puppet for obvious reasons, quickly building systems, keeping configs in sync and most important of all DRY.

Puppet makes installing packages, users, running services very easy, with a frontend like foreman more managable than ssh in for loop can ever be. In addition to foreman as a frontend I use it as an inventory backend - to query hosts and use results in puppet manifest. It is relatively straighforward to use the results if they are in form of an array for example,

$packages = [ 'git', 'python-virtualenv', 'python-dev', 's3cmd']

    package { $packages:
        ensure => latest
    }

But, if you want to install a list of packages with specific versions for each, then it is not so straightforward (atleast as far as I know), it requires you to use create_resources like so,

package { "python-dev":
        ensure => latest
    }

    $pip_packages = {
        'supervisor' => {
            ensure   => '3.0a12'
        },
        'uWSGI'    => {
            ensure => '1.1.2'
        },
        'bottle'   => {
            ensure => '0.10.9'
        }
    }

    $pip_defaults = {
        provider => pip,
        require  => Package["python-dev"]
    }

    create_resources(package, $pip_packages, $pip_defaults)

Not sure if this is just me or others have thought about it too, but having an explicit control flow construct in puppet would be nice, something like this...

$users = {
        "andy" => {
            "MacBook Air" => {
                "type" => "ssh-rsa",
                "key"  => "long key"
            }
        },
        "andrew" => {
            "MacBookAir" => {
                "type" => "ssh-rsa",
                "key"  => "long key"
            },
            "MacBookPro" => {
                "type" => "ssh-rsa",
                "key"  => "long key"
            }
        }
    }

    ## currently no built-in way to create 
    ## andy and andrew users with multiple ssh keys per users quickly

    ## I wish I can do this

    foreach { $user in $users:

        user { $user.name
            ensure => exists,
        }

        ssh_authorized_key {
            ensure => present,
            user   => "$user.name",
            key    => "$user.value.key"
            type   => "$user.value.type"
        }

    }

Currenlty the foreach thing doesn't exist. So I rigged something like this,

define useradd($name, $sshkey, $password) {

      $username = $title

      user { $username:
           managehome => true,
           comment    => "$name",
           password   => "$password",
        }

        group { $username:
        }

        Ssh_authorized_key {
            ensure => present,
            user   => "$username",
        }

        create_resources(ssh_authorized_key, $sshkey)
    }

To use it you can call it thusly (always wanted to use the word thusly.)

@useradd {  "andy":
        name               => "Andy Doe",
        sshkey             => {
            "andy@macbook"     => {
                type => "ssh-dss",
                key  => "long key"
            },
            "andy@macmini"    => {
                type => "ssh-dss",
                key  => "long key"
            }
        }
    }

That does it for tonight, food calls.

comments powered by Disqus
Fork me on GitHub