lib/aptible/cli/helpers/database.rb in aptible-cli-0.6.8 vs lib/aptible/cli/helpers/database.rb in aptible-cli-0.6.9
- old
+ new
@@ -42,81 +42,62 @@
say "=== #{environment.handle}"
environment.databases.each { |db| say db.handle }
say ''
end
- def establish_connection(database, local_port)
- ENV['ACCESS_TOKEN'] = fetch_token
- ENV['APTIBLE_DATABASE'] = database.handle
-
- remote_port = claim_remote_port(database)
- ENV['TUNNEL_PORT'] = remote_port
-
- tunnel_args = "-L #{local_port}:localhost:#{remote_port}"
- command = "ssh #{tunnel_args} #{common_ssh_args(database)}"
- Kernel.exec(command)
- end
-
def clone_database(source, dest_handle)
op = source.create_operation(type: 'clone', handle: dest_handle)
poll_for_success(op)
databases_from_handle(dest_handle, source.account).first
end
- def dump_database(database)
- execute_local_tunnel(database) do |url|
- filename = "#{database.handle}.dump"
- say "Dumping to #{filename}"
- `pg_dump #{url} > #{filename}`
+ # Creates a local tunnel and yields the helper
+
+ def with_local_tunnel(database, port = 0)
+ env = {
+ 'ACCESS_TOKEN' => fetch_token,
+ 'APTIBLE_DATABASE' => database.href
+ }
+ command = ['ssh', '-q'] + ssh_args(database)
+ Helpers::Tunnel.new(env, command).tap do |tunnel_helper|
+ tunnel_helper.start(port)
+ yield tunnel_helper
+ tunnel_helper.stop
end
end
- # Creates a local tunnel and yields the url to it
- def execute_local_tunnel(database)
- local_port = random_local_port
- pid = fork { establish_connection(database, local_port) }
+ # Creates a local PG tunnel and yields the url to it
- # TODO: Better test for connection readiness
- sleep 10
+ def with_postgres_tunnel(database)
+ if database.type != 'postgresql'
+ fail Thor::Error, 'This command only works for PostgreSQL'
+ end
- auth = "aptible:#{database.passphrase}"
- host = "localhost:#{local_port}"
- yield "postgresql://#{auth}@#{host}/db"
- ensure
- Process.kill('HUP', pid) if pid
+ with_local_tunnel(database) do |tunnel_helper|
+ auth = "aptible:#{database.passphrase}"
+ host = "localhost:#{tunnel_helper.port}"
+ yield "postgresql://#{auth}@#{host}/db"
+ end
end
- def random_local_port
- # Allocate a dummy server to discover an available port
- dummy = TCPServer.new('127.0.0.1', 0)
- port = dummy.addr[1]
- dummy.close
- port
- end
-
def local_url(database, local_port)
remote_url = database.connection_url
uri = URI.parse(remote_url)
"#{uri.scheme}://#{uri.user}:#{uri.password}@" \
"127.0.0.1:#{local_port}#{uri.path}"
end
- def claim_remote_port(database)
- ENV['ACCESS_TOKEN'] = fetch_token
-
- `ssh #{common_ssh_args(database)} 2>/dev/null`.chomp
- end
-
- def common_ssh_args(database)
+ def ssh_args(database)
host = database.account.bastion_host
port = database.account.bastion_port
- opts = " -o 'SendEnv=*' -o StrictHostKeyChecking=no " \
- '-o UserKnownHostsFile=/dev/null'
- connection_args = "-p #{port} root@#{host}"
- "#{opts} #{connection_args}"
+ ['-o', 'SendEnv=APTIBLE_DATABASE',
+ '-o', 'SendEnv=ACCESS_TOKEN',
+ '-o', 'StrictHostKeyChecking=no',
+ '-o', 'UserKnownHostsFile=/dev/null',
+ '-p', port.to_s, "root@#{host}"]
end
end
end
end
end