-
Notifications
You must be signed in to change notification settings - Fork 1
/
util.sh
206 lines (181 loc) · 5.94 KB
/
util.sh
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
#!/usr/bin/env bash
function waitForDCService {
SERVICE_NAME=$1
printf "Waiting for docker compose service '%s' to become healthy" $SERVICE_NAME
retry=0
healthy=0
while [ $retry -lt 30 ]; do
status=$(docker inspect -f {{.State.Health.Status}} $(docker compose ps -q $SERVICE_NAME))
if [[ "$status" == "healthy" ]]; then
healthy=1
break
fi
printf "."
sleep 0.5
retry=$[$retry+1]
done
if [ $healthy -eq 0 ]; then
echo "FAILED: Service took to long to start"
exitWithDockerLogs 1
fi
echo ""
}
function waitForTXCount {
SERVICE_NAME=$1
URL=$2
TX_COUNT=$3
TIMEOUT=$4
printf "Waiting for service '%s' to contain %s transactions" $SERVICE_NAME $TX_COUNT
done=false
retry=0
while [ $retry -lt $TIMEOUT ]; do
RESPONSE=$(curl -s $URL)
if echo $RESPONSE | grep -q "transaction_count: $TX_COUNT"; then
done=true
break
fi
printf "."
sleep 1
retry=$[$retry+1]
done
if [ $done == false ]; then
printf "FAILED: Service '%s' did not get %d transaction within %d seconds" $SERVICE_NAME $TX_COUNT $TIMEOUT
exitWithDockerLogs 1
fi
echo ""
}
# waitForDCService waits for a Nuts node's diagnostic to display a certain value for a given key
# Args: service name, key to check, expected value
function waitForDiagnostic {
SERVICE_NAME=$1
KEY=$2
VALUE=$3
TIMEOUT=10
printf "Waiting for service '%s' diagnostic (%s: %s)" $SERVICE_NAME $KEY $VALUE
done=false
retry=0
while [ $retry -lt $TIMEOUT ]; do
RESPONSE=$(docker compose exec $SERVICE_NAME nuts status)
if echo $RESPONSE | grep -q "${KEY}: ${VALUE}"; then
done=true
break
fi
printf "."
sleep 1
retry=$[$retry+1]
done
if [ $done == false ]; then
echo "FAILED"
exitWithDockerLogs 1
fi
echo ""
}
function exitWithDockerLogs {
EXIT_CODE=$1
docker compose logs
docker compose stop
exit $EXIT_CODE
}
# waitForKeyPress waits for the enter key to be pressed
function waitForKeyPress() {
read -p "Press enter to continue"
}
# setupNode creates a node's DID document and registers its NutsComm endpoint.
# Args: node HTTP address, node gRPC address
# Returns: the created DID
function setupNode() {
local did=$(printf '{
"selfControl": true,
"keyAgreement": true,
"assertionMethod": true,
"capabilityInvocation": true
}' | curl -s -X POST "$1/internal/vdr/v1/did" -H "Content-Type: application/json" --data-binary @- | jq -r ".id")
printf '{
"type": "NutsComm",
"endpoint": "grpc://%s"
}' "$2" | curl -s -X POST "$1/internal/didman/v1/did/$did/endpoint" -H "Content-Type: application/json" --data-binary @- > /dev/null
echo "$did"
}
# assertDiagnostic checks whether a certain string appears on a node's diagnostics page.
# Args: node HTTP address, string to assert
function assertDiagnostic() {
RESPONSE=$(curl -s "$1/status/diagnostics")
if echo $RESPONSE | grep -q "${2}"; then
echo "Diagnostics contains '${2}'"
else
echo "FAILED: diagnostics does not report '${2}'" 1>&2
echo $RESPONSE
exitWithDockerLogs 1
fi
}
# readDiagnostic reads a specific value from the node's diagnostics page.
# Args: node HTTP address, key to read
function readDiagnostic() {
# Given 'uptime'; read diagnostics, find line with 'uptime: ' and remove key + colon, print with stripped spaces
local result=$(curl -s "$1/status/diagnostics" | grep "${2}:" | sed -e "s/$2://")
if [[ $OSTYPE == 'darwin'* ]]; then
# builtin sh on mac does not accept -n option, just prints it instead
echo "${result//[[:space:]]/}"
else
echo -n "${result//[[:space:]]/}"
fi
}
# createAuthCredential issues a NutsAuthorizationCredential
# Args: issuing node HTTP address, issuer DID, subject DID
# Returns: the VC ID
function createAuthCredential() {
printf '{
"type": "NutsAuthorizationCredential",
"issuer": "%s",
"credentialSubject": {
"id": "%s",
"resources": [],
"purposeOfUse": "example",
"subject": "urn:oid:2.16.840.1.113883.2.4.6.3:123456780"
},
"visibility": "private"
}' "$2" "$3" | curl -s -X POST "$1/internal/vcr/v2/issuer/vc" -H "Content-Type: application/json" --data-binary @- | jq ".id" | sed "s/\"//g"
}
# registerStringService registers a service on a DID document, with a string as serviceEndpoint
# Args: issuing node HTTP address, DID, service type, service endpoint
function registerStringService() {
printf '{
"type": "%s",
"endpoint": "%s"
}' "$3" "$4" | curl -s -X POST "$1/internal/didman/v1/did/$2/endpoint" -H "Content-Type: application/json" --data-binary @- > /dev/null
}
# readCredential resolves a VC
# Args: node HTTP address, VC ID
# Returns: the VC as JSON
function readCredential() {
curl -s "$1/internal/vcr/v2/vc/${2//#/%23}"
}
# revokeCredential revokes a VC
# Args: node HTTP address, VC ID
function revokeCredential() {
curl -s -X DELETE "$1/internal/vcr/v2/issuer/vc/${2//#/%23}"
}
# runOnAlpine runs the given command on a Alpine docker image
# Args: Docker volume mount (hostPath:dockerPath), remaining args are the command to run
function runOnAlpine() {
# Say you have a folder './data/' that is used by the Nuts node, and you want to delete its contents.
# Running 'rm -rf ./data/*' from the run-test.sh script will fail with permission issues.
# This is due to github actions file permission issues explained in https://github.com/actions/runner/issues/691
#
# You can successfully delete the entire folder using:
# runOnAlpine "$(pwd):/host/" rm -rf /host/data
docker run --rm -v "$1" alpine "${@:2}"
}
# finds a node DID in the nuts.yaml on the provided path
function findNodeDID() {
egrep -o 'nodedid:.*' $1 | awk '{print $2}'
}
# remove any node DID from the nuts.yaml on the provided path
function removeNodeDID() {
if [[ $OSTYPE == 'darwin'* ]]; then
# sed works different on MacOS; see https://stackoverflow.com/questions/19456518
sed -i '' -e '/nodedid: did:nuts:/d' $1
else
sed -i '/nodedid: did:nuts:/d' $1
fi
}