Skip to content

Instantly share code, notes, and snippets.

@superseb
Last active April 20, 2023 07:31
Show Gist options
  • Save superseb/d6560a18ce5df47bac01477203b87950 to your computer and use it in GitHub Desktop.
Save superseb/d6560a18ce5df47bac01477203b87950 to your computer and use it in GitHub Desktop.
Single command etcd snapshot restore to inspect etcd contents
#!/usr/bin/env bash
if [ $# -ne 2 ]; then
echo "Usage: $0 [filename] [etcd_version]"
exit 1
fi
FILENAME=$1
ETCD_VERSION=$2
TIMESTAMP="$(date +%s)"
TARGET="restore_etcd_${TIMESTAMP}"
ZIPEXTENSION="\.zip"
echo "Temp directory is ${PWD}/${TARGET}"
CACERT="-----BEGIN CERTIFICATE-----\nMIIDGjCCAgKgAwIBAgIJALxnIidJgFyoMA0GCSqGSIb3DQEBCwUAMBIxEDAOBgNV\nBAMMB3Rlc3QtY2EwHhcNMjEwNTMxMTY1MjEzWhcNMzEwNTI5MTY1MjEzWjASMRAw\nDgYDVQQDDAd0ZXN0LWNhMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA\npsQ9d5w5NQ6bZl0nWUQH8FFNXl+6SPL2YDrUyjK04HUflx+KDka3jMHCt5+oV2Cr\n6vsd8gOAuj70RABBco5AjX7xl+T5iSMf6b2rlTNNC75U6hbavtFB9HajAKBTh7xA\n8nbwTIR3hnvT6LVqDcoH7aA/AG//vOk6eq2iLt1+8lG81y2b2TrRH0P3vLb1kk5j\nHLVIJnh+IzYtlNFe45wZ2qLfJCivnKBdjczFnfkbmVMz5FxyhtwHKjSvM2Z71Wzl\nNden4YV1Re4lZrKMqZzfmBM+0Ga6rAXWmHte6+a49zRNwzNDdij36YwT9PjLSfjV\nqs/wJ4N8kb4PYoebgNy+nQIDAQABo3MwcTAdBgNVHQ4EFgQUp15tAmIjQ/f9Ciq8\nUWZiPxz4cMQwQgYDVR0jBDswOYAUp15tAmIjQ/f9Ciq8UWZiPxz4cMShFqQUMBIx\nEDAOBgNVBAMMB3Rlc3QtY2GCCQC8ZyInSYBcqDAMBgNVHRMEBTADAQH/MA0GCSqG\nSIb3DQEBCwUAA4IBAQATsqfajPUzqHbqE8qTQHjJAk/Y+zU+sjMJvvfXCPQy+nhG\nerDHk3yb+ZLvlY4hDJqxWB0iTTzq7fXB8Xi8XX+7LoOwOK8DHaL90EPHLGLbUXvc\np6U2ilkxRsC2yVCCSehesbbZ/kja6f4K6HkLGjjBKFj1j3accAAgfVUBuaw8PFH8\nXgXJ8q1gOw5oAN/DK/PuLZ1EmRhC0ymlHucOZqq54HPz9Jx1j5YngAQxz5qVL832\nmPki4+URXSczHN2McQWMMMknk33iKPqfeZl/is13HuPqA5Si7a3VMJOrZe2ltOTf\nzLu2JUZq8U6kxFU9hf7sGauwuQjLAqEmQr2NSua0\n-----END CERTIFICATE-----\n"
CERT="-----BEGIN CERTIFICATE-----\nMIIDAzCCAeugAwIBAgIJAKnlD2rVEPSiMA0GCSqGSIb3DQEBCwUAMBIxEDAOBgNV\nBAMMB3Rlc3QtY2EwHhcNMjEwNTMxMTY1MjE0WhcNMzEwNTI5MTY1MjE0WjAUMRIw\nEAYDVQQDDAlsb2NhbGhvc3QwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIB\nAQCjsrvZ1sBVCo4pxb2beOs70n1981RMW0vEseA/cZR89IgSOon8rNuhHovMDToy\niAptcmDALIbLOhyRYwVRGinMX9ASRJkE0pIm9hpqCxdTAuOWCFIy0lrZWQsGn5qj\n2LBoRVRFnDgiWLIfdHO0nopsPp69PRYXPPpuJXn5M1n0qIhMmXU2MSbyNOdITQ68\nvfHFUO+cqYf0Hslgam16HSBpiCi8bZ/FgCyMU4aRQ2jwpG0613JkA3B/RTB2eswt\nFtnc8Nuuq65Br48FSedKYIDM1HgrgsNd4EAoUlO87SR5vcLSJuopDJ9P00Zk4q+B\nG2lB+pgbHaAc6+PjdMOz3m19AgMBAAGjWjBYMAkGA1UdEwQCMAAwCwYDVR0PBAQD\nAgXgMB0GA1UdJQQWMBQGCCsGAQUFBwMCBggrBgEFBQcDATAfBgNVHREEGDAWggls\nb2NhbGhvc3SCCWxvY2FsaG9zdDANBgkqhkiG9w0BAQsFAAOCAQEAhadpezzycpu2\nCkaXXM/FgJ7+UOcDq4rJr53uBqE9J7P7FbcCVAzXnlBF+jPq/z9qVvPOb5/SwTqC\nsJN33QfZlJg+Gzqy/FLsyxt/izZ4LKOhN68jLrveeGN11+oajkU3l9oZaTBV5apr\nKzoWJWP+XwmJ/XzSCZLIko9zRmW0RdZiPCB2vqRj63GczX8D6ipx//Ny/MmhpJ5M\n1YHpBmYaUo5Jx/ZbkbSSGBfplbhv567uhSfgruo8mt5t4P4whW98B6WgqT7lILQF\nC91xQ6CJh8QkOnrPxAt2L2eagy2mvUDvs3bb2Ai96wVPAemUPD76+pKsC0cwFRN9\nEHAlJ2XcKg==\n-----END CERTIFICATE-----\n"
KEY="-----BEGIN RSA PRIVATE KEY-----\nMIIEowIBAAKCAQEAo7K72dbAVQqOKcW9m3jrO9J9ffNUTFtLxLHgP3GUfPSIEjqJ\n/KzboR6LzA06MogKbXJgwCyGyzockWMFURopzF/QEkSZBNKSJvYaagsXUwLjlghS\nMtJa2VkLBp+ao9iwaEVURZw4IliyH3RztJ6KbD6evT0WFzz6biV5+TNZ9KiITJl1\nNjEm8jTnSE0OvL3xxVDvnKmH9B7JYGpteh0gaYgovG2fxYAsjFOGkUNo8KRtOtdy\nZANwf0UwdnrMLRbZ3PDbrquuQa+PBUnnSmCAzNR4K4LDXeBAKFJTvO0keb3C0ibq\nKQyfT9NGZOKvgRtpQfqYGx2gHOvj43TDs95tfQIDAQABAoIBACPkDz3O0PKUUuEj\nwtOwqlq+ZtdTn3ryVWV13oXqgDT5ZFAi15g3yhvEV8BQch8cJrUia8YWvSMXxaW2\nwTar9tghdbxbn/UnufWi5d20OtPvgTim8GbGKjcXR8yW98/OtbbW5IgynTginEM7\nRBco346mGCXDm/FSZFH8E4co1CNI6nz1GkK5AnYDaMLscefvvXRTDxEsx4VBuhYe\npJ4ZG51zNmpmj2xhzRG4qD7ymOlKTpC4lV20jDCUtW/StXh9Kpyk7FDIpZ/Ghf82\nklaES6jcA/zXmsCXwKzGA6VNJZr87YXDly1fkWll7Rm18kaX/hMxP1BixNpiqh7s\nqVsvE90CgYEAzNjMsS3eDPWeDKWkSE1f+v+Jqx/RWkzCP8IE6tzvDQo/aBvB18o8\nmjSWL4j4XM0f7lb9QZwPKQTZ6hYtEP9GGLKyqV2/CKQd/lvz/L+B/maskOTlCyiD\neLVhuJ8P2PArIszfGTuVEdZoWZaEjNLUvWkD18fc3nD/Ov3KiC8OIisCgYEAzJNu\nSG1kBgg+S0fmdSaqbIAbsPK3/XFSG+jj/dpP4MOy8GG6IFUtj4lKiIzrUugLHe8l\nJDcujsIc61OG4U1NkpRGaRaPNj1FEREoa/me66LceP8cAe2XDQeILZhjwUy0Do6x\nwHvkyYPnxYcsck8rNGelxJb9CHzqkPWmYRP1YvcCgYEAyZI4cczJqQT0fktsif0h\nilJ0PKC1mF7Z8nVP83BuBu3jkOVnbJlD4xYGB0aH5oGufxC4axxOyrVMXY1u0T/w\n0RLevcxS1ATywr3nK/miyBxuiLHENKOsI1aQj2Rt6rICMF9a1XCM8p2B105GpnA8\nCRpSPr4buAOHE5xy9GkhRjsCgYAPds2NWAeJlTHwSt0W2fdkAEMXmyFhXSGRzob9\nd3U2TlTGavzA2O96vCwQKmbXe4brmlo6ZJl2XSIGf+fgPBGzFNZFt1jYBsWjxqJB\nlzr2IPd9hfs+AhG7AGjA2ZYg1IV/3DV/kV34BaqNeexYL7faXENhmvBBpf+tOYR8\nLiAMfQKBgDcAHSjlFl5XccpiCRo9J2xnrY9uLjWIX4paTJZ6fbMO63lzWIOoJCW2\n8Y4fTrp2DSPvd6F02Q7cF9zodjmru6qNItillaitqxH1LqfSVRlVUhr8SF5UyzXX\nGgTh9av+CRKWZMuPO/3UMcaao5R1Dav3DqpM/k4Afa1whYT6dG0C\n-----END RSA PRIVATE KEY-----\n"
mkdir -p ${PWD}/${TARGET}/{unzipped,restored,ssl}
if test "${FILENAME#*$ZIPEXTENSION}" != "${FILENAME}"; then
# zipped
docker run -v ${PWD}/${FILENAME}:/tmp/${FILENAME} -v $PWD/${TARGET}/unzipped:/backup busybox sh -c "unzip /tmp/${FILENAME}"
else
cp "${PWD}/${FILENAME}" "${PWD}/${TARGET}/unzipped"
fi
echo -e $CACERT > "${PWD}/${TARGET}/ssl/ca.pem"
echo -e $CERT > "${PWD}/${TARGET}/ssl/cert.pem"
echo -e $KEY > "${PWD}/${TARGET}/ssl/key.pem"
docker run -v ${PWD}/${TARGET}/unzipped:/backup -v ${PWD}/${TARGET}/ssl:/ssl -v ${PWD}/${TARGET}/restored:/var/lib/etcd -e ETCDCTL_API=3 --entrypoint sh quay.io/coreos/etcd:v${ETCD_VERSION} -c "etcdctl snapshot restore /backup/* --cacert /ssl/ca.pem --cert /ssl/cert.pem --key /ssl/key.pem --name etcd1 --initial-cluster etcd1=https://localhost:2380 --initial-cluster-token k8s_etcd --initial-advertise-peer-urls https://localhost:2380 --data-dir /var/lib/etcd/restore"
docker run -d --name etcd-restore-${TIMESTAMP} -v $PWD/${TARGET}/ssl:/ssl -v ${PWD}/${TARGET}/restored/restore:/var/lib/etcd -e ETCDCTL_ENDPOINTS=https://localhost:2379 -e ETCDCTL_CACERT=/ssl/ca.pem -e ETCDCTL_CERT=/ssl/cert.pem -e ETCDCTL_KEY=/ssl/key.pem -e ETCDCTL_API=3 quay.io/coreos/etcd:v${ETCD_VERSION} /usr/local/bin/etcd --cert-file=/ssl/cert.pem --key-file=/ssl/key.pem --name=etcd1 --initial-cluster=etcd1=https://localhost:2380 --advertise-client-urls=https://localhost:2379 --listen-client-urls=https://localhost:2379 --initial-cluster-token=k8s_etcd --initial-advertise-peer-urls=https://localhost:2380 --data-dir=/var/lib/etcd
echo docker exec etcd-restore-${TIMESTAMP} etcdctl endpoint status
docker exec etcd-restore-${TIMESTAMP} etcdctl endpoint status --write-out=table
echo "Some commands:"
echo "==="
echo "-> Show all keys"
echo "docker exec etcd-restore-${TIMESTAMP} etcdctl get /registry --prefix=true --keys-only"
echo "==="
echo "-> Show count of keys"
echo "docker exec etcd-restore-${TIMESTAMP} etcdctl get /registry --prefix=true --keys-only | grep -v ^$ | awk -F'/' '{ if (\$3 ~ /cattle.io/) {h[\$3\"/\"\$4]++} else { h[\$3]++ }} END { for(k in h) print h[k], k }' | sort -nr"
echo "==="
echo "-> Check secret encryption key used (requires jq to be installed)"
echo "docker exec etcd-restore-${TIMESTAMP} etcdctl get \$(docker exec etcd-restore-${TIMESTAMP} etcdctl get /registry --prefix=true --keys-only | grep default-token | head -1) -w json | jq -r .kvs[].value | base64 -d | head -c 30"
echo "==="
echo "-> Check secret encryption key used for all secrets (requires jq to be installed)"
echo "for secret in \$(docker exec etcd-restore-${TIMESTAMP} etcdctl get /registry --prefix=true --keys-only | grep secret); do echo \$secret; docker exec etcd-restore-${TIMESTAMP} etcdctl get \$secret -w json | jq -r .kvs[].value | base64 -d | head -c 30; echo ""; done"
echo "==="
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment