Compare commits

...
1 Commits
Author SHA1 Message Date
Stavros c7077a7c84 fix: do not allow empty ingresses 2026-07-21 00:37:13 +03:00
2 changed files with 80 additions and 19 deletions
+18 -19
View File
@@ -201,6 +201,12 @@ func (k *KubernetesService) updateFromItem(item *unstructured.Unstructured) {
return return
} }
if len(hosts) == 0 {
k.log.App.Warn().Str("namespace", key.namespace).Str("name", key.name).Msg("No hosts found in ingress, skipping")
k.removeIngress(key)
return
}
labels, err := decoders.DecodeLabels[model.Apps](annotations, "apps") labels, err := decoders.DecodeLabels[model.Apps](annotations, "apps")
if err != nil { if err != nil {
k.log.App.Warn().Err(err).Str("namespace", key.namespace).Str("name", key.name).Msg("Failed to decode ingress labels, skipping") k.log.App.Warn().Err(err).Str("namespace", key.namespace).Str("name", key.name).Msg("Failed to decode ingress labels, skipping")
@@ -213,35 +219,28 @@ func (k *KubernetesService) updateFromItem(item *unstructured.Unstructured) {
v := validators.NewDomainValidator(validators.DomainValidatorOptions{}) v := validators.NewDomainValidator(validators.DomainValidatorOptions{})
for name, config := range labels.Apps { for name, config := range labels.Apps {
registerApp := len(hosts) == 0
if config.Config.Domain != "" { if config.Config.Domain != "" {
hostname, err := v.SafeHostname(config.Config.Domain) hostname, err := v.SafeHostname(config.Config.Domain)
if err != nil { if err != nil {
k.log.App.Warn().Err(err).Str("namespace", key.namespace).Str("name", key.name).Str("domain", config.Config.Domain).Msg("Domain is invalid, matching will rely on app name") k.log.App.Warn().Err(err).Str("namespace", key.namespace).Str("name", key.name).Str("domain", config.Config.Domain).Msg("Domain is invalid, matching will rely on app name")
} else if slices.Contains(hosts, hostname) { } else if slices.Contains(hosts, hostname) {
registerApp = true entries = append(entries, ingressEntry{
name: name,
app: config,
})
continue
} }
} }
if !registerApp { for _, host := range hosts {
for _, host := range hosts { if strings.HasPrefix(strings.ToLower(host), strings.ToLower(name+".")) {
if strings.HasPrefix(strings.ToLower(host), strings.ToLower(name+".")) { entries = append(entries, ingressEntry{
registerApp = true name: name,
break app: config,
} })
break
} }
} }
if !registerApp {
k.log.App.Warn().Str("namespace", key.namespace).Str("name", name).Str("appName", name).Msg("App name or domain does not match with ingress")
continue
}
entries = append(entries, ingressEntry{
name: name,
app: config,
})
} }
if len(entries) == 0 { if len(entries) == 0 {
@@ -231,6 +231,13 @@ func TestKubernetesService(t *testing.T) {
"tinyauth.apps.myapp.config.domain": "myapp.example.com", "tinyauth.apps.myapp.config.domain": "myapp.example.com",
"tinyauth.apps.myapp.users.allow": "alice", "tinyauth.apps.myapp.users.allow": "alice",
}) })
item.Object["spec"] = map[string]any{
"rules": []any{
map[string]any{
"host": "myapp.example.com",
},
},
}
svc.updateFromItem(&item) svc.updateFromItem(&item)
@@ -248,6 +255,61 @@ func TestKubernetesService(t *testing.T) {
assert.Equal(t, "alice", got.Users.Allow) assert.Equal(t, "alice", got.Users.Allow)
}, },
}, },
{
description: "Update from item skips annotations with no hosts",
run: func(t *testing.T, svc *KubernetesService) {
item := unstructured.Unstructured{}
item.SetNamespace("default")
item.SetName("test-ingress")
item.SetAnnotations(map[string]string{
"tinyauth.apps.myapp.config.domain": "myapp.example.com",
})
svc.updateFromItem(&item)
var got *model.App
svc.getEntry(func(name string, app *model.App) bool {
if app.Config.Domain == "myapp.example.com" {
got = app
return true
}
return false
})
assert.Nil(t, got)
},
},
{
description: "UpdateFromItem fails when label parsing fails",
run: func(t *testing.T, svc *KubernetesService) {
item := unstructured.Unstructured{}
item.SetNamespace("default")
item.SetName("test-ingress")
item.SetAnnotations(map[string]string{
"tinyauth.apps.myapp.config.domain": "myapp.example.com",
"tinyauth.apps.myapp.users.break": "i-dont-exist",
})
item.Object["spec"] = map[string]any{
"rules": []any{
map[string]any{
"host": "myapp.example.com",
},
},
}
svc.updateFromItem(&item)
var got *model.App
svc.getEntry(func(name string, app *model.App) bool {
if app.Config.Domain == "myapp.example.com" {
got = app
return true
}
return false
})
require.Nil(t, got)
},
},
{ {
description: "UpdateFromItem with no annotations removes existing cache entries", description: "UpdateFromItem with no annotations removes existing cache entries",
run: func(t *testing.T, svc *KubernetesService) { run: func(t *testing.T, svc *KubernetesService) {