
Preciso encontrar uma solução para esse problema que encontrei.
Eu tenho um hash (deve ser substituído como um parâmetro de classe inteligente posteriormente) que estou iterando em meu template.erb para gerar vários recursos de arquivo que defini usando uma matriz. Quero que a iteração pare depois de passar pelo primeiro conjunto de pares de valores-chave e, em seguida, comece a gravar no próximo arquivo.
Vou mostrar um exemplo para deixar as coisas mais claras.
#### init.pp ####
class testing (
$nameid = ['alex','ben'],
$game_code = {
alex_super_mario => {
"type" => "1",
"characters" => {
"bowser" => "123",
"luigi" => "456",
"princess" => "789" }
},
ben_mega_man => {
"type" => "2",
"characters" => {
"something" => "111213",
"else" => "131415",
"lastone" => "161718" }
},
}
) {
define testing(
$base_path = '/var/tmp/testing',
){
file {"${base_path}/${name}_file.xml":
owner => 'root',
group => 'root',
ensure => 'file',
mode => '0644',
content => template("testing/template.xml.erb"),
}
}
testing { [$nameid]: }
}
### arquivo de modelo ### template.xml.erb
<% @nameid.each do |username| %>
<UserName><%= username %></UserName>
<% end %>
<games>
<% @game_code.sort.map do |hero, value| %>
<% value.sort.map do |game,code| %>
<% if game == "characters" %>
<% code.each do |k, v| %>
<game>
<type><%= value['type'] %></type>
<gameid><%= v %></gameid>
<extcharacters>
<char>/var/tmp/<%= k %></path>
</extcharacters>
</game>
<% end %>
<% end %>
<% end %>
<% end %>
</games>
# isso gera dois arquivos do meu array $nameid = ['alex','ben'] conforme esperado.
Notice: /Stage[main]/Testing/Testing::Testing[ben]/File[**/var/tmp/testing/ben_file.xml**]/ensure: defined content as '{md5}21af03b1dd7427d17c2460bae323bc24'
Notice: /Stage[main]/Testing/Testing::Testing[alex]/File[**/var/tmp/testing/alex_file.xml**]/ensure: defined content as '{md5}21af03b1dd7427d17c2460bae323bc24'
Notice: Finished catalog run in 0.34 seconds
No entanto, olhando dentro desses arquivos, recebo dois arquivos idênticos com a saída das chaves "alex_super_mario" e "ben_mega_man" do meu hash $game_code:
A saída esperada que desejo alcançar é basicamente ter o primeiro conjunto de iterações feito para "alex_super_mario" => { .... entrar no alex_file.xml junto com o nome de usuário alex.
e o material ben_mega_man vai dentro do arquivo ben.
Isso é possível?
<UserName>alex</UserName> <--- ## this should go into the alex_file.xml
<UserName>ben</UserName> <--- ## this should go into the ben_file.xml ##
<games>
<game> ## <-- this should go to the ben_file.xml
<type>2</type>
<gameid>111213</gameid>
<extcharacters>
<char>/var/tmp/something</path>
</extcharacters>
</game>
<game>
<type>2</type>
<gameid>161718</gameid>
<extcharacters>
<char>/var/tmp/lastone</path>
</extcharacters>
</game>
<game>
<type>2</type>
<gameid>131415</gameid>
<extcharacters>
<char>/var/tmp/else</path>
</extcharacters>
</game>
<game> ### <------ these should go into the alex_file.xml
<type>1</type>
<gameid>123</gameid>
<extcharacters>
<char>/var/tmp/bowser</path>
</extcharacters>
</game>
<game>
<type>1</type>
<gameid>789</gameid>
<extcharacters>
<char>/var/tmp/princess</path>
</extcharacters>
</game>
<game>
<type>1</type>
<gameid>456</gameid>
<extcharacters>
<char>/var/tmp/luigi</path>
</extcharacters>
</game>
</games>
Responder1
Seu modelo faz um loop explicitamente sobre nameid e, em seguida, sobre todas as chaves em game_code, então é claro que cada arquivo gerado terá todos os dados nele. Talvez algo assim servisse:
<UserName><%= @name %></UserName>
<games>
<% @game_code.sort.map do |hero, value|
if (somecondition)
value.sort.map do |game,code|
<if game == "characters"
code.each do |k, v| %>
<game>
<type><%= value['type'] %></type>
<gameid><%= v %></gameid>
<extcharacters>
<char>/var/tmp/<%= k %></path>
</extcharacters>
</game>
<% end
end
end
end
end %>
</games>
onde "somecondition" está, no entanto, você deseja decidir se o hash de 'valor' atual é aquele que corresponde ao nome do seu herói atual (é difícil dizer como você deseja fazer isso, visto que as chaves em game_code não correspondem às strings em nome)