diff --git a/modules/backend/src/main/scala/docspell/backend/Config.scala b/modules/backend/src/main/scala/docspell/backend/Config.scala index 03f0e23b..721f30d5 100644 --- a/modules/backend/src/main/scala/docspell/backend/Config.scala +++ b/modules/backend/src/main/scala/docspell/backend/Config.scala @@ -11,6 +11,7 @@ import cats.implicits._ import docspell.backend.signup.{Config => SignupConfig} import docspell.common._ +import docspell.common.syntax.string._ import docspell.store.file.FileRepositoryConfig import docspell.store.{JdbcConfig, SchemaMigrateConfig} @@ -51,6 +52,12 @@ object Config { stores.get(id).map(FileRepositoryConfig.fromFileStoreConfig(chunkSize, _)) def validate: ValidatedNec[String, Files] = { + def filterEmptyRegion = + copy(stores = stores.view.mapValues { + case c: FileStoreConfig.S3 => c.copy(region = c.region.flatMap(_.asNonBlank)) + case c => c + }.toMap) + val storesEmpty = if (enabledStores.isEmpty) Validated.invalidNec( @@ -65,7 +72,7 @@ object Config { Validated.invalidNec(s"Default file store not present: ${defaultStore.id}") } - (storesEmpty |+| defaultStorePresent).map(_ => this) + (storesEmpty |+| defaultStorePresent).map(_ => filterEmptyRegion) } } diff --git a/modules/common/src/main/scala/docspell/common/FileStoreConfig.scala b/modules/common/src/main/scala/docspell/common/FileStoreConfig.scala index cb9afa9d..a6393b2f 100644 --- a/modules/common/src/main/scala/docspell/common/FileStoreConfig.scala +++ b/modules/common/src/main/scala/docspell/common/FileStoreConfig.scala @@ -29,11 +29,12 @@ object FileStoreConfig { endpoint: String, accessKey: String, secretKey: String, + region: Option[String], bucket: String ) extends FileStoreConfig { val storeType = FileStoreType.S3 override def toString = - s"S3(enabled=$enabled, endpoint=$endpoint, bucket=$bucket, accessKey=$accessKey, secretKey=***)" + s"S3(enabled=$enabled, endpoint=$endpoint, bucket=$bucket, accessKey=$accessKey, secretKey=***, region=$region)" } } diff --git a/modules/joex/src/main/resources/reference.conf b/modules/joex/src/main/resources/reference.conf index 8efc2a9a..3f740c7d 100644 --- a/modules/joex/src/main/resources/reference.conf +++ b/modules/joex/src/main/resources/reference.conf @@ -739,6 +739,7 @@ Docpell Update Check access-key = "username" secret-key = "password" bucket = "docspell" + region = "" } } } diff --git a/modules/joex/src/main/scala/docspell/joex/ConfigFile.scala b/modules/joex/src/main/scala/docspell/joex/ConfigFile.scala index 059f28a7..202a7452 100644 --- a/modules/joex/src/main/scala/docspell/joex/ConfigFile.scala +++ b/modules/joex/src/main/scala/docspell/joex/ConfigFile.scala @@ -60,7 +60,7 @@ object ConfigFile { cfg => cfg.updateCheck.enabled && cfg.updateCheck.subject.els.isEmpty, "No subject given for enabled update check!" ), - Validation(cfg => cfg.files.validate.map(_ => cfg)), + Validation(cfg => cfg.files.validate.map(f => cfg.copy(files = f))), Validation.failWhen( cfg => cfg.fullTextSearch.enabled && diff --git a/modules/restserver/src/main/resources/reference.conf b/modules/restserver/src/main/resources/reference.conf index ecb51699..8d2a7539 100644 --- a/modules/restserver/src/main/resources/reference.conf +++ b/modules/restserver/src/main/resources/reference.conf @@ -493,6 +493,7 @@ docspell.server { access-key = "username" secret-key = "password" bucket = "docspell" + region = "" } } } diff --git a/modules/restserver/src/main/scala/docspell/restserver/ConfigFile.scala b/modules/restserver/src/main/scala/docspell/restserver/ConfigFile.scala index e7132fd6..154be914 100644 --- a/modules/restserver/src/main/scala/docspell/restserver/ConfigFile.scala +++ b/modules/restserver/src/main/scala/docspell/restserver/ConfigFile.scala @@ -113,7 +113,9 @@ object ConfigFile { } def filesValidate: Validation[Config] = - Validation(cfg => cfg.backend.files.validate.map(_ => cfg)) + Validation(cfg => + cfg.backend.files.validate.map(f => cfg.copy(backend = cfg.backend.copy(files = f))) + ) def postgresFtsValidate: Validation[Config] = Validation.failWhen( diff --git a/modules/store/src/main/scala/docspell/store/file/BinnyUtils.scala b/modules/store/src/main/scala/docspell/store/file/BinnyUtils.scala index 86e29ad1..30996882 100644 --- a/modules/store/src/main/scala/docspell/store/file/BinnyUtils.scala +++ b/modules/store/src/main/scala/docspell/store/file/BinnyUtils.scala @@ -108,11 +108,22 @@ object BinnyUtils { JdbcStoreConfig("filechunk", chunkSize, BinnyUtils.TikaContentTypeDetect) GenericJdbcStore[F](ds, LoggerAdapter(logger), jdbcConfig) - case FileRepositoryConfig.S3(endpoint, accessKey, secretKey, bucket, chunkSize) => + case FileRepositoryConfig.S3( + endpoint, + accessKey, + secretKey, + bucket, + region, + chunkSize + ) => val keyMapping = S3KeyMapping.constant(bucket) val minioCfg = MinioConfig .default(endpoint, accessKey, secretKey, keyMapping) - .copy(chunkSize = chunkSize, detect = BinnyUtils.TikaContentTypeDetect) + .copy( + chunkSize = chunkSize, + detect = BinnyUtils.TikaContentTypeDetect, + region = region + ) MinioBinaryStore[F](minioCfg, LoggerAdapter(logger)) diff --git a/modules/store/src/main/scala/docspell/store/file/FileRepositoryConfig.scala b/modules/store/src/main/scala/docspell/store/file/FileRepositoryConfig.scala index 41aec6da..5b78d747 100644 --- a/modules/store/src/main/scala/docspell/store/file/FileRepositoryConfig.scala +++ b/modules/store/src/main/scala/docspell/store/file/FileRepositoryConfig.scala @@ -10,7 +10,7 @@ import fs2.io.file.Path import docspell.common.FileStoreConfig -sealed trait FileRepositoryConfig {} +sealed trait FileRepositoryConfig object FileRepositoryConfig { @@ -21,6 +21,7 @@ object FileRepositoryConfig { accessKey: String, secretKey: String, bucketName: String, + region: Option[String], chunkSize: Int ) extends FileRepositoryConfig @@ -30,8 +31,15 @@ object FileRepositoryConfig { cfg match { case FileStoreConfig.DefaultDatabase(_) => FileRepositoryConfig.Database(chunkSize) - case FileStoreConfig.S3(_, endpoint, accessKey, secretKey, bucket) => - FileRepositoryConfig.S3(endpoint, accessKey, secretKey, bucket, chunkSize) + case FileStoreConfig.S3(_, endpoint, accessKey, secretKey, region, bucket) => + FileRepositoryConfig.S3( + endpoint, + accessKey, + secretKey, + bucket, + region.map(_.trim).filter(_.nonEmpty), + chunkSize + ) case FileStoreConfig.FileSystem(_, directory) => FileRepositoryConfig.Directory(directory, chunkSize) } diff --git a/website/site/content/docs/configure/file-backends.md b/website/site/content/docs/configure/file-backends.md index 64dd3e0a..ec937cd1 100644 --- a/website/site/content/docs/configure/file-backends.md +++ b/website/site/content/docs/configure/file-backends.md @@ -73,6 +73,7 @@ files { access-key = "username" secret-key = "password" bucket = "docspell" + # region = "…" } } } diff --git a/website/site/content/docs/tools/cli.md b/website/site/content/docs/tools/cli.md index c4a7194a..2029825a 100644 --- a/website/site/content/docs/tools/cli.md +++ b/website/site/content/docs/tools/cli.md @@ -54,8 +54,8 @@ For linuxes, the default location is `~/.config/dsc/config.toml`. You can give a config file explicitly via an option or the environment variable `DSC_CONFIG`. -If you use the [pass](https://passwordstore.org) password manager, you -can add your password entry to the config file as well. +If you use the [pass](https://www.passwordstore.org) password manager, +you can add your password entry to the config file as well. ## Output format