diff --git a/HISTORY.md b/HISTORY.md index ed88889e..ef4609f6 100644 --- a/HISTORY.md +++ b/HISTORY.md @@ -1,5 +1,8 @@ # HISTORY +## v0.11.0 (June 10, 2019) + - NATS v2.0 support! (#162) + ## v0.8.4 (Feb 23, 2018) - Support to include connection `name` as part of CONNECT options (#145) - Fixed support for Ruby 2.5 due to missing OpenSSL `require` (#144) diff --git a/README.md b/README.md index 72e2d835..cd0a767a 100644 --- a/README.md +++ b/README.md @@ -3,16 +3,7 @@ A [Ruby](http://ruby-lang.org) client for the [NATS messaging system](https://nats.io). [![License Apache 2.0](https://img.shields.io/badge/License-Apache2-blue.svg)](https://www.apache.org/licenses/LICENSE-2.0) -[![Build Status](https://travis-ci.org/nats-io/ruby-nats.svg)](http://travis-ci.org/nats-io/ruby-nats) [![Gem Version](https://d25lcipzij17d.cloudfront.net/badge.svg?id=rb&type=5&v=0.10.0)](https://rubygems.org/gems/nats/versions/0.10.0) [![Yard Docs](http://img.shields.io/badge/yard-docs-blue.svg)](https://www.rubydoc.info/gems/nats) - -## Supported Platforms - -This gem and the client are known to work on the following Ruby platforms: - -- MRI 2.3.0, 2.4.0, 2.5.0 -- JRuby 9.1.2.0, 9.1.15.0, 9.2.0.0 - -If you're looking for a non-EventMachine alternative, check out the [nats-pure](https://github.com/nats-io/pure-ruby-nats) gem. +[![Build Status](https://travis-ci.org/nats-io/nats.rb.svg)](http://travis-ci.org/nats-io/nats.rb) [![Gem Version](https://d25lcipzij17d.cloudfront.net/badge.svg?id=rb&type=5&v=0.11.0)](https://rubygems.org/gems/nats/versions/0.11.0) [![Yard Docs](http://img.shields.io/badge/yard-docs-blue.svg)](https://www.rubydoc.info/gems/nats) ## Getting Started @@ -23,6 +14,16 @@ nats-sub foo & nats-pub foo 'Hello World!' ``` +Starting from [v0.11.0](https://github.com/nats-io/nats.py/releases/tag/v0.11.0) release, +you can also optionally install [NKEYS](https://github.com/nats-io/nkeys.rb) in order to use +the new NATS v2.0 auth features: + +```bash +gem install nkeys +``` + +If you're looking for a non-EventMachine alternative, check out the [nats-pure](https://github.com/nats-io/nats-pure.rb) gem. + ## Basic Usage ```ruby @@ -285,6 +286,47 @@ NATS.start { } ``` +### New Authentication (Nkeys and User Credentials) + +This requires server with version >= 2.0.0 + +NATS servers have a new security and authentication mechanism to authenticate with user credentials and NKEYS. A single file containing the JWT and NKEYS to authenticate against a NATS v2 server can be set with the `user_credentials` option: + +```ruby +require 'nats/client' + +NATS.start("tls://connect.ngs.global", user_credentials: "/path/to/creds") do |nc| + nc.subscribe("hello") do |msg| + puts "[Received] #{msg}" + end + nc.publish('hello', 'world') +end +``` + +This will create two callback handlers to present the user JWT and sign the nonce challenge from the server. The core client library never has direct access to your private key and simply performs the callback for signing the server challenge. The library will load and wipe and clear the objects it uses for each connect or reconnect. + +Bare NKEYS are also supported. The nkey seed should be in a read only file, e.g. `seed.txt`. + +```bash +> cat seed.txt +# This is my seed nkey! +SUAGMJH5XLGZKQQWAWKRZJIGMOU4HPFUYLXJMXOO5NLFEO2OOQJ5LPRDPM +``` + +Then in the client specify the path to the seed using the `nkeys_seed` option: + +```ruby +require 'nats/client' + +NATS.start("tls://connect.ngs.global", nkeys_seed: "path/to/seed.txt") do |nc| + nc.subscribe("hello") do |msg| + puts "[Received] #{msg}" + end + nc.publish('hello', 'world') +end + +``` + ## License Unless otherwise noted, the NATS source files are distributed under diff --git a/bin/nats-pub b/bin/nats-pub index 5279a0eb..40efa993 100755 --- a/bin/nats-pub +++ b/bin/nats-pub @@ -18,12 +18,13 @@ require 'rubygems' require 'nats/client' def usage - puts "Usage: nats-pub [-s server]"; exit + puts "Usage: nats-pub [-s server] [--creds CREDS]"; exit end args = ARGV.dup opts_parser = OptionParser.new do |opts| opts.on('-s SERVER') { |server| $nats_server = server } + opts.on('--creds CREDS') { |creds| $creds = creds } end args = opts_parser.parse!(args) @@ -33,7 +34,7 @@ msg ||= 'Hello World' NATS.on_error { |err| puts "Server Error: #{err}"; exit! } -NATS.start(:uri => $nats_server) do +NATS.start($nats_server, user_credentials: $creds) do NATS.publish(subject, msg) { NATS.stop } end diff --git a/bin/nats-queue b/bin/nats-queue index d1a58dd6..e481d76f 100755 --- a/bin/nats-queue +++ b/bin/nats-queue @@ -28,6 +28,7 @@ opts_parser = OptionParser.new do |opts| opts.on('-s SERVER') { |server| $nats_server = server } opts.on('-t','--time') { $show_time = true } opts.on('-r','--raw') { $show_raw = true } + opts.on('--creds CREDS') { |creds| $creds = creds } end args = opts_parser.parse!(args) @@ -54,7 +55,7 @@ end NATS.on_error { |err| puts "Server Error: #{err}"; exit! } -NATS.start(:uri => $nats_server) do +NATS.start($nats_server, user_credentials: $creds) do puts "Listening on [#{subject}], queue group [#{queue_group}]" unless $show_raw NATS.subscribe(subject, :queue => queue_group) { |msg, _, sub| puts decorate(sub, msg) diff --git a/bin/nats-request b/bin/nats-request index de62c986..befd44cc 100755 --- a/bin/nats-request +++ b/bin/nats-request @@ -29,6 +29,7 @@ opts_parser = OptionParser.new do |opts| opts.on('-t','--time') { $show_time = true } opts.on('-r','--raw') { $show_raw = true } opts.on('-n RESPONSES') { |responses| $responses = Integer(responses) if Integer(responses) > 0 } + opts.on('--creds CREDS') { |creds| $creds = creds } end args = opts_parser.parse!(args) @@ -55,7 +56,7 @@ end NATS.on_error { |err| puts "Server Error: #{err}"; exit! } -NATS.start(:uri => $nats_server) do +NATS.start($nats_server, user_credentials: $creds) do NATS.request(subject, msg) { |(msg, reply)| puts decorate(msg) exit! if $responses && ($responses-=1) < 1 diff --git a/bin/nats-sub b/bin/nats-sub index 867e7680..482218e5 100755 --- a/bin/nats-sub +++ b/bin/nats-sub @@ -20,7 +20,7 @@ require 'nats/client' ['TERM', 'INT'].each { |s| trap(s) { puts; exit! } } def usage - puts "Usage: nats-sub [-s server] [-t] [-r]"; exit + puts "Usage: nats-sub [-s server] [--creds CREDS] [-t] [-r]"; exit end args = ARGV.dup @@ -28,6 +28,7 @@ opts_parser = OptionParser.new do |opts| opts.on('-s SERVER') { |server| $nats_server = server } opts.on('-t','--time') { $show_time = true } opts.on('-r','--raw') { $show_raw = true } + opts.on('--creds CREDS') { |creds| $creds = creds } end args = opts_parser.parse!(args) @@ -53,7 +54,7 @@ end NATS.on_error { |err| puts "Server Error: #{err}"; exit! } -NATS.start(:uri => $nats_server) do +NATS.start($nats_server, user_credentials: $creds) do puts "Listening on [#{subject}]" unless $show_raw NATS.subscribe(subject) { |msg, _, sub| puts decorate(sub, msg) } end