Interpolate File Contents Into Command Argument Used in Puppet Manifest

1

I have a SQL command that I would like to use as the value of a JSON node, which is a part of an index definition. All of this is passed as a command in a puppet manifest. I would like to externalize the sql script so it can be edited independently but can't figure out how to make it all play well.

Puppet Manifest:

...
exec { 'create_index':
  command => 'curl -XPUT http://localhost:9200/_river/my_jdbc_river/_meta -d "{ \"type\": \"jdbc\", \"jdbc\": \"sql\": \"`cat /vagrant/puppet/scripts/data.sql`\" } }"
}
...

The problem is, in order to increase readability, I have newlines and to structure the index, I use quotes like this:

SQL Script (data.sql):

SELECT
  name as "data.name",
  description as "data.description"
FROM
  data

Is there any way I can pull this off?

Benny

Posted 2014-12-22T02:03:55.717

Reputation: 197

Could you elaborate on your question? I'm not sure what you mean by externalize the sql script so it can be edited independently. – spuder – 2014-12-23T02:22:20.467

Answers

0

This is not really a puppet-specific question, but more of a JSON question. To be able to include content that has newlines, you need to either escape the newlines or remove them.

If you choose to escape them, you'll have to replace each newline with an escape sequence. Your endpoint would need to recognize the escaped newlines and convert them back to regular newlines before further processing.

exec { 'create_index':
  command => 'curl -XPUT http://localhost:9200/_river/my_jdbc_river/_meta -d "{ \"type\": \"jdbc\", \"jdbc\": \"sql\": \"`cat /vagrant/puppet/scripts/data.sql | tr \'\\n\' \'\\\\n\'`\" } }"'
}

The other option is to simply remove the newline. This has the advantage to not require modifications to the endpoint:

exec { 'create_index':
  command => 'curl -XPUT http://localhost:9200/_river/my_jdbc_river/_meta -d "{ \"type\": \"jdbc\", \"jdbc\": \"sql\": \"`cat /vagrant/puppet/scripts/data.sql | tr \'\\n\' \' \'`\" } }"'
}

However I would recommend building a separate script that simply takes the path to the sql file and does all the magic and have the create_index command call that script:

exec { 'create_index':
  command => '/vagrant/puppet/scripts/create_index.sh /vagrant/puppet/scripts/data.sql'
}

#!/bin/sh

file=$1
contents=`cat "$file"`

return curl -XPUT http://localhost:9200/_river/my_jdbc_river/_meta -d "{ \"type\": \"jdbc\", \"jdbc\": \"sql\": \"${contents}\" }"

T0xicCode

Posted 2014-12-22T02:03:55.717

Reputation: 181