Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ require (
github.com/scylladb/scylla-manager/backupspec v1.0.3-0.20250818141015-50f1d9b3b087
github.com/scylladb/scylla-manager/v3/pkg/managerclient v0.0.0-20251216101300-0a07cdbca348
github.com/scylladb/scylla-manager/v3/pkg/util v0.0.0-20251216101300-0a07cdbca348
github.com/scylladb/scylla-manager/v3/swagger v0.0.0-20251216101300-0a07cdbca348
github.com/scylladb/scylla-manager/v3/swagger v0.0.0-20260108132715-a46b9332650a
github.com/spf13/cobra v1.8.0
github.com/spf13/pflag v1.0.5
github.com/stoewer/go-strcase v1.3.0
Expand Down
4 changes: 2 additions & 2 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -1085,8 +1085,8 @@ github.com/scylladb/scylla-manager/v3/pkg/managerclient v0.0.0-20251216101300-0a
github.com/scylladb/scylla-manager/v3/pkg/managerclient v0.0.0-20251216101300-0a07cdbca348/go.mod h1:Utgzogwkl2k3pc6m9QcL24gGkAnzz1BqMLR79Lj3Nt4=
github.com/scylladb/scylla-manager/v3/pkg/util v0.0.0-20251216101300-0a07cdbca348 h1:TPde79tEMiwzjzMKZoMMtRY5ygbkPTIYwDp8kaZpMMo=
github.com/scylladb/scylla-manager/v3/pkg/util v0.0.0-20251216101300-0a07cdbca348/go.mod h1:5PVjJFtbO/R3rAJtgg/HNT7FbAcj+Hfn/g39HDBIa/k=
github.com/scylladb/scylla-manager/v3/swagger v0.0.0-20251216101300-0a07cdbca348 h1:tcezb87xbIJoNfiTOrO4IXVrAlGvPyA1SsqjsckYukM=
github.com/scylladb/scylla-manager/v3/swagger v0.0.0-20251216101300-0a07cdbca348/go.mod h1:JUyR1bNef5oN9cQpolZfj2lVDYaDMVFHqyHSDA5at7g=
github.com/scylladb/scylla-manager/v3/swagger v0.0.0-20260108132715-a46b9332650a h1:GUHB5L8nftCAJzxoSBP5Ng1HkOtwohvBRxl4y9KXPqM=
github.com/scylladb/scylla-manager/v3/swagger v0.0.0-20260108132715-a46b9332650a/go.mod h1:JUyR1bNef5oN9cQpolZfj2lVDYaDMVFHqyHSDA5at7g=
github.com/scylladb/termtables v0.0.0-20191203121021-c4c0b6d42ff4 h1:8qmTC5ByIXO3GP/IzBkxcZ/99VITvnIETDhdFz/om7A=
github.com/scylladb/termtables v0.0.0-20191203121021-c4c0b6d42ff4/go.mod h1:C1a7PQSMz9NShzorzCiG2fk9+xuCgLkPeCvMHYR2OWg=
github.com/sirupsen/logrus v1.8.3 h1:DBBfY8eMYazKEJHb3JKpSPfpgd2mBCoNFlQx6C5fftU=
Expand Down
3 changes: 3 additions & 0 deletions pkg/cmd/agent/nodeinfo.go
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,9 @@ func (h *nodeInfoHandler) rcloneProviderConfig(info *scyllaclient.NodeInfo) {
Endpoint: h.config.S3.Endpoint,
Region: h.config.S3.Region,
},
Gcs: models.NodeInfoRcloneBackendConfigGcs{
Endpoint: h.config.GCS.Endpoint,
},
}
}

Expand Down
57 changes: 51 additions & 6 deletions pkg/scyllaclient/client_agent.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ package scyllaclient

import (
"context"
stdErr "errors"
"fmt"
"net"
"net/netip"
Expand Down Expand Up @@ -278,17 +279,29 @@ func (ni *NodeInfo) SupportsNativeRestoreAPI() (bool, error) {
// ScyllaObjectStorageEndpoint returns endpoint that should be used when calling /storage_service/<backup|restore> API.
// It also validates that agent's and Scylla's configurations match.
func (ni *NodeInfo) ScyllaObjectStorageEndpoint(provider backupspec.Provider) (string, error) {
if provider != backupspec.S3 {
return "", errors.Errorf("unsupported provider %s for native Scylla backup and restore", provider)
}
if len(ni.ObjectStorageEndpoints) == 0 {
return "", errors.New("no object storage endpoint configured")
}
var (
match bool
unknownOSEErr error
)
for _, ose := range ni.ObjectStorageEndpoints {
if EqualObjectStorageEndpoints(ni.RcloneBackendConfig.S3, ose) {
switch {
case isS3ObjectStorageEndpoint(ose):
match = equalS3ObjectStorageEndpoints(ni.RcloneBackendConfig.S3, ose)
case isGSObjectStorageEndpoint(ose):
match = equalGSObjectStorageEndpoints(ni.RcloneBackendConfig.Gcs, ose)
default:
unknownOSEErr = stdErr.Join(unknownOSEErr, errors.Errorf("object storage endpoint %q has unknown type %q", ose.Name, ose.Type))
}
if match {
return ose.Name, nil
}
}
if unknownOSEErr != nil {
return "", unknownOSEErr
}
return "", errors.Errorf("scylla and scylla-manager-agent backup configurations don't match. "+
"Please make sure that the same endpoint is set in both `scylla-manager-agent.yaml` %s config "+
"and in `scylla.yaml` object_storage_endpoints config", provider)
Expand Down Expand Up @@ -345,8 +358,14 @@ func (c *Client) CloudMetadata(ctx context.Context, host string) (InstanceMetada
}, nil
}

// EqualObjectStorageEndpoints checks if rclone and Scylla object storage endpoints match.
func EqualObjectStorageEndpoints(rclone models.NodeInfoRcloneBackendConfigS3, scylla models.ObjectStorageEndpoint) bool {
func isS3ObjectStorageEndpoint(ose models.ObjectStorageEndpoint) bool {
return ose.Type == "" || strings.EqualFold(ose.Type, "s3")
}

func equalS3ObjectStorageEndpoints(rclone models.NodeInfoRcloneBackendConfigS3, scylla models.ObjectStorageEndpoint) bool {
if !isS3ObjectStorageEndpoint(scylla) {
return false
}
// Get specified or region default rclone s3 endpoint
rcloneName := rclone.Endpoint
if rcloneName == "" {
Expand Down Expand Up @@ -386,6 +405,32 @@ func EqualObjectStorageEndpoints(rclone models.NodeInfoRcloneBackendConfigS3, sc
return scyllaIP == rcloneIP
}

func isGSObjectStorageEndpoint(ose models.ObjectStorageEndpoint) bool {
return strings.EqualFold(ose.Type, "gs")
}

func equalGSObjectStorageEndpoints(rclone models.NodeInfoRcloneBackendConfigGcs, scylla models.ObjectStorageEndpoint) bool {
if !isGSObjectStorageEndpoint(scylla) {
return false
}
const (
defaultScyllaGSEndpointName = "default"
defaultGSEndpoint = "https://storage.googleapis.com"
)

scyllaEndpoint := scylla.Name
if strings.EqualFold(scyllaEndpoint, defaultScyllaGSEndpointName) || scyllaEndpoint == "" {
scyllaEndpoint = defaultGSEndpoint
}

rcloneEndpoint := rclone.Endpoint
if rcloneEndpoint == "" {
rcloneEndpoint = defaultGSEndpoint
}

return scyllaEndpoint == rcloneEndpoint
}

func trimBrackets(e string) string {
return strings.TrimPrefix(strings.TrimSuffix(e, "]"), "[")
}
Loading
Loading