policy-generator/cmd/policygen/cluster.go
2025-01-17 20:43:55 +01:00

104 lines
2.8 KiB
Go

package main
import (
"context"
v1 "k8s.io/api/core/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/labels"
"k8s.io/client-go/kubernetes"
"log"
"slices"
)
type Cluster struct {
namespaces map[string]v1.Namespace
clientset *kubernetes.Clientset
// map of namespace to list of all pods
pods map[string][]v1.Pod
}
func NewCluster(clientset *kubernetes.Clientset) (*Cluster, error) {
cluster := &Cluster{
clientset: clientset,
namespaces: make(map[string]v1.Namespace),
pods: make(map[string][]v1.Pod),
}
nslist, err := cluster.clientset.CoreV1().Namespaces().List(context.Background(), metav1.ListOptions{})
if err != nil {
return nil, err
}
for _, ns := range nslist.Items {
cluster.namespaces[ns.Name] = ns
podList, err := cluster.clientset.CoreV1().Pods(ns.Name).List(context.Background(), metav1.ListOptions{})
if err != nil {
return nil, err
}
cluster.pods[ns.Name] = podList.Items
}
return cluster, nil
}
func (c *Cluster) Pods(application *Application) []v1.Pod {
selector, err := metav1.LabelSelectorAsSelector(application.Selector())
if err != nil {
log.Fatalf("Error creating selector: %v", err)
}
pods := c.pods[application.Namespace.Name]
pods = slices.DeleteFunc(slices.Clone(pods), func(pod v1.Pod) bool {
return !selector.Matches(labels.Set(pod.Labels))
})
return pods
}
func (c *Cluster) ServiceAccounts(application *Application) []string {
var res []string
for _, pod := range c.Pods(application) {
if !slices.Contains(res, pod.Spec.ServiceAccountName) {
res = append(res, pod.Spec.ServiceAccountName)
}
}
return res
}
func (c *Cluster) OwnerReferences(application *Application) []string {
var ownerReferences []string
for _, pod := range c.Pods(application) {
//log.Printf(" %s %v", pod.Name, pod.OwnerReferences)
for _, ownerReference := range pod.OwnerReferences {
owner := ownerReference.Kind + "/" + ownerReference.Name
if !slices.Contains(ownerReferences, owner) {
ownerReferences = append(ownerReferences, owner)
}
}
}
return ownerReferences
}
func (c *Cluster) IsLinkerdEnabled(application *Application) bool {
pods := c.Pods(application)
ndisabled := 0
for _, pod := range pods {
if pod.Annotations["linkerd.io/inject"] == "enabled" {
return true
}
if pod.Annotations["linkerd.io/inject"] == "disabled" {
ndisabled++
}
}
if ndisabled == len(pods) {
return false
}
ns := c.namespaces[application.Namespace.Name]
return ns.Annotations["linkerd.io/inject"] == "enabled"
}
func (c *Cluster) Ports(application *Application, nameBased bool) []Port {
// gather unique ports based on name
// or based on number.
// Warning: same name different ports
// same port different names.
// Can occur if the selector matches multiple replicasets.
return nil
}