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

时间:2017-05-13 01:16:19

标签: ruby chef devops

我在食谱中使用了这个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')}",

2 个答案:

答案 0 :(得分:1)

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

只需将用户/传递放入网址

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

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

答案 1 :(得分:1)

您需要学习如何将值插入字符串。从这个Hash定义开始:

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类,因为它是构建和操作URI的首选方法。