Search code examples
puppetregex-replace

How to comment all the uncommented lines in a file using puppet module


I have a configuration file which contains commented as well as uncommented lines. I want to comment all the uncommented lines in that file using puppet. Is there any optimal/simple way to do this? Or is there a way to run bash command (maybe sed to replace) via puppet? I am not sure that using bash command is a right approach.

It would be really helpful is someone guides me with this. Thanks in advance!


Solution

  • Is there any optimal/simple way to do this?

    There is no built-in resource type or well-known module that specifically ensures that non-blank lines of a file start with a # character.

    Or is there a way to run bash command (maybe sed to replace) via puppet?

    Yes, the Exec resource type. That's your best bet short of writing a custom resource type.

    I am not sure that using bash command is a right approach.

    In a general sense, it's not. Appropriate, specific resource types are better than Exec. But when you don't have a suitable one and can't be bothered to make one, Exec is available.

    It might look like this:

    # The file to work with, so that we don't have to repeat ourselves
    $target_file = '/etc/ssh/sshd_config'
    
    exec { "Comment uncommented ${target_file} lines":
      # Specifying the command in array form avoids complicated quoting or any
      # risk of Puppet word-splitting the command incorrectly
      command  => ['sed', '-i', '-e', '/^[[:space:]]*[^#]/ s/^/# /', $target_file],
    
      # If we didn't specify a search path then we would need to use fully-qualified
      # command names in 'command' above and 'onlyif' below
      path     => ['/bin', '/usr/bin', '/sbin', '/usr/sbin'],
    
      # The file needs to be modified only if it contains any non-blank, uncommented
      # lines.  Testing that via an 'onlyif' ensures that Puppet will not
      # run 'sed' or (more importantly) report the file changed when it does
      # not initially contain any lines that need to be commented
      onlyif   => [['grep', '-q', '^[[:space:]]*[^#]', $target_file]],
    
      # This is the default provider for any target node where the rest of this
      # resource would work anyway.  Specifying it explicitly will lead to a more
      # informative diagnostic if there is an attempt to apply this resource to
      # a system to which it is unsuited.
      provider => 'posix',
    }
    

    That does not rely on bash or any other shell to run the commands, but it does rely on sed and grep being available in one of the specified directories. In fact, it relies specifically on GNU sed or one that supports an -i option with the same semantics. Notably, that does not include BSD-style sed, such as you will find on macOS.