Skip to content

Commit

Permalink
feat: only set namespace for namespaced resources
Browse files Browse the repository at this point in the history
  • Loading branch information
adityathebe authored and moshloop committed Nov 22, 2024
1 parent 38f2f72 commit 48d747b
Show file tree
Hide file tree
Showing 2 changed files with 59 additions and 6 deletions.
17 changes: 14 additions & 3 deletions api/v1/checks.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ import (
"github.com/samber/lo"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
"k8s.io/apimachinery/pkg/runtime/schema"
k8sTypes "k8s.io/apimachinery/pkg/types"
)

Expand Down Expand Up @@ -978,17 +979,27 @@ type KubernetesResourceCheck struct {
WaitFor KubernetesResourceCheckWaitFor `json:"waitFor,omitempty"`
}

func (c *KubernetesResourceCheck) HasResourcesWithMissingNamespace() bool {
for _, r := range append(c.StaticResources, c.Resources...) {
if r.GetNamespace() == "" {
return true
}
}

return false
}

// SetMissingNamespace will set the parent canaries name to resources whose namespace
// is not explicitly specified.
func (c *KubernetesResourceCheck) SetMissingNamespace(parent Canary) {
func (c *KubernetesResourceCheck) SetMissingNamespace(parent Canary, namespacedResources map[schema.GroupVersionKind]bool) {
for i, r := range c.StaticResources {
if r.GetNamespace() == "" {
if r.GetNamespace() == "" && namespacedResources[r.GroupVersionKind()] {
c.StaticResources[i].SetNamespace(parent.GetNamespace())
}
}

for i, r := range c.Resources {
if r.GetNamespace() == "" {
if r.GetNamespace() == "" && namespacedResources[r.GroupVersionKind()] {
c.Resources[i].SetNamespace(parent.GetNamespace())
}
}
Expand Down
48 changes: 45 additions & 3 deletions checks/kubernetes_resource.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import (
"github.com/flanksource/gomplate/v3"
"github.com/flanksource/is-healthy/pkg/health"
"github.com/flanksource/is-healthy/pkg/lua"
"github.com/patrickmn/go-cache"
"github.com/samber/lo"
"github.com/sethvargo/go-retry"
"golang.org/x/sync/errgroup"
Expand Down Expand Up @@ -70,9 +71,6 @@ func (c *KubernetesResourceChecker) Check(ctx context.Context, check v1.Kubernet
return results.Failf("validation: %v", err)
}

check.SetMissingNamespace(ctx.Canary)
check.SetCanaryOwnerReference(ctx.Canary)

if check.Kubeconfig != nil {
var err error
ctx, err = ctx.WithKubeconfig(*check.Kubeconfig)
Expand All @@ -81,6 +79,17 @@ func (c *KubernetesResourceChecker) Check(ctx context.Context, check v1.Kubernet
}
}

if check.HasResourcesWithMissingNamespace() {
namespacedResources, err := fetchNamespacedResources(ctx)
if err != nil {
return results.Failf("failed to get api resources: %w", err)
}

check.SetMissingNamespace(ctx.Canary, namespacedResources)
}

check.SetCanaryOwnerReference(ctx.Canary)

if err := templateKubernetesResourceCheck(ctx.Canary.GetPersistedID(), ctx.Canary.GetCheckID(check.GetName()), &check); err != nil {
return results.Failf("templating error: %v", err)
}
Expand Down Expand Up @@ -478,3 +487,36 @@ func templateKubernetesResourceCheck(canaryID, checkID string, check *v1.Kuberne

return nil
}

var apiResourceCache = cache.New(time.Hour*24, time.Hour*24)

func fetchNamespacedResources(ctx context.Context) (map[schema.GroupVersionKind]bool, error) {
kubeconfigCacheKey := ctx.KubernetesRestConfig().Host + ctx.KubernetesRestConfig().APIPath
if val, ok := apiResourceCache.Get(kubeconfigCacheKey); ok {
return val.(map[schema.GroupVersionKind]bool), nil
}

_, resourceList, err := ctx.Kubernetes().Discovery().ServerGroupsAndResources()
if err != nil {
return nil, fmt.Errorf("failed to get server groups & resources: %w", err)
}

namespaceResources := make(map[schema.GroupVersionKind]bool)
for _, apiResourceList := range resourceList {
for _, resource := range apiResourceList.APIResources {
if resource.Namespaced {
gv, _ := schema.ParseGroupVersion(apiResourceList.GroupVersion)
key := schema.GroupVersionKind{
Group: gv.Group,
Version: gv.Version,
Kind: resource.Kind,
}

namespaceResources[key] = true
}
}
}

apiResourceCache.SetDefault(kubeconfigCacheKey, namespaceResources)
return namespaceResources, nil
}

0 comments on commit 48d747b

Please sign in to comment.