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

feature(backend) Tenant ID support #2980

Merged
merged 2 commits into from Jul 24, 2023
Merged

Conversation

xoscar
Copy link
Collaborator

@xoscar xoscar commented Jul 24, 2023

This PR adds support for tenant ID to all resources in the application

Changes

  • Adds tenant id column to all resources
  • Includes middleware adding it to the context
  • Adds tests and validations

Checklist

  • tested locally
  • added new dependencies
  • updated the docs
  • added a test

@xoscar xoscar self-assigned this Jul 24, 2023
@xoscar xoscar added the backend label Jul 24, 2023
@xoscar xoscar marked this pull request as ready for review July 24, 2023 19:54
"github.com/kubeshop/tracetest/server/http/middleware"
)

func Tenant(ctx context.Context, query string, params ...any) (string, []any) {
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

From here we can grab add the tenant query to the operation and grab the tenant id from the context

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we be more specific on this method naming? By calling it a Tenant we don't provide a hint about what is happening inside of this function and what it does.

Can we call it GetQueryWithTenant or something similar?


const HeaderTenantID = "X-Tracetest-TenantID"

func TenantMiddleware(next http.Handler) http.Handler {
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Validates that the tenant id has the proper format, if all is correct, we add it to the context so the rest of the app can use it

@@ -0,0 +1,69 @@
BEGIN;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You should also create an index for those columns:

CREATE INDEX idx_config_tenant_id
ON config(tenant_id);

Otherwise this will be very costly to query after a few weeks of saas being released.

Note: you don't have to delete the index in the down migration. Postgres deletes the index when you drop the column

func TenantID(ctx context.Context) *string {
tenantID := ctx.Value(middleware.TenantIDKey)

if tenantID == "" || tenantID == nil {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You are creating each resource with:

COLUMN tenant_id uuid DEFAULT '00000000-0000-0000-0000-000000000000';

Shouldn't you inject 00000000-0000-0000-0000-00000000000 into the context when user passes no tenant information?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I removed the default value because that might cause problems with backward compatibility, right now I think is better to have it always be NULL. Good catch!

Copy link
Member

@mathnogueira mathnogueira left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

@xoscar xoscar merged commit 6fc605c into main Jul 24, 2023
30 checks passed
@xoscar xoscar deleted the 15-oss-tenant-id-column-support branch July 24, 2023 20:53
Copy link
Contributor

@danielbdias danielbdias left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It seems ok! I liked the idea of using the context to pass the tenant_id instead of changing tons of signatures to add it to the code.

Are you thinking of adding any e2e tests for it? Maybe we can create a tracetesting transaction just for it.

return query, params
}

queryPrefix := getQueryPrefix(query)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There is a tricky thing to think about here if the query has subqueries: (it doesn't affect us now, but maybe we can add a comment here as a warning)

SELECT * FROM (select * from mytable where id = 1)

The resulting queryPrefix will be AND instead of WHERE, making the entire function return an invalid SQL query in the future.

"github.com/kubeshop/tracetest/server/http/middleware"
)

func Tenant(ctx context.Context, query string, params ...any) (string, []any) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we be more specific on this method naming? By calling it a Tenant we don't provide a hint about what is happening inside of this function and what it does.

Can we call it GetQueryWithTenant or something similar?

Comment on lines +287 to +290
if err != nil {
return Environment{}, err
}
defer tx.Rollback()
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

❤️

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

3 participants