mirror of
https://github.com/valitydev/holmes.git
synced 2024-11-06 01:45:25 +00:00
Add some fixes and a couple of quirky scripts (#88)
* Add fixes and tiny QoL improvements * Add some quirky scripts Primatily for illustrative purpose.
This commit is contained in:
parent
ce9a3371af
commit
c819da773c
@ -44,6 +44,6 @@ END
|
||||
)
|
||||
|
||||
"${WOORL[@]:-woorl}" -s "${MGPROTO}/proto/state_processing.thrift" \
|
||||
"http://${MACHINEGUN:-machinegun}:8022/v1/automaton" \
|
||||
"http://${MACHINEGUN:-machinegun}:${MACHINEGUN_PORT:-8022}/v1/automaton" \
|
||||
Automaton Call "${MACHINEDESC}" "${CALLARGS}" \
|
||||
| grep -sqF 'MachineFailed'
|
||||
|
@ -31,7 +31,7 @@ PLANID="${1}"
|
||||
BATCHID="${2}"
|
||||
[ -z "${BATCHID}" ] && usage
|
||||
|
||||
ACCOUNTER="http://${SHUMWAY:-shumway}:8022/accounter"
|
||||
ACCOUNTER="http://${SHUMWAY:-shumway}:${SHUMWAY_PORT:-8022}/accounter"
|
||||
|
||||
"${CWD}/get-posting-plan.sh" "${PLANID}" | \
|
||||
jq ".batch_list[] | select(.id == ${BATCHID})"
|
||||
|
@ -28,7 +28,7 @@ function usage {
|
||||
PLANID="${1}"
|
||||
[ -z "${PLANID}" ] && usage
|
||||
|
||||
ACCOUNTER="http://${SHUMWAY:-shumway}:8022/accounter"
|
||||
ACCOUNTER="http://${SHUMWAY:-shumway}:${SHUMWAY_PORT:-8022}/accounter"
|
||||
|
||||
"${WOORL[@]:-woorl}" -s "${DAMSEL}/proto/accounter.thrift" \
|
||||
"${ACCOUNTER}" Accounter GetPlan "\"${PLANID}\""
|
@ -5,6 +5,8 @@
|
||||
|
||||
set -e
|
||||
|
||||
CWD="$(dirname ${0})"
|
||||
|
||||
INVOICE="${1}"
|
||||
PAYMENT="${2:-1}"
|
||||
|
||||
|
91
scripts/make-invoice-payment-refund-failed.sh
Executable file
91
scripts/make-invoice-payment-refund-failed.sh
Executable file
@ -0,0 +1,91 @@
|
||||
#!/bin/bash
|
||||
#
|
||||
# This little guy repairs an invoice machine and makes a specific refund fail.
|
||||
#
|
||||
|
||||
set -e
|
||||
|
||||
CWD="$(dirname $0)"
|
||||
|
||||
source "${CWD}/lib/logging"
|
||||
|
||||
function usage {
|
||||
echo -e "Given ID of an invoice and a payment make it look like the payment refunded has failed."
|
||||
echo
|
||||
echo -e "Usage: $(em ${SCRIPTNAME} invoice_id [payment_id] [refund_id])"
|
||||
echo -e " $(em invoice_id) Invoice ID (string)."
|
||||
echo -e " $(em payment_id) Payment ID (string), $(em 1) by default."
|
||||
echo -e " $(em refund_id) Refund ID (string), last one by default."
|
||||
echo
|
||||
echo -e "More information:"
|
||||
echo -e " https://github.com/rbkmoney/damsel/blob/master/proto/payment_processing.thrift"
|
||||
exit 127
|
||||
}
|
||||
|
||||
INVOICE="${1}"
|
||||
PAYMENT="${2:-1}"
|
||||
REFUND="${3}"
|
||||
|
||||
[ -z "${INVOICE}" -o -z "${PAYMENT}" ] && usage
|
||||
|
||||
STATE="$(${CWD}/hellgate/get-invoice-state.sh ${INVOICE})"
|
||||
|
||||
info "Going on with payment $(em ${PAYMENT}) ..."
|
||||
|
||||
PAYMENT_STATE=$(echo "${STATE}" | jq ".payments[] | select(.payment.id == \"${PAYMENT}\")")
|
||||
if [ "${PAYMENT_STATE}" = "" ]; then
|
||||
err "No such payment"
|
||||
fi
|
||||
|
||||
PAYMENT_STATUS=$(echo "${PAYMENT_STATE}" | jq -r ".payment.status | keys[0]")
|
||||
if [ "${PAYMENT_STATUS}" != "captured" ]; then
|
||||
err "Payment status ($(em ${PAYMENT_STATUS})) looks wrong for this repair scenario"
|
||||
fi
|
||||
|
||||
REFUND_STATE=$(echo "${PAYMENT_STATE}" | jq ".refunds[${REFUND:--1}]")
|
||||
if [ "${REFUND_STATE}" = "null" ]; then
|
||||
err "No refunds found"
|
||||
fi
|
||||
|
||||
REFUND=$(echo "${REFUND_STATE}" | jq -r ".id")
|
||||
info "Going on with refund $(em ${REFUND}) ..."
|
||||
|
||||
REFUND_STATUS=$(echo "${REFUND_STATE}" | jq -r ".status | keys[0]")
|
||||
if [ "${REFUND_STATUS}" != "succeeded" ]; then
|
||||
err "Refund status ($(em ${REFUND_STATUS})) looks wrong for this repair scenario"
|
||||
fi
|
||||
|
||||
CHANGES=$(cat <<END
|
||||
[
|
||||
{
|
||||
"invoice_payment_change": {
|
||||
"id": "${PAYMENT}",
|
||||
"payload": {
|
||||
"invoice_payment_refund_change": {
|
||||
"id": "${REFUND}",
|
||||
"payload": {
|
||||
"invoice_payment_refund_status_changed": {
|
||||
"status": {"failed": {"failure": {
|
||||
"failure": {
|
||||
"code": "authorization_failed",
|
||||
"sub": {"code": "unknown"}
|
||||
}
|
||||
}}}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
END
|
||||
)
|
||||
|
||||
PLANID="${INVOICE}.${PAYMENT}.refund_session-${REFUND}"
|
||||
BATCH=$(${CWD}/get-posting-plan-batch.sh ${PLANID} 1)
|
||||
|
||||
${CWD}/fail-machine.sh "${INVOICE}"
|
||||
|
||||
${CWD}/repair-invoice.sh "${INVOICE}" "${CHANGES}"
|
||||
|
||||
${CWD}/submit-posting-plan.sh "${PLANID}-reverted" "$(${CWD}/revert-posting-batch.sh "${BATCH}")"
|
91
scripts/reconcile-invoice-i-dont-know-even-how.sh
Executable file
91
scripts/reconcile-invoice-i-dont-know-even-how.sh
Executable file
@ -0,0 +1,91 @@
|
||||
#!/bin/bash
|
||||
|
||||
set -e
|
||||
|
||||
CWD="$(dirname $0)"
|
||||
SCRIPTNAME="$(basename $0)"
|
||||
|
||||
source "${CWD}/lib/logging"
|
||||
|
||||
# Actual work is going here
|
||||
|
||||
INVOICE="${1}"
|
||||
PAYMENT="${2}"
|
||||
|
||||
case ${INVOICE} in
|
||||
""|"-h"|"--help" )
|
||||
echo -ne "Given ID of an invoice and a payment make it so that boss is angry no more. "
|
||||
echo
|
||||
echo
|
||||
echo -e "Usage: ${SCRIPTNAME} invoice_id payment_id"
|
||||
echo -e " invoice_id Invoice ID (string)."
|
||||
echo -e " payment_id Payment ID (string)."
|
||||
echo -e " -h, --help Show this help message."
|
||||
echo
|
||||
echo -e "More information:"
|
||||
echo -e " https://github.com/rbkmoney/damsel/blob/master/proto/payment_processing.thrift"
|
||||
exit 0
|
||||
;;
|
||||
* )
|
||||
;;
|
||||
esac
|
||||
|
||||
INVOICE_ST=$(${CWD}/hellgate/get-invoice-state.sh ${INVOICE})
|
||||
|
||||
if [ "$(echo "${INVOICE_ST}" | jq -r '.invoice.status.paid')" = "null" ]; then
|
||||
err "Invoice looks wrong for this repair scenario"
|
||||
fi
|
||||
|
||||
PAYMENT_ST="$(echo "${INVOICE_ST}" | jq -r ".payments[] | .payment | select(.id == \"${PAYMENT}\")")"
|
||||
|
||||
if [ "$(echo "${PAYMENT_ST}" | jq -r '.status.captured')" = "null" ]; then
|
||||
err "Payment with id $(em "${PAYMENT}") looks wrong for this repair scenario"
|
||||
fi
|
||||
|
||||
# Essentially we have to simulate the failed session has been restarted and then
|
||||
# finished successfully.
|
||||
CHANGES=$(cat <<END
|
||||
[
|
||||
{
|
||||
"invoice_payment_change": {
|
||||
"id": "${PAYMENT}",
|
||||
"payload": {
|
||||
"invoice_payment_status_changed": {
|
||||
"status": {
|
||||
"failed": {"failure": {
|
||||
"failure": {
|
||||
"code": "authorization_failed",
|
||||
"sub": {"code": "unknown"},
|
||||
"reason": "Manually marked as failed at $(date) by @${USER}"
|
||||
}
|
||||
}}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"invoice_status_changed": {
|
||||
"status": {
|
||||
"cancelled": {
|
||||
"details": "Manually marked as cancelled at $(date) by @${USER}"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
]
|
||||
END
|
||||
)
|
||||
|
||||
PLANID="${INVOICE}.${PAYMENT}"
|
||||
BATCH=$(${CWD}/get-posting-plan-batch.sh ${PLANID} 1)
|
||||
|
||||
# First we need to explicitly make invoice failed again. Amen.
|
||||
${CWD}/fail-machine.sh "${INVOICE}"
|
||||
|
||||
# Then we should stuff it with previously reconstructed history
|
||||
${CWD}/repair-invoice.sh --force --unset-timer "${INVOICE}" "${CHANGES}"
|
||||
|
||||
# And finally we should reconcile the state of accounts of participating parties.
|
||||
${CWD}/submit-posting-plan.sh "${PLANID}-reverted" "$(${CWD}/revert-posting-batch.sh "${BATCH}")"
|
124
scripts/reconcile-invoice-refund-but-backwards.sh
Executable file
124
scripts/reconcile-invoice-refund-but-backwards.sh
Executable file
@ -0,0 +1,124 @@
|
||||
#!/bin/bash
|
||||
|
||||
set -e
|
||||
|
||||
CWD="$(dirname $0)"
|
||||
SCRIPTNAME="$(basename $0)"
|
||||
|
||||
source "${CWD}/lib/logging"
|
||||
|
||||
INVOICE="${1}"
|
||||
PAYMENT="${2}"
|
||||
REFUND="${3}"
|
||||
|
||||
case ${INVOICE} in
|
||||
""|"-h"|"--help" )
|
||||
echo -ne "Given ID of an invoice and a payment make it look like the payment capture succeeded and the "
|
||||
echo -ne "invoice has been paid. No transaction info is bound or rebound."
|
||||
echo
|
||||
echo
|
||||
echo -e "Usage: ${SCRIPTNAME} invoice_id payment_id refund_id"
|
||||
echo -e " invoice_id Invoice ID (string)."
|
||||
echo -e " payment_id Payment ID (string)."
|
||||
echo -e " refund_id Refund ID (string)."
|
||||
echo -e " -h, --help Show this help message."
|
||||
echo
|
||||
echo -e "More information:"
|
||||
echo -e " https://github.com/rbkmoney/damsel/blob/master/proto/payment_processing.thrift"
|
||||
exit 0
|
||||
;;
|
||||
* )
|
||||
;;
|
||||
esac
|
||||
|
||||
[ -z "${INVOICE}" ] && exit 127
|
||||
[ -z "${PAYMENT}" ] && exit 127
|
||||
[ -z "${REFUND}" ] && exit 127
|
||||
|
||||
STATUS=$(cat <<END
|
||||
{
|
||||
"failed": {"failure": {
|
||||
"failure": {
|
||||
"code": "authorization_failed",
|
||||
"sub": {"code": "unknown"},
|
||||
"reason": "Manually marked as failed at $(date) by @${USER}"
|
||||
}
|
||||
}}
|
||||
}
|
||||
END
|
||||
)
|
||||
|
||||
CHANGES=$(cat <<END
|
||||
[
|
||||
{
|
||||
"invoice_payment_change": {
|
||||
"id": "${PAYMENT}",
|
||||
"payload": {
|
||||
"invoice_payment_refund_change": {
|
||||
"id": "${REFUND}",
|
||||
"payload": {
|
||||
"invoice_payment_session_change": {
|
||||
"target": {
|
||||
"refunded": []
|
||||
},
|
||||
"payload": {
|
||||
"session_started": []
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"invoice_payment_change": {
|
||||
"id": "${PAYMENT}",
|
||||
"payload": {
|
||||
"invoice_payment_refund_change": {
|
||||
"id": "${REFUND}",
|
||||
"payload": {
|
||||
"invoice_payment_session_change": {
|
||||
"target": {
|
||||
"refunded": []
|
||||
},
|
||||
"payload": {
|
||||
"session_finished": {
|
||||
"result": ${STATUS}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"invoice_payment_change": {
|
||||
"id": "${PAYMENT}",
|
||||
"payload": {
|
||||
"invoice_payment_refund_change": {
|
||||
"id": "${REFUND}",
|
||||
"payload": {
|
||||
"invoice_payment_refund_status_changed": {
|
||||
"status": ${STATUS}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
END
|
||||
)
|
||||
|
||||
PLANID="${INVOICE}.${PAYMENT}.refund_session-${REFUND}"
|
||||
BATCH=$(${CWD}/get-posting-plan-batch.sh ${PLANID} 1)
|
||||
|
||||
# First we need to explicitly make invoice failed again. Amen.
|
||||
echo ${CWD}/fail-machine.sh "${INVOICE}"
|
||||
|
||||
# Then we should stuff it with previously reconstructed history
|
||||
echo ${CWD}/repair-invoice.sh --force "${INVOICE}" "${CHANGES}"
|
||||
|
||||
# And finally we should reconcile the state of accounts of participating parties.
|
||||
echo ${CWD}/submit-posting-plan.sh "${PLANID}-reverted" "$(${CWD}/revert-posting-batch.sh "${BATCH}")"
|
153
scripts/reconstruct-contractors-from-legacy-contracts.py
Executable file
153
scripts/reconstruct-contractors-from-legacy-contracts.py
Executable file
@ -0,0 +1,153 @@
|
||||
#!/bin/env python
|
||||
#
|
||||
# Give me a list of party ids and I'll try to make first class contractor entities from those
|
||||
# contractors defined only within context of historical contracts.
|
||||
#
|
||||
|
||||
import os
|
||||
import sys
|
||||
import argparse
|
||||
import subprocess
|
||||
import itertools
|
||||
import json
|
||||
import uuid
|
||||
import copy
|
||||
|
||||
escbw = "\x1b[1;37m"
|
||||
escbr = "\x1b[1;31m"
|
||||
escby = "\x1b[1;33m"
|
||||
escrs = "\x1b[0m"
|
||||
|
||||
def em(arg):
|
||||
return "{bw}{arg}{rs}".format(bw=escbw,arg=arg,rs=escrs)
|
||||
|
||||
def err(*args):
|
||||
prefix = "{br}[ERROR]{rs}".format(br=escbr, rs=escrs)
|
||||
print(prefix, *args)
|
||||
|
||||
def info(*args):
|
||||
print(em("[INFO]"), *args)
|
||||
|
||||
cwd = os.path.dirname(os.path.realpath(__file__))
|
||||
|
||||
parser = argparse.ArgumentParser()
|
||||
parser.add_argument('-n', '--dry-run', action='store_true', default=False,
|
||||
help="do not actually do anything")
|
||||
parser.add_argument('-d', '--debug', action='store_true', default=False,
|
||||
help="print command invocation traces")
|
||||
parser.add_argument('-i', '--input-file', nargs='?',
|
||||
type=argparse.FileType('r', encoding='UTF-8'),
|
||||
help="a file to read party ids from")
|
||||
parser.add_argument('party_id', nargs='*',
|
||||
help="which parties to act upon?")
|
||||
|
||||
opts = parser.parse_args()
|
||||
|
||||
if opts.input_file:
|
||||
parties = [l.strip() for l in opts.input_file.readlines()]
|
||||
else:
|
||||
parties = opts.party_id
|
||||
|
||||
def sh(*args):
|
||||
if opts.debug:
|
||||
print('[SHELL]', *args)
|
||||
return subprocess.check_output(' '.join(args), shell=True, text=True, cwd=cwd)
|
||||
|
||||
def cmd(*args):
|
||||
if opts.debug:
|
||||
print('[CMD]', *args)
|
||||
return subprocess.check_output(args, text=True, cwd=cwd)
|
||||
|
||||
woorl_cmd = sh('test -f ./woorlrc && source ./woorlrc ; echo ${WOORL[@]:-woorl}').strip('\n').split(' ')
|
||||
|
||||
def woorl(*args, dry_run_result=None):
|
||||
if not opts.dry_run:
|
||||
return cmd(*itertools.chain(woorl_cmd, args))
|
||||
else:
|
||||
return dry_run_result
|
||||
|
||||
def mk_contractor(contractor_id, contractor):
|
||||
return {
|
||||
'contractor_modification': {
|
||||
'id': contractor_id,
|
||||
'modification': {
|
||||
'creation': contractor
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
def mk_change_contractor(contract_id, contractor_id):
|
||||
return {
|
||||
'contract_modification': {
|
||||
'id': contract_id,
|
||||
'modification': {
|
||||
'contractor_modification': contractor_id
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
userinfo = {'id': 'woorl', 'type': {'service_user': {}}}
|
||||
|
||||
partymgmt_url = 'http://{host}:{port}/v1/processing/partymgmt'.format(
|
||||
host=os.environ.get('HELLGATE', 'hellgate'),
|
||||
port=os.environ.get('HELLGATE_PORT', 8022)
|
||||
)
|
||||
|
||||
def migrate_party(party_id):
|
||||
info("[%s]" % party_id, "migrating ...")
|
||||
party = json.loads(sh('./hellgate/get-party-state.sh', party_id))
|
||||
|
||||
if 'blocked' in party['blocking']:
|
||||
return err("[%s]" % party_id, "blocked")
|
||||
|
||||
changeset = []
|
||||
contractors = {}
|
||||
if len(party['contractors']) > 0:
|
||||
contractors = copy.deepcopy(party['contractors'])
|
||||
|
||||
if len(party['contracts']) > 0:
|
||||
for contract_id, contract in party['contracts'].items():
|
||||
if 'contractor_id' not in contract:
|
||||
contractor_next = contract['contractor']
|
||||
for contractor_id, contractor in contractors.items():
|
||||
if contractor == contractor_next:
|
||||
changeset.append(mk_change_contractor(contract_id, contractor_id))
|
||||
break
|
||||
else:
|
||||
contractor_id = str(uuid.uuid4())
|
||||
contractors[contractor_id] = copy.deepcopy(contractor_next)
|
||||
changeset.append(mk_contractor(contractor_id, contractor_next))
|
||||
changeset.append(mk_change_contractor(contract_id, contractor_id))
|
||||
|
||||
if len(changeset) > 0:
|
||||
|
||||
info("[%s]" % party_id, "submitting changeset:", changeset)
|
||||
|
||||
claim = json.loads(woorl(
|
||||
'-s', '../damsel/ebin/dmsl_payment_processing_thrift.beam',
|
||||
partymgmt_url, 'PartyManagement', 'CreateClaim',
|
||||
json.dumps(userinfo),
|
||||
json.dumps(party_id),
|
||||
json.dumps(changeset),
|
||||
dry_run_result='{"id":42, "revision":1}'
|
||||
))
|
||||
|
||||
info("[%s]" % party_id, "claim %s created, revision %i" % (claim['id'], claim['revision']))
|
||||
|
||||
woorl(
|
||||
'-s', '../damsel/ebin/dmsl_payment_processing_thrift.beam',
|
||||
partymgmt_url, 'PartyManagement', 'AcceptClaim',
|
||||
json.dumps(userinfo),
|
||||
json.dumps(party_id),
|
||||
json.dumps(claim['id']),
|
||||
json.dumps(claim['revision'])
|
||||
)
|
||||
|
||||
info("[%s]" % party_id, "claim %s accepted" % claim['id'])
|
||||
|
||||
info("[%s]" % party_id, "done")
|
||||
|
||||
for party_id in parties:
|
||||
migrate_party(party_id)
|
@ -39,7 +39,7 @@ while true; do
|
||||
case "$1" in
|
||||
--force ) PARAMS='{"validate_transitions":false}' ; shift 1 ;;
|
||||
--set-timeout ) ACTION="{\"timer\":{\"set_timer\":{\"timer\":{\"timeout\":$2}}}}" ; shift 2 ;;
|
||||
--set-deadline ) ACTION="{\"timer\":{\"set_timer\":{\"timer\":{\"deadline\":$2}}}}" ; shift 2 ;;
|
||||
--set-deadline ) ACTION="{\"timer\":{\"set_timer\":{\"timer\":{\"deadline\":\"$2\"}}}}" ; shift 2 ;;
|
||||
--unset-timer ) ACTION="{\"timer\":{\"unset_timer\":{}}}" ; shift 1 ;;
|
||||
-- ) shift 1 ; break ;;
|
||||
* ) break ;;
|
||||
|
@ -28,7 +28,7 @@ PLANID="${1}"
|
||||
BATCH="${2}"
|
||||
[ -z "${BATCH}" ] && usage
|
||||
|
||||
ACCOUNTER="http://${SHUMWAY:-shumway}:8022/accounter"
|
||||
ACCOUNTER="http://${SHUMWAY:-shumway}:${SHUMWAY_PORT:-8022}/accounter"
|
||||
|
||||
"${WOORL[@]:-woorl}" -s "${DAMSEL}/proto/accounter.thrift" \
|
||||
"${ACCOUNTER}" Accounter Hold \
|
||||
|
@ -32,7 +32,7 @@ PLANID="${1}"
|
||||
BATCH="${2}"
|
||||
[ -z "${BATCH}" ] && usage
|
||||
|
||||
ACCOUNTER="http://${SHUMWAY:-shumway}:8022/accounter"
|
||||
ACCOUNTER="http://${SHUMWAY:-shumway}:${SHUMWAY_PORT:-8022}/accounter"
|
||||
|
||||
"${WOORL[@]:-woorl}" -s "${DAMSEL}/proto/accounter.thrift" \
|
||||
"${ACCOUNTER}" Accounter Hold \
|
||||
|
Loading…
Reference in New Issue
Block a user