From 0c820a67fc1ec13130d0da1902eb7bb4073992a2 Mon Sep 17 00:00:00 2001 From: Carlo <1778532+cdcme@users.noreply.github.com> Date: Tue, 9 Jun 2026 13:55:25 -0400 Subject: [PATCH] Fix GCS checksum flag derived from wrong endpoint key (#47145) Fixes https://github.com/fleetdm/fleet/issues/47142 --- server/datastore/s3/bootstrap_package.go | 2 -- server/datastore/s3/carves.go | 4 --- server/datastore/s3/common_file_store.go | 2 -- server/datastore/s3/org_logo.go | 1 - server/datastore/s3/s3.go | 2 ++ server/datastore/s3/s3_test.go | 35 ++++++++++++++++++++++ server/datastore/s3/software_installer.go | 5 +--- server/datastore/s3/software_title_icon.go | 2 -- 8 files changed, 38 insertions(+), 15 deletions(-) diff --git a/server/datastore/s3/bootstrap_package.go b/server/datastore/s3/bootstrap_package.go index 38371a6ee5..8e893bde83 100644 --- a/server/datastore/s3/bootstrap_package.go +++ b/server/datastore/s3/bootstrap_package.go @@ -20,8 +20,6 @@ func NewBootstrapPackageStore(config config.S3Config) (*BootstrapPackageStore, e s3store: s3store, pathPrefix: bootstrapPackagePrefix, fileLabel: "bootstrap package", - - gcs: isGCS(config.EndpointURL), }, }, nil } diff --git a/server/datastore/s3/carves.go b/server/datastore/s3/carves.go index eaded23e78..537df166ca 100644 --- a/server/datastore/s3/carves.go +++ b/server/datastore/s3/carves.go @@ -32,8 +32,6 @@ const ( type CarveStore struct { *s3store metadatadb fleet.CarveStore - - gcs bool } // NewCarveStore creates a new store with the given config @@ -46,8 +44,6 @@ func NewCarveStore(config config.S3Config, metadatadb fleet.CarveStore) (*CarveS return &CarveStore{ s3store: s3store, metadatadb: metadatadb, - - gcs: isGCS(config.EndpointURL), }, nil } diff --git a/server/datastore/s3/common_file_store.go b/server/datastore/s3/common_file_store.go index 8a7b2a1eed..358a2a8f51 100644 --- a/server/datastore/s3/common_file_store.go +++ b/server/datastore/s3/common_file_store.go @@ -35,8 +35,6 @@ type commonFileStore struct { *s3store pathPrefix string fileLabel string // how to call the file in error messages - - gcs bool } func isGCS(endpointURL string) bool { diff --git a/server/datastore/s3/org_logo.go b/server/datastore/s3/org_logo.go index 1507004d29..83b6fdc03b 100644 --- a/server/datastore/s3/org_logo.go +++ b/server/datastore/s3/org_logo.go @@ -29,7 +29,6 @@ func NewOrgLogoStore(cfg config.S3Config) (*OrgLogoStore, error) { s3store: s3store, pathPrefix: "org-logos", fileLabel: "org logo", - gcs: isGCS(cfg.EndpointURL), }, }, nil } diff --git a/server/datastore/s3/s3.go b/server/datastore/s3/s3.go index 5afac1e078..a8c6eee9ed 100644 --- a/server/datastore/s3/s3.go +++ b/server/datastore/s3/s3.go @@ -38,6 +38,7 @@ type s3store struct { bucket string prefix string cloudFrontConfig *config.S3CloudFrontConfig + gcs bool } type installerNotFoundError struct{} @@ -174,6 +175,7 @@ func newS3Store(cfg config.S3ConfigInternal) (*s3store, error) { bucket: cfg.Bucket, prefix: cfg.Prefix, cloudFrontConfig: cfg.CloudFrontConfig, + gcs: gcsEndpoint, }, nil } diff --git a/server/datastore/s3/s3_test.go b/server/datastore/s3/s3_test.go index b1d9ede6a1..5913cd1607 100644 --- a/server/datastore/s3/s3_test.go +++ b/server/datastore/s3/s3_test.go @@ -136,6 +136,41 @@ func TestSoftwareInstallerStoreGCSIAMAuthUsesBearerToken(t *testing.T) { } } +func TestSoftwareInstallerStoreGCSFlagFromPrefixedEndpoint(t *testing.T) { + // Top-level EndpointURL deliberately empty: the documented GCS config + // sets only the per-prefix endpoint, and gcs must still resolve true. + store, err := NewSoftwareInstallerStore(config.S3Config{ + SoftwareInstallersBucket: "bucket", + SoftwareInstallersPrefix: "prefix", + SoftwareInstallersRegion: "us-east-1", + SoftwareInstallersEndpointURL: "https://storage.googleapis.com", + }) + require.NoError(t, err) + require.True(t, store.gcs) +} + +func TestSoftwareInstallerStoreGCSFlagFalseForNonGCSEndpoint(t *testing.T) { + store, err := NewSoftwareInstallerStore(config.S3Config{ + SoftwareInstallersBucket: "bucket", + SoftwareInstallersPrefix: "prefix", + SoftwareInstallersRegion: "us-east-1", + SoftwareInstallersEndpointURL: "https://s3.example.com", + }) + require.NoError(t, err) + require.False(t, store.gcs) +} + +func TestCarveStoreGCSFlagFromPrefixedEndpoint(t *testing.T) { + store, err := NewCarveStore(config.S3Config{ + CarvesBucket: "carves-bucket", + CarvesPrefix: "carves-prefix", + CarvesRegion: "us-east-1", + CarvesEndpointURL: "https://storage.googleapis.com", + }, nil) + require.NoError(t, err) + require.True(t, store.gcs) +} + func TestCarveStoreGCSIAMAuthUsesBearerToken(t *testing.T) { type requestInfo struct { AuthHeader string diff --git a/server/datastore/s3/software_installer.go b/server/datastore/s3/software_installer.go index efa0ed762b..360db50adf 100644 --- a/server/datastore/s3/software_installer.go +++ b/server/datastore/s3/software_installer.go @@ -21,8 +21,6 @@ func NewSoftwareInstallerStore(config config.S3Config) (*SoftwareInstallerStore, s3store: s3store, pathPrefix: softwareInstallersPrefix, fileLabel: "software installer", - - gcs: isGCS(config.EndpointURL), }, }, nil } @@ -36,14 +34,13 @@ func NewTestSoftwareInstallerStore(conf config.S3Config) (*SoftwareInstallerStor SigningPublicKeyID: conf.SoftwareInstallersCloudFrontURLSigningPublicKeyID, Signer: conf.SoftwareInstallersCloudFrontSigner, }, + gcs: isGCS(conf.EndpointURL), } return &SoftwareInstallerStore{ &commonFileStore{ s3store: store, pathPrefix: softwareInstallersPrefix, fileLabel: "software installer", - - gcs: isGCS(conf.EndpointURL), }, }, nil } diff --git a/server/datastore/s3/software_title_icon.go b/server/datastore/s3/software_title_icon.go index 85c9d07c9f..838243fda7 100644 --- a/server/datastore/s3/software_title_icon.go +++ b/server/datastore/s3/software_title_icon.go @@ -19,8 +19,6 @@ func NewSoftwareTitleIconStore(config config.S3Config) (*SoftwareTitleIconStore, s3store: s3store, pathPrefix: "software-title-icons", fileLabel: "software title icon", - - gcs: isGCS(config.EndpointURL), }, }, nil }