Skip to content

Commit

Permalink
WIP extend tunnel while in use, destroy when exiting
Browse files Browse the repository at this point in the history
  • Loading branch information
antoineleclair committed Jun 19, 2024
1 parent e46fe71 commit 2ca15a0
Showing 1 changed file with 42 additions and 30 deletions.
72 changes: 42 additions & 30 deletions src/commands/postgres/tunnel.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import {Command, Flags} from '@oclif/core'
import {getDisco} from '../../config.js'
import {request} from '../../auth-request.js'
import {createTunnel} from 'tunnel-ssh';
import {createTunnel} from 'tunnel-ssh'

export default class PostgresTunnel extends Command {
static description = 'create a temporary tunnel to access Postgres through localhost'
Expand All @@ -17,8 +17,8 @@ export default class PostgresTunnel extends Command {
public async run(): Promise<void> {
const {flags} = await this.parse(PostgresTunnel)
const discoConfig = getDisco(flags.disco || null)
const dbInfoUrl = `https://${discoConfig.host}/api/projects/postgres-addon/cgi/endpoints/tunnels`;

const dbInfoUrl = `https://${discoConfig.host}/api/projects/postgres-addon/cgi/endpoints/tunnels`
const dbInfoResponse = await request({
method: 'POST',
url: dbInfoUrl,
Expand All @@ -29,57 +29,69 @@ export default class PostgresTunnel extends Command {
discoConfig,
expectedStatuses: [200],
})
const dbInfoRespBody = (await dbInfoResponse.json()) as {dbInfo: {instance: string, database: string, user: string, password: string}}
const {dbInfo} = dbInfoRespBody;
const dbInfoRespBody = (await dbInfoResponse.json()) as {
dbInfo: {instance: string; database: string; user: string; password: string}
}
const {dbInfo} = dbInfoRespBody
const url = `https://${discoConfig.host}/api/tunnels`
const reqBody = {
project: `postgres-instance-${dbInfo.instance}`,
service: 'postgres',
};
project: `postgres-instance-${dbInfo.instance}`,
service: 'postgres',
}
const res = await request({
method: 'POST',
url,
body: reqBody,
discoConfig,
expectedStatuses: [201],
})
const respBody = (await res.json()) as {tunnel: {host: string, password: string, port: number}}
const respBody = (await res.json()) as {tunnel: {host: string; password: string; port: number}}
const tunnelPort = respBody.tunnel.port
const connString = `postgresql://${dbInfo.user}:${dbInfo.password}@localhost/${dbInfo.database}`


const sshOptions = {
host: discoConfig.host,
port: respBody.tunnel.port,
username: 'root',
password: respBody.tunnel.password
};
password: respBody.tunnel.password,
}


const forwardOptions = {
dstAddr: respBody.tunnel.host,
dstPort: 5432
dstAddr: respBody.tunnel.host,
dstPort: 5432,
}

const tunnelOptions = {
autoClose: true
autoClose: true,
}

const serverOptions = {
host: 'localhost',
port: 5432
host: 'localhost',
port: 5432,
}

await createTunnel(tunnelOptions, serverOptions, sshOptions, forwardOptions);





// this.log(`host: ${respBody.tunnel.host}`)
// this.log(`password: ${respBody.tunnel.password}`)
// this.log(`port: ${respBody.tunnel.port}`)

this.log("Tunnel created. Connection string:")
const [_, tunnelClient] = await createTunnel(tunnelOptions, serverOptions, sshOptions, forwardOptions)
this.log('Tunnel created. Connection string:')
this.log(connString)
const extendInterval = setInterval(async () => {
await request({
method: 'POST',
url: `https://${discoConfig.host}/api/tunnels/${tunnelPort}`,
discoConfig,
expectedStatuses: [200],
})
}, 60_000)
process.on('SIGINT', () => {
clearInterval(extendInterval)
tunnelClient.destroy()
request({
method: 'DELETE',
url: `https://${discoConfig.host}/api/tunnels/${tunnelPort}`,
discoConfig,
expectedStatuses: [200],
}).then(() => {
process.exit(0) // eslint-disable-line n/no-process-exit
})
})
}
}

0 comments on commit 2ca15a0

Please sign in to comment.