Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

s3: allow setting bucket lookup type #7684

Merged
merged 4 commits into from
Mar 21, 2024
Merged
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
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
* [CHANGE] Querier: the CLI flag `-querier.minimize-ingester-requests` has been moved from "experimental" to "advanced". #7638
* [CHANGE] Ingester: `/ingester/flush` endpoint is now only allowed to execute only while the ingester is in `Running` state. The 503 status code is returned if the endpoint is called while the ingester is not in `Running` state. #7486
* [FEATURE] Store-gateway: Allow specific tenants to be enabled or disabled via `-store-gateway.enabled-tenants` or `-store-gateway.disabled-tenants` CLI flags or their corresponding YAML settings. #7653
* [FEATURE] New `-<prefix>.s3.bucket-lookup-type` flag configures lookup style type, used to access bucket in s3 compatible providers. #7684
* [ENHANCEMENT] Store-gateway: merge series from different blocks concurrently. #7456
* [ENHANCEMENT] Store-gateway: Add `stage="wait_max_concurrent"` to `cortex_bucket_store_series_request_stage_duration_seconds` which records how long the query had to wait for its turn for `-blocks-storage.bucket-store.max-concurrent`. #7609
* [BUGFIX] Rules: improve error handling when querier is local to the ruler. #7567
Expand Down
44 changes: 44 additions & 0 deletions cmd/mimir/config-descriptor.json
Original file line number Diff line number Diff line change
Expand Up @@ -5812,6 +5812,17 @@
"fieldType": "string",
"fieldCategory": "advanced"
},
{
"kind": "field",
"name": "bucket_lookup_type",
"required": false,
"desc": "Bucket lookup style type, used to access bucket in S3-compatible service. Default is auto. Supported values are: auto, path, virtual-hosted.",
"fieldValue": null,
"fieldDefaultValue": "auto",
"fieldFlag": "blocks-storage.s3.bucket-lookup-type",
"fieldType": "string",
"fieldCategory": "advanced"
},
{
"kind": "field",
"name": "storage_class",
Expand Down Expand Up @@ -11686,6 +11697,17 @@
"fieldType": "string",
"fieldCategory": "advanced"
},
{
"kind": "field",
"name": "bucket_lookup_type",
"required": false,
"desc": "Bucket lookup style type, used to access bucket in S3-compatible service. Default is auto. Supported values are: auto, path, virtual-hosted.",
"fieldValue": null,
"fieldDefaultValue": "auto",
"fieldFlag": "ruler-storage.s3.bucket-lookup-type",
"fieldType": "string",
"fieldCategory": "advanced"
},
{
"kind": "field",
"name": "storage_class",
Expand Down Expand Up @@ -13760,6 +13782,17 @@
"fieldType": "string",
"fieldCategory": "advanced"
},
{
"kind": "field",
"name": "bucket_lookup_type",
"required": false,
"desc": "Bucket lookup style type, used to access bucket in S3-compatible service. Default is auto. Supported values are: auto, path, virtual-hosted.",
"fieldValue": null,
"fieldDefaultValue": "auto",
"fieldFlag": "alertmanager-storage.s3.bucket-lookup-type",
"fieldType": "string",
"fieldCategory": "advanced"
},
{
"kind": "field",
"name": "storage_class",
Expand Down Expand Up @@ -16067,6 +16100,17 @@
"fieldType": "string",
"fieldCategory": "advanced"
},
{
"kind": "field",
"name": "bucket_lookup_type",
"required": false,
"desc": "Bucket lookup style type, used to access bucket in S3-compatible service. Default is auto. Supported values are: auto, path, virtual-hosted.",
"fieldValue": null,
"fieldDefaultValue": "auto",
"fieldFlag": "common.storage.s3.bucket-lookup-type",
"fieldType": "string",
"fieldCategory": "advanced"
},
{
"kind": "field",
"name": "storage_class",
Expand Down
8 changes: 8 additions & 0 deletions cmd/mimir/help-all.txt.tmpl
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,8 @@ Usage of ./cmd/mimir/mimir:
Path at which alertmanager configurations are stored.
-alertmanager-storage.s3.access-key-id string
S3 access key ID
-alertmanager-storage.s3.bucket-lookup-type value
Bucket lookup style type, used to access bucket in S3-compatible service. Default is auto. Supported values are: auto, path, virtual-hosted.
-alertmanager-storage.s3.bucket-name string
S3 bucket name
-alertmanager-storage.s3.endpoint string
Expand Down Expand Up @@ -667,6 +669,8 @@ Usage of ./cmd/mimir/mimir:
JSON either from a Google Developers Console client_credentials.json file, or a Google Developers service account key. Needs to be valid JSON, not a filesystem path.
-blocks-storage.s3.access-key-id string
S3 access key ID
-blocks-storage.s3.bucket-lookup-type value
Bucket lookup style type, used to access bucket in S3-compatible service. Default is auto. Supported values are: auto, path, virtual-hosted.
-blocks-storage.s3.bucket-name string
S3 bucket name
-blocks-storage.s3.endpoint string
Expand Down Expand Up @@ -835,6 +839,8 @@ Usage of ./cmd/mimir/mimir:
JSON either from a Google Developers Console client_credentials.json file, or a Google Developers service account key. Needs to be valid JSON, not a filesystem path.
-common.storage.s3.access-key-id string
S3 access key ID
-common.storage.s3.bucket-lookup-type value
Bucket lookup style type, used to access bucket in S3-compatible service. Default is auto. Supported values are: auto, path, virtual-hosted.
-common.storage.s3.bucket-name string
S3 bucket name
-common.storage.s3.endpoint string
Expand Down Expand Up @@ -2251,6 +2257,8 @@ Usage of ./cmd/mimir/mimir:
Directory to scan for rules
-ruler-storage.s3.access-key-id string
S3 access key ID
-ruler-storage.s3.bucket-lookup-type value
Bucket lookup style type, used to access bucket in S3-compatible service. Default is auto. Supported values are: auto, path, virtual-hosted.
-ruler-storage.s3.bucket-name string
S3 bucket name
-ruler-storage.s3.endpoint string
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4618,6 +4618,11 @@ The s3_backend block configures the connection to Amazon S3 object storage backe
# CLI flag: -<prefix>.s3.list-objects-version
[list_objects_version: <string> | default = ""]

# (advanced) Bucket lookup style type, used to access bucket in S3-compatible
# service. Default is auto. Supported values are: auto, path, virtual-hosted.
# CLI flag: -<prefix>.s3.bucket-lookup-type
[bucket_lookup_type: <string> | default = "auto"]

# (experimental) The S3 storage class to use, not set by default. Details can be
# found at https://aws.amazon.com/s3/storage-classes/. Supported values are:
# STANDARD, REDUCED_REDUNDANCY, GLACIER, STANDARD_IA, ONEZONE_IA,
Expand Down
1 change: 1 addition & 0 deletions pkg/storage/bucket/s3/bucket_client.go
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@ func newS3Config(cfg Config) (s3.Config, error) {
SendContentMd5: cfg.SendContentMd5,
SSEConfig: sseCfg,
ListObjectsVersion: cfg.ListObjectsVersion,
BucketLookupType: cfg.BucketLookupType,
AWSSDKAuth: cfg.NativeAWSAuthEnabled,
PartSize: cfg.PartSize,
HTTPConfig: s3.HTTPConfig{
Expand Down
76 changes: 60 additions & 16 deletions pkg/storage/bucket/s3/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import (
"flag"
"fmt"
"net/http"
"slices"
"strings"
"time"

Expand All @@ -36,9 +37,11 @@ const (
)

var (
supportedSignatureVersions = []string{SignatureVersionV4, SignatureVersionV2}
supportedSSETypes = []string{SSEKMS, SSES3}
supportedStorageClasses = s3_service.ObjectStorageClass_Values()
supportedSignatureVersions = []string{SignatureVersionV4, SignatureVersionV2}
supportedSSETypes = []string{SSEKMS, SSES3}
supportedStorageClasses = s3_service.ObjectStorageClass_Values()
supportedBucketLookupTypes = thanosS3BucketLookupTypesValues()

errUnsupportedSignatureVersion = fmt.Errorf("unsupported signature version (supported values: %s)", strings.Join(supportedSignatureVersions, ", "))
errUnsupportedSSEType = errors.New("unsupported S3 SSE type")
errUnsupportedStorageClass = fmt.Errorf("unsupported S3 storage class (supported values: %s)", strings.Join(supportedStorageClasses, ", "))
Expand All @@ -47,6 +50,21 @@ var (
errInvalidSTSEndpoint = errors.New("sts-endpoint must be a valid url")
)

var thanosS3BucketLookupTypes = map[string]s3.BucketLookupType{
s3.AutoLookup.String(): s3.AutoLookup,
s3.VirtualHostLookup.String(): s3.VirtualHostLookup,
s3.PathLookup.String(): s3.PathLookup,
}

func thanosS3BucketLookupTypesValues() (list []string) {
for k := range thanosS3BucketLookupTypes {
list = append(list, k)
}
// sort the list for consistent output in help, where it's used
slices.Sort(list)
return list
}

// HTTPConfig stores the http.Transport configuration for the s3 minio client.
type HTTPConfig struct {
IdleConnTimeout time.Duration `yaml:"idle_conn_timeout" category:"advanced"`
Expand Down Expand Up @@ -76,19 +94,20 @@ func (cfg *HTTPConfig) RegisterFlagsWithPrefix(prefix string, f *flag.FlagSet) {

// Config holds the config options for an S3 backend
type Config struct {
Endpoint string `yaml:"endpoint"`
Region string `yaml:"region"`
BucketName string `yaml:"bucket_name"`
SecretAccessKey flagext.Secret `yaml:"secret_access_key"`
AccessKeyID string `yaml:"access_key_id"`
Insecure bool `yaml:"insecure" category:"advanced"`
SignatureVersion string `yaml:"signature_version" category:"advanced"`
ListObjectsVersion string `yaml:"list_objects_version" category:"advanced"`
StorageClass string `yaml:"storage_class" category:"experimental"`
NativeAWSAuthEnabled bool `yaml:"native_aws_auth_enabled" category:"experimental"`
PartSize uint64 `yaml:"part_size" category:"experimental"`
SendContentMd5 bool `yaml:"send_content_md5" category:"experimental"`
STSEndpoint string `yaml:"sts_endpoint"`
Endpoint string `yaml:"endpoint"`
Region string `yaml:"region"`
BucketName string `yaml:"bucket_name"`
SecretAccessKey flagext.Secret `yaml:"secret_access_key"`
AccessKeyID string `yaml:"access_key_id"`
Insecure bool `yaml:"insecure" category:"advanced"`
SignatureVersion string `yaml:"signature_version" category:"advanced"`
ListObjectsVersion string `yaml:"list_objects_version" category:"advanced"`
BucketLookupType s3.BucketLookupType `yaml:"bucket_lookup_type" category:"advanced"`
StorageClass string `yaml:"storage_class" category:"experimental"`
NativeAWSAuthEnabled bool `yaml:"native_aws_auth_enabled" category:"experimental"`
PartSize uint64 `yaml:"part_size" category:"experimental"`
SendContentMd5 bool `yaml:"send_content_md5" category:"experimental"`
STSEndpoint string `yaml:"sts_endpoint"`

SSE SSEConfig `yaml:"sse"`
HTTP HTTPConfig `yaml:"http"`
Expand All @@ -113,6 +132,7 @@ func (cfg *Config) RegisterFlagsWithPrefix(prefix string, f *flag.FlagSet) {
f.BoolVar(&cfg.NativeAWSAuthEnabled, prefix+"s3.native-aws-auth-enabled", false, "If enabled, it will use the default authentication methods of the AWS SDK for go based on known environment variables and known AWS config files.")
f.Uint64Var(&cfg.PartSize, prefix+"s3.part-size", 0, "The minimum file size in bytes used for multipart uploads. If 0, the value is optimally computed for each object.")
f.BoolVar(&cfg.SendContentMd5, prefix+"s3.send-content-md5", false, "If enabled, a Content-MD5 header is sent with S3 Put Object requests. Consumes more resources to compute the MD5, but may improve compatibility with object storage services that do not support checksums.")
f.Var(newBucketLookupTypeValue(s3.AutoLookup, &cfg.BucketLookupType), prefix+"s3.bucket-lookup-type", fmt.Sprintf("Bucket lookup style type, used to access bucket in S3-compatible service. Default is auto. Supported values are: %s.", strings.Join(supportedBucketLookupTypes, ", ")))
f.StringVar(&cfg.STSEndpoint, prefix+"s3.sts-endpoint", "", "Accessing S3 resources using temporary, secure credentials provided by AWS Security Token Service.")
cfg.SSE.RegisterFlagsWithPrefix(prefix+"s3.sse.", f)
cfg.HTTP.RegisterFlagsWithPrefix(prefix, f)
Expand Down Expand Up @@ -227,3 +247,27 @@ func parseKMSEncryptionContext(data string) (map[string]string, error) {
err := errors.Wrap(json.Unmarshal([]byte(data), &decoded), "unable to parse KMS encryption context")
return decoded, err
}

// bucketLookupTypeValue is an adapter between s3.BucketLookupType and flag.Value.
type bucketLookupTypeValue s3.BucketLookupType

func newBucketLookupTypeValue(value s3.BucketLookupType, p *s3.BucketLookupType) *bucketLookupTypeValue {
*p = value
return (*bucketLookupTypeValue)(p)
}

func (v *bucketLookupTypeValue) String() string {
if v == nil {
return s3.AutoLookup.String()
}
return s3.BucketLookupType(*v).String()
}

func (v *bucketLookupTypeValue) Set(s string) error {
t, ok := thanosS3BucketLookupTypes[s]
if !ok {
return fmt.Errorf("unsupported bucket lookup type: %s", s)
}
*v = bucketLookupTypeValue(t)
return nil
}
18 changes: 18 additions & 0 deletions tools/doc-generator/parse/parser.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ import (
"github.com/pkg/errors"
"github.com/prometheus/common/model"
"github.com/prometheus/prometheus/model/relabel"
"github.com/thanos-io/objstore/providers/s3"

"github.com/grafana/mimir/pkg/ingester/activeseries"
"github.com/grafana/mimir/pkg/storage/tsdb"
Expand Down Expand Up @@ -583,6 +584,23 @@ func getCustomFieldEntry(cfg interface{}, field reflect.StructField, fieldValue
FieldCategory: getFieldCategory(field, fieldFlag.Name),
}, nil
}
if field.Type == reflect.TypeOf(s3.BucketLookupType(0)) {
fieldFlag, err := getFieldFlag(field, fieldValue, flags)
if err != nil || fieldFlag == nil {
return nil, err
}

return &ConfigEntry{
Kind: KindField,
Name: getFieldName(field),
Required: isFieldRequired(field),
FieldFlag: fieldFlag.Name,
FieldDesc: getFieldDescription(cfg, field, fieldFlag.Usage),
FieldType: "string",
FieldDefault: getFieldDefault(field, fieldFlag.DefValue),
FieldCategory: getFieldCategory(field, fieldFlag.Name),
}, nil
}

return nil, nil
}
Expand Down
Loading