From bd750fccb3e27f78cd63129afa3ce688dbf968f7 Mon Sep 17 00:00:00 2001 From: Simon Marsh Date: Sat, 12 Dec 2020 15:00:23 +0000 Subject: [PATCH] Add API endpoint to force a registry refresh. --- API.md | 14 ++++++++++++++ dn42regsrv.go | 3 ++- regapi.go | 26 ++++++++++++++++++++++++++ registry.go | 24 ++++++++++++++++++++---- 4 files changed, 62 insertions(+), 5 deletions(-) diff --git a/API.md b/API.md index 6e4fc8c..d199dae 100644 --- a/API.md +++ b/API.md @@ -296,6 +296,20 @@ wget -O - -q http://localhost:8042/api/dns/.meta | jq } ``` +It is also possible to force a refresh of the registry data. +To limit abuse, the refresh endpoint is protected by a secret token that must be passed using the `Authorization` header. + +``` +POST /api/registry/.meta/refresh +``` + +Example : +``` +wget -O - -q --header='Authorization: secret' --post-data='' http://localhost:8042/api/registry/.meta/refresh +``` + +The token is set using the `--AuthToken` command line parameter. + ## Route Origin Authorisation (ROA) API Route Origin Authorisation (ROA) data can be obtained from the server in diff --git a/dn42regsrv.go b/dn42regsrv.go index 31814d6..b2cd63b 100644 --- a/dn42regsrv.go +++ b/dn42regsrv.go @@ -124,6 +124,7 @@ func main() { gitPath = flag.StringP("GitPath", "g", "/usr/bin/git", "Path to git executable") autoPull = flag.BoolP("AutoPull", "a", true, "Automatically pull the registry") branch = flag.StringP("Branch", "p", "master", "git branch to pull") + authToken = flag.StringP("AuthToken", "t", "secret", "Auth token for refresh endpoint") ) flag.Parse() @@ -140,7 +141,7 @@ func main() { } InitialiseRegistryData(*regDir, interval, - *gitPath, *autoPull, *branch) + *gitPath, *autoPull, *branch, *authToken) // initialise router router := mux.NewRouter() diff --git a/regapi.go b/regapi.go index ad7ab9b..8a2cc5b 100644 --- a/regapi.go +++ b/regapi.go @@ -51,6 +51,10 @@ func InitRegistryAPI(params ...interface{}) { s.HandleFunc("/{type}/{object}/{key}", regKeyHandler) s.HandleFunc("/{type}/{object}/{key}/{attribute}", regAttributeHandler) + // add PUSH method to refresh registry + router.HandleFunc("/registry/.meta/refresh", regRefreshHandler). + Methods("POST") + log.Info("Registry API installed") } @@ -68,6 +72,28 @@ func regMetaHandler(w http.ResponseWriter, r *http.Request) { ResponseJSON(w, rv) } +////////////////////////////////////////////////////////////////////////// +// force a registry refresh + +func regRefreshHandler(w http.ResponseWriter, r *http.Request) { + + token := r.Header.Get("Authorization") + if token == AuthorisationToken { + + // trigger a refresh + RegistryRefresh <- true + + // all good + response := struct{ status string }{"ok"} + ResponseJSON(w, response) + + } else { + + w.WriteHeader(http.StatusForbidden) + w.Write([]byte("403 - Forbidden")) + } +} + ////////////////////////////////////////////////////////////////////////// // filter functions diff --git a/registry.go b/registry.go index 7c56622..8aed9dd 100644 --- a/registry.go +++ b/registry.go @@ -71,9 +71,13 @@ type Registry struct { // and a variable for the actual data var RegistryData *Registry -// store the current commit has +// store the previous commit var previousCommit string +// also store the registry refresh ticker +var AuthorisationToken string +var RegistryRefresh chan bool + ////////////////////////////////////////////////////////////////////////// // utility and manipulation functions @@ -636,7 +640,9 @@ func refreshRegistry(regDir string, gitPath string, branch string) { // called from main to initialse the registry data and syncing func InitialiseRegistryData(regDir string, refresh time.Duration, - gitPath string, autoPull bool, branch string) { + gitPath string, autoPull bool, branch string, token string) { + + AuthorisationToken = token // validate that the regDir/data path exists dataPath := regDir + "/data" @@ -680,10 +686,20 @@ func InitialiseRegistryData(regDir string, refresh time.Duration, previousCommit = getCommitHash(regDir, gitPath) reloadRegistry(dataPath, previousCommit) + // create the refresh timer + RegistryRefresh = make(chan bool) + ticker := time.NewTicker(refresh) + go func() { - // every refresh interval - for range time.Tick(refresh) { + for { + + select { + // when the ticker ticks + case <-RegistryRefresh: + case <-ticker.C: + } + log.Debug("Refresh Timer") // automatically try to refresh the registry ?