diff --git a/pkg/ccl/backupccl/BUILD.bazel b/pkg/ccl/backupccl/BUILD.bazel index 2617d31fd96b..40336466d8aa 100644 --- a/pkg/ccl/backupccl/BUILD.bazel +++ b/pkg/ccl/backupccl/BUILD.bazel @@ -187,6 +187,7 @@ go_test( "//pkg/blobs", "//pkg/ccl/kvccl", "//pkg/ccl/multiregionccl", + "//pkg/ccl/multiregionccl/multiregionccltestutils", "//pkg/ccl/multitenantccl", "//pkg/ccl/partitionccl", "//pkg/ccl/storageccl", diff --git a/pkg/ccl/backupccl/backup_tenant_test.go b/pkg/ccl/backupccl/backup_tenant_test.go index 81454c5e8da9..b8126af1eeab 100644 --- a/pkg/ccl/backupccl/backup_tenant_test.go +++ b/pkg/ccl/backupccl/backup_tenant_test.go @@ -10,17 +10,21 @@ package backupccl import ( "context" + "fmt" "testing" "github.com/cockroachdb/cockroach/pkg/base" + "github.com/cockroachdb/cockroach/pkg/ccl/multiregionccl/multiregionccltestutils" _ "github.com/cockroachdb/cockroach/pkg/cloud/impl" // register cloud storage providers "github.com/cockroachdb/cockroach/pkg/jobs" "github.com/cockroachdb/cockroach/pkg/jobs/jobspb" "github.com/cockroachdb/cockroach/pkg/roachpb" + "github.com/cockroachdb/cockroach/pkg/sql" _ "github.com/cockroachdb/cockroach/pkg/sql/importer" "github.com/cockroachdb/cockroach/pkg/testutils" "github.com/cockroachdb/cockroach/pkg/testutils/jobutils" "github.com/cockroachdb/cockroach/pkg/testutils/serverutils" + "github.com/cockroachdb/cockroach/pkg/testutils/skip" "github.com/cockroachdb/cockroach/pkg/testutils/sqlutils" "github.com/cockroachdb/cockroach/pkg/testutils/testcluster" "github.com/cockroachdb/cockroach/pkg/util/leaktest" @@ -109,3 +113,114 @@ func TestBackupTenantImportingTable(t *testing.T) { } require.Equal(t, 1, rowCount) } + +// TestTenantBackupMultiRegionDatabases ensures secondary tenants restoring +// MR databases respect the +// sql.multi_region.allow_abstractions_for_secondary_tenants.enabled cluster +// setting. +func TestTenantBackupMultiRegionDatabases(t *testing.T) { + defer leaktest.AfterTest(t)() + defer log.Scope(t).Close(t) + + skip.UnderStressRace(t, "times out") + + tc, db, cleanup := multiregionccltestutils.TestingCreateMultiRegionCluster( + t, 3 /*numServers*/, base.TestingKnobs{}, + ) + defer cleanup() + sqlDB := sqlutils.MakeSQLRunner(db) + + tenID := roachpb.MakeTenantID(10) + _, tSQL := serverutils.StartTenant(t, tc.Server(0), base.TestTenantArgs{ + TenantID: tenID, + TestingKnobs: base.TestingKnobs{JobsTestingKnobs: jobs.NewTestingKnobsWithShortIntervals()}, + }) + defer tSQL.Close() + tenSQLDB := sqlutils.MakeSQLRunner(tSQL) + + waitForSettingToTakeEffect := func(expValue string) { + testutils.SucceedsSoon(t, func() error { + var val string + tenSQLDB.QueryRow(t, + fmt.Sprintf( + "SHOW CLUSTER SETTING %s", sql.SecondaryTenantsMultiRegionAbstractionsEnabledSettingName, + ), + ).Scan(&val) + + if val != expValue { + return errors.Newf("waiting for cluster setting to be set to %q", expValue) + } + return nil + }) + } + + setTenantReadOnlyClusterSetting := func(val string) { + sqlDB.Exec( + t, + fmt.Sprintf( + "ALTER TENANT $1 SET CLUSTER SETTING %s = '%s'", + sql.SecondaryTenantsMultiRegionAbstractionsEnabledSettingName, + val, + ), + tenID.ToUint64(), + ) + } + + setTenantReadOnlyClusterSetting("true") + waitForSettingToTakeEffect("true") + + // Setup. + const tenDst = "userfile:///ten_backup" + const hostDst = "userfile:///host_backup" + tenSQLDB.Exec(t, `CREATE DATABASE mrdb PRIMARY REGION "us-east1"`) + tenSQLDB.Exec(t, fmt.Sprintf("BACKUP DATABASE mrdb INTO '%s'", tenDst)) + + sqlDB.Exec(t, `CREATE DATABASE mrdb PRIMARY REGION "us-east1"`) + sqlDB.Exec(t, fmt.Sprintf("BACKUP DATABASE mrdb INTO '%s'", hostDst)) + + { + // Flip the tenant-read only cluster setting; ensure database can be restored + // on the system tenant but not on the secondary tenant. + setTenantReadOnlyClusterSetting("false") + waitForSettingToTakeEffect("false") + + tenSQLDB.Exec(t, "DROP DATABASE mrdb CASCADE") + tenSQLDB.ExpectErr( + t, + "setting .* disallows secondary tenant to restore a multi-region database", + fmt.Sprintf("RESTORE DATABASE mrdb FROM LATEST IN '%s'", tenDst), + ) + + // The system tenant should remain unaffected. + sqlDB.Exec(t, "DROP DATABASE mrdb CASCADE") + sqlDB.Exec(t, fmt.Sprintf("RESTORE DATABASE mrdb FROM LATEST IN '%s'", hostDst)) + } + + { + // Flip the tenant-read only cluster setting back to true and ensure the + // restore succeeds. + setTenantReadOnlyClusterSetting("true") + waitForSettingToTakeEffect("true") + + tenSQLDB.Exec(t, fmt.Sprintf("RESTORE DATABASE mrdb FROM LATEST IN '%s'", tenDst)) + } + + { + // Ensure tenant's restoring non multi-region databases are unaffected + // by this setting. We set sql.defaults.primary_region for good measure. + tenSQLDB.Exec( + t, + fmt.Sprintf( + "SET CLUSTER SETTING %s = 'us-east1'", sql.DefaultPrimaryRegionClusterSettingName, + ), + ) + setTenantReadOnlyClusterSetting("false") + waitForSettingToTakeEffect("false") + + tenSQLDB.Exec(t, "CREATE DATABASE nonMrDB") + tenSQLDB.Exec(t, fmt.Sprintf("BACKUP DATABASE nonMrDB INTO '%s'", tenDst)) + + tenSQLDB.Exec(t, "DROP DATABASE nonMrDB CASCADE") + tenSQLDB.Exec(t, fmt.Sprintf("RESTORE DATABASE nonMrDB FROM LATEST IN '%s'", tenDst)) + } +} diff --git a/pkg/ccl/backupccl/restore_planning.go b/pkg/ccl/backupccl/restore_planning.go index 9566b8709753..d297c96bd61e 100644 --- a/pkg/ccl/backupccl/restore_planning.go +++ b/pkg/ccl/backupccl/restore_planning.go @@ -1598,6 +1598,11 @@ func doRestorePlan( } } + err = ensureMultiRegionDatabaseRestoreIsAllowed(p, restoreDBs) + if err != nil { + return err + } + databaseModifiers, newTypeDescs, err := planDatabaseModifiersForRestore(ctx, p, sqlDescs, restoreDBs) if err != nil { return err @@ -1949,6 +1954,33 @@ func renameTargetDatabaseDescriptor( return nil } +// ensureMultiRegionDatabaseRestoreIsAllowed returns an error if restoring a +// multi-region database is not allowed. +func ensureMultiRegionDatabaseRestoreIsAllowed( + p sql.PlanHookState, restoreDBs []catalog.DatabaseDescriptor, +) error { + if p.ExecCfg().Codec.ForSystemTenant() || + sql.SecondaryTenantsMultiRegionAbstractionsEnabled.Get(&p.ExecCfg().Settings.SV) { + // The system tenant is always allowed to restore multi-region databases; + // secondary tenants are only allowed to restore multi-region databases + // if the cluster setting above allows such. + return nil + } + for _, dbDesc := range restoreDBs { + // If a database descriptor being restored is a multi-region database, + // return an error. + if dbDesc.IsMultiRegion() { + return pgerror.Newf( + pgcode.InvalidDatabaseDefinition, + "setting %s disallows secondary tenant to restore a multi-region database", + sql.SecondaryTenantsMultiRegionAbstractionsEnabledSettingName, + ) + } + } + // We're good. + return nil +} + func planDatabaseModifiersForRestore( ctx context.Context, p sql.PlanHookState, @@ -1959,6 +1991,12 @@ func planDatabaseModifiersForRestore( defaultPrimaryRegion := catpb.RegionName( sql.DefaultPrimaryRegion.Get(&p.ExecCfg().Settings.SV), ) + if !p.ExecCfg().Codec.ForSystemTenant() && + !sql.SecondaryTenantsMultiRegionAbstractionsEnabled.Get(&p.ExecCfg().Settings.SV) { + // We don't want to restore "regular" databases as multi-region databases + // for secondary tenants. + return nil, nil, nil + } if defaultPrimaryRegion == "" { return nil, nil, nil } diff --git a/pkg/ccl/logictestccl/testdata/logic_test/multi_region b/pkg/ccl/logictestccl/testdata/logic_test/multi_region index 9ab01b8b00ff..207008fcb5b2 100644 --- a/pkg/ccl/logictestccl/testdata/logic_test/multi_region +++ b/pkg/ccl/logictestccl/testdata/logic_test/multi_region @@ -1,3 +1,4 @@ +# tenant-cluster-setting-override-opt: allow-multi-region-abstractions-for-secondary-tenants # LogicTest: multiregion-9node-3region-3azs multiregion-9node-3region-3azs-tenant query TTTT colnames diff --git a/pkg/ccl/logictestccl/testdata/logic_test/multi_region_default_primary_region b/pkg/ccl/logictestccl/testdata/logic_test/multi_region_default_primary_region index 62630959c557..15b3b80eeae5 100644 --- a/pkg/ccl/logictestccl/testdata/logic_test/multi_region_default_primary_region +++ b/pkg/ccl/logictestccl/testdata/logic_test/multi_region_default_primary_region @@ -1,3 +1,4 @@ +# tenant-cluster-setting-override-opt: allow-multi-region-abstractions-for-secondary-tenants # LogicTest: multiregion-9node-3region-3azs multiregion-9node-3region-3azs-tenant statement ok diff --git a/pkg/ccl/logictestccl/testdata/logic_test/multi_region_drop_region b/pkg/ccl/logictestccl/testdata/logic_test/multi_region_drop_region index 4df0179f7ba6..9742b0f82d2e 100644 --- a/pkg/ccl/logictestccl/testdata/logic_test/multi_region_drop_region +++ b/pkg/ccl/logictestccl/testdata/logic_test/multi_region_drop_region @@ -1,3 +1,4 @@ +# tenant-cluster-setting-override-opt: allow-multi-region-abstractions-for-secondary-tenants # LogicTest: multiregion-9node-3region-3azs multiregion-9node-3region-3azs-tenant query TTTT diff --git a/pkg/ccl/logictestccl/testdata/logic_test/multi_region_privileges b/pkg/ccl/logictestccl/testdata/logic_test/multi_region_privileges index a0469c98e1df..e627d0567831 100644 --- a/pkg/ccl/logictestccl/testdata/logic_test/multi_region_privileges +++ b/pkg/ccl/logictestccl/testdata/logic_test/multi_region_privileges @@ -1,3 +1,4 @@ +# tenant-cluster-setting-override-opt: allow-multi-region-abstractions-for-secondary-tenants # LogicTest: multiregion-9node-3region-3azs multiregion-9node-3region-3azs-tenant user root diff --git a/pkg/ccl/logictestccl/testdata/logic_test/multi_region_secondary_tenants_abstractions_disallowed b/pkg/ccl/logictestccl/testdata/logic_test/multi_region_secondary_tenants_abstractions_disallowed new file mode 100644 index 000000000000..26cd9c8bf802 --- /dev/null +++ b/pkg/ccl/logictestccl/testdata/logic_test/multi_region_secondary_tenants_abstractions_disallowed @@ -0,0 +1,10 @@ +# LogicTest: multiregion-9node-3region-3azs-tenant + +statement error pq: setting sql.multi_region.allow_abstractions_for_secondary_tenants.enabled disallows use of multi-region abstractions +CREATE DATABASE db PRIMARY REGION "us-east1" + +statement ok +CREATE DATABASE db + +statement error pq: setting sql.multi_region.allow_abstractions_for_secondary_tenants.enabled disallows use of multi-region abstractions +ALTER DATABASE db SET PRIMARY REGION "us-east-1" diff --git a/pkg/ccl/logictestccl/testdata/logic_test/multi_region_show b/pkg/ccl/logictestccl/testdata/logic_test/multi_region_show index 7e067c2d52a1..4cd1e775d2bf 100644 --- a/pkg/ccl/logictestccl/testdata/logic_test/multi_region_show +++ b/pkg/ccl/logictestccl/testdata/logic_test/multi_region_show @@ -1,3 +1,4 @@ +# tenant-cluster-setting-override-opt: allow-multi-region-abstractions-for-secondary-tenants # LogicTest: multiregion-9node-3region-3azs multiregion-9node-3region-3azs-tenant statement ok diff --git a/pkg/ccl/logictestccl/testdata/logic_test/multi_region_zone_configs b/pkg/ccl/logictestccl/testdata/logic_test/multi_region_zone_configs index 83a7579d1d26..be7f16f3d1cf 100644 --- a/pkg/ccl/logictestccl/testdata/logic_test/multi_region_zone_configs +++ b/pkg/ccl/logictestccl/testdata/logic_test/multi_region_zone_configs @@ -1,4 +1,4 @@ -# tenant-cluster-setting-override-opt: allow-zone-configs-for-secondary-tenants +# tenant-cluster-setting-override-opt: allow-zone-configs-for-secondary-tenants allow-multi-region-abstractions-for-secondary-tenants # LogicTest: multiregion-9node-3region-3azs multiregion-9node-3region-3azs-tenant query TTTT diff --git a/pkg/ccl/logictestccl/testdata/logic_test/regional_by_row b/pkg/ccl/logictestccl/testdata/logic_test/regional_by_row index 0603c8e462a7..b1676397dbf6 100644 --- a/pkg/ccl/logictestccl/testdata/logic_test/regional_by_row +++ b/pkg/ccl/logictestccl/testdata/logic_test/regional_by_row @@ -1,4 +1,4 @@ -# tenant-cluster-setting-override-opt: allow-zone-configs-for-secondary-tenants +# tenant-cluster-setting-override-opt: allow-zone-configs-for-secondary-tenants allow-multi-region-abstractions-for-secondary-tenants # LogicTest: multiregion-9node-3region-3azs multiregion-9node-3region-3azs-vec-off multiregion-9node-3region-3azs-tenant statement ok diff --git a/pkg/ccl/logictestccl/testdata/logic_test/regional_by_row_auto_rehoming b/pkg/ccl/logictestccl/testdata/logic_test/regional_by_row_auto_rehoming index 1a8e56f40144..9b601400e2a3 100644 --- a/pkg/ccl/logictestccl/testdata/logic_test/regional_by_row_auto_rehoming +++ b/pkg/ccl/logictestccl/testdata/logic_test/regional_by_row_auto_rehoming @@ -1,3 +1,4 @@ +# tenant-cluster-setting-override-opt: allow-multi-region-abstractions-for-secondary-tenants # LogicTest: multiregion-9node-3region-3azs multiregion-9node-3region-3azs-tenant statement ok diff --git a/pkg/ccl/logictestccl/testdata/logic_test/regional_by_row_placement_restricted b/pkg/ccl/logictestccl/testdata/logic_test/regional_by_row_placement_restricted index deaaae9e1233..1c414d4e529e 100644 --- a/pkg/ccl/logictestccl/testdata/logic_test/regional_by_row_placement_restricted +++ b/pkg/ccl/logictestccl/testdata/logic_test/regional_by_row_placement_restricted @@ -1,3 +1,4 @@ +# tenant-cluster-setting-override-opt: allow-multi-region-abstractions-for-secondary-tenants # LogicTest: multiregion-9node-3region-3azs multiregion-9node-3region-3azs-vec-off multiregion-9node-3region-3azs-tenant statement ok diff --git a/pkg/ccl/logictestccl/testdata/logic_test/regional_by_row_rename_column b/pkg/ccl/logictestccl/testdata/logic_test/regional_by_row_rename_column index 862ae7b2d54e..40edf06cf434 100644 --- a/pkg/ccl/logictestccl/testdata/logic_test/regional_by_row_rename_column +++ b/pkg/ccl/logictestccl/testdata/logic_test/regional_by_row_rename_column @@ -1,3 +1,4 @@ +# tenant-cluster-setting-override-opt: allow-multi-region-abstractions-for-secondary-tenants # LogicTest: multiregion-9node-3region-3azs multiregion-9node-3region-3azs-vec-off multiregion-9node-3region-3azs-tenant # This test seems to flake (#60717). diff --git a/pkg/ccl/logictestccl/testdata/logic_test/regional_by_table_placement_restricted b/pkg/ccl/logictestccl/testdata/logic_test/regional_by_table_placement_restricted index 7a01d3d8d634..ba5d2903c8d9 100644 --- a/pkg/ccl/logictestccl/testdata/logic_test/regional_by_table_placement_restricted +++ b/pkg/ccl/logictestccl/testdata/logic_test/regional_by_table_placement_restricted @@ -1,3 +1,4 @@ +# tenant-cluster-setting-override-opt: allow-multi-region-abstractions-for-secondary-tenants # LogicTest: multiregion-9node-3region-3azs multiregion-9node-3region-3azs-vec-off multiregion-9node-3region-3azs-tenant statement ok diff --git a/pkg/sql/descriptor.go b/pkg/sql/descriptor.go index 8cd96227dcda..4537167fb7d0 100644 --- a/pkg/sql/descriptor.go +++ b/pkg/sql/descriptor.go @@ -361,6 +361,25 @@ var DefaultPrimaryRegion = settings.RegisterStringSetting( "", ).WithPublic() +// SecondaryTenantsMultiRegionAbstractionsEnabledSettingName is the name of the +// cluster setting that governs secondary tenant multi-region abstraction usage. +const SecondaryTenantsMultiRegionAbstractionsEnabledSettingName = "sql.multi_region.allow_abstractions_for_secondary_tenants.enabled" + +// SecondaryTenantsMultiRegionAbstractionsEnabled controls if secondary tenants +// are allowed to use multi-region abstractions. In particular, it controls if +// secondary tenants are allowed to add a region to their database. It has no +// effect on the system tenant. +// +// This setting has no effect for existing multi-region databases that have +// already been configured. It only affects regions being added to new +// databases. +var SecondaryTenantsMultiRegionAbstractionsEnabled = settings.RegisterBoolSetting( + settings.TenantReadOnly, + SecondaryTenantsMultiRegionAbstractionsEnabledSettingName, + "allow secondary tenants to use multi-region abstractions", + false, +) + // maybeInitializeMultiRegionMetadata initializes multi-region metadata if a // primary region is supplied and works as a pass-through otherwise. It creates // a new region config from the given parameters and reserves an ID for the @@ -372,6 +391,21 @@ func (p *planner) maybeInitializeMultiRegionMetadata( regions []tree.Name, placement tree.DataPlacement, ) (*multiregion.RegionConfig, error) { + if !p.execCfg.Codec.ForSystemTenant() && + !SecondaryTenantsMultiRegionAbstractionsEnabled.Get(&p.execCfg.Settings.SV) { + // There was no primary region provided, let the thing pass through. + if primaryRegion == "" && len(regions) == 0 { + return nil, nil + } + + return nil, errors.WithHint(pgerror.Newf( + pgcode.InvalidDatabaseDefinition, + "setting %s disallows use of multi-region abstractions", + SecondaryTenantsMultiRegionAbstractionsEnabledSettingName, + ), + "consider omitting the primary region") + } + if primaryRegion == "" && len(regions) == 0 { defaultPrimaryRegion := DefaultPrimaryRegion.Get(&p.execCfg.Settings.SV) if defaultPrimaryRegion == "" { diff --git a/pkg/sql/logictest/logic.go b/pkg/sql/logictest/logic.go index 5dc0949f3ed6..cbbd1af294fe 100644 --- a/pkg/sql/logictest/logic.go +++ b/pkg/sql/logictest/logic.go @@ -171,6 +171,8 @@ import ( // The options are: // - allow-zone-configs-for-secondary-tenants: If specified, secondary tenants // are allowed to alter their zone configurations. +// - allow-multi-region-abstractions-for-secondary-tenants: If specified, +// secondary tenants are allowed to make use of multi-region abstractions. // // // ########################################### @@ -1855,6 +1857,22 @@ func (t *logicTest) newCluster( t.Fatal(err) } } + + if clusterSettingOverrideArgs.overrideMultiTenantMultiRegionAbstractionsAllowed { + conn := t.cluster.ServerConn(0) + // Allow secondary tenants to make use of multi-region abstractions if the + // configuration indicates as such. As this is a tenant read-only cluster + // setting, only the operator is allowed to set it. + if _, err := conn.Exec( + fmt.Sprintf( + "ALTER TENANT $1 SET CLUSTER SETTING %s = true", + sql.SecondaryTenantsMultiRegionAbstractionsEnabledSettingName, + ), + serverutils.TestTenantID().ToUint64(), + ); err != nil { + t.Fatal(err) + } + } } var randomWorkmem int @@ -1963,35 +1981,16 @@ func (t *logicTest) newCluster( } if clusterSettingOverrideArgs.overrideMultiTenantZoneConfigsAllowed { - // Wait until all tenant servers are aware of the setting override. - testutils.SucceedsSoon(t.rootT, func() error { - for i := 0; i < len(t.tenantAddrs); i++ { - pgURL, cleanup := sqlutils.PGUrl(t.rootT, t.tenantAddrs[0], "Tenant", url.User(security.RootUser)) - defer cleanup() - if params.ServerArgs.Insecure { - pgURL.RawQuery = "sslmode=disable" - } - db, err := gosql.Open("postgres", pgURL.String()) - if err != nil { - t.Fatal(err) - } - defer db.Close() - - var val string - err = db.QueryRow( - "SHOW CLUSTER SETTING sql.zone_configs.allow_for_secondary_tenant.enabled", - ).Scan(&val) - if err != nil { - t.Fatal(errors.Wrapf(err, "%d", i)) - } - if val == "false" { - return errors.Errorf("tenant server %d is still waiting zone config cluster setting update", - i, - ) - } - } - return nil - }) + t.waitForTenantReadOnlyClusterSettingToTakeEffectOrFatal( + "sql.zone_configs.allow_for_secondary_tenant.enabled", "true", params.ServerArgs.Insecure, + ) + } + if clusterSettingOverrideArgs.overrideMultiTenantMultiRegionAbstractionsAllowed { + t.waitForTenantReadOnlyClusterSettingToTakeEffectOrFatal( + sql.SecondaryTenantsMultiRegionAbstractionsEnabledSettingName, + "true", + params.ServerArgs.Insecure, + ) } // db may change over the lifetime of this function, with intermediate @@ -1999,6 +1998,43 @@ func (t *logicTest) newCluster( t.clusterCleanupFuncs = append(t.clusterCleanupFuncs, t.setUser(security.RootUser, 0 /* nodeIdxOverride */)) } +// waitForTenantReadOnlyClusterSettingToTakeEffectOrFatal waits until all tenant +// servers are aware about the supplied setting's expected value. Fatal's if +// this doesn't happen within the SucceedsSoonDuration. +func (t *logicTest) waitForTenantReadOnlyClusterSettingToTakeEffectOrFatal( + settingName string, expValue string, insecure bool, +) { + // Wait until all tenant servers are aware of the setting override. + testutils.SucceedsSoon(t.rootT, func() error { + for i := 0; i < len(t.tenantAddrs); i++ { + pgURL, cleanup := sqlutils.PGUrl(t.rootT, t.tenantAddrs[0], "Tenant", url.User(security.RootUser)) + defer cleanup() + if insecure { + pgURL.RawQuery = "sslmode=disable" + } + db, err := gosql.Open("postgres", pgURL.String()) + if err != nil { + t.Fatal(err) + } + defer db.Close() + + var val string + err = db.QueryRow( + fmt.Sprintf("SHOW CLUSTER SETTING %s", settingName), + ).Scan(&val) + if err != nil { + t.Fatal(errors.Wrapf(err, "%d", i)) + } + if val != expValue { + return errors.Errorf("tenant server %d is still waiting zone config cluster setting update", + i, + ) + } + } + return nil + }) +} + // shutdownCluster performs the necessary cleanup to shutdown the current test // cluster. func (t *logicTest) shutdownCluster() { @@ -2211,10 +2247,15 @@ func readTestFileConfigs( } type tenantClusterSettingOverrideArgs struct { - // if set, the sql.zone_configs.allow_for_secondary_tenant.enabled defaults + // If set, the sql.zone_configs.allow_for_secondary_tenant.enabled default // is set to true by the host. This is allows logic tests that run on // secondary tenants to use zone configurations. overrideMultiTenantZoneConfigsAllowed bool + // If set, the + // sql.multi_region.allow_abstractions_for_secondary_tenants.enabled default + // is set to true by the host. This allows logic tests that run on secondary + // tenants to make use of multi-region abstractions. + overrideMultiTenantMultiRegionAbstractionsAllowed bool } // tenantClusterSettingOverrideOpt is implemented by options for configuring @@ -2224,6 +2265,19 @@ type tenantClusterSettingOverrideOpt interface { apply(*tenantClusterSettingOverrideArgs) } +// tenantClusterSettingOverrideMultiTenantMultiRegionAbstractionsAllowed +// corresponds to the allow-multi-region-abstractions-for-secondary-tenants +// directive. +type tenantClusterSettingOverrideMultiTenantMultiRegionAbstractionsAllowed struct{} + +var _ tenantClusterSettingOverrideOpt = &tenantClusterSettingOverrideMultiTenantMultiRegionAbstractionsAllowed{} + +func (t tenantClusterSettingOverrideMultiTenantMultiRegionAbstractionsAllowed) apply( + args *tenantClusterSettingOverrideArgs, +) { + args.overrideMultiTenantMultiRegionAbstractionsAllowed = true +} + // tenantClusterSettingOverrideMultiTenantZoneConfigsAllowed corresponds to // the allow-zone-configs-for-secondary-tenants directive. type tenantClusterSettingOverrideMultiTenantZoneConfigsAllowed struct{} @@ -2352,6 +2406,8 @@ func readTenantClusterSettingOverrideArgs( switch opt { case "allow-zone-configs-for-secondary-tenants": res = append(res, tenantClusterSettingOverrideMultiTenantZoneConfigsAllowed{}) + case "allow-multi-region-abstractions-for-secondary-tenants": + res = append(res, tenantClusterSettingOverrideMultiTenantMultiRegionAbstractionsAllowed{}) default: t.Fatalf("unrecognized cluster option: %s", opt) }