Add basic http auth for /admin/status. Update docs.

This commit is contained in:
jholdstock 2020-08-03 15:20:52 +01:00 committed by David Hill
parent ba77d39f35
commit e0fc5b8d04
3 changed files with 53 additions and 18 deletions

View File

@ -77,6 +77,24 @@ dcrstakepool deployment.
## Monitoring ## Monitoring
A monitoring system with alerting should be pointed at vspd and tested/verified
to be operating properly. An ideal solution would monitor the following:
- **Front-end host:**
- vspd and dcrd processes are running.
- No errors in vspd or dcrd logs.
- Both dcrd and vspd are keeping up to date with new blocks.
- Web front-end is accessible from the internet.
- vspd `/admin/status` endpoint indicates no issues.
- **Voting wallet hosts:**
- dcrwallet and dcrd processes are running.
- No errors in dcrwallet or dcrd logs.
- dcrwallet has voting enabled and is unlocked.
- Both dcrd and dcrwallet are keeping up to date with new blocks.
### Logs ### Logs
Any event logged at the `[ERR]` level is worthy of immediate investigation. Any event logged at the `[ERR]` level is worthy of immediate investigation.
@ -87,11 +105,18 @@ The `[WRN]` level is used to indicate events which are of interest, but do not
necessarily require investigation (eg. bad requests from clients, recoverable necessarily require investigation (eg. bad requests from clients, recoverable
errors). errors).
### Voting Wallets ### Voting Wallet Status
The current status of the voting wallets is displayed in a table on the `/admin` The current status of the voting wallets is displayed in a table on the `/admin`
page, and the same information can be retrieved as a JSON object from page, and the same information can be retrieved as a JSON object from
`/admin/status` for automated monitoring. `/admin/status` for automated monitoring. This endpoint requires Basic HTTP
Authentication with the username `admin` and the password set in vspd
configuration. A 200 HTTP status will be returned if the voting wallets seem
healthy, or a 500 status will be used to indicate something is wrong.
```bash
$ curl --user admin:12345 --request GET http://localhost:8800/admin/status
```
```json ```json
{ {
@ -109,20 +134,6 @@ page, and the same information can be retrieved as a JSON object from
} }
``` ```
<!--
// TODO: Content copied from dcrstakepool repo, should be updated for vspd when we have a
suitable HTTP endpoint:
A monitoring system with alerting should be pointed at dcrstakepool and
tested/verified to be operating properly. There is a hidden /status page which
throws 500 if the RPC client is shutdown. If your monitoring system supports it,
add additional points of verification such as: checking that the /stats page
loads and has expected information in it, create a test account and setup
automated login testing, etc.
-->
## Backup ## Backup
The bbolt database file used by vspd is stored in the process home directory, at The bbolt database file used by vspd is stored in the process home directory, at

View File

@ -61,7 +61,24 @@ func walletStatus(c *gin.Context) map[string]WalletStatus {
// statusJSON is the handler for "GET /admin/status". It returns a JSON object // statusJSON is the handler for "GET /admin/status". It returns a JSON object
// describing the current status of voting wallets. // describing the current status of voting wallets.
func statusJSON(c *gin.Context) { func statusJSON(c *gin.Context) {
c.AbortWithStatusJSON(http.StatusOK, walletStatus(c)) httpStatus := http.StatusOK
wallets := walletStatus(c)
// Respond with HTTP status 500 if any voting wallets have issues.
for _, wallet := range wallets {
if wallet.InfoError ||
wallet.BestBlockError ||
!wallet.Connected ||
!wallet.DaemonConnected ||
!wallet.Voting ||
!wallet.Unlocked {
httpStatus = http.StatusInternalServerError
break
}
}
c.AbortWithStatusJSON(httpStatus, wallets)
} }
// adminPage is the handler for "GET /admin". // adminPage is the handler for "GET /admin".

View File

@ -208,11 +208,18 @@ func router(debugMode bool, cookieSecret []byte, dcrd rpc.DcrdConnect, wallets r
withWalletClients(wallets), withSession(cookieStore), requireAdmin(), withWalletClients(wallets), withSession(cookieStore), requireAdmin(),
) )
admin.GET("", adminPage) admin.GET("", adminPage)
admin.GET("/status", statusJSON)
admin.POST("/ticket", ticketSearch) admin.POST("/ticket", ticketSearch)
admin.GET("/backup", downloadDatabaseBackup) admin.GET("/backup", downloadDatabaseBackup)
admin.POST("/logout", adminLogout) admin.POST("/logout", adminLogout)
// Require Basic HTTP Auth on /admin/status endpoint.
basic := router.Group("/admin").Use(
withWalletClients(wallets), gin.BasicAuth(gin.Accounts{
"admin": cfg.AdminPass,
}),
)
basic.GET("/status", statusJSON)
return router return router
} }