Ruby Chef recipe如何从数据库获取/检索参数?

Ruby Chef recipe如何从数据库获取/检索参数?,ruby,chef-infra,chef-recipe,Ruby,Chef Infra,Chef Recipe,我一直在尝试学习Chef,并尝试测试一本小的Chef烹饪书,它可以制作Windows2008R2服务器的dcpromo 我不记得这两个文件最初是从哪里得到的,但我能让它正常工作 原始dcpromo_unattend.txt.erb文件为: [DCINSTALL] SafeModeAdminPassword=<%= @admin_password %> RebootOnCompletion=Yes ReplicaOrNewDomain=domain NewDomain=forest N

我一直在尝试学习Chef,并尝试测试一本小的Chef烹饪书,它可以制作Windows2008R2服务器的dcpromo

我不记得这两个文件最初是从哪里得到的,但我能让它正常工作

原始dcpromo_unattend.txt.erb文件为:

[DCINSTALL]
SafeModeAdminPassword=<%= @admin_password %>
RebootOnCompletion=Yes
ReplicaOrNewDomain=domain
NewDomain=forest
NewDomainDNSName=<%= @domain_name %>
ForestLevel=3
DomainLevel=3
InstallDNS=yes
我不太确定如何传递admin_密码和domain_name参数,因此我在dcpromo_unattend.txt.erb文件中硬编码了这两个参数,经过一些调整后,我能够让烹饪书正常工作

现在,我希望能够将管理员密码和域名值放入数据库,因此我尝试添加:

begin
  dcpromote = Chef::DataBagItem.load(:dcpromote, :main)
rescue
  Chef::Log.fatal("Could not find the 'main' item in the 'dcpromote' data bag - Raising fatal error!!")
  raise
end
并将原始模板部分更改为:

template dcpromo_file do
  source "dcpromo_unattend.txt.erb"
  variables({
    :admin_password => dcpromote['admin_password'],
    :domain_name => dcpromote['domain_name']
  })
end
我创建了一个名为“dcpromote”的数据包,但它似乎不起作用

有人能解释一下原始模板代码是如何工作的吗?例如,它应该从哪里检索管理员密码和域名参数

另外,有谁能告诉我,为了从“dcpromote”数据库中读取管理员密码和域名,我所做的更改有什么问题吗

谢谢, 吉姆

编辑:我想我已经盯着这个看了几个小时了,事实上,我甚至不知道我所做的是如何工作的

我的意思是,我拥有的erb文件具有硬编码的密码和域:

[DCINSTALL]
SafeModeAdminPassword=xxxxxxxxx
RebootOnCompletion=Yes
ReplicaOrNewDomain=domain
NewDomain=forest
NewDomainDNSName=WHATEVER.com
ForestLevel=4
DomainLevel=4
InstallDNS=yes
请注意,该文件中没有对管理员密码或域名的引用

那么,recipe/default.rb的这一部分是如何工作的呢

template dcpromo_file do
  source "dcpromo_unattend.txt.erb"
  variables({
    :admin_password => '',
    :domain_name => ''
  })
end
有人能准确地解释这部分配方代码的作用吗:

  variables({
    :admin_password => '',
    :domain_name => ''
  })
?

谢谢, 吉姆

编辑2:

在@Draco-Ater建议的更改后添加整个default.rb:

#
# Cookbook Name:: dcpromote
# Recipe:: default
#
# Copyright (c) 2015 The Authors, All Rights Reserved.
# 


class ServerHelper 
    extend ::Windows::Helper

  class << self
    def dism
      @@dism ||= locate_sysnative_cmd("dism.exe")
    end

    def powershell
      @@powershell ||= locate_sysnative_cmd('WindowsPowershell\v1.0\powershell.exe')
    end

    def feature_installed?(feature)
      cmd = Mixlib::ShellOut.new("#{dism} /online /Get-Features", {:returns => [0,42,127]}).run_command
      !!(cmd.stderr.empty? && (cmd.stdout =~  /^Feature Name : #{feature}.?$\n^State : Enabled.?$/i))
    end
  end
end

windows_reboot 60 do
  action :nothing
end

#
# Following snippet from: https://supermarket.chef.io/cookbooks/ad
# This snippet checks for presence of a databag named "dcpromote" and for presence
# of an item in the databag named "main".  If that item is not present, then
# this snippet logs a fatal error.
begin
  dcpromote = Chef::DataBagItem.load('dcpromote', 'main')
rescue
  Chef::Log.fatal("Could not find the 'main' item in the 'dcpromote' data bag - Raising fatal error!!")
  raise
end




directory Chef::Config[:file_cache_path]
dcpromo_file = File.join(Chef::Config[:file_cache_path], 'dcpromo_unattend.txt')
#cert_script = File.join(Chef::Config[:file_cache_path], 'setupca.vbs')
# Available from e.g. http://blogs.technet.com/b/pki/archive/2009/09/18/automated-ca-installs-using-vb-script-on-windows-server-2008-and-2008r2.aspx

template dcpromo_file do
  source "dcpromo_unattend.txt.erb"
  variables(
    :admin_password => dcpromote['admin_password'],
    :domain_name => dcpromote['domain_name']
  )

end

powershell_script "run_dcpromo" do
  code "dcpromo /unattend:#{dcpromo_file}"
  #notifies :request, 'windows_reboot[60]'
  not_if { ServerHelper.feature_installed? 'DirectoryServices-DomainController' }
end

windows_feature 'DirectoryServices-DomainController' do
  action :install
  #notifies :request, 'windows_reboot[60]'
end
最后是无人参与的txt文件:

[DCINSTALL]
SafeModeAdminPassword=
RebootOnCompletion=Yes
ReplicaOrNewDomain=domain
NewDomain=forest
NewDomainDNSName=whateverisforever123.com
ForestLevel=4
DomainLevel=4
InstallDNS=yes
为什么无人参与的txt文件在运行期间更改了两次(为什么密码值消失)

谢谢, 吉姆

编辑3:

作为记录,我可以通过向模板文件中添加一个额外的参数来设置netbios名称,从而实现这一点:

[DCINSTALL]
RebootOnCompletion=Yes
ReplicaOrNewDomain=domain
NewDomain=forest
SafeModeAdminPassword=<%= @admin_password %>
NewDomainDNSName=<%= @domain_name %>
ForestLevel=4
DomainLevel=4
InstallDNS=yes
DomainNetbiosName=<%= @domain_netbios_name %>

Jim

让我们从模板文件本身开始

[DCINSTALL]
SafeModeAdminPassword=<%= @admin_password %>
RebootOnCompletion=Yes
ReplicaOrNewDomain=domain
NewDomain=forest
NewDomainDNSName=<%= @domain_name %>
ForestLevel=3
DomainLevel=3
InstallDNS=yes
目前,它们是由空字符串初始化的,但如果您在配方中放入其他内容,它也将在模板中更改。它不会中断,如果您传递一些模板中未使用的变量,它将只是冗余代码

现在,你可以像那样把你的密码和域名放在那里,让它工作(在目标机器上生成正确的配置文件)

现在我们要将这些值移动到数据包中。使用“主”数据包项创建“dcpromote”数据包

knife data bag create dcpromote main
并编辑json文件。最后你应该有这样的东西:

{
  "id": "main", # <= data bag item name
  "admin_password": "my_pass",
  "domain_name": "localhost"
}
并在创建配置文件时使用它:

variables(
  :admin_password => dcpromote['admin_password'],
  :domain_name => dcpromote['domain_name']
)

感谢您的解释和评论-我按照您的建议使用add'l info编辑了我的原始帖子,解释了我进行这些更改后发生的情况。还有几个测试:(a)如果我在default.rb中对powershell_脚本和资源进行了注释,无人参与的txt文件将正常结束,即。,填充了密码参数,并且(b)我尝试更改模板erb文件中参数的顺序,但密码项仍然为空。我认为在无人参与的文件中使用空密码参数是一种误导。看看这个页面:它说“为了保护,在安装AD DS后,密码会从应答文件中删除”,所以这可能就是密码参数为空的原因。所以,底线仍然是为什么dcpromo会得到一个“错误32”?我不知道为什么,但根据这个:,“错误32”是“ExitBadNetbiosDomainName”,“NetBIOS名称无效”。我在这里帮不了你。这已经是另一个问题了——根本不涉及模板或厨师。最好你分开问。
 variables(
    :admin_password => '',
    :domain_name => ''
 )
variables(
    :admin_password => 'my_pass',
    :domain_name => 'localhost'
)
knife data bag create dcpromote main
{
  "id": "main", # <= data bag item name
  "admin_password": "my_pass",
  "domain_name": "localhost"
}
begin
  dcpromote = Chef::DataBagItem.load( 'dcpromote', 'main' )
rescue
  Chef::Log.fatal("Could not find the 'main' item in the 'dcpromote' data bag - Raising fatal error!!")
  raise
end
variables(
  :admin_password => dcpromote['admin_password'],
  :domain_name => dcpromote['domain_name']
)