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

时间:2015-06-14 00:29:45

标签: ruby chef chef-recipe

我一直在努力学习厨师并尝试测试一个可以做Windows 2008 R2服务器的dcpromo的小厨师食谱。

我不记得我原来在哪里获得这两个文件,但我能够让它正常工作。

原始的dcpromo_unattend.txt.erb文件是:

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

并且default.rb中包含此部分:

template dcpromo_file do
  source "dcpromo_unattend.txt.erb"
  variables({
    :admin_password => '',
    :domain_name => ''
  })
end

我不太确定如何传递admin_password和domain_name参数,因此我在dcpromo_unattend.txt.erb文件中进行了硬编码,经过一些调整后,能够使菜谱工作。< / p>

现在,我希望能够将admin_password和domain_name值放入数据库中,所以我尝试添加:

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”的数据库,但这似乎没有用。

有人可以解释原始模板代码应该如何工作,即,它假设从哪里检索admin_password和domain_name参数?

此外,任何人都可以告诉我为了从“dcpromote”数据库中读取admin_password和domain_name所做的更改有什么问题吗?

谢谢, 吉姆

编辑:我想我已经盯着这几个小时了,实际上,我甚至不明白我的工作是怎么回事。

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

[DCINSTALL]
SafeModeAdminPassword=xxxxxxxxx
RebootOnCompletion=Yes
ReplicaOrNewDomain=domain
NewDomain=forest
NewDomainDNSName=WHATEVER.com
ForestLevel=4
DomainLevel=4
InstallDNS=yes

请注意,该文件中没有对admin_password或domain_name的引用。

那么,这部分配方/ 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

这本食谱/食谱仍然没有与数据库一起使用。

澄清一下:当我使用硬编码设置admin_password和domain_name的早期代码运行它时,它可以工作。

但是,如果我尝试使用数据库的代码,它就不起作用。当我用数据库运行它时:

1)[这很奇怪]:如果我在运行期间查看“无人值守”的txt文件,它看起来像是已填充,但最后,密码项设置为空,即无人值守文本文件在运行期间发生了变化。

2)最后运行Powershell时,看起来它会出现错误32。

这是控制台输出:

PS C:\Users\Administrator> chef-client -o dcpromote_usedatabag
Starting Chef Client, version 12.3.0
[2015-06-14T07:24:47-07:00] INFO: *** Chef 12.3.0 ***
[2015-06-14T07:24:47-07:00] INFO: Chef-client pid: 260
[2015-06-14T07:25:04-07:00] WARN: Run List override has been provided.
[2015-06-14T07:25:04-07:00] WARN: Original Run List: []
[2015-06-14T07:25:04-07:00] WARN: Overridden Run List: [recipe[dcpromote_usedatabag]]
[2015-06-14T07:25:04-07:00] INFO: Run List is [recipe[dcpromote_usedatabag]]
[2015-06-14T07:25:04-07:00] INFO: Run List expands to [dcpromote_usedatabag]
[2015-06-14T07:25:04-07:00] INFO: Starting Chef Run for node8
[2015-06-14T07:25:04-07:00] INFO: Running start handlers
[2015-06-14T07:25:04-07:00] INFO: Start handlers complete.
[2015-06-14T07:25:04-07:00] INFO: HTTP Request Returned 404 Not Found:
resolving cookbooks for run list: ["dcpromote_usedatabag"]
[2015-06-14T07:25:04-07:00] INFO: Loading cookbooks [dcpromote_usedatabag@0.1.1, windows@1.37.0, che
[2015-06-14T07:25:04-07:00] INFO: Skipping removal of obsoleted cookbooks from the cache
Synchronizing Cookbooks:
[2015-06-14T07:25:04-07:00] INFO: Storing updated cookbooks/dcpromote_usedatabag/recipes/default.rb
[2015-06-14T07:25:04-07:00] INFO: Storing updated cookbooks/dcpromote_usedatabag/templates/default/d
erb in the cache.
[2015-06-14T07:25:04-07:00] INFO: Storing updated cookbooks/dcpromote_usedatabag/Berksfile in the ca
[2015-06-14T07:25:04-07:00] INFO: Storing updated cookbooks/dcpromote_usedatabag/.kitchen.yml in the
  - windows
  - chef_handler
[2015-06-14T07:25:04-07:00] INFO: Storing updated cookbooks/dcpromote_usedatabag/chefignore in the c
[2015-06-14T07:25:04-07:00] INFO: Storing updated cookbooks/dcpromote_usedatabag/metadata.rb in the
[2015-06-14T07:25:04-07:00] INFO: Storing updated cookbooks/dcpromote_usedatabag/README.md in the ca
  - dcpromote_usedatabag
Compiling Cookbooks...
[2015-06-14T07:25:04-07:00] INFO: +++++++++++++++++++++++++++  HI ++++++++++++++++++++++++++++
[2015-06-14T07:25:04-07:00] INFO: +++++++++++++++++++++++++++  HI ++++++++++++++++++++++++++++
[2015-06-14T07:25:04-07:00] INFO: +++++++++++++++++++++++++++  In template +++++++++++++++++++++++++
[2015-06-14T07:25:04-07:00] INFO: +++++++++++++++++++++++++++  In template +++++++++++++++++++++++++
[2015-06-14T07:25:04-07:00] INFO: ++++ xoutput = [123]
Converging 5 resources
Recipe: dcpromote_usedatabag::default
  * windows_reboot[60] action nothing[2015-06-14T07:25:04-07:00] INFO: Processing windows_reboot[60]
romote_usedatabag::default line 28)
 (skipped due to action :nothing)
  * directory[c:/chef/cache] action create[2015-06-14T07:25:04-07:00] INFO: Processing directory[c:/
reate (dcpromote_usedatabag::default line 47)
 (up to date)
  * template[c:/chef/cache/dcpromo_unattend.txt] action create[2015-06-14T07:25:04-07:00] INFO: Proc
hef/cache/dcpromo_unattend.txt] action create (dcpromote_usedatabag::default line 52)
[2015-06-14T07:25:04-07:00] INFO: template[c:/chef/cache/dcpromo_unattend.txt] created file c:/chef/
nd.txt

    - create new file c:/chef/cache/dcpromo_unattend.txt[2015-06-14T07:25:04-07:00] INFO: template[c
_unattend.txt] updated file contents c:/chef/cache/dcpromo_unattend.txt

    - update content in file c:/chef/cache/dcpromo_unattend.txt from none to 798057
    --- c:/chef/cache/dcpromo_unattend.txt      2015-06-14 07:25:04.000000000 -0700
    +++ C:/Users/ADMINI~1/AppData/Local/Temp/chef-rendered-template20150614-260-1cvaiw  2015-06-14 0
700
    @@ -1 +1,10 @@
    +[DCINSTALL]
    +SafeModeAdminPassword=P@ssw0rd$123
    +RebootOnCompletion=Yes
    +ReplicaOrNewDomain=domain
    +NewDomain=forest
    +NewDomainDNSName=whateverisforever123.com
    +ForestLevel=4
    +DomainLevel=4
    +InstallDNS=yes
  * powershell_script[run_dcpromo] action run[2015-06-14T07:25:04-07:00] INFO: Processing powershell
 action run (dcpromote_usedatabag::default line 68)


    ================================================================================
    Error executing action `run` on resource 'powershell_script[run_dcpromo]'
    ================================================================================

    Mixlib::ShellOut::ShellCommandFailed
    ------------------------------------
    Expected process to exit with [0], but received '32'
    ---- Begin output of "powershell.exe" -NoLogo -NonInteractive -NoProfile -ExecutionPolicy Unrest
None -File "C:/Users/ADMINI~1/AppData/Local/Temp/chef-script20150614-260-dfo5yi.ps1" ----
    STDOUT:
    STDERR:
    ---- End output of "powershell.exe" -NoLogo -NonInteractive -NoProfile -ExecutionPolicy Unrestri
ne -File "C:/Users/ADMINI~1/AppData/Local/Temp/chef-script20150614-260-dfo5yi.ps1" ----
    Ran "powershell.exe" -NoLogo -NonInteractive -NoProfile -ExecutionPolicy Unrestricted -InputForm
ers/ADMINI~1/AppData/Local/Temp/chef-script20150614-260-dfo5yi.ps1" returned 32

    Resource Declaration:
    ---------------------
    # In c:/chef/cache/cookbooks/dcpromote_usedatabag/recipes/default.rb

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

    Compiled Resource:
    ------------------
    # Declared in c:/chef/cache/cookbooks/dcpromote_usedatabag/recipes/default.rb:68:in `from_file'

    powershell_script("run_dcpromo") do
      action "run"
      retries 0
      retry_delay 2
      default_guard_interpreter :powershell_script
      command "run_dcpromo"
      backup 5
      returns 0
      code "dcpromo /unattend:c:/chef/cache/dcpromo_unattend.txt"
      interpreter "powershell.exe"
      declared_type :powershell_script
      cookbook_name "dcpromote_usedatabag"
      recipe_name "default"
      not_if { #code block }
    end

[2015-06-14T07:26:22-07:00] INFO: Running queued delayed notifications before re-raising exception

Running handlers:
[2015-06-14T07:26:22-07:00] ERROR: Running exception handlers
Running handlers complete
[2015-06-14T07:26:22-07:00] ERROR: Exception handlers complete
[2015-06-14T07:26:22-07:00] FATAL: Stacktrace dumped to c:/chef/cache/chef-stacktrace.out
Chef Client failed. 1 resources updated in 98.15625 seconds
[2015-06-14T07:26:22-07:00] FATAL: Mixlib::ShellOut::ShellCommandFailed: powershell_script[run_dcpro
tabag::default line 68) had an error: Mixlib::ShellOut::ShellCommandFailed: Expected process to exit
ved '32'
---- Begin output of "powershell.exe" -NoLogo -NonInteractive -NoProfile -ExecutionPolicy Unrestrict
 -File "C:/Users/ADMINI~1/AppData/Local/Temp/chef-script20150614-260-dfo5yi.ps1" ----
STDOUT:
STDERR:
---- End output of "powershell.exe" -NoLogo -NonInteractive -NoProfile -ExecutionPolicy Unrestricted
File "C:/Users/ADMINI~1/AppData/Local/Temp/chef-script20150614-260-dfo5yi.ps1" ----
Ran "powershell.exe" -NoLogo -NonInteractive -NoProfile -ExecutionPolicy Unrestricted -InputFormat N
ADMINI~1/AppData/Local/Temp/chef-script20150614-260-dfo5yi.ps1" returned 32
PS C:\Users\Administrator>

这是最后的无人值守的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 %>

然后修改default.rb以设置该参数:

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

吉姆

1 个答案:

答案 0 :(得分:3)

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

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

<% %>内的代码是ruby代码。在@内以<% %>开头的内容是变量。 =是打印值的简写。因此,模板使用2个变量来设置值,只需将它们打印出来即可。

变量来自哪里?完全来自配方中的代码(此处不需要{}):

 variables(
    :admin_password => '',
    :domain_name => ''
 )

目前它们是由空字符串初始化的,但是如果你在配方中添加了其他内容,它也会在模板中更改。它不会破坏,如果你传递一些模板中没有使用的变量,它将只是冗余代码。

现在你可以将你的密码和域名放在那里并使其正常工作(在目标机器上生成正确的配置文件)

variables(
    :admin_password => 'my_pass',
    :domain_name => 'localhost'
)

现在我们要将值移到数据包中。使用'main'数据包项创建一个'dcpromote'数据库。

knife data bag create dcpromote main

并编辑json文件。最后你应该有类似的东西:

{
  "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']
)