Skip to content

Commit 3c9f2ee

Browse files
craig[bot]msbutlerajstorm
committed
153628: backup: remove bulkio.backup.deprecated_full_backup_with_subdir.enabled setting r=jeffswenson a=msbutler This patch removes the bulkio.backup.deprecated_full_backup_with_subdir.enabled cluster setting, since when set to true, the backups will now fail. Informs #139159 Release note (ops change): this patch removes the bulkio.backup.deprecated_full_backup_with_subdir.enabled cluster setting, since backups will now fail if it is set to true. 153668: external connection: fix sql injection vuln in ALTER EXTERNAL CONNECTION r=jeffswenson a=msbutler Previously, the sql command which ran directly on system.external_connections passed the external connection name via string parsing, which makes the query vulnerable to sql injection. This patch fixes this vulnerability by passing the name as a parameter. Epic: none Release note: none 153755: roachprod: fix NewPromClient creating IAP token source when disabled r=golgeek a=ajstorm ## Summary Fixes a bug introduced in the IAP authentication refactor (ba62711) where `NewPromClient()` would always attempt to create an IAP token source, even when Prometheus integration was disabled. ## Problem After the recent IAP authentication refactor, users running `roachprod start` outside of Google Cloud environments would encounter this error: ``` failed to create IAP token source: failed to get default credentials: glcoud not on path ``` This happens even when `ROACHPROD_PROM_HOST_URL=""` is set to disable Prometheus integration. ## Root Cause The condition in `NewPromClient()` only checked `if c.httpClient == nil` but didn't verify whether the client was disabled. When `ROACHPROD_PROM_HOST_URL=""` is set, `promRegistrationUrl` becomes `""` which correctly sets `disabled: true`, but the IAP token source creation was still being attempted. ## Solution Modified the condition to also check `!c.disabled`, ensuring that when Prometheus integration is disabled, no IAP authentication is attempted. 🤖 Generated with [Claude Code](https://claude.ai/code) Co-authored-by: Michael Butler <[email protected]> Co-authored-by: Adam Storm <[email protected]>
4 parents 75a4639 + 329737d + 4f53f78 + 33bde20 commit 3c9f2ee

File tree

6 files changed

+18
-44
lines changed

6 files changed

+18
-44
lines changed

docs/generated/settings/settings-for-tenants.txt

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@ admission.epoch_lifo.epoch_duration duration 100ms the duration of an epoch, for
55
admission.epoch_lifo.queue_delay_threshold_to_switch_to_lifo duration 105ms the queue delay encountered by a (tenant,priority) for switching to epoch-LIFO ordering application
66
admission.sql_kv_response.enabled boolean true when true, work performed by the SQL layer when receiving a KV response is subject to admission control application
77
admission.sql_sql_response.enabled boolean true when true, work performed by the SQL layer when receiving a DistSQL response is subject to admission control application
8-
bulkio.backup.deprecated_full_backup_with_subdir.enabled boolean false when true, a backup command with a user specified subdirectory will create a full backup at the subdirectory if no backup already exists at that subdirectory application
98
bulkio.backup.file_size byte size 128 MiB target size for individual data files produced during BACKUP application
109
bulkio.backup.read_timeout duration 5m0s amount of time after which a read attempt is considered timed out, which causes the backup to fail application
1110
bulkio.backup.read_with_priority_after duration 1m0s amount of time since the read-as-of time above which a BACKUP should use priority when retrying reads application

docs/generated/settings/settings.html

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,6 @@
99
<tr><td><div id="setting-admission-kv-enabled" class="anchored"><code>admission.kv.enabled</code></div></td><td>boolean</td><td><code>true</code></td><td>when true, work performed by the KV layer is subject to admission control</td><td>Advanced/Self-Hosted</td></tr>
1010
<tr><td><div id="setting-admission-sql-kv-response-enabled" class="anchored"><code>admission.sql_kv_response.enabled</code></div></td><td>boolean</td><td><code>true</code></td><td>when true, work performed by the SQL layer when receiving a KV response is subject to admission control</td><td>Basic/Standard/Advanced/Self-Hosted</td></tr>
1111
<tr><td><div id="setting-admission-sql-sql-response-enabled" class="anchored"><code>admission.sql_sql_response.enabled</code></div></td><td>boolean</td><td><code>true</code></td><td>when true, work performed by the SQL layer when receiving a DistSQL response is subject to admission control</td><td>Basic/Standard/Advanced/Self-Hosted</td></tr>
12-
<tr><td><div id="setting-bulkio-backup-deprecated-full-backup-with-subdir-enabled" class="anchored"><code>bulkio.backup.deprecated_full_backup_with_subdir.enabled</code></div></td><td>boolean</td><td><code>false</code></td><td>when true, a backup command with a user specified subdirectory will create a full backup at the subdirectory if no backup already exists at that subdirectory</td><td>Basic/Standard/Advanced/Self-Hosted</td></tr>
1312
<tr><td><div id="setting-bulkio-backup-file-size" class="anchored"><code>bulkio.backup.file_size</code></div></td><td>byte size</td><td><code>128 MiB</code></td><td>target size for individual data files produced during BACKUP</td><td>Basic/Standard/Advanced/Self-Hosted</td></tr>
1413
<tr><td><div id="setting-bulkio-backup-read-timeout" class="anchored"><code>bulkio.backup.read_timeout</code></div></td><td>duration</td><td><code>5m0s</code></td><td>amount of time after which a read attempt is considered timed out, which causes the backup to fail</td><td>Basic/Standard/Advanced/Self-Hosted</td></tr>
1514
<tr><td><div id="setting-bulkio-backup-read-with-priority-after" class="anchored"><code>bulkio.backup.read_with_priority_after</code></div></td><td>duration</td><td><code>1m0s</code></td><td>amount of time since the read-as-of time above which a BACKUP should use priority when retrying reads</td><td>Basic/Standard/Advanced/Self-Hosted</td></tr>

pkg/backup/backup_test.go

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -730,7 +730,7 @@ func TestBackupAndRestoreJobDescription(t *testing.T) {
730730
sqlDB.ExpectErr(
731731
t,
732732
fmt.Sprintf(
733-
`No full backup exists in "%s" to append an incremental backup to. To take a full backup, remove the subdirectory from the backup command`,
733+
`No full backup exists in "%s" to append an incremental backup to`,
734734
nonExistentFullDir,
735735
),
736736
"BACKUP INTO $4 IN ($1, $2, $3)", append(collections, nonExistentFullDir)...,
@@ -3518,8 +3518,7 @@ func TestBackupAsOfSystemTime(t *testing.T) {
35183518
equalDir,
35193519
beforeTs))
35203520

3521-
sqlDB.ExpectErr(t, "A full backup already exists in .* Consider running an incremental backup"+
3522-
" to this full backup via `BACKUP INTO ",
3521+
sqlDB.ExpectErr(t, "pq: a full backup already exists in .*",
35233522
fmt.Sprintf(`BACKUP DATABASE data INTO '%s' AS OF SYSTEM TIME %s`, equalDir,
35243523
equalTs))
35253524
}

pkg/backup/backupdest/backup_destination.go

Lines changed: 3 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,6 @@ import (
2424
"github.com/cockroachdb/cockroach/pkg/jobs/jobspb"
2525
"github.com/cockroachdb/cockroach/pkg/roachpb"
2626
"github.com/cockroachdb/cockroach/pkg/security/username"
27-
"github.com/cockroachdb/cockroach/pkg/settings"
2827
"github.com/cockroachdb/cockroach/pkg/settings/cluster"
2928
"github.com/cockroachdb/cockroach/pkg/sql"
3029
"github.com/cockroachdb/cockroach/pkg/sql/pgwire/pgcode"
@@ -55,17 +54,6 @@ const (
5554
// will contain one.
5655
var backupPathRE = regexp.MustCompile("^/?[^\\/]+/[^\\/]+/[^\\/]+/" + backupbase.DeprecatedBackupManifestName + "$")
5756

58-
// featureFullBackupUserSubdir, when true, will create a full backup at a user
59-
// specified subdirectory if no backup already exists at that subdirectory. As
60-
// of 22.1, this feature is default disabled, and will be totally disabled by 22.2.
61-
var featureFullBackupUserSubdir = settings.RegisterBoolSetting(
62-
settings.ApplicationLevel,
63-
"bulkio.backup.deprecated_full_backup_with_subdir.enabled",
64-
"when true, a backup command with a user specified subdirectory will create a full backup at"+
65-
" the subdirectory if no backup already exists at that subdirectory",
66-
false,
67-
settings.WithPublic)
68-
6957
// TODO(adityamaru): Move this to the soon to be `backupinfo` package.
7058
func containsManifest(ctx context.Context, exportStore cloud.ExternalStorage) (bool, error) {
7159
r, _, err := exportStore.ReadFile(ctx, backupbase.DeprecatedBackupManifestName, cloud.ReadOptions{NoFileSize: true})
@@ -165,30 +153,13 @@ func ResolveDest(
165153
return ResolvedDestination{}, err
166154
}
167155
if exists && !dest.Exists {
168-
// We disallow a user from writing a full backup to a path in a collection containing an
169-
// existing backup iff we're 99.9% confident this backup was planned on a 22.1 node.
170156
return ResolvedDestination{},
171-
errors.Newf("A full backup already exists in %s. "+
172-
"Consider running an incremental backup to this full backup via `BACKUP INTO '%s' IN '%s'`",
173-
plannedBackupDefaultURI, chosenSuffix, dest.To[0])
157+
errors.Newf("a full backup already exists in %s", plannedBackupDefaultURI)
174158

175159
} else if !exists {
176160
if dest.Exists {
177-
// Implies the user passed a subdirectory in their backup command, either
178-
// explicitly or using LATEST; however, we could not find an existing
179-
// backup in that subdirectory.
180-
// - Pre 22.1: this was fine. we created a full backup in their specified subdirectory.
181-
// - 22.1: throw an error: full backups with an explicit subdirectory are deprecated.
182-
// User can use old behavior by switching the 'bulkio.backup.full_backup_with_subdir.
183-
// enabled' to true.
184-
// - 22.2+: the backup will fail unconditionally.
185-
// TODO (msbutler): throw error in 22.2
186-
if !featureFullBackupUserSubdir.Get(execCfg.SV()) {
187-
return ResolvedDestination{},
188-
errors.Errorf("No full backup exists in %q to append an incremental backup to. "+
189-
"To take a full backup, remove the subdirectory from the backup command "+
190-
"(i.e. run 'BACKUP ... INTO <collectionURI>'). ", chosenSuffix)
191-
}
161+
return ResolvedDestination{},
162+
errors.Errorf("No full backup exists in %q to append an incremental backup to", chosenSuffix)
192163
}
193164
// There's no full backup in the resolved subdirectory; therefore, we're conducting a full backup.
194165
return ResolvedDestination{

pkg/cloud/externalconn/record.go

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -355,20 +355,26 @@ func (e *MutableExternalConnection) Create(ctx context.Context, txn isql.Txn) er
355355
}
356356

357357
func (e *MutableExternalConnection) Update(ctx context.Context, txn isql.Txn) error {
358-
cols, qargs, err := e.marshalChanges()
358+
cols, qargsForChanges, err := e.marshalChanges()
359359
if err != nil {
360360
return err
361361
}
362362

363+
qargs := make([]interface{}, 0, 1+len(qargsForChanges))
364+
qargs = append(qargs, e.ConnectionName())
365+
qargs = append(qargs, qargsForChanges...)
366+
363367
var setClauses []string
364-
for i, col := range cols {
365-
setClauses = append(setClauses, fmt.Sprintf("%s = $%d", col, i+1))
368+
placeHolder := 2
369+
for _, col := range cols {
370+
setClauses = append(setClauses, fmt.Sprintf("%s = $%d", col, placeHolder))
371+
placeHolder++
366372
}
367373

368374
updateQuery := fmt.Sprintf(`UPDATE system.external_connections
369375
SET %s, updated = now()
370-
WHERE connection_name = '%s'`,
371-
strings.Join(setClauses, ", "), e.ConnectionName())
376+
WHERE connection_name = $1`,
377+
strings.Join(setClauses, ", "))
372378

373379
_, err = txn.ExecEx(ctx, "ExternalConnection.Update", txn.KV(), sessiondata.NodeUserSessionDataOverride, updateQuery, qargs...)
374380
return err

pkg/roachprod/promhelperclient/client.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -113,8 +113,8 @@ func NewPromClient(options ...Option) (*PromClient, error) {
113113
option.apply(c)
114114
}
115115

116-
// If the client is not set, create a new client
117-
if c.httpClient == nil {
116+
// If the client is not set and not disabled, create a new client
117+
if c.httpClient == nil && !c.disabled {
118118
iapTokenSource, err := roachprodutil.NewIAPTokenSource(roachprodutil.IAPTokenSourceOptions{
119119
OAuthClientID: OAuthClientID,
120120
ServiceAccountEmail: ServiceAccountEmail,

0 commit comments

Comments
 (0)