From e1c6d4bb636fd10fe2a4f551d2cd5be197fa5a6b Mon Sep 17 00:00:00 2001 From: Larry Zhao Date: Fri, 4 Jan 2019 09:39:40 +0800 Subject: [PATCH 1/2] add support to custom certificates --- lib/etcdv3.rb | 3 ++- lib/etcdv3/connection.rb | 14 ++++++++++---- lib/etcdv3/connection_wrapper.rb | 5 +++-- spec/etcdv3/connection_wrapper_spec.rb | 4 ++-- 4 files changed, 17 insertions(+), 9 deletions(-) diff --git a/lib/etcdv3.rb b/lib/etcdv3.rb index 4b0a11d..4dc8e9a 100644 --- a/lib/etcdv3.rb +++ b/lib/etcdv3.rb @@ -24,7 +24,8 @@ class Etcdv3 def initialize(options = {}) @options = options @timeout = options[:command_timeout] || DEFAULT_TIMEOUT - @conn = ConnectionWrapper.new(@timeout, *sanitized_endpoints) + @custom_certificates = options[:custom_certificates] + @conn = ConnectionWrapper.new(endpoints: sanitized_endpoints, timeout: @timeout, custom_certificates: @custom_certificates) warn "WARNING: `url` is deprecated. Please use `endpoints` instead." if @options.key?(:url) authenticate(@options[:user], @options[:password]) if @options.key?(:user) end diff --git a/lib/etcdv3/connection.rb b/lib/etcdv3/connection.rb index 634d20d..5ae4657 100644 --- a/lib/etcdv3/connection.rb +++ b/lib/etcdv3/connection.rb @@ -12,10 +12,10 @@ class Connection attr_reader :endpoint, :hostname, :handlers, :credentials - def initialize(url, timeout, metadata={}) + def initialize(url, timeout, metadata={}, custom_certificates=nil) @endpoint = URI(url) @hostname = "#{@endpoint.hostname}:#{@endpoint.port}" - @credentials = resolve_credentials + @credentials = resolve_credentials(custom_certificates) @timeout = timeout @handlers = handler_map(metadata) end @@ -38,13 +38,19 @@ def handler_map(metadata={}) ] end - def resolve_credentials + def resolve_credentials(custom_certificates) case @endpoint.scheme when 'http' :this_channel_is_insecure when 'https' # Use default certs for now. - GRPC::Core::ChannelCredentials.new + return GRPC::Core::ChannelCredentials.new if custom_certificates.nil? + + GRPC::Core::ChannelCredentials.new( + File.read(custom_certificates[:root_ca]), + File.read(custom_certificates[:key]), + File.read(custom_certificates[:cert]) + ) else raise "Unknown scheme: #{@endpoint.scheme}" end diff --git a/lib/etcdv3/connection_wrapper.rb b/lib/etcdv3/connection_wrapper.rb index 7fad7d4..cf31650 100644 --- a/lib/etcdv3/connection_wrapper.rb +++ b/lib/etcdv3/connection_wrapper.rb @@ -3,10 +3,11 @@ class ConnectionWrapper attr_accessor :connection, :endpoints, :user, :password, :token, :timeout - def initialize(timeout, *endpoints) + def initialize(endpoints:, timeout:, custom_certificates: nil) @user, @password, @token = nil, nil, nil @timeout = timeout - @endpoints = endpoints.map{|endpoint| Etcdv3::Connection.new(endpoint, @timeout) } + @custom_certificates = custom_certificates + @endpoints = endpoints.map{|endpoint| Etcdv3::Connection.new(endpoint, @timeout, {}, @custom_certificates) } @connection = @endpoints.first end diff --git a/spec/etcdv3/connection_wrapper_spec.rb b/spec/etcdv3/connection_wrapper_spec.rb index f9b969e..649c526 100644 --- a/spec/etcdv3/connection_wrapper_spec.rb +++ b/spec/etcdv3/connection_wrapper_spec.rb @@ -5,7 +5,7 @@ let(:endpoints) { ['http://localhost:2379', 'http://localhost:2389'] } describe '#initialize' do - subject { Etcdv3::ConnectionWrapper.new(10, *endpoints) } + subject { Etcdv3::ConnectionWrapper.new(endpoints: endpoints, timeout: 10) } it { is_expected.to have_attributes(user: nil, password: nil, token: nil) } it 'sets hostnames in correct order' do expect(subject.endpoints.map(&:hostname)).to eq(['localhost:2379', 'localhost:2389']) @@ -16,7 +16,7 @@ end describe "#rotate_connection_endpoint" do - subject { Etcdv3::ConnectionWrapper.new(10, *endpoints) } + subject { Etcdv3::ConnectionWrapper.new(endpoints: endpoints, timeout: 10) } before do subject.rotate_connection_endpoint end From b3e28b4353e204b31ceef831491ec169d34f2e87 Mon Sep 17 00:00:00 2001 From: Larry Zhao Date: Fri, 4 Jan 2019 09:44:34 +0800 Subject: [PATCH 2/2] update README to include instructions on how to instantiate with custom certificates --- README.md | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index b723dad..fa8caa6 100644 --- a/README.md +++ b/README.md @@ -27,8 +27,11 @@ conn = Etcdv3.new(endpoints: 'https://hostname:port') conn = Etcdv3.new(endpoints: 'https://hostname:port', user: 'root', password: 'mysecretpassword') # Secure connection specifying custom certificates -# Coming soon... - +conn = Etcdv3.new(endpoints: 'https://hostname:port', custom_certificates: { + root_ca: 'path-to-root-ca.pem', + key: 'path-to-private-key.pem', + cert: 'path-to-cert.pem' +}) ``` **High Availability**