【问题标题】:Chef Bash onliner to grep the content of a file in another fileChef Bash onliner grep 另一个文件中的文件内容
【发布时间】:2019-03-07 16:45:13
【问题描述】:

如果该内容尚不存在(以幂等方式),我需要使用 chef 将文件的内容放入另一个文件中。

file1.txt有以下内容:

subject=/DC=corp/DC=NAME/CN=COMPANY Issuing CA
issuer=/CN=COMPANY Root CA
-----BEGIN CERTIFICATE-----
fewfgwgwegarearentnsrtntrstrntnsrtntnstrntrnsrtnstrnsrtnrtnsrtnr
gregargragregrGRGrgregREGREGRGZTDNBFNFGNFGNFGNFGNBDVvhrhrehrehre
gewgreaghareherhherhhaeharehrehreahreahrehearhreahreahaerhrehher
-----END CERTIFICATE-----

subject=/CN=COMPANY Root CA
issuer=/CN=COMPANY Root CA
-----BEGIN CERTIFICATE-----
INjIVNRIVNRVINRvORIniNNknjnejvejnringringrongrognreonganaI6udddd
febwgpubgiurbguiregbeagubpaegigreaignaeingreaingeaingaeinhaddddd
findaofgbugbrluigblzriugbzrugaRIGjRIJgaprjgarigarianbnblkrnbnjna
wfefrgregeGWGWG=
-----END CERTIFICATE-----

第二个文件是/opt/chef/embedded/ssl/certs/cacert.pem,如果不存在的话,我需要将来自file1.txt 的链放入其中。

我正在使用的资源是这样的:

bash 'add company cert chain to chef certs' do
  code <<-EOH
    cat /etc/pki/ca-trust/source/anchors/comp.corp.ca.chain.2018.crt >> /opt/chef/embedded/ssl/certs/cacert.pem
  EOH
not_if 'grep "$(cat /etc/pki/ca-trust/source/anchors/comp.corp.ca.chain.2018.crt)" /opt/chef/embedded/ssl/certs/cacert.pem'
end

由于某种原因,这不起作用。

谁能解释一下我做错了什么?

谢谢。

加比

【问题讨论】:

    标签: bash chef-infra


    【解决方案1】:

    如果你只是想比较两个文件,

    not_if 'cmp /etc/pki/ca-trust/source/anchors/sdl.corp.ca.chain.2018.crt /opt/chef/embedded/ssl/certs/cacert.pem'
    

    为此尝试使用grep 既奇怪又复杂。

    如果您想验证 file1 是否作为 file2 的子文件存在,那么严格执行此操作可能需要一个简单的 Awk 脚本或类似脚本。

    awk 'BEGIN { rc=1 }
        NR == FNR { k[++i] = $0; next }
        k[j+1] == $0 { j++ }
        j > i { rc=0; nextfile }
        k[j] =! $0 { j = 0 }
        END { exit rc }' file1 file2
    

    (临时;未正确测试。)

    【讨论】:

    • 谢谢!但我无法比较它们,因为这两个文件总是不同的。第一个拥有第二个应该得到的东西,如果它还没有的话。你的解释中有什么我想念的吗?
    • 不是真的;从您的解释中不清楚这些文件是否应该相同或需要再次安装文件的条件。
    【解决方案2】:

    在过去,您可以使用Chef::Util::FileEdit,但它是deprecated

    相反,您可以使用其他厨师资源来实现它。 其中一次是使用ruby_block resource,它具有所有的红宝石功能。这意味着您可以使用 ruby​​ 的力量来为您做这件事(不要忘记提供not_ifonly_if 守卫...

    类似:

    ruby_block 'concatenate files' do
      block do
        f1 = File.read('first.file')
        f2 = File.read('second.file')
        content = f1 + f2
        File.open('combined.file', 'w') { |f| f.write content }
      end
      not_if { File.read('combined.file').includes? 'some anchor text' }
    end
    

    另一个想法是离线创建所需的证书链,将其存储在encrypted data bag 中,然后使用您的配方将其放置在节点上。

    【讨论】:

    • 首先,谢谢。但我的问题是 some anchor text 这是某种动态的东西。
    • 我在回答中添加了另一个想法。
    【解决方案3】:

    解决方案实际上要简单得多,它是由我的一位同事提供给我的。 无需比较某些字符串或文件中是否存在变量或类似的东西。 条件很简单,只要

    not_if "knife ssl check <url>".
    

    【讨论】:

      【解决方案4】:

      我会稍微重写一下。

      needle=$(cat /etc/pki/ca-trust/source/anchors/sdl.corp.ca.chain.2018.crt)
      
      if ! grep -Fxq "$needle" /opt/chef/embedded/ssl/certs/cacert.pem
      then
          $(cat /etc/pki/ca-trust/source/anchors/comp.corp.ca.chain.2018.crt >> /opt/chef/embedded/ssl/certs/cacert.pem)
      fi
      

      【讨论】:

      • 仅供参考,这是一个非常复杂的 grep。我建议也许抓住签名的第一行并搜索它。碰撞的可能性很小。
      • cat 周围的命令替换是一个错误,尽管隐约无害。您正在获取cat 的输出并将其作为新命令执行,但由于没有输出——因为您将所有输出重定向到文件——因此没有要执行的命令。你只会得到一个效率低下的子进程,它什么都不做。
      • grep 在换行符分隔的多行字符串上碰巧有效,但没有达到您的预期。这等效于(但效率低于)grep -Fxqf /etc/pki/ca-trust/source/anchors/sdl.corp.ca.chain.2018.crt /opt/chef/embedded/ssl/certs/cacert.pem,即如果文件至少有一行相同,则将匹配。
      • 欣赏它。我认为有一些错误,因为我没有实际测试它并用手卡住它。虽然希望这个概念是正确的。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-05-24
      • 2020-04-09
      • 1970-01-01
      • 2013-02-10
      相关资源
      最近更新 更多