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
12 changes: 12 additions & 0 deletions bulker/bulkerlib/implementations/s3.go
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ type S3Config struct {
Bucket string `mapstructure:"bucket,omitempty" json:"bucket,omitempty" yaml:"bucket,omitempty"`
Region string `mapstructure:"region,omitempty" json:"region,omitempty" yaml:"region,omitempty"`
Endpoint string `mapstructure:"endpoint,omitempty" json:"endpoint,omitempty" yaml:"endpoint,omitempty"`
AddressingStyle string `mapstructure:"addressingStyle,omitempty" json:"addressingStyle,omitempty" yaml:"addressingStyle,omitempty"`
UsePresignedURL bool `mapstructure:"usePresignedURL,omitempty" json:"usePresignedURL,omitempty" yaml:"usePresignedURL,omitempty"`

RoleARN string `mapstructure:"roleARN" json:"roleARN" yaml:"roleARN"`
Expand Down Expand Up @@ -136,7 +137,18 @@ func NewS3(s3Config *S3Config) (*S3, error) {
o.Region = s3Config.Region
if s3Config.Endpoint != "" {
o.BaseEndpoint = &s3Config.Endpoint
}
// Preserve historical behavior by default (path-style for custom endpoints),
// but allow explicit override via addressingStyle.
switch s3Config.AddressingStyle {
case "path":
o.UsePathStyle = true
case "virtual-hosted":
o.UsePathStyle = false
case "auto", "":
o.UsePathStyle = s3Config.Endpoint != ""
default:
o.UsePathStyle = s3Config.Endpoint != ""
}
}
client := s3.NewFromConfig(awsCfg, o)
Expand Down
19 changes: 18 additions & 1 deletion webapps/console/lib/schema/destinations.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,10 @@ const s3Regions = [
"us-gov-west-1",
] as const;

// Allowed S3 URL addressing styles. "auto" preserves the historical behavior:
// path-style for custom endpoints, virtual-hosted-style for AWS.
const s3AddressingStyles = ["auto", "virtual-hosted", "path"] as const;

export const MASKED_SECRET = "__MASKED_BY_JITSU__";

/**
Expand Down Expand Up @@ -888,7 +892,13 @@ export const coreDestinations: DestinationType<any>[] = [
.describe(
"Authentication Method::S3 authentication method: <a target='_blank' rel='noopener noreferrer' href='https://docs.jitsu.com/destinations/block-storage/s3#advanced-iam-role-for-jitsu'>IAM Role based</a> or Access Key"
),
region: z.enum(s3Regions).default(s3Regions[0]).describe("S3 Region::S3 Region"),
region: z
.string()
.min(1)
.default(s3Regions[0])
.describe(
"S3 Region::S3 Region. Any AWS region (e.g. us-east-1, eu-central-1) or custom region for S3-compatible storage."
),
roleARN: z
.string()
.optional()
Expand All @@ -905,6 +915,13 @@ export const coreDestinations: DestinationType<any>[] = [
secretAccessKey: z.string().optional().describe("S3 Secret Access Key::S3 Secret Access Key"),
bucket: z.string().describe("S3 Bucket Name::S3 Bucket Name"),
endpoint: z.string().optional().describe("Custom endpoint of S3-compatible server"),
addressingStyle: z
.enum(s3AddressingStyles)
.optional()
.default("auto")
.describe(
"S3 Addressing Style::S3 URL addressing style: auto (path-style for custom endpoint, virtual-hosted otherwise), virtual-hosted, or path"
),
})
.merge(blockStorageSettings),
credentialsUi: {
Expand Down