-
Notifications
You must be signed in to change notification settings - Fork 129
Add table for Gateway audit logs #816
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
base: main
Are you sure you want to change the base?
Changes from 9 commits
320a3bd
638c9f0
81d0b74
df79170
7a80f59
ed88983
d5a6f49
49be232
bf1c318
95fd8bf
71f5cfd
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,22 @@ | ||
| /* | ||
| * Licensed under the Apache License, Version 2.0 (the "License"); | ||
| * you may not use this file except in compliance with the License. | ||
| * You may obtain a copy of the License at | ||
| * | ||
| * http://www.apache.org/licenses/LICENSE-2.0 | ||
| * | ||
| * Unless required by applicable law or agreed to in writing, software | ||
| * distributed under the License is distributed on an "AS IS" BASIS, | ||
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
| * See the License for the specific language governing permissions and | ||
| * limitations under the License. | ||
| */ | ||
| package io.trino.gateway.ha; | ||
|
|
||
| public enum AuditAction { | ||
| CREATE, | ||
| UPDATE, | ||
| DELETE, | ||
| ACTIVATE, | ||
| DEACTIVATE | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,19 @@ | ||
| /* | ||
| * Licensed under the Apache License, Version 2.0 (the "License"); | ||
| * you may not use this file except in compliance with the License. | ||
| * You may obtain a copy of the License at | ||
| * | ||
| * http://www.apache.org/licenses/LICENSE-2.0 | ||
| * | ||
| * Unless required by applicable law or agreed to in writing, software | ||
| * distributed under the License is distributed on an "AS IS" BASIS, | ||
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
| * See the License for the specific language governing permissions and | ||
| * limitations under the License. | ||
| */ | ||
| package io.trino.gateway.ha; | ||
|
|
||
| public enum AuditContext { | ||
| TRINO_GW_UI, | ||
| TRINO_GW_API, | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,27 @@ | ||
| /* | ||
| * Licensed under the Apache License, Version 2.0 (the "License"); | ||
| * you may not use this file except in compliance with the License. | ||
| * You may obtain a copy of the License at | ||
| * | ||
| * http://www.apache.org/licenses/LICENSE-2.0 | ||
| * | ||
| * Unless required by applicable law or agreed to in writing, software | ||
| * distributed under the License is distributed on an "AS IS" BASIS, | ||
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
| * See the License for the specific language governing permissions and | ||
| * limitations under the License. | ||
| */ | ||
| package io.trino.gateway.ha; | ||
|
|
||
| import static java.util.Objects.requireNonNullElse; | ||
|
|
||
| public interface AuditLogger | ||
| { | ||
| void logAudit(String user, String ip, String backendName, AuditAction action, AuditContext context, boolean success, String userComment); | ||
|
|
||
| static String sanitizeComment(String comment) | ||
| { | ||
| String c = requireNonNullElse(comment, ""); | ||
| return c.replaceAll("\\s+", " ").trim(); | ||
| } | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,47 @@ | ||
| /* | ||
| * Licensed under the Apache License, Version 2.0 (the "License"); | ||
| * you may not use this file except in compliance with the License. | ||
| * You may obtain a copy of the License at | ||
| * | ||
| * http://www.apache.org/licenses/LICENSE-2.0 | ||
| * | ||
| * Unless required by applicable law or agreed to in writing, software | ||
| * distributed under the License is distributed on an "AS IS" BASIS, | ||
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
| * See the License for the specific language governing permissions and | ||
| * limitations under the License. | ||
| */ | ||
| package io.trino.gateway.ha; | ||
|
|
||
| import io.airlift.log.Logger; | ||
| import io.trino.gateway.ha.persistence.dao.AuditLogDao; | ||
| import org.jdbi.v3.core.Jdbi; | ||
|
|
||
| import java.sql.Timestamp; | ||
| import java.time.Instant; | ||
|
|
||
| import static java.util.Objects.requireNonNull; | ||
|
|
||
| public class DatabaseAuditLogger | ||
| implements AuditLogger | ||
| { | ||
| private static final Logger log = Logger.get(DatabaseAuditLogger.class); | ||
| private final AuditLogDao dao; | ||
|
|
||
| public DatabaseAuditLogger(Jdbi jdbi) | ||
| { | ||
| dao = requireNonNull(jdbi, "jdbi is null").onDemand(AuditLogDao.class); | ||
| } | ||
|
|
||
| @Override | ||
| public void logAudit(String user, String ip, String backendName, AuditAction action, AuditContext context, boolean success, String userComment) | ||
| { | ||
| try { | ||
| dao.log(user, ip, backendName, action.toString(), context.toString(), success ? 1 : 0, | ||
| AuditLogger.sanitizeComment(userComment), Timestamp.from(Instant.now())); | ||
| } | ||
| catch (Exception e) { | ||
| log.error("Failed to write audit log to database: %s", e.getMessage()); | ||
| } | ||
| } | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,30 @@ | ||
| /* | ||
| * Licensed under the Apache License, Version 2.0 (the "License"); | ||
| * you may not use this file except in compliance with the License. | ||
| * You may obtain a copy of the License at | ||
| * | ||
| * http://www.apache.org/licenses/LICENSE-2.0 | ||
| * | ||
| * Unless required by applicable law or agreed to in writing, software | ||
| * distributed under the License is distributed on an "AS IS" BASIS, | ||
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
| * See the License for the specific language governing permissions and | ||
| * limitations under the License. | ||
| */ | ||
| package io.trino.gateway.ha; | ||
|
|
||
| import io.airlift.log.Logger; | ||
|
|
||
| public class LogAuditLogger | ||
| implements AuditLogger | ||
| { | ||
| private static final Logger log = Logger.get(LogAuditLogger.class); | ||
|
|
||
| @Override | ||
| public void logAudit(String user, String ip, String backendName, AuditAction action, AuditContext context, boolean success, String userComment) | ||
| { | ||
| String comment = AuditLogger.sanitizeComment(userComment); | ||
| log.info("GW_AUDIT_LOG: user=%s, ipAddress=%s, backend=%s, action=%s, context=%s, success=%s, userComment=%s", | ||
| user, ip, backendName, action, context, success, comment); | ||
| } | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,35 @@ | ||
| /* | ||
| * Licensed under the Apache License, Version 2.0 (the "License"); | ||
| * you may not use this file except in compliance with the License. | ||
| * You may obtain a copy of the License at | ||
| * | ||
| * http://www.apache.org/licenses/LICENSE-2.0 | ||
| * | ||
| * Unless required by applicable law or agreed to in writing, software | ||
| * distributed under the License is distributed on an "AS IS" BASIS, | ||
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
| * See the License for the specific language governing permissions and | ||
| * limitations under the License. | ||
| */ | ||
| package io.trino.gateway.ha.persistence.dao; | ||
|
|
||
| import org.jdbi.v3.sqlobject.customizer.Bind; | ||
| import org.jdbi.v3.sqlobject.statement.SqlUpdate; | ||
|
|
||
| import java.sql.Timestamp; | ||
|
|
||
| public interface AuditLogDao | ||
| { | ||
| @SqlUpdate(""" | ||
| INSERT INTO gateway_audit_logs (user_name, ip_address, backend_name, operation, context, success, user_comment, change_time) | ||
| VALUES (:user_name, :ip_address, :backend_name, :operation, :context, :success, :user_comment, :change_time) | ||
| """) | ||
| void log(@Bind("user_name") String user_name, | ||
| @Bind("ip_address") String ip_address, | ||
| @Bind("backend_name") String backend_name, | ||
| @Bind("operation") String operation, | ||
| @Bind("context") String context, | ||
| @Bind("success") int success, | ||
| @Bind("user_comment") String user_comment, | ||
| @Bind("change_time") Timestamp change_time); | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -76,3 +76,17 @@ CREATE TABLE IF NOT EXISTS exact_match_source_selectors ( | |
| PRIMARY KEY (environment, source(128), query_type), | ||
| UNIQUE (source(128), environment, query_type(128), resource_group_id) | ||
| ); | ||
|
|
||
| CREATE TABLE IF NOT EXISTS gateway_audit_logs ( | ||
| audit_id BIGINT NOT NULL AUTO_INCREMENT, | ||
| user_name VARCHAR(256) NOT NULL, | ||
| ip_address VARCHAR(45), | ||
| backend_name VARCHAR(256) NOT NULL, | ||
| operation VARCHAR(256) NOT NULL, | ||
| context VARCHAR(256) NOT NULL, | ||
|
||
| success BOOLEAN NOT NULL, | ||
| user_comment VARCHAR(1024), | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. How about text? |
||
| change_time TIMESTAMP NOT NULL, | ||
|
||
|
|
||
| PRIMARY KEY(audit_id) | ||
| ); | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -67,3 +67,16 @@ CREATE TABLE exact_match_source_selectors( | |
| PRIMARY KEY (environment, source, resource_group_id), | ||
| UNIQUE (source, environment, query_type, resource_group_id) | ||
| ); | ||
|
|
||
| CREATE TABLE gateway_audit_logs ( | ||
| audit_id NUMBER GENERATED ALWAYS as IDENTITY(START with 1 INCREMENT by 1), | ||
|
||
| user_name VARCHAR(256) NOT NULL, | ||
| ip_address VARCHAR2(45), | ||
| backend_name VARCHAR(256) NOT NULL, | ||
| operation VARCHAR(256) NOT NULL, | ||
| context VARCHAR(256) NOT NULL, | ||
|
||
| success NUMBER(1) NOT NULL CHECK (success IN (0,1)), | ||
| user_comment VARCHAR(1024), | ||
| change_time TIMESTAMP NOT NULL, | ||
|
||
| PRIMARY KEY(audit_id) | ||
| ); | ||
| Original file line number | Diff line number | Diff line change | ||||
|---|---|---|---|---|---|---|
|
|
@@ -76,3 +76,17 @@ CREATE TABLE IF NOT EXISTS exact_match_source_selectors ( | |||||
| PRIMARY KEY (environment, source, query_type), | ||||||
| UNIQUE (source, environment, query_type, resource_group_id) | ||||||
| ); | ||||||
|
|
||||||
| CREATE TABLE IF NOT EXISTS gateway_audit_logs ( | ||||||
| audit_id BIGSERIAL, | ||||||
|
||||||
| audit_id BIGSERIAL, | |
| audit_id BIGSERIAL PRIMARY KEY, |
not so sure, but can you do this instead of line 91?
Outdated
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
JSONB?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In my opinion, I think having different columns can make management simpler as well as being better for querying
Outdated
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
why not BOOLEAN?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
How about text?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ideally comments will be kept sort and brief which is why the 1024 limit is kept, anything going over should be truncated
Outdated
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
How about TIMESTAMPTZ NOT NULL DEFAULT now()?

There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
256 seems to be too long. isn't this one of AuditActions?
64 seems to be sufficient