Repository URL to install this package:
Version:
6.0.19 ▾
|
python3-tvault-contego
/
usr
/
lib
/
python3
/
dist-packages
/
contego
/
nova
/
extension
/
driver
/
vaultswift.py
|
---|
# vim: tabstop=4 shiftwidth=4 softtabstop=4
# Copyright (c) 2014 TrilioData, Inc.
# All Rights Reserved.
import logging
import signal
import socket
from optparse import OptionParser, OptionGroup, SUPPRESS_HELP
from os import environ, walk, _exit as os_exit
from os.path import isfile, isdir, join
from six import text_type
from sys import argv as sys_argv, exit, stderr
from time import gmtime, strftime
from swiftclient import RequestException
from swiftclient.utils import config_true_value, generate_temp_url, prt_bytes
from swiftclient.multithreading import OutputManager
from swiftclient.exceptions import ClientException
from swiftclient import __version__ as client_version
from swiftclient.service import (
SwiftService,
SwiftError,
SwiftUploadObject,
get_conn,
)
from swiftclient.command_helpers import (
print_account_stats,
print_container_stats,
print_object_stats,
)
try:
from shlex import quote as sh_quote
except ImportError:
from pipes import quote as sh_quote
BASENAME = "swift"
commands = (
"delete",
"download",
"list",
"post",
"stat",
"upload",
"capabilities",
"info",
"tempurl",
"auth",
)
"""
{'verbose': 1, 'os_username': 'demo', 'os_user_domain_name': None, 'os_cacert': None, 'os_tenant_name': 'demo', 'os_user_domain_id': None, 'prefix': None, 'auth_version': u'2.0', 'ssl_compression': True, 'os_password': 'project1', 'os_user_id': None, 'os_project_id': None, 'long': False, 'totals': False, 'snet': False, 'os_tenant_id': None, 'os_project_name': None, 'os_service_type': None, 'insecure': False, 'os_help': None, 'os_project_domain_id': None, 'os_storage_url': None, 'human': False, 'auth': 'http://192.168.1.138:5000/v2.0', 'os_auth_url': 'http://192.168.1.138:5000/v2.0', 'user': 'demo', 'key': 'project1', 'os_region_name': 'RegionOne', 'info': False, 'retries': 5, 'os_auth_token': None, 'delimiter': None, 'os_options': {u'project_name': None, u'region_name': 'RegionOne', u'tenant_name': 'demo', u'user_domain_name': None, u'endpoint_type': None, u'object_storage_url': None, u'project_domain_id': None, u'user_id': None, u'user_domain_id': None, u'tenant_id': None, u'service_type': None, u'project_id': None, u'auth_token': None, u'project_domain_name': None}, 'debug': False, 'os_project_domain_name': None, 'os_endpoint_type': None}
"""
swift_list = None
swift_stat = None
swift_upload = None
swift_download = None
swift_delete = None
swift_post = None
swift_cap = None
def immediate_exit(signum, frame):
stderr.write(" Aborted\n")
os_exit(2)
def st_delete(args, options):
_opts = dict(options)
global swift_delete
if swift_delete is None:
swift_delete = SwiftService(options=_opts)
try:
if not args:
del_iter = swift_delete.delete(options=_opts)
else:
container = args[0]
if "/" in container:
raise Exception(
"WARNING: / in container name; you "
"might have meant '%s' instead of '%s'."
% (container.replace("/", " ", 1), container)
)
return
objects = args[1:]
if objects:
del_iter = swift_delete.delete(
container=container, objects=objects, options=_opts
)
else:
del_iter = swift_delete.delete(container=container, options=_opts)
for r in del_iter:
c = r.get("container", "")
o = r.get("object", "")
a = r.get("attempts")
if r["success"]:
if options.verbose:
a = " [after {0} attempts]".format(a) if a > 1 else ""
if r["action"] == "delete_object":
if options.yes_all:
p = "{0}/{1}".format(c, o)
else:
p = o
elif r["action"] == "delete_segment":
p = "{0}/{1}".format(c, o)
elif r["action"] == "delete_container":
p = c
print("{0}{1}".format(p, a))
else:
p = "{0}/{1}".format(c, o) if o else c
raise Exception("Error Deleting: {0}: {1}".format(p, r["error"]))
except SwiftError as err:
raise Exception(err.value)
def st_download(args, options):
global swift_download
if options.out_file == "-":
options.verbose = 0
if options.out_file and len(args) != 2:
raise Exception("-o option only allowed for single file downloads")
if not options.prefix:
options.remove_prefix = False
if options.out_directory and len(args) == 2:
raise Exception("Please use -o option for single file downloads and renames")
if (not args and not options.yes_all) or (args and options.yes_all):
raise Exception(
"Usage: %s download %s\n%s",
BASENAME,
st_download_options,
st_download_help,
)
return
_opts = dict(options).copy()
if swift_download is None:
swift_download = SwiftService(options=_opts)
try:
if not args:
down_iter = swift_download.download(options=_opts)
else:
container = args[0]
if "/" in container:
raise Exception(
"WARNING: / in container name; you "
"might have meant '%s' instead of '%s'."
% (container.replace("/", " ", 1), container)
)
return
objects = args[1:]
if not objects:
down_iter = swift_download.download(container, options=_opts)
else:
down_iter = swift_download.download(container, objects, options=_opts)
for down in down_iter:
if options.out_file == "-" and "contents" in down:
contents = down["contents"]
for chunk in contents:
print(chunk)
else:
if down["success"]:
if options.verbose:
start_time = down["start_time"]
headers_receipt = down["headers_receipt"] - start_time
auth_time = down["auth_end_time"] - start_time
finish_time = down["finish_time"]
read_length = down["read_length"]
attempts = down["attempts"]
total_time = finish_time - start_time
down_time = total_time - auth_time
_mega = 1000000
if down["pseudodir"]:
time_str = (
"auth %.3fs, headers %.3fs, total %.3fs, "
"pseudo" % (auth_time, headers_receipt, total_time)
)
else:
speed = float(read_length) / down_time / _mega
time_str = (
"auth %.3fs, headers %.3fs, total %.3fs, "
"%.3f MB/s"
% (auth_time, headers_receipt, total_time, speed,)
)
path = down["path"]
if attempts > 1:
print(
"%s [%s after %d attempts]" % (path, time_str, attempts)
)
else:
print("%s [%s]" % (path, time_str))
else:
error = down["error"]
path = down["path"]
container = down["container"]
obj = down["object"]
if isinstance(error, ClientException):
if error.http_status == 304 and options.skip_identical:
print("Skipped identical file '%s'" % path)
continue
if error.http_status == 404:
raise Exception("Object '%s/%s' not found", container, obj)
raise Exception(
"Error downloading object '%s/%s': %s", container, obj, error,
)
except SwiftError as e:
raise
except Exception as e:
raise
def st_list(args, options):
global swift_list
global swift_cap
def _print_stats(options, stats):
total_count = total_bytes = 0
container = stats.get("container", None)
for item in stats["listing"]:
item_name = item.get("name")
if not options.long and not options.human:
print(item.get("name", item.get("subdir")))
else:
if not container: # listing containers
item_bytes = item.get("bytes")
byte_str = prt_bytes(item_bytes, options.human)
count = item.get("count")
total_count += count
try:
meta = item.get("meta")
utc = gmtime(float(meta.get("x-timestamp")))
datestamp = strftime("%Y-%m-%d %H:%M:%S", utc)
except TypeError:
datestamp = "????-??-?? ??:??:??"
if not options.totals:
print("%5s %s %s %s" % (count, byte_str, datestamp, item_name))
else: # list container contents
subdir = item.get("subdir")
content_type = item.get("content_type")
if subdir is None:
item_bytes = item.get("bytes")
byte_str = prt_bytes(item_bytes, options.human)
date, xtime = item.get("last_modified").split("T")
xtime = xtime.split(".")[0]
else:
item_bytes = 0
byte_str = prt_bytes(item_bytes, options.human)
date = xtime = ""
item_name = subdir
if not options.totals:
print(
"%s %10s %8s %24s %s"
% (byte_str, date, xtime, content_type, item_name)
)
total_bytes += item_bytes
# report totals
if options.long or options.human:
if not container:
print(
"%5s %s"
% (
prt_bytes(total_count, True),
prt_bytes(total_bytes, options.human),
)
)
else:
print(prt_bytes(total_bytes, options.human))
if options.delimiter and not args:
raise Exception("-d option only allowed for container listings")
_opts = dict(options).copy()
if _opts["human"]:
_opts.pop("human")
_opts["long"] = True
if options.totals and not options.long and not options.human:
raise Exception("Listing totals only works with -l or --lh.")
return
if swift_cap is None:
swift_cap = SwiftService(options=_opts)
try:
capabilities_result = swift_cap.capabilities()
capabilities = capabilities_result["capabilities"]
account_listing_limit = capabilities["swift"]["account_listing_limit"]
except SwiftError as e:
raise
# Use a 'marker' to iterate over containers that have
# more objects than the listing limit and store the
# found objects in a set so that there are no duplicates.
_opts["marker"] = ""
container = None
item_set = set()
if swift_list is None:
swift_list = SwiftService(options=_opts)
try:
if args:
container = args[0]
args = args[1:]
if "/" in container or args:
raise Exception("Usage error")
return
while True:
stats_parts_gen = swift_list.list(container=container, options=_opts)
gen_empty = True
for stats in stats_parts_gen:
if stats["success"]:
gen_empty = False
for item in stats["listing"]:
item_set.add(item.get("name"))
if len(stats["listing"]) < account_listing_limit:
return list(item_set)
else:
# If more than the listing_limit items were returned,
# we need to set the 'marker' to the last one before
# calling again.
_opts["marker"] = item.get("name")
continue
else:
raise stats["error"]
if gen_empty:
return list(item_set)
return []
except SwiftError as e:
raise
def st_stat(args, options):
global swift_stat
_opts = dict(options).copy()
if swift_stat is None:
swift_stat = SwiftService(options=_opts)
try:
if not args:
stat_result = swift_stat.stat(options=_opts)
if not stat_result["success"]:
raise stat_result["error"]
return stat_result
else:
container = args[0]
if "/" in container:
raise Exception(
"WARNING: / in container name; you might have "
"meant '%s' instead of '%s'."
% (container.replace("/", " ", 1), container)
)
return
args = args[1:]
if not args:
stat_result = swift_stat.stat(container=container, options=_opts)
if not stat_result["success"]:
raise stat_result["error"]
return stat_result
else:
if len(args) == 1:
objects = [args[0]]
stat_results = swift_stat.stat(
container=container, objects=objects, options=_opts
)
for stat_result in stat_results: # only 1 result
if stat_result["success"]:
return stat_result
else:
raise stat_result
else:
raise Exception(
"Usage: %s stat %s\n%s",
BASENAME,
st_stat_options,
st_stat_help,
)
except SwiftError as e:
raise
def st_post(args, options):
global swift_post
if (
options.read_acl or options.write_acl or options.sync_to or options.sync_key
) and not args:
raise Exception("-r, -w, -t, and -k options only allowed for containers")
_opts = dict(options).copy()
if swift_post is None:
swift_post = SwiftService(options=_opts)
try:
if not args:
result = swift_post.post(options=_opts)
else:
container = args[0]
if "/" in container:
raise Exception(
"WARNING: / in container name; you might have "
"meant '%s' instead of '%s'."
% (args[0].replace("/", " ", 1), args[0])
)
return
args = args[1:]
if args:
if len(args) == 1:
objects = [args[0]]
results_iterator = swift_post.post(
container=container, objects=objects, options=_opts
)
result = next(results_iterator)
else:
raise Exception(
"Usage: %s post %s\n%s",
BASENAME,
st_post_options,
st_post_help,
)
return
else:
result = swift_post.post(container=container, options=_opts)
if not result["success"]:
raise result
except SwiftError as e:
raise
def st_upload(args, options):
global swift_upload
container = args[0]
files = args[1:]
if options.object_name is not None:
if len(files) > 1:
raise Exception("object-name only be used with 1 file or dir")
return
else:
orig_path = files[0]
if options.segment_size:
try:
# If segment size only has digits assume it is bytes
int(options.segment_size)
except ValueError:
try:
size_mod = "BKMG".index(options.segment_size[-1].upper())
multiplier = int(options.segment_size[:-1])
except ValueError:
raise Exception("Invalid segment size")
return
options.segment_size = str((1024 ** size_mod) * multiplier)
if int(options.segment_size) <= 0:
raise Exception("segment-size should be positive")
return
_opts = dict(options).copy()
if swift_upload is None:
swift_upload = SwiftService(options=_opts)
try:
objs = []
dir_markers = []
for f in files:
if isfile(f):
objs.append(f)
elif isdir(f):
for (_dir, _ds, _fs) in walk(f):
if not (_ds + _fs):
dir_markers.append(_dir)
else:
objs.extend([join(_dir, _f) for _f in _fs])
else:
raise Exception("Local file '%s' not found" % f)
# Now that we've collected all the required files and dir markers
# build the tuples for the call to upload
if options.object_name is not None:
objs = [
SwiftUploadObject(
o, object_name=o.replace(orig_path, options.object_name, 1)
)
for o in objs
]
dir_markers = [
SwiftUploadObject(
None,
object_name=d.replace(orig_path, options.object_name, 1),
options={"dir_marker": True},
)
for d in dir_markers
]
for r in swift_upload.upload(container, objs + dir_markers, options=_opts):
if r["success"]:
if options.verbose:
if "attempts" in r and r["attempts"] > 1:
if "object" in r:
print(
"%s [after %d attempts]" % (r["object"], r["attempts"])
)
else:
if "object" in r:
print(r["object"])
elif "for_object" in r:
print(
"%s segment %s"
% (r["for_object"], r["segment_index"])
)
else:
error = r["error"]
if "action" in r and r["action"] == "create_container":
# it is not an error to be unable to create the
# container so print a warning and carry on
if isinstance(error, ClientException):
if r["headers"] and "X-Storage-Policy" in r["headers"]:
msg = (
" with Storage Policy %s"
% r["headers"]["X-Storage-Policy"].strip()
)
else:
msg = " ".join(
str(x)
for x in (error.http_status, error.http_reason,)
)
if error.http_response_content:
if msg:
msg += ": "
msg += error.http_response_content[:60]
msg = ": %s" % msg
else:
msg = ": %s" % error
raise Exception(
"Warning: failed to create container " "'%s'%s",
container,
msg,
)
else:
too_large = (
isinstance(error, ClientException)
and error.http_status == 413
)
if too_large and options.verbose > 0:
raise Exception(
"Consider using the --segment-size option "
"to chunk the object"
)
raise Exception("%s" % error)
except SwiftError as e:
raise
def st_capabilities(args, options):
global swift_cap
def _print_compo_cap(name, capabilities):
for feature, options in sorted(list(capabilities.items()), key=lambda x: x[0]):
print("%s: %s" % (name, feature))
if options:
print(" Options:")
for key, value in sorted(list(options.items()), key=lambda x: x[0]):
print(" %s: %s" % (key, value))
if args and len(args) > 2:
raise Exception(
"Usage: %s capabilities %s\n%s",
BASENAME,
st_capabilities_options,
st_capabilities_help,
)
return
_opts = dict(options).copy()
if swift_cap is None:
swift_cap = SwiftService(options=_opts)
try:
if len(args) == 2:
url = args[1]
capabilities_result = swift_cap.capabilities(url)
capabilities = capabilities_result["capabilities"]
else:
capabilities_result = swift_cap.capabilities()
capabilities = capabilities_result["capabilities"]
_print_compo_cap("Core", {"swift": capabilities["swift"]})
del capabilities["swift"]
_print_compo_cap("Additional middleware", capabilities)
except SwiftError as e:
raise
def st_auth(args, options):
_opts = vars(options)
if options.verbose > 1:
if options.auth_version in ("1", "1.0"):
print("export ST_AUTH=%s" % sh_quote(options.auth))
print("export ST_USER=%s" % sh_quote(options.user))
print("export ST_KEY=%s" % sh_quote(options.key))
else:
print("export OS_IDENTITY_API_VERSION=%s" % sh_quote(options.auth_version))
print("export OS_AUTH_VERSION=%s" % sh_quote(options.auth_version))
print("export OS_AUTH_URL=%s" % sh_quote(options.auth))
for k, v in sorted(_opts.items()):
if v and k.startswith("os_") and k not in ("os_auth_url", "os_options"):
print("export %s=%s" % (k.upper(), sh_quote(v)))
else:
conn = get_conn(_opts)
url, token = conn.get_auth()
print("export OS_STORAGE_URL=%s" % sh_quote(url))
print("export OS_AUTH_TOKEN=%s" % sh_quote(token))
def st_tempurl(args, options):
args = args[1:]
if len(args) < 4:
raise Exception(
"Usage: %s tempurl %s\n%s", BASENAME, st_tempurl_options, st_tempurl_help,
)
return
method, seconds, path, key = args[:4]
try:
seconds = int(seconds)
except ValueError:
raise Exception("Seconds must be an integer")
return
if method.upper() not in ["GET", "PUT", "HEAD", "POST", "DELETE"]:
print(
"WARNING: Non default HTTP method %s for "
"tempurl specified, possibly an error" % method.upper()
)
url = generate_temp_url(
path, seconds, key, method, absolute=options.absolute_expiry
)
print(url)