Skip to content

Commit

Permalink
Granular and Extended Event Alerting
Browse files Browse the repository at this point in the history
fixes vmware-archive#105

This feature adds support to alert on specific event type per resource.
For example, to watch only create and update events on deployment resource, kubewatch.yaml should be
 resource:
  deployment:
    watch: true
    events:
      create: true
      update: true
      delete: false
This also adds custom event type 'loadbalancercreate' to notify when there is a loadbalancer created for a service.
 resource:
  services:
    watch: true
    events:
      create: true
      update: true
      delete: true
      loadbalancercreate: true
  • Loading branch information
akshaychitneni authored and unbreakab1e committed Mar 5, 2019
1 parent 85513b3 commit 69cca93
Show file tree
Hide file tree
Showing 5 changed files with 245 additions and 107 deletions.
60 changes: 48 additions & 12 deletions cmd/resource.go
Original file line number Diff line number Diff line change
Expand Up @@ -36,84 +36,120 @@ var resourceConfigCmd = &cobra.Command{
var b bool
b, err = cmd.Flags().GetBool("svc")
if err == nil {
conf.Resource.Services = b
conf.Resource.Services.Watch = b
conf.Resource.Services.Events.Create = b
conf.Resource.Services.Events.Update = b
conf.Resource.Services.Events.Delete = b
} else {
logrus.Fatal("svc", err)
}

b, err = cmd.Flags().GetBool("deployments")
if err == nil {
conf.Resource.Deployment = b
conf.Resource.Deployment.Watch = b
conf.Resource.Deployment.Events.Create = b
conf.Resource.Deployment.Events.Update = b
conf.Resource.Deployment.Events.Delete = b
} else {
logrus.Fatal("deployments", err)
}

b, err = cmd.Flags().GetBool("po")
if err == nil {
conf.Resource.Pod = b
conf.Resource.Pod.Watch = b
conf.Resource.Pod.Events.Create = b
conf.Resource.Pod.Events.Update = b
conf.Resource.Pod.Events.Delete = b
} else {
logrus.Fatal("po", err)
}

b, err = cmd.Flags().GetBool("rs")
if err == nil {
conf.Resource.ReplicaSet = b
conf.Resource.ReplicaSet.Watch = b
conf.Resource.ReplicaSet.Events.Create = b
conf.Resource.ReplicaSet.Events.Update = b
conf.Resource.ReplicaSet.Events.Delete = b
} else {
logrus.Fatal("rs", err)
}

b, err = cmd.Flags().GetBool("rc")
if err == nil {
conf.Resource.ReplicationController = b
conf.Resource.ReplicationController.Watch = b
conf.Resource.ReplicationController.Events.Create = b
conf.Resource.ReplicationController.Events.Update = b
conf.Resource.ReplicationController.Events.Delete = b
} else {
logrus.Fatal("rc", err)
}

b, err = cmd.Flags().GetBool("ns")
if err == nil {
conf.Resource.Namespace = b
conf.Resource.Namespace.Watch = b
conf.Resource.Namespace.Events.Create = b
conf.Resource.Namespace.Events.Update = b
conf.Resource.Namespace.Events.Delete = b
} else {
logrus.Fatal("ns", err)
}

b, err = cmd.Flags().GetBool("jobs")
if err == nil {
conf.Resource.Job = b
conf.Resource.Job.Watch = b
conf.Resource.Job.Events.Create = b
conf.Resource.Job.Events.Update = b
conf.Resource.Job.Events.Delete = b
} else {
logrus.Fatal("jobs", err)
}

b, err = cmd.Flags().GetBool("pv")
if err == nil {
conf.Resource.PersistentVolume = b
conf.Resource.PersistentVolume.Watch = b
conf.Resource.PersistentVolume.Events.Create = b
conf.Resource.PersistentVolume.Events.Update = b
conf.Resource.PersistentVolume.Events.Delete = b
} else {
logrus.Fatal("pv", err)
}

b, err = cmd.Flags().GetBool("ds")
if err == nil {
conf.Resource.DaemonSet = b
conf.Resource.DaemonSet.Watch = b
conf.Resource.DaemonSet.Events.Create = b
conf.Resource.DaemonSet.Events.Update = b
conf.Resource.DaemonSet.Events.Delete = b
} else {
logrus.Fatal("ds", err)
}

b, err = cmd.Flags().GetBool("secret")
if err == nil {
conf.Resource.Secret = b
conf.Resource.Secret.Watch = b
conf.Resource.Secret.Events.Create = b
conf.Resource.Secret.Events.Update = b
conf.Resource.Secret.Events.Delete = b
} else {
logrus.Fatal("secret", err)
}

b, err = cmd.Flags().GetBool("configmap")
if err == nil {
conf.Resource.ConfigMap = b
conf.Resource.ConfigMap.Watch = b
conf.Resource.ConfigMap.Events.Create = b
conf.Resource.ConfigMap.Events.Update = b
conf.Resource.ConfigMap.Events.Delete = b
} else {
logrus.Fatal("configmap", err)
}

b, err = cmd.Flags().GetBool("ing")
if err == nil {
conf.Resource.Ingress = b
conf.Resource.Ingress.Watch = b
conf.Resource.Ingress.Events.Create = b
conf.Resource.Ingress.Events.Update = b
conf.Resource.Ingress.Events.Delete = b
} else {
logrus.Fatal("ing", err)
}
Expand Down
120 changes: 84 additions & 36 deletions config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -37,18 +37,30 @@ type Handler struct {

// Resource contains resource configuration
type Resource struct {
Deployment bool `json:"deployment"`
ReplicationController bool `json:"rc"`
ReplicaSet bool `json:"rs"`
DaemonSet bool `json:"ds"`
Services bool `json:"svc"`
Pod bool `json:"po"`
Job bool `json:"job"`
PersistentVolume bool `json:"pv"`
Namespace bool `json:"ns"`
Secret bool `json:"secret"`
ConfigMap bool `json:"configmap"`
Ingress bool `json:"ing"`
Deployment WatchType `json:"deployment"`
ReplicationController WatchType `json:"rc"`
ReplicaSet WatchType `json:"rs"`
DaemonSet WatchType `json:"ds"`
Services WatchType `json:"svc"`
Pod WatchType `json:"po"`
Job WatchType `json:"job"`
PersistentVolume WatchType `json:"pv"`
Namespace WatchType `json:"ns"`
Secret WatchType `json:"secret"`
ConfigMap WatchType `json:"configmap"`
Ingress WatchType `json:"ing"`
}

type WatchType struct {
Watch bool `json:"watch"`
Events EventType `json:"events"`
}

type EventType struct {
Create bool `json:"create"`
Update bool `json:"update"`
Delete bool `json:"delete"`
LoadBalancerCreate bool `json:"loadbalancercreate"`
}

// Config struct contains kubewatch configuration
Expand Down Expand Up @@ -144,41 +156,77 @@ func (c *Config) Load() error {
}

func (c *Config) CheckMissingResourceEnvvars() {
if !c.Resource.DaemonSet && os.Getenv("KW_DAEMONSET") == "true" {
c.Resource.DaemonSet = true
if !c.Resource.DaemonSet.Watch && os.Getenv("KW_DAEMONSET") == "true" {
c.Resource.DaemonSet.Watch = true
c.Resource.DaemonSet.Events.Create = true
c.Resource.DaemonSet.Events.Update = true
c.Resource.DaemonSet.Events.Delete = true
}
if !c.Resource.ReplicaSet && os.Getenv("KW_REPLICASET") == "true" {
c.Resource.ReplicaSet = true
if !c.Resource.ReplicaSet.Watch && os.Getenv("KW_REPLICASET") == "true" {
c.Resource.ReplicaSet.Watch = true
c.Resource.ReplicaSet.Events.Create = true
c.Resource.ReplicaSet.Events.Update = true
c.Resource.ReplicaSet.Events.Delete = true
}
if !c.Resource.Namespace && os.Getenv("KW_NAMESPACE") == "true" {
c.Resource.Namespace = true
if !c.Resource.Namespace.Watch && os.Getenv("KW_NAMESPACE") == "true" {
c.Resource.Namespace.Watch = true
c.Resource.Namespace.Events.Create = true
c.Resource.Namespace.Events.Update = true
c.Resource.Namespace.Events.Delete = true
}
if !c.Resource.Deployment && os.Getenv("KW_DEPLOYMENT") == "true" {
c.Resource.Deployment = true
if !c.Resource.Deployment.Watch && os.Getenv("KW_DEPLOYMENT") == "true" {
c.Resource.Deployment.Watch = true
c.Resource.Deployment.Events.Create = true
c.Resource.Deployment.Events.Update = true
c.Resource.Deployment.Events.Delete = true
}
if !c.Resource.Pod && os.Getenv("KW_POD") == "true" {
c.Resource.Pod = true
if !c.Resource.Pod.Watch && os.Getenv("KW_POD") == "true" {
c.Resource.Pod.Watch = true
c.Resource.Pod.Events.Create = true
c.Resource.Pod.Events.Update = true
c.Resource.Pod.Events.Delete = true
}
if !c.Resource.ReplicationController && os.Getenv("KW_REPLICATION_CONTROLLER") == "true" {
c.Resource.ReplicationController = true
if !c.Resource.ReplicationController.Watch && os.Getenv("KW_REPLICATION_CONTROLLER") == "true" {
c.Resource.ReplicationController.Watch = true
c.Resource.ReplicationController.Events.Create = true
c.Resource.ReplicationController.Events.Update = true
c.Resource.ReplicationController.Events.Delete = true
}
if !c.Resource.Services && os.Getenv("KW_SERVICE") == "true" {
c.Resource.Services = true
if !c.Resource.Services.Watch && os.Getenv("KW_SERVICE") == "true" {
c.Resource.Services.Watch = true
c.Resource.Services.Events.Create = true
c.Resource.Services.Events.Update = true
c.Resource.Services.Events.Delete = true
}
if !c.Resource.Job && os.Getenv("KW_JOB") == "true" {
c.Resource.Job = true
if !c.Resource.Job.Watch && os.Getenv("KW_JOB") == "true" {
c.Resource.Job.Watch = true
c.Resource.Job.Events.Create = true
c.Resource.Job.Events.Update = true
c.Resource.Job.Events.Delete = true
}
if !c.Resource.PersistentVolume && os.Getenv("KW_PERSISTENT_VOLUME") == "true" {
c.Resource.PersistentVolume = true
if !c.Resource.PersistentVolume.Watch && os.Getenv("KW_PERSISTENT_VOLUME") == "true" {
c.Resource.PersistentVolume.Watch = true
c.Resource.PersistentVolume.Events.Create = true
c.Resource.PersistentVolume.Events.Update = true
c.Resource.PersistentVolume.Events.Delete = true
}
if !c.Resource.Secret && os.Getenv("KW_SECRET") == "true" {
c.Resource.Secret = true
if !c.Resource.Secret.Watch && os.Getenv("KW_SECRET") == "true" {
c.Resource.Secret.Watch = true
c.Resource.Secret.Events.Create = true
c.Resource.Secret.Events.Update = true
c.Resource.Secret.Events.Delete = true
}
if !c.Resource.ConfigMap && os.Getenv("KW_CONFIGMAP") == "true" {
c.Resource.ConfigMap = true
if !c.Resource.ConfigMap.Watch && os.Getenv("KW_CONFIGMAP") == "true" {
c.Resource.ConfigMap.Watch = true
c.Resource.ConfigMap.Events.Create = true
c.Resource.ConfigMap.Events.Update = true
c.Resource.ConfigMap.Events.Delete = true
}
if !c.Resource.Ingress && os.Getenv("KW_INGRESS") == "true" {
c.Resource.Ingress = true
if !c.Resource.Ingress.Watch && os.Getenv("KW_INGRESS") == "true" {
c.Resource.Ingress.Watch = true
c.Resource.Ingress.Events.Create = true
c.Resource.Ingress.Events.Update = true
c.Resource.Ingress.Events.Delete = true
}
if (c.Handler.Slack.Channel == "") && (os.Getenv("SLACK_CHANNEL") != "") {
c.Handler.Slack.Channel = os.Getenv("SLACK_CHANNEL")
Expand Down
44 changes: 36 additions & 8 deletions kubewatch-configmap.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,39 @@ data:
token: <token>
channel: <channel>
resource:
deployment: false
replicationcontroller: false
replicaset: false
daemonset: false
services: true
pod: true
secret: false
configmap: false
deployment:
watch: true
events:
create: true
update: false
delete: true
replicationcontroller:
watch: true
events:
create: true
replicaset:
watch: true
events:
create: true
daemonset:
watch: true
events:
create: true
services:
watch: true
events:
create: true
update: true
loadbalancercreate: true
pod:
watch: true
events:
create: true
secret:
watch: true
events:
create: true
configmap:
watch: true
events:
create: true
Loading

0 comments on commit 69cca93

Please sign in to comment.