Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feat: allows the MySQL module to connect through an SSH connection #183

Draft
wants to merge 5 commits into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 5 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -31,10 +31,10 @@ Exemple scenario:
npm install @fabernovel/heart-lighthouse @fabernovel/heart-slack @fabernovel/heart-mysql
```

2. Set the credentials for Slack (API key) and MySQL (database URL)
2. Set the credentials for Slack (Access token) and MySQL (database URL)

```bash
echo HEART_SLACK_API_TOKEN=xoxb-rest-of-token >> .env
echo HEART_SLACK_ACCESS_TOKEN=xoxb-rest-of-token >> .env
echo HEART_MYSQL_DATABASE_URL=login:[email protected]:3306 >> .env
```

Expand Down Expand Up @@ -64,7 +64,7 @@ With the example scenario given previously, the Docker image is used as follow:

```shell
docker run --rm\
--env HEART_SLACK_API_TOKEN=xoxb-rest-of-token\
--env HEART_SLACK_ACCESS_TOKEN=xoxb-rest-of-token\
--env HEART_MYSQL_DATABASE_URL=login:[email protected]:3306\
fabernovel/heart:latest\
lighthouse --config '{"url":"https://heart.fabernovel.com"}' --only-listeners=mysql,slack
Expand All @@ -81,8 +81,8 @@ With the example scenario given previously, the GitHub Action is used as follow:
with:
analysis_service: lighthouse
listener_services_only: mysql,slack
mysql_database_url: login:[email protected]:3306
slack_api_token: ${{ secrets.SLACK_API_TOKEN }}
mysql_database_url: ${{ secrets.HEART_MYSQL_DATABASE_URL }}
slack_access_token: ${{ secrets.HEART_SLACK_ACCESS_TOKEN }}
```

# Design
Expand Down
61 changes: 61 additions & 0 deletions common/config/rush/pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 4 additions & 2 deletions modules/mysql/.env.schema.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,13 @@
"type": "object",
"required": ["HEART_MYSQL_DATABASE_URL"],
"properties": {
"HEART_MYSQL_DATABASE_URL": { "type": "string", "format": "uri" }
"HEART_MYSQL_DATABASE_URL": { "type": "string", "format": "uri" },
"HEART_MYSQL_SERVER_URL": { "type": "string", "format": "uri" }
},
"errorMessage": {
"properties": {
"HEART_MYSQL_DATABASE_URL": "HEART_MYSQL_DATABASE_URL is required and must be a URL"
"HEART_MYSQL_DATABASE_URL": "HEART_MYSQL_DATABASE_URL is required and must be a URL",
"HEART_MYSQL_SERVER_URL": "HEART_MYSQL_SERVER_URL must be a URL"
}
}
}
4 changes: 3 additions & 1 deletion modules/mysql/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -36,13 +36,15 @@
"@fabernovel/heart-common": "workspace:^4.0.0-alpha.9",
"@mikro-orm/core": "^5.7.14",
"@mikro-orm/migrations": "^5.7.14",
"@mikro-orm/mysql": "^5.7.14"
"@mikro-orm/mysql": "^5.7.14",
"ssh2": "^1.14.0"
},
"devDependencies": {
"@jest/globals": "^29.6.2",
"@mikro-orm/cli": "^5.7.14",
"@types/jest": "^29.5.3",
"@types/node": "^18.16.19",
"@types/ssh2": "^1.11.13",
"@typescript-eslint/eslint-plugin": "^6.2.1",
"@typescript-eslint/parser": "^6.2.1",
"eslint": "^8.46.0",
Expand Down
2 changes: 1 addition & 1 deletion modules/mysql/src/MySQLModule.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import {
type ModuleMetadata,
logger,
} from "@fabernovel/heart-common"
import { MySQLClient } from "./client/Client.js"
import { MySQLClient } from "./client/MySQLClient.js"

export class MySQLModule extends Module implements ModuleListenerDatabaseInterface {
#client: MySQLClient
Expand Down
48 changes: 48 additions & 0 deletions modules/mysql/src/client/SshClient.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
import { env } from "node:process"
import { Client } from "ssh2"
import databaseConfig from "../config/mikro-orm.config.js"

export class SshClient {
#client = new Client()
#databaseUrl = new URL(databaseConfig.clientUrl ?? "")
#serverUrl = new URL(env.HEART_MYSQL_DATABASE_URL ? `ssh://${env.HEART_MYSQL_DATABASE_URL}` : "")

constructor() {
this.#client
.on("ready", () => {
console.log("Client :: ready")
this.#client.forwardIn(this.#databaseUrl.host, Number(this.#databaseUrl.port), (err) => {
if (err) throw err
console.log("Listening for this.#clientections on server on port 8000!")
})
})
.on("tcp connection", (info, accept) => {
console.log("TCP :: INCOMING CONNECTION:")
console.dir(info)
accept()
.on("close", () => {
console.log("TCP :: CLOSED")
})
.on("data", (data) => {
console.log("TCP :: DATA: " + data)
})
.end(
[
"HTTP/1.1 404 Not Found",
"Date: Thu, 15 Nov 2012 02:07:58 GMT",
"Server: ForwardedConnection",
"Content-Length: 0",
"Connection: close",
"",
"",
].join("\r\n")
)
})
.connect({
host: this.#serverUrl.host,
port: Number(this.#serverUrl.port),
username: this.#serverUrl.username,
password: this.#serverUrl.password,
})
}
}