Skip to content

Commit

Permalink
adding polling to V3 backups/snapshots, adding length param to RFC112…
Browse files Browse the repository at this point in the history
…3 checker

Signed-off-by: Michael Haigh <mhaigh@netapp.com>
  • Loading branch information
MichaelHaigh committed Apr 18, 2024
1 parent 5348330 commit e024d76
Show file tree
Hide file tree
Showing 3 changed files with 84 additions and 36 deletions.
52 changes: 48 additions & 4 deletions tkSrc/create.py
Expand Up @@ -75,6 +75,42 @@ def monitorProtectionTask(protectionID, protectionType, appID, background, pollT
return False


def monitorV3ProtectionTask(protection, pollTimer, parser, v3, skip_tls_verify):
name = protection["metadata"]["name"]
singular = protection["kind"].lower()
resource_class = astraSDK.k8s.getResources(config_context=v3, skip_tls_verify=skip_tls_verify)
print(f"Waiting for {singular} to complete.", end="")
sys.stdout.flush()
err_counter = []
while len(err_counter) < 3:
try:
resources = resource_class.main(
f"{singular}s", filters=[{"keyFilter": "metadata.name", "valFilter": name}]
)
if not resources:
raise Exception("astraSDK.k8s.getResources().main() failed")
elif not resources["items"]:
raise Exception(f"{singular} {name} not found")
elif len(resources["items"]) > 1:
raise Exception(f"Multiple {singular}s found with name {name}")
resource = resources["items"][0]
if resource["status"]["state"] == "Completed":
print("complete!")
sys.stdout.flush()
return resource
elif resource["status"]["state"] == "Failed" or resource["status"]["state"] == "Error":
print(f"{singular} failed")
return False
time.sleep(pollTimer)
print(".", end="")
sys.stdout.flush()
except Exception as err:
err_counter.append(err)
for err in set([str(e) for e in err_counter]):
resource_class.printError(err + "\n")
return False


def createV3ConnectorOperator(v3, dry_run, skip_tls_verify, verbose, operator_version):
"""Creates the Arch 3.0 Astra Connector Operator"""
context, config_file = tuple(v3.split("@"))
Expand Down Expand Up @@ -305,7 +341,7 @@ def createV3Protection(
template = helpers.setupJinja("protection")
v3_dict = yaml.safe_load(
template.render(
name=helpers.isRFC1123(f"{app}-{granularity}") + "-",
name=helpers.isRFC1123(f"{app}-{granularity}", ignore_length=True) + "-",
appName=app,
appVaultName=bucket,
backupRetention=backupRetention,
Expand Down Expand Up @@ -392,7 +428,7 @@ def main(args, parser, ard):
args.bucket = ard.getSingleDict("buckets", "status.state", "available", parser)[
"metadata"
]["name"]
createV3Backup(
backup = createV3Backup(
args.v3,
args.dry_run,
args.skip_tls_verify,
Expand All @@ -404,6 +440,10 @@ def main(args, parser, ard):
args.snapshot,
args.reclaimPolicy,
)
if not args.dry_run and not args.background:
monitorV3ProtectionTask(
backup, args.pollTimer, parser, args.v3, args.skip_tls_verify
)
else:
protectionID = astraSDK.backups.takeBackup(quiet=args.quiet, verbose=args.verbose).main(
args.app,
Expand Down Expand Up @@ -656,19 +696,23 @@ def main(args, parser, ard):
args.bucket = ard.getSingleDict("buckets", "status.state", "available", parser)[
"metadata"
]["name"]
createV3Snapshot(
snapshot = createV3Snapshot(
args.v3,
args.dry_run,
args.skip_tls_verify,
args.quiet,
args.verbose,
args.name,
args.ame,
args.app,
args.bucket,
reclaimPolicy=args.reclaimPolicy,
createdTimeout=args.createdTimeout,
readyToUseTimeout=args.readyToUseTimeout,
)
if not args.dry_run and not args.background:
monitorV3ProtectionTask(
snapshot, args.pollTimer, parser, args.v3, args.skip_tls_verify
)
else:
protectionID = astraSDK.snapshots.takeSnap(quiet=args.quiet, verbose=args.verbose).main(
args.app,
Expand Down
4 changes: 2 additions & 2 deletions tkSrc/helpers.py
Expand Up @@ -310,11 +310,11 @@ def run(command, captureOutput=False, ignoreErrors=False, env=None):
return True


def isRFC1123(string, parser=None):
def isRFC1123(string, parser=None, ignore_length=False):
"""isRFC1123 returns the input 'string' if it conforms to RFC 1123 spec,
otherwise it throws an error and exits"""
regex = re.compile("[a-z0-9]([-a-z0-9]*[a-z0-9])?$")
if regex.match(string) is not None and len(string) < 64:
if regex.match(string) is not None and (len(string) < 64 or ignore_length):
return string
else:
error = (
Expand Down
64 changes: 34 additions & 30 deletions tkSrc/parser.py
Expand Up @@ -1145,21 +1145,23 @@ def create_backup_args(self):
choices=["Delete", "Retain"],
help="Define how to handle the snapshot data when the snapshot CR is deleted",
)
else:
self.subparserCreateBackup.add_argument(
"-b",
"--background",
default=False,
action="store_true",
help="Run backup operation in the background",
)
self.subparserCreateBackup.add_argument(
"-t",
"--pollTimer",
type=int,
default=5,
help="The frequency (seconds) to poll the operation status (default: %(default)s)",
)
pollingGroup = self.subparserCreateBackup.add_argument_group(
title="polling group", description="optionally modify default polling mechanism"
)
pollingGroup.add_argument(
"-b",
"--background",
default=False,
action="store_true",
help="Run backup operation in the background rather than polling for status",
)
pollingGroup.add_argument(
"-t",
"--pollTimer",
type=int,
default=5,
help="The frequency (seconds) to poll the operation status (default: %(default)s)",
)

def create_cluster_args(self):
"""create cluster args and flags"""
Expand Down Expand Up @@ -1531,21 +1533,23 @@ def create_snapshot_args(self):
help="The time (in minutes) to wait for Snapshot CR to complete before returning "
"timeout error (default: 30)",
)
else:
self.subparserCreateSnapshot.add_argument(
"-b",
"--background",
default=False,
action="store_true",
help="Run snapshot operation in the background",
)
self.subparserCreateSnapshot.add_argument(
"-t",
"--pollTimer",
type=int,
default=5,
help="The frequency (seconds) to poll the operation status (default: %(default)s)",
)
pollingGroup = self.subparserCreateSnapshot.add_argument_group(
title="polling group", description="optionally modify default polling mechanism"
)
pollingGroup.add_argument(
"-b",
"--background",
default=False,
action="store_true",
help="Run backup operation in the background rather than polling for status",
)
pollingGroup.add_argument(
"-t",
"--pollTimer",
type=int,
default=5,
help="The frequency (seconds) to poll the operation status (default: %(default)s)",
)

def create_user_args(self):
"""create user args and flags"""
Expand Down

0 comments on commit e024d76

Please sign in to comment.