Skip to content

Commit

Permalink
Add support for storage class configuration (#1714)
Browse files Browse the repository at this point in the history
* Add support for storage class configuration

* Update changelog

* Get rid of irrelevant character from changelog

* CR Changes

* Change order of parameters to fake server with header

* Add test to check that storage class value is added to header

* Fix typo in changelog

* Fix changelog
  • Loading branch information
amitsetty committed Sep 12, 2022
1 parent 9a135a9 commit 8cc206b
Show file tree
Hide file tree
Showing 4 changed files with 57 additions and 11 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
compactor.compaction.flush_size_bytes. [#1696](https://github.com/grafana/tempo/pull/1696) (@joe-elliott)
* [CHANGE] Return 200 instead of 206 when blocks failed is < tolerate_failed_blocks. [#1725](https://github.com/grafana/tempo/pull/1725) (@joe-elliott)
* [CHANGE] Update Go to 1.19 [#1665](https://github.com/grafana/tempo/pull/1665) (@ie-pham)
* [FEATURE] Add capability to configure the used S3 Storage Class [#1697](https://github.com/grafana/tempo/pull/1714) (@amitsetty)
* [ENHANCEMENT] cache: expose username and sentinel_username redis configuration options for ACL-based Redis Auth support [#1708](https://github.com/grafana/tempo/pull/1708) (@jsievenpiper)
* [ENHANCEMENT] metrics-generator: expose span size as a metric [#1662](https://github.com/grafana/tempo/pull/1662) (@ie-pham)
* [ENHANCEMENT] Set Max Idle connections to 100 for Azure, should reduce DNS errors in Azure [#1632](https://github.com/grafana/tempo/pull/1632) (@electron0zero)
Expand Down
2 changes: 2 additions & 0 deletions tempodb/backend/s3/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,4 +21,6 @@ type Config struct {
SignatureV2 bool `yaml:"signature_v2"`
ForcePathStyle bool `yaml:"forcepathstyle"`
Tags map[string]string `yaml:"tags"`
StorageClass string `yaml:"storage_class"`
Metadata map[string]string `yaml:"metadata"`
}
18 changes: 11 additions & 7 deletions tempodb/backend/s3/s3.go
Original file line number Diff line number Diff line change
Expand Up @@ -103,14 +103,20 @@ func internalNew(cfg *Config, confirm bool) (backend.RawReader, backend.RawWrite
return rw, rw, rw, nil
}

func getPutObjectOptions(rw *readerWriter) minio.PutObjectOptions {
return minio.PutObjectOptions{
PartSize: rw.cfg.PartSize,
UserTags: rw.cfg.Tags,
StorageClass: rw.cfg.StorageClass,
UserMetadata: rw.cfg.Metadata,
}
}

// Write implements backend.Writer
func (rw *readerWriter) Write(ctx context.Context, name string, keypath backend.KeyPath, data io.Reader, size int64, _ bool) error {
objName := backend.ObjectFileName(keypath, name)

putObjectOptions := minio.PutObjectOptions{
PartSize: rw.cfg.PartSize,
UserTags: rw.cfg.Tags,
}
putObjectOptions := getPutObjectOptions(rw)

info, err := rw.core.Client.PutObject(
ctx,
Expand Down Expand Up @@ -138,9 +144,7 @@ func (rw *readerWriter) Append(ctx context.Context, name string, keypath backend
var a appendTracker
objectName := backend.ObjectFileName(keypath, name)

options := minio.PutObjectOptions{
PartSize: rw.cfg.PartSize,
}
options := getPutObjectOptions(rw)
if tracker != nil {
a = tracker.(appendTracker)
} else {
Expand Down
47 changes: 43 additions & 4 deletions tempodb/backend/s3/s3_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,9 @@ import (
"github.com/stretchr/testify/require"
)

const tagHeader = "X-Amz-Tagging"
const storageClassHeader = "X-Amz-Storage-Class"

func TestHedge(t *testing.T) {
tests := []struct {
name string
Expand Down Expand Up @@ -118,17 +121,17 @@ func TestReadError(t *testing.T) {
assert.Equal(t, wups, errB)
}

func fakeServerWithTags(t *testing.T, obj *url.Values) *httptest.Server {
func fakeServerWithHeader(t *testing.T, obj *url.Values, testedHeaderName string) *httptest.Server {
require.NotNil(t, obj)

server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
switch method := r.Method; method {
case "PUT":
// https://docs.aws.amazon.com/AmazonS3/latest/API/API_PutObject.html
switch tagHeaders := r.Header.Get("X-Amz-Tagging"); tagHeaders {
switch testedHeaderValue := r.Header.Get(testedHeaderName); testedHeaderValue {
case "":
default:
value, err := url.ParseQuery(tagHeaders)
value, err := url.ParseQuery(testedHeaderValue)
require.NoError(t, err)
*obj = value
}
Expand Down Expand Up @@ -162,7 +165,7 @@ func TestObjectBlockTags(t *testing.T) {
// rawObject := raw.Object{}
var obj url.Values

server := fakeServerWithTags(t, &obj)
server := fakeServerWithHeader(t, &obj, tagHeader)
_, w, _, err := New(&Config{
Region: "blerg",
AccessKey: "test",
Expand All @@ -185,3 +188,39 @@ func TestObjectBlockTags(t *testing.T) {
})
}
}

func TestObjectStorageClass(t *testing.T) {

tests := []struct {
name string
StorageClass string
// expectedObject raw.Object
}{
{
"Standard", "STANDARD",
},
}

for _, tc := range tests {
t.Run(tc.name, func(t *testing.T) {
// rawObject := raw.Object{}
var obj url.Values

server := fakeServerWithHeader(t, &obj, storageClassHeader)
_, w, _, err := New(&Config{
Region: "blerg",
AccessKey: "test",
SecretKey: flagext.SecretWithValue("test"),
Bucket: "blerg",
Insecure: true,
Endpoint: server.URL[7:], // [7:] -> strip http://
StorageClass: tc.StorageClass,
})
require.NoError(t, err)

ctx := context.Background()
_ = w.Write(ctx, "object", backend.KeyPath{"test"}, bytes.NewReader([]byte{}), 0, false)
require.Equal(t, obj.Has(tc.StorageClass), true)
})
}
}

0 comments on commit 8cc206b

Please sign in to comment.