Skip to content

Commit d645f2d

Browse files
authored
Merge pull request #6 from home-operations/buroa/guarded
2 parents 4b66c73 + 24d4e87 commit d645f2d

File tree

6 files changed

+76
-38
lines changed

6 files changed

+76
-38
lines changed

README.md

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,6 @@ gatus-sidecar [options]
5151
| `--output` | `/config/gatus-sidecar.yaml` | File to write generated YAML |
5252
| `--default-interval` | `1m` | Default interval value for endpoints |
5353
| `--default-dns` | `tcp://1.1.1.1:53` | Default DNS resolver for endpoints |
54-
| `--default-condition` | `[STATUS] == 200` | Default condition for health checks |
5554
| `--annotation-config` | `gatus.home-operations.com/endpoint` | Annotation key for YAML config override |
5655

5756
### 🌐 HTTPRoute Mode

internal/config/config.go

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ type Config struct {
1818
DefaultInterval time.Duration
1919
DefaultDNSResolver string
2020
TemplateAnnotation string
21+
GuardedAnnotation string
2122
EnabledAnnotation string
2223
}
2324

@@ -26,15 +27,16 @@ func Load() *Config {
2627
flag.StringVar(&cfg.Namespace, "namespace", "", "Namespace to watch (empty for all)")
2728
flag.StringVar(&cfg.GatewayName, "gateway-name", "", "Gateway name to filter HTTPRoutes (optional)")
2829
flag.StringVar(&cfg.IngressClass, "ingress-class", "", "Ingress class to filter Ingresses (optional)")
29-
flag.BoolVar(&cfg.AutoRoutes, "auto-routes", true, "Automatically create endpoints for HTTPRoutes")
30-
flag.BoolVar(&cfg.AutoIngresses, "auto-ingresses", true, "Automatically create endpoints for Ingresses")
30+
flag.BoolVar(&cfg.AutoRoutes, "auto-routes", false, "Automatically create endpoints for HTTPRoutes")
31+
flag.BoolVar(&cfg.AutoIngresses, "auto-ingresses", false, "Automatically create endpoints for Ingresses")
3132
flag.BoolVar(&cfg.AutoServices, "auto-services", false, "Automatically create endpoints for Services")
3233
flag.BoolVar(&cfg.AutoGroup, "auto-group", false, "Automatically group endpoints by namespace (for Services) or gateway/ingress class (for HTTPRoutes/Ingresses)")
3334
flag.StringVar(&cfg.Output, "output", "/config/gatus-sidecar.yaml", "File to write generated YAML")
3435
flag.DurationVar(&cfg.DefaultInterval, "default-interval", time.Minute, "Default interval value for endpoints")
3536
flag.StringVar(&cfg.DefaultDNSResolver, "default-dns", "tcp://1.1.1.1:53", "Default DNS resolver for endpoints")
3637
flag.StringVar(&cfg.TemplateAnnotation, "annotation-config", "gatus.home-operations.com/endpoint", "Annotation key for YAML config override")
3738
flag.StringVar(&cfg.EnabledAnnotation, "annotation-enabled", "gatus.home-operations.com/enabled", "Annotation key for enabling/disabling resource processing")
39+
flag.StringVar(&cfg.GuardedAnnotation, "annotation-guarded", "gatus.home-operations.com/guarded", "Annotation key for guarding endpoints")
3840
flag.Parse()
3941
return cfg
4042
}

internal/controller/httproute.go

Lines changed: 22 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -40,8 +40,11 @@ func (h *HTTPRouteHandler) ShouldProcess(obj metav1.Object, cfg *config.Config)
4040
return false
4141
}
4242

43-
_, hasAnnotation := annotations[cfg.EnabledAnnotation]
44-
return hasAnnotation
43+
_, hasEnabledAnnotation := annotations[cfg.EnabledAnnotation]
44+
_, hasGuardedAnnotation := annotations[cfg.GuardedAnnotation]
45+
_, hasTemplateAnnotation := annotations[cfg.TemplateAnnotation]
46+
47+
return hasEnabledAnnotation || hasGuardedAnnotation || hasTemplateAnnotation
4548
}
4649

4750
return true
@@ -66,19 +69,30 @@ func (h *HTTPRouteHandler) ExtractURL(obj metav1.Object) string {
6669
}
6770

6871
func (h *HTTPRouteHandler) ApplyTemplate(cfg *config.Config, obj metav1.Object, endpoint *endpoint.Endpoint) {
69-
if cfg.AutoGroup {
70-
route, ok := obj.(*gatewayv1.HTTPRoute)
71-
if !ok {
72-
return
73-
}
72+
route, ok := obj.(*gatewayv1.HTTPRoute)
73+
if !ok {
74+
return
75+
}
7476

75-
// Group by first ParentRef (usually the Gateway)
77+
if cfg.AutoGroup {
7678
if len(route.Spec.ParentRefs) > 0 {
7779
endpoint.Group = string(route.Spec.ParentRefs[0].Name)
7880
}
7981
}
8082

8183
endpoint.Conditions = []string{"[STATUS] == 200"}
84+
85+
annotations := obj.GetAnnotations()
86+
if annotations != nil {
87+
if guardedValue, ok := annotations[cfg.GuardedAnnotation]; ok && (guardedValue == "true" || guardedValue == "1") {
88+
endpoint.URL = "1.1.1.1"
89+
endpoint.DNS = map[string]any{
90+
"query-name": firstHTTPRouteHostname(route),
91+
"query-type": "A",
92+
}
93+
endpoint.Conditions = []string{"len([BODY]) == 0"}
94+
}
95+
}
8296
}
8397

8498
// Helper functions for HTTPRoute

internal/controller/ingress.go

Lines changed: 22 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -41,8 +41,11 @@ func (h *IngressHandler) ShouldProcess(obj metav1.Object, cfg *config.Config) bo
4141
return false
4242
}
4343

44-
_, hasAnnotation := annotations[cfg.EnabledAnnotation]
45-
return hasAnnotation
44+
_, hasEnabledAnnotation := annotations[cfg.EnabledAnnotation]
45+
_, hasGuardedAnnotation := annotations[cfg.GuardedAnnotation]
46+
_, hasTemplateAnnotation := annotations[cfg.TemplateAnnotation]
47+
48+
return hasEnabledAnnotation || hasGuardedAnnotation || hasTemplateAnnotation
4649
}
4750

4851
return true
@@ -73,20 +76,31 @@ func (h *IngressHandler) ExtractURL(obj metav1.Object) string {
7376
}
7477

7578
func (h *IngressHandler) ApplyTemplate(cfg *config.Config, obj metav1.Object, endpoint *endpoint.Endpoint) {
76-
if cfg.AutoGroup {
77-
ingress, ok := obj.(*networkingv1.Ingress)
78-
if !ok {
79-
return
80-
}
79+
ingress, ok := obj.(*networkingv1.Ingress)
80+
if !ok {
81+
return
82+
}
8183

82-
// Group by ingress class if available
84+
if cfg.AutoGroup {
8385
ingressClass := getIngressClass(ingress)
8486
if ingressClass != "" {
8587
endpoint.Group = ingressClass
8688
}
8789
}
8890

8991
endpoint.Conditions = []string{"[STATUS] == 200"}
92+
93+
annotations := obj.GetAnnotations()
94+
if annotations != nil {
95+
if guardedValue, ok := annotations[cfg.GuardedAnnotation]; ok && (guardedValue == "true" || guardedValue == "1") {
96+
endpoint.URL = "1.1.1.1"
97+
endpoint.DNS = map[string]any{
98+
"query-name": firstIngressHostname(ingress),
99+
"query-type": "A",
100+
}
101+
endpoint.Conditions = []string{"len([BODY]) == 0"}
102+
}
103+
}
90104
}
91105

92106
// Helper functions for Ingress

internal/controller/service.go

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -36,8 +36,11 @@ func (h *ServiceHandler) ShouldProcess(obj metav1.Object, cfg *config.Config) bo
3636
return false
3737
}
3838

39-
_, hasAnnotation := annotations[cfg.EnabledAnnotation]
40-
return hasAnnotation
39+
_, hasEnabledAnnotation := annotations[cfg.EnabledAnnotation]
40+
_, hasGuardedAnnotation := annotations[cfg.GuardedAnnotation]
41+
_, hasTemplateAnnotation := annotations[cfg.TemplateAnnotation]
42+
43+
return hasEnabledAnnotation || hasGuardedAnnotation || hasTemplateAnnotation
4144
}
4245

4346
return true
@@ -63,12 +66,12 @@ func (h *ServiceHandler) ExtractURL(obj metav1.Object) string {
6366
}
6467

6568
func (h *ServiceHandler) ApplyTemplate(cfg *config.Config, obj metav1.Object, endpoint *endpoint.Endpoint) {
69+
endpoint.Client = nil // Use default client configuration
70+
endpoint.Conditions = []string{"[CONNECTED] == true"}
71+
6672
if cfg.AutoGroup {
6773
endpoint.Group = obj.GetNamespace()
6874
}
69-
70-
endpoint.Client = nil // Use default client configuration
71-
endpoint.Conditions = []string{"[CONNECTED] == true"}
7275
}
7376

7477
// NewServiceController creates a controller for Service resources

internal/endpoint/endpoint.go

Lines changed: 20 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -7,9 +7,11 @@ type Endpoint struct {
77
Name string `yaml:"name"`
88
Group string `yaml:"group,omitempty"`
99
URL string `yaml:"url"`
10+
Conditions []string `yaml:"conditions,omitempty"`
1011
Interval string `yaml:"interval"`
12+
DNS map[string]any `yaml:"dns,omitempty"`
1113
Client map[string]any `yaml:"client,omitempty"`
12-
Conditions []string `yaml:"conditions,omitempty"`
14+
UI map[string]any `yaml:"ui,omitempty"`
1315
Extra map[string]any `yaml:",inline,omitempty"` // For additional template fields
1416
}
1517

@@ -28,12 +30,16 @@ func (e *Endpoint) ApplyTemplate(templateData map[string]any) {
2830
e.setStringField(&e.Group, value)
2931
case "url":
3032
e.setStringField(&e.URL, value)
33+
case "conditions":
34+
e.setConditionsField(value)
3135
case "interval":
3236
e.setStringField(&e.Interval, value)
37+
case "dns":
38+
e.setMapField(&e.DNS, value)
3339
case "client":
34-
e.setClientField(value)
35-
case "conditions":
36-
e.setConditionsField(value)
40+
e.setMapField(&e.Client, value)
41+
case "ui":
42+
e.setMapField(&e.UI, value)
3743
default:
3844
// Store other fields in Extra for inline YAML output
3945
e.AddExtraField(key, value)
@@ -55,16 +61,6 @@ func (e *Endpoint) setStringField(field *string, value any) {
5561
}
5662
}
5763

58-
// setClientField merges client settings
59-
func (e *Endpoint) setClientField(value any) {
60-
if client, ok := value.(map[string]any); ok {
61-
if e.Client == nil {
62-
e.Client = make(map[string]any)
63-
}
64-
maps.Copy(e.Client, client)
65-
}
66-
}
67-
6864
// setConditionsField handles different condition formats
6965
func (e *Endpoint) setConditionsField(value any) {
7066
switch v := value.(type) {
@@ -82,3 +78,13 @@ func (e *Endpoint) setConditionsField(value any) {
8278
e.Conditions = []string{v}
8379
}
8480
}
81+
82+
// setMapField merges map settings into the specified field
83+
func (e *Endpoint) setMapField(field *map[string]any, value any) {
84+
if mapValue, ok := value.(map[string]any); ok {
85+
if *field == nil {
86+
*field = make(map[string]any)
87+
}
88+
maps.Copy(*field, mapValue)
89+
}
90+
}

0 commit comments

Comments
 (0)