Linux 如何在puppet中的exec命令资源中传递多个值?

Linux 如何在puppet中的exec命令资源中传递多个值?,linux,puppet,Linux,Puppet,我想使用puppet在默认密钥库中部署证书 我有两个文件root.crt和intermediateca.crt由puppet管理。我将来会有很多别名和证书文件 别名可以是rootca、intermediateca。此别名和文件路径应传递给exec命令 alias=rootca, intermediateca filecert= "/var/lib/certs/rootca", "/var/lib/certs/intermediateca.crt" 现在,我正在运行一个exec命令,它将别名和c

我想使用puppet在默认密钥库中部署证书

我有两个文件root.crt和intermediateca.crt由puppet管理。我将来会有很多别名和证书文件

别名可以是rootca、intermediateca。此别名和文件路径应传递给exec命令

alias=rootca, intermediateca
filecert= "/var/lib/certs/rootca", "/var/lib/certs/intermediateca.crt"
现在,我正在运行一个exec命令,它将别名和crt文件作为exec命令资源中的参数

    '/var/lib/certs':
      ensure => directory;

    '/var/lib/certs/root.crt':
      source => "puppet:///modules/${module_name}/sonarqube/${::env}/var/lib/certs/root.crt",
      mode   => '0644',
      notify => Exec['markitrootca'];

    '/var/lib/certs/intermediateca.crt':
      source => "puppet:///modules/${module_name}/sonarqube/${::env}/var/lib/certs/intermediateca.crt",
      mode   => '0644',
      notify => Exec['markitintermediateca'];

  }
  exec {
    'markitrootca':
      path => "/usr/bin",
      command => "keytool -importcert -keystore ${keystore} -alias markitrootca -file /var/lib/certs/root.crt  -storepass ${storepass} -noprompt  2>/dev/null",
      provider => shell,
      refreshonly => true;

    'markitintermediateca':
      path => "/usr/bin",
      command => "keytool -importcert -keystore ${keystore} -alias markitintermediateca  -file /var/lib/certs/intermediateca.crt/ -storepass ${storepass} -noprompt 2>/dev/null",
      provider => shell,
      refreshonly => true;
  }

上述解决方案工作正常,但我只想为多个别名和文件路径编写一个exec。我怎样才能做到这一点呢?

听起来你在问的是,如何迭代一个散列,并让迭代中的每个资源通知一个
exec
资源。鉴于此,您可以在散列上使用lambda迭代器。如果不是这样,请用术语和细节澄清问题。首先,使用密钥构造哈希:

$certs = { 'rootca'         => '/var/lib/certs/rootca',
           'intermediateca' => '/var/lib/certs/intermediateca.crt' }
然后,您可以使用
each
方法迭代散列

$certs.each |String $cert, String $loc| {
  # code here
}
填充lambda的主体对于您的情况如下所示:

$certs.each |String $cert, String $loc| {
  file { $loc:
    source => "puppet:///modules/${module_name}/sonarqube/${::env}${loc}",
    mode   => '0644',
    notify => Exec['install_cert'];
  }
}
请注意,在您的问题中,您似乎在使用每个资源的默认属性,但由于缺少身体的其余部分,因此不清楚,因此我将其转换为常规资源

    '/var/lib/certs':
      ensure => directory;

    '/var/lib/certs/root.crt':
      source => "puppet:///modules/${module_name}/sonarqube/${::env}/var/lib/certs/root.crt",
      mode   => '0644',
      notify => Exec['markitrootca'];

    '/var/lib/certs/intermediateca.crt':
      source => "puppet:///modules/${module_name}/sonarqube/${::env}/var/lib/certs/intermediateca.crt",
      mode   => '0644',
      notify => Exec['markitintermediateca'];

  }
  exec {
    'markitrootca':
      path => "/usr/bin",
      command => "keytool -importcert -keystore ${keystore} -alias markitrootca -file /var/lib/certs/root.crt  -storepass ${storepass} -noprompt  2>/dev/null",
      provider => shell,
      refreshonly => true;

    'markitintermediateca':
      path => "/usr/bin",
      command => "keytool -importcert -keystore ${keystore} -alias markitintermediateca  -file /var/lib/certs/intermediateca.crt/ -storepass ${storepass} -noprompt 2>/dev/null",
      provider => shell,
      refreshonly => true;
  }
整个代码体如下所示:

$certs = { 'rootca'         => '/var/lib/certs/rootca',
           'intermediateca' => '/var/lib/certs/intermediateca.crt' }

$certs.each |String $cert, String $loc| {
  file { $loc:
    source => "puppet:///modules/${module_name}/sonarqube/${::env}${loc}",
    mode   => '0644',
    notify => Exec['install_cert'];
  }
}

exec { 'install_cert':
  path        => "/usr/bin",
  command     => "keytool -importcert -keystore ${keystore} -alias $alias -storepass ${storepass} -noprompt -trustcacerts",
  provider    => linux,
  subscribe   => File['/var/lib/certs/'],
  refreshonly => true;
}
由于您在问题中没有提到什么是
keystore
storepass
,因此我不得不假设您在其他地方定义了它们。另外,您正在订阅
文件['/var/lib/certs/']
,我还必须假设该文件在其他地方

您还可以在此处进行其他改进,包括:

  • 未在
    exec
    中指定提供程序
  • 不使用
    exec
    中的
    路径
    ,因为它是字符串而不是搜索路径数组,而是提供
    keytool
    的完整路径
  • 不订阅
    文件['/var/lib/certs/']
    ,因为
    exec
    不关心该目录,而
    notify
    提供了必要的功能
  • 不指定证书的路径,因为它们始终位于同一位置,因此可以使用单个数组而不是哈希
  • env
    看起来像是一个事实,而不是一个全局变量,因此应该这样指定它
  • 您的
    文件
    资源没有深度
    ,而只是将它们存储在
    env
    目录中

可以找到有关lambda迭代器的有用文档。

您在这里询问的是如何迭代散列并让迭代中的每个资源通知一个
exec
资源。鉴于此,您可以在散列上使用lambda迭代器。如果不是这样,请用术语和细节澄清问题。首先,使用密钥构造哈希:

$certs = { 'rootca'         => '/var/lib/certs/rootca',
           'intermediateca' => '/var/lib/certs/intermediateca.crt' }
然后,您可以使用
each
方法迭代散列

$certs.each |String $cert, String $loc| {
  # code here
}
填充lambda的主体对于您的情况如下所示:

$certs.each |String $cert, String $loc| {
  file { $loc:
    source => "puppet:///modules/${module_name}/sonarqube/${::env}${loc}",
    mode   => '0644',
    notify => Exec['install_cert'];
  }
}
请注意,在您的问题中,您似乎在使用每个资源的默认属性,但由于缺少身体的其余部分,因此不清楚,因此我将其转换为常规资源

    '/var/lib/certs':
      ensure => directory;

    '/var/lib/certs/root.crt':
      source => "puppet:///modules/${module_name}/sonarqube/${::env}/var/lib/certs/root.crt",
      mode   => '0644',
      notify => Exec['markitrootca'];

    '/var/lib/certs/intermediateca.crt':
      source => "puppet:///modules/${module_name}/sonarqube/${::env}/var/lib/certs/intermediateca.crt",
      mode   => '0644',
      notify => Exec['markitintermediateca'];

  }
  exec {
    'markitrootca':
      path => "/usr/bin",
      command => "keytool -importcert -keystore ${keystore} -alias markitrootca -file /var/lib/certs/root.crt  -storepass ${storepass} -noprompt  2>/dev/null",
      provider => shell,
      refreshonly => true;

    'markitintermediateca':
      path => "/usr/bin",
      command => "keytool -importcert -keystore ${keystore} -alias markitintermediateca  -file /var/lib/certs/intermediateca.crt/ -storepass ${storepass} -noprompt 2>/dev/null",
      provider => shell,
      refreshonly => true;
  }
整个代码体如下所示:

$certs = { 'rootca'         => '/var/lib/certs/rootca',
           'intermediateca' => '/var/lib/certs/intermediateca.crt' }

$certs.each |String $cert, String $loc| {
  file { $loc:
    source => "puppet:///modules/${module_name}/sonarqube/${::env}${loc}",
    mode   => '0644',
    notify => Exec['install_cert'];
  }
}

exec { 'install_cert':
  path        => "/usr/bin",
  command     => "keytool -importcert -keystore ${keystore} -alias $alias -storepass ${storepass} -noprompt -trustcacerts",
  provider    => linux,
  subscribe   => File['/var/lib/certs/'],
  refreshonly => true;
}
由于您在问题中没有提到什么是
keystore
storepass
,因此我不得不假设您在其他地方定义了它们。另外,您正在订阅
文件['/var/lib/certs/']
,我还必须假设该文件在其他地方

您还可以在此处进行其他改进,包括:

  • 未在
    exec
    中指定提供程序
  • 不使用
    exec
    中的
    路径
    ,因为它是字符串而不是搜索路径数组,而是提供
    keytool
    的完整路径
  • 不订阅
    文件['/var/lib/certs/']
    ,因为
    exec
    不关心该目录,而
    notify
    提供了必要的功能
  • 不指定证书的路径,因为它们始终位于同一位置,因此可以使用单个数组而不是哈希
  • env
    看起来像是一个事实,而不是一个全局变量,因此应该这样指定它
  • 您的
    文件
    资源没有深度
    ,而只是将它们存储在
    env
    目录中

可以找到有关lambda迭代器的有用文档。

有一种更好的方法可以做到这一点。您可以使用对象/任务数组简单地定义一个
hiera
yaml文件,或者直接将其写入

而不是像


  # Run Start Script* 
  exec { 'run  script':
    command     => "somecmdhere",
    provider    => shell,
    cwd         => 'dir',
    refreshonly => false,
    logoutput   => true
  }

  exec { 'run installation script':
    command     => "${target_dir}/${start_service_script}",
    provider    => shell,
    cwd         => $target_dir,
    refreshonly => false,
    logoutput   => $cmdlogoutput
  }

您可以使用具有参数类型和对象的create resource来创建

创建资源('package',)

在这种情况下,我们将使用

#goes and looks for yaml file with variable exec scripts. This can be done by also defining it in puppet. 

$listofExecCommands = hiera_hash('execScripts::allscripts)





create_resources('exec', $listofExecCommands)


然后,无论您在何处定义YAML文件,都可以在不更改代码的情况下重复使用它。 您可以将其用于RPMS NPM包,这太棒了!请确保您的yaml是正确的*

#RPM packages to be installed
execScripts::allscripts:
   'script1':
     command: 'installed'
     provider: 'yum'
     cwd: 'somedir'
   'script2':
     command: 'installed'
     provider: 'yum'
     cwd: 'somedir'


有一种更好的方法可以做到这一点。您可以使用对象/任务数组简单地定义一个
hiera
yaml文件,或者直接将其写入

而不是像


  # Run Start Script* 
  exec { 'run  script':
    command     => "somecmdhere",
    provider    => shell,
    cwd         => 'dir',
    refreshonly => false,
    logoutput   => true
  }

  exec { 'run installation script':
    command     => "${target_dir}/${start_service_script}",
    provider    => shell,
    cwd         => $target_dir,
    refreshonly => false,
    logoutput   => $cmdlogoutput
  }

您可以使用具有参数类型和对象的create resource来创建

创建资源('package',)

在这种情况下,我们将使用

#goes and looks for yaml file with variable exec scripts. This can be done by also defining it in puppet. 

$listofExecCommands = hiera_hash('execScripts::allscripts)





create_resources('exec', $listofExecCommands)


然后,无论您在何处定义YAML文件,都可以在不更改代码的情况下重复使用它。 您可以将其用于RPMS NPM包,这太棒了!请确保您的yaml是正确的*

#RPM packages to be installed
execScripts::allscripts:
   'script1':
     command: 'installed'
     provider: 'yum'
     cwd: 'somedir'
   'script2':
     command: 'installed'
     provider: 'yum'
     cwd: 'somedir'