Commit bd9fec2c authored by Adam Harrison-Fuller's avatar Adam Harrison-Fuller
Browse files

Adding Sentinel support and a /healthz endpoint

parent ef2d9bb9
......@@ -63,12 +63,13 @@ issues in the projects you specify in the config file.
* CONFIG_DIR - The directory the application should look for config.yaml in.
* REDIS_URL - The URL of the Redis host e.g. `redis:6379`
* REDIS_PASSWORD - Password for Redis, if an empty password is required set to `REDIS_PASSWORD=`
* USE_SENTINEL - If set the REDIS_URL will be treated as a sentinel and the current master acquired via the sentinel.
### Run it
#### Via Docker
```bash
docker run -e GITLAB_API_TOKEN=<INSERT_TOKEN> -e CONFIG_DIR=/app -v REDIS_URL=<REDIS_URL> -v REDIS_PASSWORD=<REDIS_PASSWORD> -v <PATH_TO_CONFIG_DIR>/config adamhf/rss-sync:latest
docker run -e GITLAB_API_TOKEN=<INSERT_TOKEN> -e CONFIG_DIR=/app -v REDIS_URL=<REDIS_URL> -v REDIS_PASSWORD=<REDIS_PASSWORD> -v ${PWD}:/config adamhf/rss-sync:latest
```
#### Via docker-compose
......@@ -81,6 +82,9 @@ Two metrics (above and beyond what are exposed by the Go Prometheus library) are
* last_run_time - The time of the last feed checks, useful for creating alerts to check for successful runs.
* issues_created - The total number of issues created in Gitlab, useful to check for runaways.
## Healthz Endpoint
A /healthz endpoint is exposed on :8081/healthz which will fail if it is unable to connect to Redis.
## Example Issues
### GKE Release Notes
Feed URL: https://cloud.google.com/feeds/kubernetes-engine-release-notes.xml
......
......@@ -42,6 +42,7 @@ type EnvValues struct {
RedisPassword string
ConfDir string
GitlabAPIKey string
UseSentinel bool
}
func hasExistingGitlabIssue(guid string, projectID int, gitlabClient *gitlab.Client) bool {
......@@ -84,7 +85,7 @@ func (feed Feed) checkFeed(redisClient *redis.Client, gitlabClient *gitlab.Clien
var oldArticle []*gofeed.Item
for _, item := range rss.Items {
found := redisClient.SIsMember(feed.ID, item.GUID).Val()
if found == true {
if found {
oldArticle = append(oldArticle, item)
} else {
newArticle = append(newArticle, item)
......@@ -187,11 +188,20 @@ func initialise(env EnvValues) (redisClient *redis.Client, client *gitlab.Client
client = gitlab.NewClient(nil, env.GitlabAPIKey)
config = readConfig(path.Join(env.ConfDir, "config.yaml"))
redisClient = redis.NewClient(&redis.Options{
Addr: env.RedisURL,
Password: env.RedisPassword,
DB: 0, // use default DB
})
if !env.UseSentinel {
redisClient = redis.NewClient(&redis.Options{
Addr: env.RedisURL,
Password: env.RedisPassword,
DB: 0, // use default DB
})
} else {
redisClient = redis.NewFailoverClient(&redis.FailoverOptions{
SentinelAddrs: []string{env.RedisURL},
Password: env.RedisPassword,
MasterName: "mymaster",
DB: 0, // use default DB
})
}
if err := redisClient.Ping().Err(); err != nil {
panic(fmt.Sprintf("Unable to connect to Redis @ %s", env.RedisURL))
......@@ -205,7 +215,7 @@ func initialise(env EnvValues) (redisClient *redis.Client, client *gitlab.Client
func main() {
env := readEnv()
redisClient, gitlabClient, config := initialise(env)
go checkLiveliness(redisClient)
go func() {
for {
log.Printf("Running checks at %s\n", time.Now().Format(time.RFC850))
......@@ -224,6 +234,8 @@ func main() {
func readEnv() EnvValues {
var gitlabPAToken, configDir, redisURL, redisPassword string
useSentinel := false
if envGitlabAPIToken := os.Getenv("GITLAB_API_TOKEN"); envGitlabAPIToken == "" {
panic("Could not find GITLAB_API_TOKEN specified as an environment variable")
} else {
......@@ -247,10 +259,33 @@ func readEnv() EnvValues {
redisPassword = envRedisPassword
}
_, hasRedisSentinel := os.LookupEnv("USE_SENTINEL")
if hasRedisSentinel {
log.Printf("Running in sentinel mode")
useSentinel = true
}
return EnvValues{
RedisURL: redisURL,
RedisPassword: redisPassword,
ConfDir: configDir,
GitlabAPIKey: gitlabPAToken,
UseSentinel: useSentinel,
}
}
func checkLiveliness(client *redis.Client) {
http.HandleFunc("/healthz", func(w http.ResponseWriter, r *http.Request) {
if err := client.Ping().Err(); err != nil {
http.Error(w, "Unable to connect to the redis master", http.StatusInternalServerError)
} else {
fmt.Fprintf(w, "All is well!")
}
})
err := http.ListenAndServe(":8081", nil)
if err != nil {
log.Printf("Unable to start /healthz webserver")
}
}
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment