2022-06-23 02:20:56 +00:00
|
|
|
#!/usr/bin/python3
|
|
|
|
|
2022-10-25 14:43:20 +00:00
|
|
|
import argparse
|
2023-06-28 17:21:43 +00:00
|
|
|
from itertools import cycle
|
2022-06-23 02:20:56 +00:00
|
|
|
import json
|
2022-12-30 10:47:28 +00:00
|
|
|
import sys
|
2023-05-03 11:33:16 +00:00
|
|
|
import tempfile
|
2023-06-25 10:12:19 +00:00
|
|
|
import time
|
2022-06-23 02:20:56 +00:00
|
|
|
from concurrent.futures import ProcessPoolExecutor
|
2022-11-17 17:08:20 +00:00
|
|
|
|
|
|
|
from helpers.cmd import random_payload
|
|
|
|
from helpers.aws_cli import create_bucket, upload_object
|
2022-06-23 02:20:56 +00:00
|
|
|
|
2024-07-02 17:45:31 +00:00
|
|
|
ERROR_WRONG_CONTAINERS_COUNT = 1
|
|
|
|
ERROR_WRONG_OBJECTS_COUNT = 2
|
|
|
|
MAX_WORKERS = 50
|
|
|
|
DEFAULT_LOCATION = ""
|
|
|
|
|
2022-10-25 14:43:20 +00:00
|
|
|
parser = argparse.ArgumentParser()
|
2022-06-23 02:20:56 +00:00
|
|
|
|
|
|
|
parser.add_argument('--size', help='Upload objects size in kb.')
|
|
|
|
parser.add_argument('--buckets', help='Number of buckets to create.')
|
|
|
|
parser.add_argument('--out', help='JSON file with output.')
|
|
|
|
parser.add_argument('--preload_obj', help='Number of pre-loaded objects.')
|
2023-06-28 17:21:43 +00:00
|
|
|
parser.add_argument('--endpoint', help='S3 Gateways addresses separated by comma.')
|
2022-11-17 17:08:20 +00:00
|
|
|
parser.add_argument('--update', help='True/False, False by default. Save existed buckets from target file (--out). '
|
|
|
|
'New buckets will not be created.')
|
2024-07-02 17:45:31 +00:00
|
|
|
parser.add_argument('--location', help=f'AWS location constraint. Default is "{DEFAULT_LOCATION}"', action="append")
|
2022-06-23 02:20:56 +00:00
|
|
|
parser.add_argument('--versioning', help='True/False, False by default.')
|
2023-07-13 12:50:03 +00:00
|
|
|
parser.add_argument('--ignore-errors', help='Ignore preset errors', action='store_true')
|
|
|
|
parser.add_argument('--no-verify-ssl', help='Ignore SSL verifications', action='store_true')
|
2022-12-30 10:47:28 +00:00
|
|
|
parser.add_argument('--workers', help='Count of workers in preset. Max = 50, Default = 50', default=50)
|
2023-08-08 15:57:06 +00:00
|
|
|
parser.add_argument('--sleep', help='Time to sleep between buckets creation and objects upload (in seconds), '
|
2023-06-25 10:12:19 +00:00
|
|
|
'Default = 8', default=8)
|
2024-02-05 15:56:36 +00:00
|
|
|
parser.add_argument('--acl', help='Bucket ACL. Default is private. Expected values are: private, public-read or public-read-write.', default="private")
|
2022-06-23 02:20:56 +00:00
|
|
|
|
2022-10-25 14:43:20 +00:00
|
|
|
args = parser.parse_args()
|
2022-06-23 02:20:56 +00:00
|
|
|
print(args)
|
|
|
|
|
|
|
|
def main():
|
2023-06-28 17:21:43 +00:00
|
|
|
buckets = []
|
2022-12-30 10:47:28 +00:00
|
|
|
objects_list = []
|
2023-07-13 12:50:03 +00:00
|
|
|
ignore_errors = args.ignore_errors
|
|
|
|
no_verify_ssl = args.no_verify_ssl
|
2022-06-23 02:20:56 +00:00
|
|
|
|
2023-06-28 17:21:43 +00:00
|
|
|
endpoints = args.endpoint.split(',')
|
2024-07-02 17:45:31 +00:00
|
|
|
if not args.location:
|
|
|
|
args.location = [DEFAULT_LOCATION]
|
2023-06-28 17:21:43 +00:00
|
|
|
|
2022-12-30 10:47:28 +00:00
|
|
|
workers = int(args.workers)
|
2023-05-23 16:04:38 +00:00
|
|
|
objects_per_bucket = int(args.preload_obj)
|
|
|
|
|
2022-06-23 02:20:56 +00:00
|
|
|
if args.update:
|
|
|
|
# Open file
|
|
|
|
with open(args.out) as f:
|
|
|
|
data_json = json.load(f)
|
2023-06-28 17:21:43 +00:00
|
|
|
buckets = data_json['buckets']
|
|
|
|
buckets_count = len(buckets)
|
2022-06-23 02:20:56 +00:00
|
|
|
# Get CID list
|
|
|
|
else:
|
2023-05-23 16:04:38 +00:00
|
|
|
buckets_count = int(args.buckets)
|
|
|
|
print(f"Create buckets: {buckets_count}")
|
2022-10-25 14:43:20 +00:00
|
|
|
|
2022-12-30 10:47:28 +00:00
|
|
|
with ProcessPoolExecutor(max_workers=min(MAX_WORKERS, workers)) as executor:
|
2024-07-02 17:45:31 +00:00
|
|
|
buckets_runs = [executor.submit(create_bucket, endpoint, args.versioning, location, args.acl, no_verify_ssl)
|
|
|
|
for _, endpoint, location in
|
|
|
|
zip(range(buckets_count), cycle(endpoints), cycle(args.location))]
|
2022-06-23 02:20:56 +00:00
|
|
|
|
|
|
|
for run in buckets_runs:
|
2023-06-28 17:21:43 +00:00
|
|
|
bucket_name = run.result()
|
|
|
|
if bucket_name:
|
|
|
|
buckets.append(bucket_name)
|
2022-06-23 02:20:56 +00:00
|
|
|
|
|
|
|
print("Create buckets: Completed")
|
|
|
|
|
2023-06-28 17:21:43 +00:00
|
|
|
print(f" > Buckets: {buckets}")
|
2024-04-01 13:10:04 +00:00
|
|
|
if buckets_count > 0 and len(buckets) != buckets_count:
|
2023-06-28 17:21:43 +00:00
|
|
|
print(f"Buckets mismatch in preset: expected {buckets_count}, created {len(buckets)}")
|
2022-12-30 10:47:28 +00:00
|
|
|
if not ignore_errors:
|
2023-05-23 16:04:38 +00:00
|
|
|
sys.exit(ERROR_WRONG_CONTAINERS_COUNT)
|
2022-06-23 02:20:56 +00:00
|
|
|
|
2023-06-25 10:12:19 +00:00
|
|
|
if args.sleep != 0:
|
|
|
|
print(f"Sleep for {args.sleep} seconds")
|
|
|
|
time.sleep(args.sleep)
|
|
|
|
|
2023-05-23 16:04:38 +00:00
|
|
|
print(f"Upload objects to each bucket: {objects_per_bucket} ")
|
2023-05-03 11:33:16 +00:00
|
|
|
payload_file = tempfile.NamedTemporaryFile()
|
|
|
|
random_payload(payload_file, args.size)
|
2022-06-23 02:20:56 +00:00
|
|
|
print(" > Create random payload: Completed")
|
|
|
|
|
2023-06-28 17:21:43 +00:00
|
|
|
total_objects = objects_per_bucket * buckets_count
|
2022-06-23 02:20:56 +00:00
|
|
|
|
2023-06-28 17:21:43 +00:00
|
|
|
with ProcessPoolExecutor(max_workers=min(MAX_WORKERS, workers)) as executor:
|
2023-07-13 12:50:03 +00:00
|
|
|
objects_runs = [executor.submit(upload_object, bucket, payload_file.name, endpoint, no_verify_ssl)
|
2023-06-28 17:21:43 +00:00
|
|
|
for _, bucket, endpoint in
|
|
|
|
zip(range(total_objects), cycle(buckets), cycle(endpoints))]
|
|
|
|
|
|
|
|
for run in objects_runs:
|
|
|
|
result = run.result()
|
2023-07-19 11:55:44 +00:00
|
|
|
if result:
|
2023-06-28 17:21:43 +00:00
|
|
|
bucket = result[0]
|
|
|
|
endpoint = result[1]
|
|
|
|
object_id = result[2]
|
|
|
|
objects_list.append({'bucket': bucket, 'object': object_id})
|
|
|
|
print(f" > Uploaded object {object_id} for bucket {bucket} via endpoint {endpoint}.")
|
2022-06-23 02:20:56 +00:00
|
|
|
|
2023-05-23 16:04:38 +00:00
|
|
|
if total_objects > 0 and len(objects_list) != total_objects:
|
|
|
|
print(f"Objects mismatch in preset: expected {total_objects}, created {len(objects_list)}")
|
2022-12-30 10:47:28 +00:00
|
|
|
if not ignore_errors:
|
2023-05-23 16:04:38 +00:00
|
|
|
sys.exit(ERROR_WRONG_OBJECTS_COUNT)
|
2022-12-30 10:47:28 +00:00
|
|
|
|
2023-06-28 17:21:43 +00:00
|
|
|
data = {'buckets': buckets, 'objects': objects_list, 'obj_size': args.size + " Kb"}
|
2022-06-23 02:20:56 +00:00
|
|
|
|
2022-10-25 15:01:08 +00:00
|
|
|
with open(args.out, 'w+') as f:
|
2022-10-25 15:06:43 +00:00
|
|
|
json.dump(data, f, ensure_ascii=False, indent=2)
|
2022-06-23 02:20:56 +00:00
|
|
|
|
2022-12-30 10:47:28 +00:00
|
|
|
print("Result:")
|
2023-06-28 17:21:43 +00:00
|
|
|
print(f" > Total Buckets has been created: {len(buckets)}.")
|
2022-12-30 10:47:28 +00:00
|
|
|
print(f" > Total Objects has been created: {len(objects_list)}.")
|
2022-06-23 02:20:56 +00:00
|
|
|
|
|
|
|
|
|
|
|
if __name__ == "__main__":
|
|
|
|
main()
|