http_request put 请求的预期语法是什么?

What is the expected syntax for http_request put request?

我在我的食谱中使用这个 http_request 块:

http_request 'some request' do
  url 'https://'"#{node[:chef][:node_name]}"'/v1/xyz'
  headers ({
     'AUTHORIZATION' => "Basic #{Base64.encode64('#{node[\'user\']}:#{node[\'password\']')}",
    })
  action :get
end

但是当我尝试执行它时出现此错误:

[2017-05-12T21:39:04-04:00] ERROR: http_request[some request] (mi_activemq::default line 58) had an error: OpenSSL::SSL::SSLError: SSL Error connecting to https://... - SSL_connect returned=1 errno=0 state=error: certificate verify failed

如果我硬编码 username:password 这会按预期工作:

'AUTHORIZATION' => "Basic #{Base64.encode64('username:password')}",

你那里有各种转义字符,但错误与证书或 URL 中的名称错误有关。

只要把user/pass放在URL,

url "https://#{node['user']}:#{node['password']@#{node['fqdn']}/v1/xyz"

其中 node['fqdn'] 是证书中的名称。

您需要了解如何将值插入字符串。从这个哈希定义开始:

node = {
  chef: {
    node_name: 'foo'
  }
}

而这个字符串定义:

'https://'"#{node[:chef][:node_name]}"'/v1/xyz'
# => "https://foo/v1/xyz"

Ruby 会将相邻的字符串连接成一个字符串:

'foo'"bar"'baz' # => "foobarbaz"

但是代码很难读,所以除非你有充分的理由,否则不要那样做。而是简单地写它:

'foobarbaz' # => "foobarbaz"

或:

"foobarbaz" # => "foobarbaz"

请记住,您的代码越混乱,您或其他人就越难在六个月内弄清楚它的含义。

所以,不要使用上面的字符串,而是使用:

"https://#{node[:chef][:node_name]}/v1/xyz"
# => "https://foo/v1/xyz"

您的代码还有其他问题:

require 'base64'
"Basic #{Base64.encode64('#{node[\'user\']}:#{node[\'password\']')}"
# > "Basic I3tub2RlWyd1c2VyJ119OiN7bm9kZVsncGFzc3dvcmQnXQ==\n"

这就是问题的症结所在:

'#{node[\'user\']}:#{node[\'password\']'
# => "\#{node['user']}:\#{node['password']"

当代码运行时,传递给 Base64.encode64 的值就是那个字符串。你的变量没有被插入,所以你总是会得到:

# > "Basic I3tub2RlWyd1c2VyJ119OiN7bm9kZVsncGFzc3dvcmQnXQ==\n"

对于结果字符串。它没有对您的用户名或密码进行编码。

第二个潜在问题是您的 node 哈希可能没有 'user''password' 键,但我们无法判断,因为您没有提供足够的信息。

调用 encode64 的更清晰的方法是:

encoded_user_password = Base64.encode64(
  node.values_at('user', 'password').join(':')
)

然后将其插入到字符串中:

"Basic #{encoded_user_password}"

我还建议您熟悉 Ruby 的 URI class,因为这是构建和操作 URI 的首选方式。