Take the 2-minute tour ×
Server Fault is a question and answer site for professional system and network administrators. It's 100% free, no registration required.

My goal is to define a class that takes, as input, an array of pairs. Since I'm not sure how to define an array of pairs, I'm just going to use a pair of arrays instead.

class student($username, $full_name){
  notify {"user":  message => "username: ${username}\n"}
  notify {"fullname":  message => "fullname: ${full_name}\n"}
  exec {'finger': command => "/usr/bin/finger ${username}", logoutput => true }
}

$users = ['elion', 'azee', 'root']
$names = ['El Lion', 'Avery Zee', "Rooty Root"]

class { 'student':
  username => $users,
  full_name => $names
}

Upon doing a 'puppet apply file.pp' I expect the output to iterate through the two arrays, printing out the notifications and fingering the students (that sounds horrible) in the order given by the arrays. I tried this and what ended up happening, is that puppet conflated the arrays into one string, so the $users value ended up being: elionazeeroot and the $names value ended up being El Lion Avery Zee Rooty Root.

Two questions:

  1. Is there a way to define a class to handle a group of data, like I'm trying to do here?
  2. I suspect that I'm not using the right construct to achieve my goal. What should I be doing instead?
share|improve this question
    
Possible duplicate of serverfault.com/questions/509075/… –  dawud May 31 '13 at 9:05
    
Hiera would probably make your life much easier. It's dead-simple to set up too. –  Ger Apeldoorn May 31 '13 at 9:31

1 Answer 1

up vote 2 down vote accepted

The natural way to represent your data in a programming language would be a hash like this:

$users = {
  elion => 'El Lion',
  azee  => 'Avery Zee',
  root  => 'Rooty Root,
}

While doing that in Puppet is possible, I've found it's best to decide what a resource definition for a single entry would be and then structure the hash as something you could pass to create_resources(). In this case, that would mean something like this:

define student ($full_name) {
  notify { "user ${title}":
    message => "username: ${title}\n",
  }
  notify { "fullname ${title}":
    message => "fullname: ${full_name}\n",
  }
  exec { "finger ${title}":
    command   => "/usr/bin/finger ${title}",
    logoutput => true,
  }
}

$users = {
  elion => { full_name => 'El Lion'   },
  azee  => { full_name => 'Avery Zee' },
  root  => { full_name => 'Rooty Root },
}

create_resources(student, $users)

However, as Ger notes, you'll be best off if you use Hiera. Hiera lets you separate your code (the manifest definitions) from your data (in this case, the particular names of the students). In full, here's what I would do for your setup:

  • Put the student data in a hiera file. You can use JSON or YAML; I like YAML. It would be something like this:

    classroom::users:
      elion:
        full_name: El Lion
      azee:
        full_name: Avery Zee
      root:
        full_name: Rooty Root
    
  • Define a resource type for students and put it in classroom/manifests/student.pp in Puppet's $modulepath. It would look like the student resource type above, but would be named classroom::student.

  • Define a classroom class in classroom/manifests/init.pp with the following content:

    class classroom (
      $users = hiera('classroom::users', undef),
    ) {
      create_resources(classroom::student, $users)
    }
    

If you're using Puppet 3.x, the hiera() call in the class parameters is redundant, but you need it if you're still on Puppet 2.7.

share|improve this answer
    
This is pretty. I was going to try to do something similar with the new lambdas, but this is much nicer –  tel Jul 16 at 2:37

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.