Пример #1
0
def _step_delete_secret_and_build_delta(
        workflow: Workflow, step: Step,
        param: str) -> Optional[clientside.Update]:
    """Write a new secret (or `None`) to `step`, or raise.

    Return a `clientside.Update`, or `None` if the database is not modified.

    Raise Workflow.DoesNotExist if the Workflow was deleted.
    """
    with workflow.cooperative_lock():  # raises Workflow.DoesNotExist
        try:
            step.refresh_from_db()
        except Step.DoesNotExist:
            return None  # no-op

        if step.secrets.get(param) is None:
            return None  # no-op

        step.secrets = dict(step.secrets)  # shallow copy
        del step.secrets[param]
        step.save(update_fields=["secrets"])

        return clientside.Update(
            steps={
                step.id: clientside.StepUpdate(secrets=step.secret_metadata)
            })
Пример #2
0
def _step_set_secret_and_build_delta(
        workflow: Workflow, step: Step, param: str,
        secret: str) -> Optional[clientside.Update]:
    """Write a new secret to `step`, or raise.

    Return a `clientside.Update`, or `None` if the database is not modified.

    Raise Workflow.DoesNotExist if the Workflow was deleted.
    """
    with workflow.cooperative_lock():  # raises Workflow.DoesNotExist
        try:
            step.refresh_from_db()
        except Step.DoesNotExist:
            return None  # no-op

        if step.secrets.get(param, {}).get("secret") == secret:
            return None  # no-op

        try:
            module_zipfile = MODULE_REGISTRY.latest(step.module_id_name)
        except KeyError:
            raise HandlerError(
                f"BadRequest: ModuleZipfile {step.module_id_name} does not exist"
            )
        module_spec = module_zipfile.get_spec()
        if not any(p.type == "secret" and p.secret_logic.provider == "string"
                   for p in module_spec.param_fields):
            raise HandlerError(
                f"BadRequest: param is not a secret string parameter")

        created_at = datetime.datetime.now()
        created_at_str = (
            created_at.strftime("%Y-%m-%dT%H:%M:%S") + "." +
            created_at.strftime("%f")[0:3]  # milliseconds
            + "Z")

        step.secrets = {
            **step.secrets,
            param: {
                "name": created_at_str,
                "secret": secret
            },
        }
        step.save(update_fields=["secrets"])

        return clientside.Update(
            steps={
                step.id: clientside.StepUpdate(secrets=step.secret_metadata)
            })
Пример #3
0
def _locked_step(workflow_id: int, step: Step):
    """Refresh step from database and yield with workflow lock.

    Raise Workflow.DoesNotExist or Step.DoesNotExist in the event of a
    race. (Even soft-deleted Step or Tab raises Step.DoesNotExist,
    to simulate hard deletion -- because sooner or later soft-delete won't be
    a thing any more.)
    """
    # raise Workflow.DoesNotExist
    with Workflow.lookup_and_cooperative_lock(id=workflow_id):
        # raise Step.DoesNotExist
        step.refresh_from_db()
        if step.is_deleted or step.tab.is_deleted:
            raise Step.DoesNotExist("soft-deleted")
        yield