Add knife config by template

Since the chef-client provisioner is cleaning the node and client at the chef-server from the provisioned node
it needs to have a flexible configuration

This is replacing the used knife flags: -s '<chef-server-url>' -k '/tmp/packer-chef-client/client.pem' -u '<client-name>'
and puts their values into a generated knife.rb

Additionally the knife.rb may include the optional ssl_verify_mode attribute to enable the verify mode verify_none

Background:

When deleting node and client to a self-hosted chef-server using self signed cerfiticates the usage of

    knife node delete <node-name> -y -s '<chef-server-url>' -k '/tmp/packer-chef-client/client.pem' -u '<client-name>'

will lead into a ssl verification failure.

The error output of the knife call is somthing like:

    2015/06/24 12:29:17 ui:     docker: WARNING: No knife configuration file found
    docker: WARNING: No knife configuration file found
    2015/06/24 12:29:17 ui:     docker: ERROR: SSL Validation failure connecting to host: 172.16.117.63 - SSL_connect returned=1 errno=0 state=SSLv3 read server certificate B:
    certificate verify failed
    docker: ERROR: SSL Validation failure connecting to host: 172.16.117.63 - SSL_connect returned=1 errno=0 state=SSLv3 read server certificate B: certificate verify failed
    2015/06/24 12:29:17 ui:     docker: ERROR: Could not establish a secure connection to the server.
    docker: ERROR: Could not establish a secure connection to the server.
    2015/06/24 12:29:17 ui:     docker: Use 'knife ssl check' to troubleshoot your SSL configuration.
    docker: Use 'knife ssl check' to troubleshoot your SSL configuration.
    2015/06/24 12:29:17 ui:     docker: If your Chef Server uses a self-signed certificate, you can use
    docker: If your Chef Server uses a self-signed certificate, you can use
    2015/06/24 12:29:17 ui:     docker: 'knife ssl fetch' to make knife trust the server's certificates.
    docker: 'knife ssl fetch' to make knife trust the server's certificates.
    2015/06/24 12:29:17 ui:     docker:
    docker:
    2015/06/24 12:29:17 ui:     docker: Original Exception: OpenSSL::SSL::SSLError: SSL_connect returned=1 errno=0 state=SSLv3 read server certificate B: certificate verify failed
    docker: Original Exception: OpenSSL::SSL::SSLError: SSL_connect returned=1 errno=0 state=SSLv3 read server certificate B: certificate verify failed
    2015/06/24 12:29:17 packer-builder-docker: 2015/06/24 12:29:17 Executed command exit status: 100
This commit is contained in:
Schreiter, Wulf-Thilo 2015-06-24 13:46:59 +02:00
parent 8f0e28fae1
commit 18438cf291
1 changed files with 51 additions and 10 deletions

View File

@ -187,14 +187,20 @@ func (p *Provisioner) Provision(ui packer.Ui, comm packer.Communicator) error {
}
err = p.executeChef(ui, comm, configPath, jsonPath)
knifeConfigPath, err2 := p.createKnifeConfig(
ui, comm, nodeName, serverUrl, p.config.ClientKey, p.config.SslVerifyMode)
if err2 != nil {
return fmt.Errorf("Error creating knife config on node: %s", err2)
}
if !p.config.SkipCleanNode {
if err2 := p.cleanNode(ui, comm, nodeName); err2 != nil {
if err2 := p.cleanNode(ui, comm, nodeName, knifeConfigPath); err2 != nil {
return fmt.Errorf("Error cleaning up chef node: %s", err2)
}
}
if !p.config.SkipCleanClient {
if err2 := p.cleanClient(ui, comm, nodeName); err2 != nil {
if err2 := p.cleanClient(ui, comm, nodeName, knifeConfigPath); err2 != nil {
return fmt.Errorf("Error cleaning up chef client: %s", err2)
}
}
@ -273,6 +279,32 @@ func (p *Provisioner) createConfig(ui packer.Ui, comm packer.Communicator, nodeN
return remotePath, nil
}
func (p *Provisioner) createKnifeConfig(ui packer.Ui, comm packer.Communicator, nodeName string, serverUrl string, clientKey string, sslVerifyMode string) (string, error) {
ui.Message("Creating configuration file 'knife.rb'")
// Read the template
tpl := DefaultKnifeTemplate
ctx := p.config.ctx
ctx.Data = &ConfigTemplate{
NodeName: nodeName,
ServerUrl: serverUrl,
ClientKey: clientKey,
SslVerifyMode: sslVerifyMode,
}
configString, err := interpolate.Render(tpl, &ctx)
if err != nil {
return "", err
}
remotePath := filepath.ToSlash(filepath.Join(p.config.StagingDir, "knife.rb"))
if err := comm.Upload(remotePath, bytes.NewReader([]byte(configString)), nil); err != nil {
return "", err
}
return remotePath, nil
}
func (p *Provisioner) createJson(ui packer.Ui, comm packer.Communicator) (string, error) {
ui.Message("Creating JSON attribute file")
@ -334,32 +366,30 @@ func (p *Provisioner) createDir(ui packer.Ui, comm packer.Communicator, dir stri
return nil
}
func (p *Provisioner) cleanNode(ui packer.Ui, comm packer.Communicator, node string) error {
func (p *Provisioner) cleanNode(ui packer.Ui, comm packer.Communicator, node string, knifeConfigPath string) error {
ui.Say("Cleaning up chef node...")
args := []string{"node", "delete", node}
if err := p.knifeExec(ui, comm, node, args); err != nil {
if err := p.knifeExec(ui, comm, node, knifeConfigPath, args); err != nil {
return fmt.Errorf("Failed to cleanup node: %s", err)
}
return nil
}
func (p *Provisioner) cleanClient(ui packer.Ui, comm packer.Communicator, node string) error {
func (p *Provisioner) cleanClient(ui packer.Ui, comm packer.Communicator, node string, knifeConfigPath string) error {
ui.Say("Cleaning up chef client...")
args := []string{"client", "delete", node}
if err := p.knifeExec(ui, comm, node, args); err != nil {
if err := p.knifeExec(ui, comm, node, knifeConfigPath, args); err != nil {
return fmt.Errorf("Failed to cleanup client: %s", err)
}
return nil
}
func (p *Provisioner) knifeExec(ui packer.Ui, comm packer.Communicator, node string, args []string) error {
func (p *Provisioner) knifeExec(ui packer.Ui, comm packer.Communicator, node string, knifeConfigPath string, args []string) error {
flags := []string{
"-y",
"-s", fmt.Sprintf("'%s'", p.config.ServerUrl),
"-k", fmt.Sprintf("'%s'", p.config.ClientKey),
"-u", fmt.Sprintf("'%s'", node),
"-c", knifeConfigPath,
}
cmdText := fmt.Sprintf(
@ -573,3 +603,14 @@ environment "{{.ChefEnvironment}}"
ssl_verify_mode :{{.SslVerifyMode}}
{{end}}
`
var DefaultKnifeTemplate = `
log_level :info
log_location STDOUT
chef_server_url "{{.ServerUrl}}"
client_key "{{.ClientKey}}"
node_name "{{.NodeName}}"
{{if ne .SslVerifyMode ""}}
ssl_verify_mode :{{.SslVerifyMode}}
{{end}}
`