Skip to content

Commit

Permalink
Require payment for app deployment requests. (#928)
Browse files Browse the repository at this point in the history
Adds three new options for deployment/undeployment:

```
    "--min-required-payment",
    help="Requests must have a minimum payment to be processed",

    "--payment-address",
    help="The address to which payments should be made.  Default is the current laconic account.",

    "--all-requests",
    help="Handle requests addressed to anyone (by default only requests to my payment address are examined).",
```

In this mode, requests should be designated for a particular address with the attribute `to` and include a `payment` attribute which is the tx hash for the payment.

The deployer will confirm the payment (to the right account, right amount, not used before, etc.) and then proceed with the deployment or undeployment.

Reviewed-on: https://git.vdb.to/cerc-io/stack-orchestrator/pulls/928
Reviewed-by: David Boreham <[email protected]>
Co-authored-by: Thomas E Lackey <[email protected]>
Co-committed-by: Thomas E Lackey <[email protected]>
  • Loading branch information
telackey authored and David Boreham committed Aug 21, 2024
1 parent 44b9709 commit 75ff607
Show file tree
Hide file tree
Showing 3 changed files with 586 additions and 124 deletions.
65 changes: 59 additions & 6 deletions stack_orchestrator/deploy/webapp/deploy_webapp_from_registry.py
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@
generate_hostname_for_app,
match_owner,
skip_by_tag,
confirm_payment,
)


Expand All @@ -54,6 +55,7 @@ def process_app_deployment_request(
force_rebuild,
fqdn_policy,
recreate_on_deploy,
payment_address,
logger,
):
logger.log("BEGIN - process_app_deployment_request")
Expand All @@ -78,6 +80,9 @@ def process_app_deployment_request(
else:
fqdn = f"{requested_name}.{default_dns_suffix}"

# Normalize case (just in case)
fqdn = fqdn.lower()

# 3. check ownership of existing dnsrecord vs this request
dns_lrn = f"{dns_record_namespace}/{fqdn}"
dns_record = laconic.get_record(dns_lrn)
Expand Down Expand Up @@ -119,7 +124,7 @@ def process_app_deployment_request(
app_deployment_lrn = app_deployment_request.attributes.deployment
if not app_deployment_lrn.startswith(deployment_record_namespace):
raise Exception(
"Deployment CRN %s is not in a supported namespace"
"Deployment LRN %s is not in a supported namespace"
% app_deployment_request.attributes.deployment
)

Expand Down Expand Up @@ -222,6 +227,7 @@ def process_app_deployment_request(
dns_lrn,
deployment_dir,
app_deployment_request,
payment_address,
logger,
)
logger.log("Publication complete.")
Expand Down Expand Up @@ -305,6 +311,23 @@ def dump_known_requests(filename, requests, status="SEEN"):
@click.option(
"--log-dir", help="Output build/deployment logs to directory.", default=None
)
@click.option(
"--min-required-payment",
help="Requests must have a minimum payment to be processed",
default=0,
)
@click.option(
"--payment-address",
help="The address to which payments should be made. "
"Default is the current laconic account.",
default=None,
)
@click.option(
"--all-requests",
help="Handle requests addressed to anyone (by default only requests to"
"my payment address are examined).",
is_flag=True,
)
@click.pass_context
def command( # noqa: C901
ctx,
Expand All @@ -326,6 +349,9 @@ def command( # noqa: C901
force_rebuild,
recreate_on_deploy,
log_dir,
min_required_payment,
payment_address,
all_requests,
):
if request_id and discover:
print("Cannot specify both --request-id and --discover", file=sys.stderr)
Expand Down Expand Up @@ -366,6 +392,10 @@ def command( # noqa: C901
exclude_tags = [tag.strip() for tag in exclude_tags.split(",") if tag]

laconic = LaconicRegistryClient(laconic_config, log_file=sys.stderr)
if not payment_address:
payment_address = laconic.whoami().address

main_logger.log(f"Payment address: {payment_address}")

# Find deployment requests.
# single request
Expand All @@ -375,18 +405,20 @@ def command( # noqa: C901
# all requests
elif discover:
main_logger.log("Discovering deployment requests...")
requests = laconic.app_deployment_requests()
if all_requests:
requests = laconic.app_deployment_requests()
else:
requests = laconic.app_deployment_requests({"to": payment_address})

if only_update_state:
if not dry_run:
dump_known_requests(state_file, requests)
return

previous_requests = {}
if state_file:
main_logger.log(f"Loading known requests from {state_file}...")
previous_requests = load_known_requests(state_file)
else:
previous_requests = {}

# Collapse related requests.
requests.sort(key=lambda r: r.createTime)
Expand Down Expand Up @@ -452,7 +484,10 @@ def command( # noqa: C901

# Find deployments.
main_logger.log("Discovering existing app deployments...")
deployments = laconic.app_deployments()
if all_requests:
deployments = laconic.app_deployments()
else:
deployments = laconic.app_deployments({"by": payment_address})
deployments_by_request = {}
for d in deployments:
if d.attributes.request:
Expand All @@ -466,7 +501,7 @@ def command( # noqa: C901
if r.attributes.request:
cancellation_requests[r.attributes.request] = r

requests_to_execute = []
requests_to_check_for_payment = []
for r in requests_by_name.values():
if r.id in cancellation_requests and match_owner(
cancellation_requests[r.id], r
Expand All @@ -488,7 +523,24 @@ def command( # noqa: C901
)
else:
main_logger.log(f"Request {r.id} needs to processed.")
requests_to_check_for_payment.append(r)

requests_to_execute = []
if min_required_payment:
for r in requests_to_check_for_payment:
main_logger.log(f"{r.id}: Confirming payment...")
if confirm_payment(
laconic, r, payment_address, min_required_payment, main_logger
):
main_logger.log(f"{r.id}: Payment confirmed.")
requests_to_execute.append(r)
else:
main_logger.log(
f"Skipping request {r.id}: unable to verify payment."
)
dump_known_requests(state_file, [r], status="UNPAID")
else:
requests_to_execute = requests_to_check_for_payment

main_logger.log(
"Found %d unsatisfied request(s) to process." % len(requests_to_execute)
Expand Down Expand Up @@ -531,6 +583,7 @@ def command( # noqa: C901
force_rebuild,
fqdn_policy,
recreate_on_deploy,
payment_address,
build_logger,
)
status = "DEPLOYED"
Expand Down
Loading

0 comments on commit 75ff607

Please sign in to comment.