1
0
mirror of https://github.com/mail-in-a-box/mailinabox.git synced 2026-03-28 19:47:23 +01:00

switching between backup options in the admin wasn't working at all

* going from s3 to file target wasn't working
* use 'local' in the config instead of a file: url, for the local target, so it is not path-specific
* break out the S3 fields since users can't be expected to know how to form a URL
* use boto to generate a list of S3 hosts
* use boto to validate that the user input for s3 is valid
* fix lots of html errors in the backup admin
This commit is contained in:
Joshua Tauberer
2015-08-09 18:25:26 +00:00
parent c7f8ead496
commit 3b4b57c081
3 changed files with 101 additions and 25 deletions

View File

@@ -297,6 +297,42 @@ def run_duplicity_verification():
env["STORAGE_ROOT"],
], get_env(env))
def validate_target(config):
import urllib.parse
try:
p = urllib.parse.urlparse(config["target"])
except ValueError:
return "invalid target"
if p.scheme == "s3":
import boto.s3
from boto.exception import BotoServerError
# match to a Region
for region in boto.s3.regions():
if region.endpoint == p.hostname:
break
else:
raise ValueError("Invalid S3 region/host.")
bucket = p.path[1:].split('/')[0]
path = '/'.join(p.path[1:].split('/')[1:]) + '/'
if bucket == "":
raise ValueError("Enter an S3 bucket name.")
# connect to the region & bucket
try:
conn = region.connect(aws_access_key_id=config["target_user"], aws_secret_access_key=config["target_pass"])
bucket = conn.get_bucket(bucket)
except BotoServerError as e:
if e.status == 403:
raise ValueError("Invalid S3 access key or secret access key.")
elif e.status == 404:
raise ValueError("Invalid S3 bucket name.")
elif e.status == 301:
raise ValueError("Incorrect region for this bucket.")
raise ValueError(e.reason)
def backup_set_custom(env, target, target_user, target_pass, min_age):
config = get_backup_config(env, for_save=True)
@@ -309,6 +345,15 @@ def backup_set_custom(env, target, target_user, target_pass, min_age):
config["target_user"] = target_user
config["target_pass"] = target_pass
config["min_age_in_days"] = min_age
# Validate.
try:
if config["target"] != "local":
# "local" isn't supported by the following function, which expects a full url in the target key,
# which is what is there except when loading the config prior to saving
validate_target(config)
except ValueError as e:
return str(e)
write_backup_config(env, config)
@@ -320,7 +365,7 @@ def get_backup_config(env, for_save=False):
# Defaults.
config = {
"min_age_in_days": 3,
"target": "file://" + os.path.join(backup_root, 'encrypted'),
"target": "local",
}
# Merge in anything written to custom.yaml.
@@ -338,6 +383,9 @@ def get_backup_config(env, for_save=False):
# helper fields for the admin
config["file_target_directory"] = os.path.join(backup_root, 'encrypted')
config["enc_pw_file"] = os.path.join(backup_root, 'secret_key.txt')
if config["target"] == "local":
# Expand to the full URL.
config["target"] = "file://" + config["file_target_directory"]
return config