我有json文件作为环境文件导入到厨师,
{
"mongodb": {
"replicaset": {
"nodes": [
"test-mongo1:27017",
"test-mongo2:27017"
]
}
}
}
我添加如下主厨菜谱模板来构建mongo连接字符串,
"mongo": {
"url" : "mongodb://<% node['mongodb']['replicaset']['nodes'].each do |replica| -%>admin:123456@<%= replica %>/user_db1",
<% end %>
但输出如下,未验证为JSON
"mongo": {
"url" : "mongodb://admin:123456@test-mongo1:27017/user_db1",
admin:123456@test-mongo2:27017/user_db1",
预期结果:
"mongo": {
"url" : "mongodb://admin:123456@test-mongo1:27017/user_db1,admin:123456@test-mongo2:27017/user_db1",
关注How to Run for each loop in template chef,但我的红宝石不是最好的,因为我刚刚开始使用所有这些东西。任何帮助都会很棒,谢谢。
答案 0 :(得分:3)
首先,我们可以尝试修复循环,以便只在内部块中包含必要的部分:
"mongo": {
"url" : "mongodb://<% node['mongodb']['replicaset']['nodes'].each do |replica| -%>admin:123456@<%= replica %>/user_db1,<% end %>",
然而,这仍然会导致一个问题:有一个尾随逗号,因为我们总是在每次迭代后添加它。
因此,更好的方法是首先构建一个URL列表,然后用逗号将它们连接到一个字符串。这样,元素之间只添加了一个逗号。这应该工作:
"mongo": {
"url" : "mongodb://<%= node['mongodb']['replicaset']['nodes'].map { |replica| "admin:123456@#{replica}/user_db1" }.join(",") %>",
基本上,此代码的作用如下:
output = ""
output << "\"mongo\": {\n"
output << " \"url\" : \"mongodb://"
urls = node['mongodb']['replicaset']['nodes'].map do |replica|
output << "admin:123456@"
output << replica
output << "/user_db1"
end
output << urls.join(", ")
output << "\","
此处,output
表示ERB模板的输出。在实际的ERB实现中,涉及的逻辑要多一些,但基本逻辑与此类似。
在实际食谱中执行此操作时,通常更好的方法是在食谱中构建URL并将其传递给模板预建:
在recipes/default.rb
:
urls = node['mongodb']['replicaset']['nodes'].map do |replica|
"admin:123456@#{replica}/user_db1"
end
template '/path/to/mongo.json' do
source 'my_template.json.erb'
variables mongo_urls: urls
end
在templates/default/my_template.json.erb
:
"mongo": {
"url" : "mongodb://<%= @mongo_urls.join(",") %>",