-
Notifications
You must be signed in to change notification settings - Fork 38
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
draft: new kubernetes resource check
[skip ci]
- Loading branch information
1 parent
085f91b
commit 6c44678
Showing
11 changed files
with
901 additions
and
41 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,106 @@ | ||
package checks | ||
|
||
import ( | ||
"fmt" | ||
"strings" | ||
|
||
"github.com/flanksource/canary-checker/api/context" | ||
v1 "github.com/flanksource/canary-checker/api/v1" | ||
"github.com/flanksource/canary-checker/pkg" | ||
"github.com/flanksource/commons/logger" | ||
"github.com/flanksource/duty/types" | ||
) | ||
|
||
// maximum number of static & non static resources a canary can have | ||
const maxResourcesAllowed = 10 | ||
const annotationkey = "flanksource.canary-checker/kubernetes-resource-canary" | ||
|
||
type KubernetesResourceChecker struct{} | ||
|
||
func (c *KubernetesResourceChecker) Type() string { | ||
return "kubernetes_resource" | ||
} | ||
|
||
func (c *KubernetesResourceChecker) Run(ctx *context.Context) pkg.Results { | ||
var results pkg.Results | ||
for _, conf := range ctx.Canary.Spec.KubernetesResource { | ||
results = append(results, c.Check(ctx, conf)...) | ||
} | ||
return results | ||
} | ||
|
||
func (c *KubernetesResourceChecker) applyKubeconfig(ctx *context.Context, kubeConfig types.EnvVar) error { | ||
val, err := ctx.GetEnvValueFromCache(kubeConfig) | ||
if err != nil { | ||
return fmt.Errorf("failed to get kubeconfig from env: %w", err) | ||
} | ||
|
||
if strings.HasPrefix(val, "/") { | ||
kClient, kube, err := pkg.NewKommonsClientWithConfigPath(val) | ||
if err != nil { | ||
return fmt.Errorf("failed to initialize kubernetes client from the provided kubeconfig: %w", err) | ||
} | ||
|
||
ctx = ctx.WithDutyContext(ctx.WithKommons(kClient)) | ||
ctx = ctx.WithDutyContext(ctx.WithKubernetes(kube)) | ||
} else { | ||
kClient, kube, err := pkg.NewKommonsClientWithConfig(val) | ||
if err != nil { | ||
return fmt.Errorf("failed to initialize kubernetes client from the provided kubeconfig: %w", err) | ||
} | ||
|
||
ctx = ctx.WithDutyContext(ctx.WithKommons(kClient)) | ||
ctx = ctx.WithDutyContext(ctx.WithKubernetes(kube)) | ||
} | ||
|
||
return nil | ||
} | ||
|
||
func (c *KubernetesResourceChecker) Check(ctx *context.Context, check v1.KubernetesResourceCheck) pkg.Results { | ||
result := pkg.Success(check, ctx.Canary) | ||
var results pkg.Results | ||
results = append(results, result) | ||
|
||
totalResources := len(check.StaticResources) + len(check.Resources) | ||
if totalResources > maxResourcesAllowed { | ||
return results.Failf("too many resources (%d). only %d allowed", totalResources, maxResourcesAllowed) | ||
} | ||
|
||
if check.Kubeconfig != nil { | ||
if err := c.applyKubeconfig(ctx, *check.Kubeconfig); err != nil { | ||
return results.Failf("failed to apply kube config: %v", err) | ||
} | ||
} | ||
|
||
for i := range check.StaticResources { | ||
resource := check.StaticResources[i] | ||
|
||
// annotate the resource with the canary ID so we can easily clean it up later | ||
resource.SetAnnotations(map[string]string{annotationkey: ctx.Canary.ID()}) | ||
if err := ctx.Kommons().ApplyUnstructured(ctx.Namespace, &resource); err != nil { | ||
return results.Failf("failed to apply static resource %s: %v", resource.GetName(), err) | ||
} | ||
} | ||
|
||
for i := range check.Resources { | ||
resource := check.Resources[i] | ||
resource.SetAnnotations(map[string]string{annotationkey: ctx.Canary.ID()}) | ||
if err := ctx.Kommons().ApplyUnstructured(ctx.Namespace, &resource); err != nil { | ||
return results.Failf("failed to apply resource %s: %v", resource.GetName(), err) | ||
} | ||
|
||
defer func() { | ||
if err := ctx.Kommons().DeleteUnstructured(ctx.Namespace, &resource); err != nil { | ||
logger.Errorf("failed to delete resource %s: %v", resource.GetName(), err) | ||
} | ||
}() | ||
} | ||
|
||
if check.WaitForReady { | ||
logger.Infof("waiting for resources to be ready.") | ||
} | ||
|
||
// run the actual check now | ||
|
||
return nil | ||
} |
Oops, something went wrong.