Added support for S3 storage classes (#28319)

* Added support for S3 storage classes

* Added missing translations for S3 storage class

* Changed default storage class values to preserve original behaviour

* Changed storage class description and example

* Fix translations ordering

* Change configuration defaults to empty strings

* Remove redundant empty string check

* Validate storage class variable against constants from S3 API docs

* Validate export storage class against constants

* Use slices for config validation

* Applied patch for translation ordering
Этот коммит содержится в:
Nadav Tasher
2024-11-13 08:59:44 +02:00
коммит произвёл GitHub
родитель 8c3f4a5818
Коммит 5e47c97db4
12 изменённых файлов: 86 добавлений и 5 удалений

Просмотреть файл

@@ -15,6 +15,7 @@ import (
"path/filepath"
"reflect"
"regexp"
"slices"
"strconv"
"strings"
"time"
@@ -267,6 +268,19 @@ const (
LocalModeSocketPath = "/var/tmp/mattermost_local.socket"
ConnectedWorkspacesSettingsDefaultMaxPostsPerSync = 50 // a bit more than 4 typical screenfulls of posts
// These storage classes are the valid values for the x-amz-storage-class header. More documentation here https://docs.aws.amazon.com/AmazonS3/latest/API/API_PutObject.html#AmazonS3-PutObject-request-header-StorageClass
StorageClassStandard = "STANDARD"
StorageClassReducedRedundancy = "REDUCED_REDUNDANCY"
StorageClassStandardIA = "STANDARD_IA"
StorageClassOnezoneIA = "ONEZONE_IA"
StorageClassIntelligentTiering = "INTELLIGENT_TIERING"
StorageClassGlacier = "GLACIER"
StorageClassDeepArchive = "DEEP_ARCHIVE"
StorageClassOutposts = "OUTPOSTS"
StorageClassGlacierIR = "GLACIER_IR"
StorageClassSnow = "SNOW"
StorageClassExpressOnezone = "EXPRESS_ONEZONE"
)
func GetDefaultAppCustomURLSchemes() []string {
@@ -1649,6 +1663,7 @@ type FileSettings struct {
AmazonS3Trace *bool `access:"environment_file_storage,write_restrictable,cloud_restrictable"`
AmazonS3RequestTimeoutMilliseconds *int64 `access:"environment_file_storage,write_restrictable,cloud_restrictable"` // telemetry: none
AmazonS3UploadPartSizeBytes *int64 `access:"environment_file_storage,write_restrictable,cloud_restrictable"` // telemetry: none
AmazonS3StorageClass *string `access:"environment_file_storage,write_restrictable,cloud_restrictable"` // telemetry: none
// Export store settings
DedicatedExportStore *bool `access:"environment_file_storage,write_restrictable"`
ExportDriverName *string `access:"environment_file_storage,write_restrictable"`
@@ -1666,6 +1681,7 @@ type FileSettings struct {
ExportAmazonS3RequestTimeoutMilliseconds *int64 `access:"environment_file_storage,write_restrictable"` // telemetry: none
ExportAmazonS3PresignExpiresSeconds *int64 `access:"environment_file_storage,write_restrictable"` // telemetry: none
ExportAmazonS3UploadPartSizeBytes *int64 `access:"environment_file_storage,write_restrictable"` // telemetry: none
ExportAmazonS3StorageClass *string `access:"environment_file_storage,write_restrictable"` // telemetry: none
}
func (s *FileSettings) SetDefaults(isUpdate bool) {
@@ -1778,6 +1794,10 @@ func (s *FileSettings) SetDefaults(isUpdate bool) {
s.AmazonS3UploadPartSizeBytes = NewPointer(int64(FileSettingsDefaultS3UploadPartSizeBytes))
}
if s.AmazonS3StorageClass == nil {
s.AmazonS3StorageClass = NewPointer("")
}
if s.DedicatedExportStore == nil {
s.DedicatedExportStore = NewPointer(false)
}
@@ -1843,6 +1863,10 @@ func (s *FileSettings) SetDefaults(isUpdate bool) {
if s.ExportAmazonS3UploadPartSizeBytes == nil {
s.ExportAmazonS3UploadPartSizeBytes = NewPointer(int64(FileSettingsDefaultS3ExportUploadPartSizeBytes))
}
if s.ExportAmazonS3StorageClass == nil {
s.ExportAmazonS3StorageClass = NewPointer("")
}
}
type EmailSettings struct {
@@ -3958,6 +3982,14 @@ func (s *FileSettings) isValid() *AppError {
return NewAppError("Config.IsValid", "model.config.is_valid.amazons3_timeout.app_error", map[string]any{"Value": *s.MaxImageDecoderConcurrency}, "", http.StatusBadRequest)
}
if *s.AmazonS3StorageClass != "" && !slices.Contains([]string{StorageClassStandard, StorageClassReducedRedundancy, StorageClassStandardIA, StorageClassOnezoneIA, StorageClassIntelligentTiering, StorageClassGlacier, StorageClassDeepArchive, StorageClassOutposts, StorageClassGlacierIR, StorageClassSnow, StorageClassExpressOnezone}, *s.AmazonS3StorageClass) {
return NewAppError("Config.IsValid", "model.config.is_valid.storage_class.app_error", map[string]any{"Value": *s.AmazonS3StorageClass}, "", http.StatusBadRequest)
}
if *s.ExportAmazonS3StorageClass != "" && !slices.Contains([]string{StorageClassStandard, StorageClassReducedRedundancy, StorageClassStandardIA, StorageClassOnezoneIA, StorageClassIntelligentTiering, StorageClassGlacier, StorageClassDeepArchive, StorageClassOutposts, StorageClassGlacierIR, StorageClassSnow, StorageClassExpressOnezone}, *s.ExportAmazonS3StorageClass) {
return NewAppError("Config.IsValid", "model.config.is_valid.storage_class.app_error", map[string]any{"Value": *s.ExportAmazonS3StorageClass}, "", http.StatusBadRequest)
}
return nil
}