Skip to content

Commit

Permalink
roachpb,sql: limit the syntax of tenant names
Browse files Browse the repository at this point in the history
This commit limits the lexicographical structure of tenant names to be
that of DNS hostnames: start with a letter or digit, followed by a
combination of letters, digits or hyphens. In particular periods and
underscores are not allowed.

There is a minimum length of 1 character and a maximum of 100, like in
CC serverless.

Release note: None
  • Loading branch information
knz committed Dec 13, 2022
1 parent 8d79035 commit d6c3d5d
Show file tree
Hide file tree
Showing 4 changed files with 70 additions and 0 deletions.
15 changes: 15 additions & 0 deletions pkg/roachpb/tenant.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ package roachpb
import (
"context"
"math"
"regexp"
"strconv"

"github.com/cockroachdb/errors"
Expand Down Expand Up @@ -145,5 +146,19 @@ func IsSystemTenantName(tenantName TenantName) bool {
return tenantName == "system"
}

// We limit tenant names to what is allowed in a DNS hostname, so
// that we can use SNI to identify tenants and also as a prefix
// to a database name in connection strings. However there cannot
// be a hyphen at the end.
var tenantNameRe = regexp.MustCompile(`^[a-z0-9]([a-z0-9---]{0,98}[a-z0-9])?$`)

func (n TenantName) IsValid() error {
if !tenantNameRe.MatchString(string(n)) {
return errors.WithHint(errors.Newf("invalid tenant name"),
"Tenant names must start and end with a lowercase letter or digit, contain only lowercase letters, digits or hyphens, with a maximum of 100 characters.")
}
return nil
}

// Silence unused warning.
var _ = TenantFromContext
22 changes: 22 additions & 0 deletions pkg/sql/logictest/testdata/logic_test/tenant
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,22 @@ CREATE TENANT "tenant-one"
statement ok
CREATE TENANT "two"

statement error invalid tenant name
CREATE TENANT "ABC"

statement error invalid tenant name
CREATE TENANT "-a-"

# More than 100 characters.
statement error invalid tenant name
CREATE TENANT "11111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111"

statement error invalid tenant name
CREATE TENANT "invalid_name"

statement error invalid tenant name
CREATE TENANT "invalid.name"

statement ok
CREATE TENANT three

Expand Down Expand Up @@ -165,3 +181,9 @@ id active name crdb_internal.pb_to_json
6 false NULL {"droppedName": "five-requiring-quotes", "id": "6", "name": "", "state": "DROP", "tenantReplicationJobId": "0"}
7 false NULL {"droppedName": "to-be-reclaimed", "id": "7", "name": "", "state": "DROP", "tenantReplicationJobId": "0"}
8 true to-be-reclaimed {"droppedName": "", "id": "8", "name": "to-be-reclaimed", "state": "ACTIVE", "tenantReplicationJobId": "0"}

# More valid tenant names.
statement ok
CREATE TENANT "1";
CREATE TENANT "a-b";
CREATE TENANT "hello-100"
24 changes: 24 additions & 0 deletions pkg/sql/logictest/testdata/logic_test/tenant_builtins
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,15 @@ SELECT crdb_internal.create_tenant(5)
----
5

query error invalid tenant name
SELECT crdb_internal.create_tenant(10, 'ABC')

query error invalid tenant name
SELECT crdb_internal.create_tenant(10, 'invalid_name')

query error invalid tenant name
SELECT crdb_internal.create_tenant(10, 'invalid.name')

query I
SELECT crdb_internal.create_tenant(10, 'tenant-number-ten')
----
Expand Down Expand Up @@ -55,6 +64,21 @@ SELECT crdb_internal.rename_tenant(5, 'my-new-tenant-name')
----
5

query error invalid tenant name
SELECT crdb_internal.rename_tenant(5, 'AAA')

query error invalid tenant name
SELECT crdb_internal.rename_tenant(5, '-a-')

query error invalid tenant name
SELECT crdb_internal.rename_tenant(5, '11111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111')

query error invalid tenant name
SELECT crdb_internal.rename_tenant(5, 'invalid_name')

query error invalid tenant name
SELECT crdb_internal.rename_tenant(5, 'invalid.name')

# Check for duplicate names.
query error name "tenant-number-ten" is already taken
SELECT crdb_internal.rename_tenant(5, 'tenant-number-ten')
Expand Down
9 changes: 9 additions & 0 deletions pkg/sql/tenant.go
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,11 @@ func CreateTenantRecord(
if err := rejectIfSystemTenant(info.ID, op); err != nil {
return roachpb.TenantID{}, err
}
if info.Name != "" {
if err := info.Name.IsValid(); err != nil {
return roachpb.TenantID{}, pgerror.WithCandidateCode(err, pgcode.Syntax)
}
}

tenID := info.ID
if tenID == 0 {
Expand Down Expand Up @@ -789,6 +794,10 @@ func TestingUpdateTenantRecord(
func (p *planner) RenameTenant(
ctx context.Context, tenantID uint64, tenantName roachpb.TenantName,
) error {
if err := tenantName.IsValid(); err != nil {
return pgerror.WithCandidateCode(err, pgcode.Syntax)
}

if err := p.RequireAdminRole(ctx, "rename tenant"); err != nil {
return err
}
Expand Down

0 comments on commit d6c3d5d

Please sign in to comment.