Skip to content

Commit deee5db

Browse files
committed
Add Postgres support and set as default database
1 parent 66dc2ea commit deee5db

File tree

7 files changed

+348
-25
lines changed

7 files changed

+348
-25
lines changed

README.md

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
1-
# Proxy Authorization Service for Prefect UI and Prefect CLI
1+
# Proxy Authorization Service for Prefect UI and Prefect CLI
2+
23
![Docker Cloud Automated build](https://img.shields.io/docker/cloud/automated/softrams/prefect-auth-proxy)
34

45
[Prefect](https://prefect.io) is a great platform for building data flows/pipelines. It supports hybrid execution with execution engines running on-premises with
@@ -14,11 +15,11 @@ Prefect UI and CLI to enable authentication/authorization for API. All the reque
1415

1516
## Setup
1617

17-
This initial implementation uses API Key and MySQL database backend to authenticate and authorize requests.
18+
This initial implementation uses API Key and MySQL/Postgres database backend to authenticate and authorize requests.
1819

1920
### Setup Database
2021

21-
This service looks for prefect_api_keys table in MYSQL Database. Please refer to data/db_init.sql for the initial schema and sample data.
22+
This service looks for prefect_api_keys table in MYSQL/Postgres Database. Please refer to data/`<database>`/db_init.sql for the initial schema and sample data.
2223

2324
```sql
2425
-- create table prefect_api_keys
@@ -58,16 +59,18 @@ The following Environment Variables are available to configure the Proxy service
5859
| `PORT` | `3000` | Port |
5960
| `LOG_LEVEL_OVERRIDE_DURATION` | `300` | Log level override duration (seconds) |
6061
| `ENV` | `NA` | Environment Name |
61-
| `DB_HOST` | `NULL` | MySQL Database Server Host |
62-
| `DB_USER` | `NULL` | MySQL Database Server User |
63-
| `DB_PASSWORD` | `NULL` | MySQL Database Server Password |
64-
| `DB_DATABASE` | `NULL` | MySQL Database Name |
62+
| `DB_TYPE` | `postgres` | Database Type [postgres/mysql] |
63+
| `DB_HOST` | `NULL` | Database Server Host |
64+
| `DB_USER` | `NULL` | Database Server User |
65+
| `DB_PASSWORD` | `NULL` | Database Server Password |
66+
| `DB_DATABASE` | `NULL` | Database Name |
6567

6668
### Docker Image
6769

6870
#### Use pre-built docker image
6971

7072
Use docker image from Docker hub
73+
7174
```bash
7275
# Run using pre-built docker image from docker hub
7376
# Prepare environment variables in .env file

data/README.md

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
# Running Database in a local container
2+
3+
## Postgres
4+
5+
```bash
6+
docker pull postgres
7+
8+
docker run --name proxydb \
9+
--mount type=bind,source=$(pwd)/data/postgres,target=/docker-entrypoint-initdb.d \
10+
-p 5432:5432 \
11+
-e POSTGRES_PASSWORD=`<PASSWORD>` \
12+
-d postgres
13+
14+
```
15+
16+
## MySQL
17+
18+
```bash
19+
docker pull mysql
20+
21+
docker run --name proxydb \
22+
--mount type=bind,source=$(pwd)/data/postgres,target=/docker-entrypoint-initdb.d \
23+
-p 3306:3306 \
24+
-e MYSQL_ROOT_PASSWORD=`<PASSWORD>` \
25+
-d mysql
26+
27+
```
File renamed without changes.

data/postgres/db_init.sql

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
CREATE TABLE prefect_api_keys (
2+
user_id varchar(128) NOT NULL,
3+
scopes varchar(2000) NOT NULL,
4+
api_key varchar(128) NOT NULL,
5+
key_issu_dt timestamp NOT NULL,
6+
key_expr_dt timestamp NOT NULL,
7+
creatd_dt timestamp NOT NULL,
8+
last_updatd_dt timestamp NOT NULL,
9+
creatd_by varchar(11) NOT NULL,
10+
last_updatd_by varchar(11) NOT NULL,
11+
PRIMARY KEY (user_id)
12+
);
13+
14+
insert into prefect_api_keys (user_id, scopes, api_key, key_issu_dt, key_expr_dt, creatd_dt, last_updatd_dt, creatd_by, last_updatd_by)
15+
values('USERID', 'mutation/*, query/*', 'TestKey001', '2021-12-27 00:00:00', '2022-12-31 00:00:00', '2021-12-30 00:00:00', '2021-12-30 00:00:00', 'ADMINUSERID', 'ADMINUSERID')

index.js

Lines changed: 52 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,10 @@
11
const express = require("express");
22
const bodyParser = require("body-parser");
33
const { createProxyMiddleware } = require("http-proxy-middleware");
4+
45
const mysql = require("mysql");
6+
const { Pool, Client } = require("pg");
7+
58
const { parse } = require("graphql");
69

710
// Create Express Server
@@ -101,13 +104,23 @@ let dbConn;
101104
async function initDBConnection() {
102105
return new Promise(async (resolve, reject) => {
103106
try {
104-
dbConn = mysql.createPool({
105-
connectionLimit: 5,
106-
host: process.env.DB_HOST,
107-
user: process.env.DB_USER,
108-
password: process.env.DB_PASSWORD,
109-
database: process.env.DB_DATABASE,
110-
});
107+
if (process.env.DB_TYPE === "mysql") {
108+
dbConn = mysql.createPool({
109+
connectionLimit: 5,
110+
host: process.env.DB_HOST,
111+
user: process.env.DB_USER,
112+
password: process.env.DB_PASSWORD,
113+
database: process.env.DB_DATABASE,
114+
});
115+
} else {
116+
dbConn = new Pool({
117+
user: process.env.DB_USER,
118+
host: process.env.DB_HOST,
119+
database: process.env.DB_DATABASE,
120+
password: process.env.DB_PASSWORD,
121+
port: 5432,
122+
});
123+
}
111124
resolve(true);
112125
} catch (err) {
113126
console.log("Failure in creating DB connection pool:", err);
@@ -124,7 +137,37 @@ async function dbQuery(query, params) {
124137
reject(error);
125138
} else {
126139
// console.log('dbQuery Results:', results);
127-
resolve(results);
140+
resolve(results.rows ? results.rows : results);
141+
}
142+
});
143+
} catch (err) {
144+
console.log("Failure in query: ", err);
145+
reject(err);
146+
}
147+
});
148+
}
149+
150+
async function fetchAPIKeysInfo(key) {
151+
return new Promise(async (resolve, reject) => {
152+
try {
153+
let query = "";
154+
let params;
155+
if (process.env.DB_TYPE === "mysql") {
156+
params = [key];
157+
query =
158+
"select * from prefect_api_keys where api_key=? and CURDATE() < key_expr_dt";
159+
} else {
160+
params = [key];
161+
query =
162+
"select * from prefect_api_keys where api_key=$1 and CURRENT_TIMESTAMP < key_expr_dt";
163+
}
164+
165+
dbConn.query(query, params, (error, results) => {
166+
if (error) {
167+
reject(error);
168+
} else {
169+
// console.log('dbQuery Results:', results);
170+
resolve(results.rows ? results.rows : results);
128171
}
129172
});
130173
} catch (err) {
@@ -201,10 +244,7 @@ app.use(async (req, res, next) => {
201244
let acl = tokenCache.get(apiKey);
202245
if (!acl) {
203246
// Fetch ACL from database and store in cache
204-
const aclDB = await dbQuery(
205-
"select * from prefect_api_keys where api_key=? and CURDATE() < key_expr_dt",
206-
[apiKey]
207-
);
247+
const aclDB = await fetchAPIKeysInfo(apiKey);
208248
if (aclDB && aclDB.length > 0) {
209249
acl = aclDB[0];
210250
acl.ops = acl.scopes.split(",").map((el) => el.trim());

0 commit comments

Comments
 (0)