puppet template remove the last comma
Asked Answered
F

4

8

I have the following puppet example template:

{
  "servers" : [ {
    "port" : 9200,
    "host" : "localhost",

    "queries" : [
      <% @markets.each do |market| -%>
      {
      "outputWriters" : [ { "@class" : "com.googlecode.jmxtrans.model.output.StdOutWriter" } ],
      "obj" : "solr/market_<%= market %>:type=queryResultCache,id=org.apache.solr.search.LRUCache",
      "attr" : [ "hits","hitratio" ]
    },
    <% end -%>
    ],
    "numQueryThreads" : 2
  } ],
}

Applying it with market=['UK','FR','IT'], I get the following:

{
  "servers" : [ {
    "port" : 9200,
    "host" : "localhost",

    "queries" : [
            {
      "outputWriters" : [ { "@class" : "com.googlecode.jmxtrans.model.output.StdOutWriter" } ],
      "obj" : "solr/market_UK:type=queryResultCache,id=org.apache.solr.search.LRUCache",
      "attr" : [ "hits","hitratio" ]
    },
          {
      "outputWriters" : [ { "@class" : "com.googlecode.jmxtrans.model.output.StdOutWriter" } ],
      "obj" : "solr/market_FR:type=queryResultCache,id=org.apache.solr.search.LRUCache",
      "attr" : [ "hits","hitratio" ]
    },
          {
      "outputWriters" : [ { "@class" : "com.googlecode.jmxtrans.model.output.StdOutWriter" } ],
      "obj" : "solr/market_IT:type=queryResultCache,id=org.apache.solr.search.LRUCache",
      "attr" : [ "hits","hitratio" ]
    },
        ],
    "numQueryThreads" : 2
  } ],
}

The problem is the last comma, which makes it an invalid solr config.

Instead of applying markets.each do, I could use market.map and join(','). but how to use map in this case?

I can use map as follows:

<%= @markets.map{ |market| "hello_"+market }.join(',') -%>

this would print hello_UK,hello_FR,hello_IT (note that we don't have a comma after hello_IT), but I would need something like this:

{
  "servers" : [ {
    "port" : 9200,
    "host" : "localhost",

    "queries" : [
      <% @markets.map |market| -%>
      {
      "outputWriters" : [ { "@class" : "com.googlecode.jmxtrans.model.output.StdOutWriter" } ],
      "obj" : "solr/market_<%= market %>:type=queryResultCache,id=org.apache.solr.search.LRUCache",
      "attr" : [ "hits","hitratio" ]
    },
    <% }.join(',') -%>
    ],
    "numQueryThreads" : 2
  } ],
}

this does not work.

so, how to make it work? or how to modify my puppet template to remove the last comma?

Forfeiture answered 13/8, 2013 at 9:51 Comment(4)
Old trick is to include a fixed dummy entry after your list that does not break anything. Maybe that's an option.Consolidation
I'd use jbuilderCardigan
@Stefan, how would you plug jbuilder for a puppet template?Forfeiture
@DavidPortabella I don't know Puppet, creating JSON with a builder just seemed obvious.Cardigan
P
23

This is actually a Ruby problem rather than a Puppet problem. Since this is an array, just change the .each to .each_with_index. Then you can wrap the final comma in a check to see whether the current index value is one less than the size of the index. For example, the following code adds a comma only if the current market is not the last one in the array:

<% @markets.each_with_index do |market, i| -%>

and then

}<%= ',' if i < (@markets.size - 1) %>
Publishing answered 16/8, 2013 at 10:23 Comment(4)
I'm not sure why you call it a workaround; it's a solution. Puppet uses the ERB (Embedded Ruby) templating system and Ruby is the code you use to manipulate the templates. All Puppet does is set up the variable scope and provide a few helper functions. It can't help you with iteration through an array - that's something you have to solve in the Ruby code. Glad to have been of help either way, ofc.Publishing
it works and it solves the problem, and I am very grateful that you shared it. however, you will agree with me that it is ugly code. maybe it is the only type of solution available, in which case it means that erb is quite poor (compared to Scala and playframework template, for instance). or maybe there is a way to do it without this trick, maybe using the @markets.map{ |market| ... }.join(','), but i didn't find out how.Forfeiture
It is ugly, I guess. ERB is very basic - just a way of evaluating Ruby embedded in text - and the only magic it adds is the ability to control unwanted whitespace ;) As a Scala coder, you must have enough issues with the Puppet DSL, let alone the templating.Publishing
don't forget the 'do': markets.each_with_index do |market, i|Balladry
P
3

I saw on a puppet labs site (https://ask.puppetlabs.com/question/4195/joining-array-from-hieraconcat-other-value-in-erb/) this form of solution.

<%= quorum.map{ |srv| "#{srv}:#{portNum}" }.join(',') %>

This code lets you take an array and create a variation of each element then join them all together with the appropriate join text (not including a spurious comma at end).

Profusive answered 23/10, 2014 at 20:49 Comment(0)
E
0

For Puppet 4.10.12 Ben's answer wasn't working for me, but the following similar syntax did.

server=<%= $servers.map |$server| { "${server['hostname']}:${server['port']}" }.join(',') %>
Enumeration answered 20/3, 2019 at 17:3 Comment(0)
M
0

This is easier if you do it backwards. Instead of suffixing all but the last section with a comma, you can prefix all but the first section with a comma instead. This is a bit easier to implement with a variable that changes state after the first section:

<%- comma = ""; @markets.map |market| -%><%= comma -%>

...

<%- comma = "," -%>
<%- } -%>
Marijuana answered 24/7, 2020 at 12:58 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.