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 的首选方式。
我在我的食谱中使用这个 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 的首选方式。