80 lines
2.9 KiB
Kotlin
80 lines
2.9 KiB
Kotlin
import aws.sdk.kotlin.services.s3.S3Client
|
|
import backup.BackupClient
|
|
import com.github.ajalt.clikt.core.CliktCommand
|
|
import com.github.ajalt.clikt.core.subcommands
|
|
import com.github.ajalt.clikt.parameters.arguments.argument
|
|
import com.github.ajalt.clikt.parameters.arguments.help
|
|
import com.github.ajalt.clikt.parameters.types.file
|
|
import kotlinx.coroutines.runBlocking
|
|
import kotlin.system.exitProcess
|
|
|
|
fun main(args: Array<String>) =
|
|
runBlocking {
|
|
S3Client.fromEnvironment().use { s3 ->
|
|
S3BackupTool()
|
|
.subcommands(
|
|
Create(s3),
|
|
Restore(s3),
|
|
RestoreFile(s3),
|
|
)
|
|
.main(args)
|
|
}
|
|
}
|
|
|
|
class S3BackupTool : CliktCommand(
|
|
help = "A simple AWS S3 backup tool. This tool assumes credentials are properly configured using aws-cli.",
|
|
) {
|
|
override fun run() {
|
|
shortHelp(currentContext)
|
|
}
|
|
}
|
|
|
|
class Create(val s3: S3Client) : CliktCommand(
|
|
help = "Create a backup of a file or directory.",
|
|
) {
|
|
val source by argument().file(mustExist = true).help("File or directory to backup")
|
|
val bucket by argument().help("Name of S3 bucket to backup to")
|
|
|
|
override fun run() =
|
|
runBlocking {
|
|
val backupKey = BackupClient(s3, bucket).upload(source)
|
|
echo("Successfully created backup with key '$backupKey'")
|
|
}
|
|
}
|
|
|
|
class Restore(val s3: S3Client) : CliktCommand(
|
|
help = "Restore a backup from AWS S3.",
|
|
) {
|
|
val bucket by argument().help("Name of S3 bucket to restore the backup from")
|
|
val backupKey by argument().help("The S3 key of the backup to restore")
|
|
val destination by argument().file(mustExist = true).help("Directory to restore to")
|
|
|
|
override fun run() =
|
|
runBlocking {
|
|
if (!destination.isDirectory) {
|
|
echo("Destination must be an existing directory", err = true)
|
|
exitProcess(1)
|
|
}
|
|
BackupClient(s3, bucket).restore(destination.toPath(), backupKey)
|
|
echo("Successfully restored backup '$backupKey' to '$destination'")
|
|
}
|
|
}
|
|
|
|
class RestoreFile(val s3: S3Client) : CliktCommand(
|
|
help = "Restore a single file from a backup from AWS S3.",
|
|
) {
|
|
val bucket by argument().help("Name of S3 bucket to restore the backup from")
|
|
val backupKey by argument().help("The S3 key of the backup to restore")
|
|
val filePath by argument().help("File path within the backup")
|
|
val destination by argument().file(mustExist = true).help("Directory to restore to")
|
|
|
|
override fun run() =
|
|
runBlocking {
|
|
if (!destination.isDirectory) {
|
|
echo("Destination must be an existing directory", err = true)
|
|
exitProcess(1)
|
|
}
|
|
BackupClient(s3, bucket).restoreFile(destination.toPath(), backupKey, filePath)
|
|
echo("Successfully restored '$filePath' from backup '$backupKey' to '$destination'")
|
|
}
|
|
} |