Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[STK-227] Pingdom support #55

Merged
merged 10 commits into from
May 31, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion Jenkinsfile
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ toolsNode(toolsImage: 'stakater/pipeline-tools:1.5.1') {
stage('Build Binary') {
sh """
cd ${srcDir}
go build -o ..out/${repoName.toLowerCase()}
go build -o ../out/${repoName.toLowerCase()}
"""
}

Expand Down
3 changes: 2 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ This controller will continuously watch ingresses in the namespace it is running
Currently we support the following monitors:

- [UptimeRobot](https://uptimerobot.com)
- [Pingdom](https://pingdom.com) ([Additional Config](https://github.com/stakater/IngressMonitorController/blob/master/docs/pingdom-configuration.md))

## Deploying to Kubernetes

Expand Down Expand Up @@ -83,7 +84,7 @@ type MonitorService interface {
Update(m Monitor)
GetByName(name string) (*Monitor, error)
Remove(m Monitor)
Setup(apiKey string, url string, alertContacts string)
Setup(provider Provider)
}
```

Expand Down
10 changes: 10 additions & 0 deletions docs/pingdom-configuration.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
# Pingdom Configuration

Currently additional pingdom configurations can be added through a set of annotations to each ingress object, the current supported annotations are:

| Annotation | Description |
|:--------------------------------------------------------:|:------------------------------------------------:|
| monitor.stakater.com/pingdom/resolution | The pingdom check interval in minutes |
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why do we have this as a pingdom the only configuration? Surely this could be abstracted away and used between uptimerobot as well?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes you are correct, this should be done. Feel free to leave an issue or create a PR and we'll be welcome to add this change as soon as possible

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@drubin I've opened the issue here #69.

| monitor.stakater.com/pingdom/send-notification-when-down | How many failed check attempts before notifying |
| monitor.stakater.com/pingdom/paused | Set to "true" to pause checks |
| monitor.stakater.com/pingdom/notify-when-back-up | Set to "false" to disable recovery notifications |
Binary file removed src/..out/ingressmonitorcontroller
Binary file not shown.
5 changes: 4 additions & 1 deletion src/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,17 +18,20 @@ type Provider struct {
ApiKey string `yaml:"apiKey"`
ApiURL string `yaml:"apiURL"`
AlertContacts string `yaml:"alertContacts"`
Username string `yaml:"username"`
Password string `yaml:"password"`
}

func (p *Provider) createMonitorService() MonitorServiceProxy {
monitorService := (&MonitorServiceProxy{}).OfType(p.Name)
monitorService.Setup(p.ApiKey, p.ApiURL, p.AlertContacts)
monitorService.Setup(*p)
return monitorService
}

func ReadConfig(filePath string) Config {
var config Config
// Read YML
log.Println("Reading YAML Configuration")
source, err := ioutil.ReadFile(filePath)
if err != nil {
log.Panic(err)
Expand Down
33 changes: 19 additions & 14 deletions src/controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ const monitorHealthAnnotation = "monitor.stakater.com/healthEndpoint" // "/healt

// MonitorController which can be used for monitoring ingresses
type MonitorController struct {
clientset *kubernetes.Clientset
kubeClient kubernetes.Interface
namespace string
indexer cache.Indexer
queue workqueue.RateLimitingInterface
Expand All @@ -29,19 +29,19 @@ type MonitorController struct {
config Config
}

func NewMonitorController(namespace string, clientset *kubernetes.Clientset, config Config) *MonitorController {
func NewMonitorController(namespace string, kubeClient kubernetes.Interface, config Config) *MonitorController {
controller := &MonitorController{
clientset: clientset,
namespace: namespace,
config: config,
kubeClient: kubeClient,
namespace: namespace,
config: config,
}

controller.monitorServices = setupMonitorServicesForProviders(config.Providers)

queue := workqueue.NewRateLimitingQueue(workqueue.DefaultControllerRateLimiter())

// Create the Ingress Watcher
ingressListWatcher := cache.NewListWatchFromClient(clientset.ExtensionsV1beta1().RESTClient(), "ingresses", namespace, fields.Everything())
ingressListWatcher := cache.NewListWatchFromClient(kubeClient.ExtensionsV1beta1().RESTClient(), "ingresses", namespace, fields.Everything())

indexer, informer := cache.NewIndexerInformer(ingressListWatcher, &v1beta1.Ingress{}, 0, cache.ResourceEventHandlerFuncs{
AddFunc: controller.onIngressAdded,
Expand Down Expand Up @@ -154,9 +154,9 @@ func (c *MonitorController) getMonitorName(ingressName string, namespace string)

func (c *MonitorController) getMonitorURL(ingress *v1beta1.Ingress) string {
ingressWrapper := IngressWrapper{
ingress: ingress,
namespace: c.namespace,
clientset: c.clientset,
ingress: ingress,
namespace: c.namespace,
kubeClient: c.kubeClient,
}

return ingressWrapper.getURL()
Expand All @@ -174,7 +174,7 @@ func (c *MonitorController) handleIngressOnCreationOrUpdation(ingress *v1beta1.I
if value, ok := annotations[monitorEnabledAnnotation]; ok {
if value == "true" {
// Annotation exists and is enabled
c.createOrUpdateMonitors(monitorName, monitorURL)
c.createOrUpdateMonitors(monitorName, monitorURL, annotations)
} else {
// Annotation exists but is disabled
c.removeMonitorsIfExist(monitorName)
Expand Down Expand Up @@ -202,26 +202,31 @@ func (c *MonitorController) removeMonitorIfExists(monitorService MonitorServiceP
}
}

func (c *MonitorController) createOrUpdateMonitors(monitorName string, monitorURL string) {
func (c *MonitorController) createOrUpdateMonitors(monitorName string, monitorURL string, annotations map[string]string) {
for index := 0; index < len(c.monitorServices); index++ {
monitorService := c.monitorServices[index]
c.createOrUpdateMonitor(monitorService, monitorName, monitorURL)
c.createOrUpdateMonitor(monitorService, monitorName, monitorURL, annotations)
}
}

func (c *MonitorController) createOrUpdateMonitor(monitorService MonitorServiceProxy, monitorName string, monitorURL string) {
func (c *MonitorController) createOrUpdateMonitor(monitorService MonitorServiceProxy, monitorName string, monitorURL string, annotations map[string]string) {
m, _ := monitorService.GetByName(monitorName)

if m != nil { // Monitor Already Exists
log.Println("Monitor already exists for ingress: " + monitorName)
if m.url != monitorURL { // Monitor does not have the same url
// update the monitor with the new url
m.url = monitorURL
m.annotations = annotations
monitorService.Update(*m)
}
} else {
// Create a new monitor for this ingress
m := Monitor{name: monitorName, url: monitorURL}
m := Monitor{
name: monitorName,
url: monitorURL,
annotations: annotations,
}
monitorService.Add(m)
}
}
Expand Down
Loading