Need to put iterative value in a file

35 views
Skip to first unread message

Quentin lenglet

unread,
May 4, 2017, 2:34:44 PM5/4/17
to Puppet Users
Ho everyone,

I have a lot of difficulty on Puppet for writing my own module and I don't succeed to understand how the module are made on Internet.
I need to develop a custom module for put ssh keys into the right file. My ideas is to put an array with the SSH keys and write the key in the file with an iterative way.
But i don't find any clear method to do that.
Can you help me ?

This is my code:

# == Class: lpsc::config
class lpsc::config inherits lpsc {


  file { '/etc/ssh/sshd_config':
    ensure  => present,
    owner   => 'root',
    group   => 'root',
    mode    => '0600',
  }

 if ($lpsc::ssh_keys == undef)
        {
        notify{"Pas de clef à rajouter":}
        }
 else
        {
        notify{"On peut rajouter une clef ${lpsc::ssh_keys}":}
        $demofiles = "/root/.ssh/test"
        $lpsc::ssh_keys.each | String  $value | {
          file {$demofiles:
          ensure  => present,
          replace => 'yes',
          owner   => 'root',
          group   => 'root',
          mode    => '0600',
          content => $value,
        }

        }
        }

}
Thx for your help

Have a good day!

Quentin Lenglet

Henrik Lindberg

unread,
May 5, 2017, 1:55:45 PM5/5/17
to puppet...@googlegroups.com
You logic creates one file for each ssh_key - it will not work since
your are telling the agent to ensure that the very same file has
different content.

You need on file resource and you want the content to be the list of
keys in text form. The easiest is probably to use the "join" function in
stdlib. Join with a ',' or ' ' depending on what you want as separator
in your file.

Hope that helps,
- henrik



> Thx for your help
>
> Have a good day!
>
> Quentin Lenglet
>
> --
> You received this message because you are subscribed to the Google
> Groups "Puppet Users" group.
> To unsubscribe from this group and stop receiving emails from it, send
> an email to puppet-users...@googlegroups.com
> <mailto:puppet-users...@googlegroups.com>.
> To view this discussion on the web visit
> https://groups.google.com/d/msgid/puppet-users/182731ab-a16b-4002-a3c7-48671035f630%40googlegroups.com
> <https://groups.google.com/d/msgid/puppet-users/182731ab-a16b-4002-a3c7-48671035f630%40googlegroups.com?utm_medium=email&utm_source=footer>.
> For more options, visit https://groups.google.com/d/optout.


--

Visit my Blog "Puppet on the Edge"
http://puppet-on-the-edge.blogspot.se/

Dirk Heinrichs

unread,
May 5, 2017, 2:12:57 PM5/5/17
to puppet...@googlegroups.com
On 04.05.2017 09:26, Quentin lenglet wrote:

        $demofiles = "/root/.ssh/test"
        $lpsc::ssh_keys.each | String  $value | {
          file {$demofiles:

This will not work, since the loop potentially creates multiple file resources with the same name ("/root/.ssh/test"), which is not allowed. The resource names inside the loop must be unique (for each resource type). They're best coupled with the loop counter variable ($value in this case).

HTH...

    Dirk
--
Dirk Heinrichs
Senior Systems Engineer, Delivery Pipeline
OpenTextTM Discovery | Recommind
Email: dirk.he...@recommind.com
Website: www.recommind.de

Recommind GmbH, Von-Liebig-Straße 1, 53359 Rheinbach

Vertretungsberechtigte Geschäftsführer John Marshall Doolittle, Gordon Davies, Roger Illing, Registergericht Amtsgericht Bonn, Registernummer HRB 10646

This e-mail may contain confidential and/or privileged information. If you are not the intended recipient (or have received this e-mail in error) please notify the sender immediately and destroy this e-mail. Any unauthorized copying, disclosure or distribution of the material in this e-mail is strictly forbidden

Diese E-Mail enthält vertrauliche und/oder rechtlich geschützte Informationen. Wenn Sie nicht der richtige Adressat sind oder diese E-Mail irrtümlich erhalten haben, informieren Sie bitte sofort den Absender und vernichten Sie diese Mail. Das unerlaubte Kopieren sowie die unbefugte Weitergabe dieser Mail sind nicht gestattet.

John Gelnaw

unread,
May 5, 2017, 3:19:27 PM5/5/17
to Puppet Users
The two ways I can think of, you can use ssh_authorized_key as part of a defined type, or you can create a file resource with a template, and use iteration within the template.

Iteration within the template requires "future parser" or Puppet 4.x.

James Perry

unread,
May 5, 2017, 6:58:00 PM5/5/17
to Puppet Users
Have you looked into the sshkey type already built into Puppet at https://docs.puppet.com/puppet/4.10/types/sshkey.html?  

Another option or possible combination would be to look at file_line function in Puppet's stdlib package. Using that you can append a line to an existing file or replace a line based on a regex matcher. 

Below is an example I did to fix the LS color for a directory from dark blue to a lighter blue.
file_line { 'dir_colors':
path => '/etc/DIR_COLORS',
line => "DIR ${dir_default_color} # directory",
match => '^DIR\s*.*',
replace => true,
}


Maybe this would better allow you to do what you want. If Puppet is managing the file then that file{} block will be auto-required before the file_line block(s) are run. 

You could hack it to be in your for loop or make a define that took in the file name, key to add the lines you want. 

Possibly something along these lines (note I didn't test this worked perfectly). You will have to provide the full path to the file for the $ssh_file parameter.

define ssh::builder (
String $ssh_file,
String $ssh_key,
$ensure => present,
) {
file_line { "${ssh_key}":
line => "${ssh_key}",
path => "${ssh_file}",
ensure => $ensure,
}
}

You would call it with ssh::builder { "${ssh_key_from_loop}": 
   ensure => 'present',
   ssh_file => '/full/path/to/file',
   ssh_key => "${ssh_key_from_loop}",
}

The reason I used ssh_key for the title in both cases was because that will be unique, which puppet requires. Now it only assumes a single file. 

Now if you want to create ssh keys per user, then you would want to use the sshkey and ssh_authorized_key types to make this easier. In the ssh_key you can specify a target file. I haven't tried to see if it handles writing more than one key to the same file or not. You might want to test that first because if that works it would seriously make your code a lot simpler. 
   

Quentin lenglet

unread,
May 9, 2017, 10:24:28 AM5/9/17
to Puppet Users
Hi,

Thx a lot for all your response.
I admit that i have some difficulty to understand how maje good module but i need to try harder after all.

I will try the different solutions that you send me.

Best regards

Quentin Lenglet
Message has been deleted

Henrik Lindberg

unread,
May 9, 2017, 2:27:11 PM5/9/17
to puppet...@googlegroups.com
Hi,
I made some comments in your code below. Most importantly perhaps is
showing you where you have that syntax error.

The error you get should tell you both line and the position on the line
where the error occurs, but sometimes it is not possible for the parser
to recognize a larger block of text and the error is not precise.

On 09/05/17 16:02, Quentin lenglet wrote:
> Hi
>
> My code looks like that:
>
> # == Class: lpsc::config

The syntax in the heading comment for classes and defines are used for
documentation (generated by 'puppet string' - we use Yard tags and
Markdown markup language for these comments. What you have here may be
a surprise to you if you want to generate documentation.

> class lpsc::config inherits lpsc {
>
> define lpsc::builder (
> String $ssh_file,
> String $ssh_key,
> $ensure => present,

The syntax error is here, it should be a '=', not a '=>'.

> ) {
> file_line { "${ssh_key}":
> line => "${ssh_key}",
> path => "${ssh_file}",
> ensure => $ensure,
> }
> }
>
if ssh_key, and ssh_file are already strings, you do not need to
interpolate them. You can just write:

line => $ssh_key

You win nothing by interpolating a single string. (It is just slower).

> file { '/etc/ssh/sshd_config':
> ensure => present,
> owner => 'root',
> group => 'root',
> mode => '0600',
> }
>
> if ($lpsc::ssh_keys == undef)
> {
> notify{"Pas de clef à rajouter":}
> }
> else
> {
> notify{"On peut rajouter une clef ${lpsc::ssh_keys}":}
> $demofiles = "/root/.ssh/test"
> # file {$demofiles:
> # ensure => present,
> # replace => 'no',
> # owner => 'root',
> # group => 'root',
> # mode => '0600',
> # content => $lpsc::ssh_keys[0],
> #}
> $lpsc::ssh_keys.each |$key|{
> lpsc::builder{"$key":
> ensure => 'present',
> ssh_file => $demofiles,
> ssh_key => "$key",

You want to indent the lines in the body of 'each' by two spaces.
> }
>
> }
>
> }
>

Best,
- henrik

Quentin lenglet

unread,
May 9, 2017, 2:39:12 PM5/9/17
to Puppet Users
Hi and thx for your message.

But now, i have an other problem. I move my lpsc::builder into a file name builder.pp.
But when i try this code:


# == Class: lpsc::config
class lpsc::config inherits lpsc {

 if ($lpsc::ssh_keys == undef)
        {
        notify{"Pas de clef à rajouter":}
        }
 else
        {
        notify{"On peut rajouter une clef ${lpsc::ssh_keys}":}
        $demofiles = "/root/.ssh/test"
        $lpsc::ssh_keys.each |String $key|{

                lpsc::builder{"$key":
                ensure => 'present',
                ssh_file => $demofiles,
                ssh_key => "$key",
        }

        }

}

Puppet tell me that i have an "Syntax error at end of file" config, which is this file.

Best,

Quentin Lenglet

Henrik Lindberg

unread,
May 9, 2017, 4:06:52 PM5/9/17
to puppet...@googlegroups.com

On 09/05/17 16:39, Quentin lenglet wrote:
> Hi and thx for your message.
>
> But now, i have an other problem. I move my lpsc::builder into a file
> name builder.pp.

Your { } needs to be balanced. It reaches the end and there is a '}'
missing.

Proper indenting of code and braces help a lot.

Best,

- henrik

> But when i try this code:
>
> # == Class: lpsc::config
> class lpsc::config inherits lpsc {
>
> if ($lpsc::ssh_keys == undef)
> {
> notify{"Pas de clef à rajouter":}
> }
> else
> {
> notify{"On peut rajouter une clef ${lpsc::ssh_keys}":}
> $demofiles = "/root/.ssh/test"
> $lpsc::ssh_keys.each |String $key|{
> lpsc::builder{"$key":
> ensure => 'present',
> ssh_file => $demofiles,
> ssh_key => "$key",
> }
>
> }
>
> }
>
> Puppet tell me that i have an "Syntax error at end of file" config,
> which is this file.
>
> Best,
>
> Quentin Lenglet
>
> --
> You received this message because you are subscribed to the Google
> Groups "Puppet Users" group.
> To unsubscribe from this group and stop receiving emails from it, send
> an email to puppet-users...@googlegroups.com
> <mailto:puppet-users...@googlegroups.com>.
> To view this discussion on the web visit
>
https://groups.google.com/d/msgid/puppet-users/4bbc2031-1668-4c4a-bdc4-f8c2ae96e102%40googlegroups.com
>
<https://groups.google.com/d/msgid/puppet-users/4bbc2031-1668-4c4a-bdc4-f8c2ae96e102%40googlegroups.com?utm_medium=email&utm_source=footer>.
> For more options, visit https://groups.google.com/d/optout.


Quentin lenglet

unread,
May 11, 2017, 6:39:48 AM5/11/17
to Puppet Users
Hi

Oh my god it works!

I have my each value of my tab written in the config file i precise.L Thx a lot everybody.
With all your advice and indication, I understand what I did.

Best ;)

Quentin Lenglet
Reply all
Reply to author
Forward
0 new messages