How do I establish a ruby Datamapper connection to MariaDB on Amazon RDS with SSL?
Here's what I did:
A non-SSL connection works when testing with:
uri = 'mysql://user:pass#host:port/db_name'
connection = DataObjects::Connection.new(uri)
=> #<DataObjects::Mysql::Connection:0x000056179a3a5921
connection.secure?
=> false
According to the MySQL datamapper wiki, an ssl connection requires the following options: :ssl_ca, :client_key, and :client_cert.
This would result in the following code:
uri = 'mysql://user:pass#host:port/db_name?'
ssl_opts = 'ssl[ssl_ca]=file&ssl[client_key]=file&ssl[client_cert]=file'
connection = DataObjects::Connection.new(uri + ssl_opts)
connection.secure?
=> false
However the only files get is the RDS combind CA bundle, refered from the RDS docs
I do not have a client_cert at all.
Connecting with the mysql client on cli works with SSL:
mysql --ssl -h host -u user -p pass db_name
Welcome to the MariaDB monitor. Commands end with ; or \g.
Your MariaDB connection id is 1638
Server version: 10.1.26-MariaDB MariaDB Server
In doc
https://github.com/datamapper/do/wiki/MySQL
It also says
as tested only ca_cert was required to connect to RDS.
So try adding only ca_cert path and do a test
There's only one parameter required: :ssl => {:ca_cert => 'pem_file'}.
However it looks like using uri string for configuration does not work. The reason is a limitation in Addressable::Uri. It cannot handle query strings which aim to represent hashes with more than 1 level.
The good news is that it works using DataMapper.setup with a config Hash:
DataMapper.setup(:default,
:adapter => 'mysql',
:user => 'user',
:database => 'db_name',
:host => 'host',
:password => 'pass',
:ssl => {
:ca_cert => '/path/to/rds-combined-ca-bundle.pem'
}
)
Related
I'm attempting to use ruby to connect to mongodb. But first I need to connect to the server hosting mongo.
There is a bastion host that is able to be connected to publicly. The database host is only able to be connected to through the bastion.
Here is my code:
require 'net/ssh/gateway'
require 'mongo'
include Mongo
ops_host = '<PUBLIC IP/DNS>'
db_host = '<PRIVATE IP>'
port = '27017'
user = 'ubuntu'
key = File.read("<PATHTOKEY>")
gateway = Net::SSH::Gateway.new( ops_host, user, :key_data => key, :keys_only => TRUE)
gateway.ssh(db_host, user, :key_data => key, :keys_only => TRUE) do |ssh|
puts ssh.exec!("hostname")
client = MongoClient.new(db_host, port)
db = client.db('<DBNAME>')
coll = db.collection('profiles')
puts coll.find().count()
end
I'm able to connect to the database host as the puts ssh.exec!("hostname") command returns the correct hostname, but I cannot get mongo to connect as I keep recieving Failed to connect to a master node errors.
I keep getting Redis::Timeout error in my application (both in UI and in background jobs). I am using AWS ElastiCache service for Redis.
This is how I create a Redis connection. In my config/application.rb , I have:
$redis = Redis.new(host: REDIS_HOST, port: REDIS_PORT, db: REDIS_DB)
How can I avoid getting timeout errors? I am using the default connection settings as follows:
> $redis.client.options[:reconnect_attempts]
=> 1
> $redis.client.options[:timeout]
=> 5.0
> $redis.client.options[:tcp_keepalive]
=> 0
> $redis.client.options[:inherit_socket]
=> false
You should pool your Redis connections with the help of the Connection Pool Gem and increase the timeout value if the problem persists:
ConnectionPool.new(size: 5, timeout: 3) {Redis.new({:host => 'localhost', :port => 6379, :db => 1, :timeout => 240})}
Redis Gem
I wrote a Ruby script that's trying to connect to a Postgres database hosted on Heroku.
If I use a hardcoded password, or if I load the password using gets, everything works fine.
However, if I load the password using IO.noecho, I get the following exception:
storing.rb:11:in `initialize': FATAL: password authentication failed for user "***" (PG::ConnectionBad)
FATAL: no pg_hba.conf entry for host "****", user "***", database "***", SSL off
from storing.rb:11:in `new'
from storing.rb:11:in `create_conn'
from fetch_currencies.rb:11:in `<main>'
Here's my code:
def create_conn(password)
conn = PGconn.connect(
:host => '***',
:port => 5432,
:dbname => '***',
:user => '***',
:password => password)
return conn
end
puts 'Postgres DB password:'
pass = STDIN.noecho(&:gets)
conn = create_conn(pass)
I tried printing the password after loading it, as well as checking whether it's a String, and everything seems to be fine. What could be the problem?
The problem, of course, was that I didn't chomp the input, so I guess the terminating new line character was also passed as part of the password.
The right way to go is then
pass = STDIN.noecho(&:gets).chomp
I am attempting to use redis store as my session store on heroku. It works fine in development but I am unable to get a redis connection on heroku. It is attempting to connect to a 127.0.0.1 instead of the correct redis server.
Error:
ActionView::Template::Error (Error connecting to Redis on 127.0.0.1:6379 (ECONNREFUSED)):
I have set the heroku redis config to the correct server (not really using for the session store but it is set)
REDISTOGO_URL: redis://redistogo:#################################carp.redistogo.com:9274/
session_store.rb
GrnAuth::Application.config.session_store :redis_store, :server => APP_CONFIG['redis_server'], key: '_grn_session'
environment.rb
# Load the rails application
require File.expand_path('../application', __FILE__)
require 'yaml'
APP_CONFIG = YAML.load_file("#{Rails.root}/config/config.yml")[Rails.env]
# Initialize the rails application
GrnAuth::Application.initialize!
config.yml
development:
redis_server: redis://localhost:6379/
test:
redis_server: redis://localhost:6379/
production:
redis_server: redis://redistogo:#################################carp.redistogo.com:9274/
When I console in to heroku I can check APP_CONFIG['redis_server'] and it is set to the redis server.
I have also set up a redis connection just to use that works.
redis.rb
uri = URI.parse(ENV["REDISTOGO_URL"] || "redis://localhost:6379/" )
$redis = Redis.new(:host => uri.host, :port => uri.port, :password => uri.password)
When I console in to heroku I can do and get the following
irb(main):001:0> $redis
=> #<Redis client v3.0.1 for redis://carp.redistogo.com:9274/0>
Any help would be much appreciated. Thank you.
It looks like this:
GrnAuth::Application.config.session_store :redis_store, :server => APP_CONFIG['redis_server'], key: '_grn_session'
Should instead be this:
GrnAuth::Application.config.session_store :redis_store, :servers => APP_CONFIG['redis_server'], key: '_grn_session'
Is there any way to get resque-web to work with a Redis To Go hosted redis instance?
UPDATE:
#Nemo157's suggestion was correct. Ended up creating a test-evn.rb containing:
uri = URI.parse(" redis://XXXX#catfish.redistogo.com:9122")
Resque.redis = Redis.new(:host => uri.host, :port => uri.port, :password => uri.password)
Pass it the config file you're using to setup redis in the app, e.g.
resque-web ./environment.rb
where environment.rb contains something like:
Resque.redis = Redis.new(:host => "path.to.host", :port => 6379)
Note: I haven't tested this since all my redis instances have been on localhost, but that's my understanding of how it works.