1
0
Fork 0
mirror of https://github.com/kyverno/kyverno.git synced 2025-03-05 23:46:56 +00:00
kyverno/pkg/policyviolation/helpers.go
2019-11-13 13:41:08 -08:00

107 lines
3.2 KiB
Go

package policyviolation
import (
"fmt"
"reflect"
"time"
"github.com/golang/glog"
kyverno "github.com/nirmata/kyverno/pkg/api/kyverno/v1"
v1 "k8s.io/api/apps/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
unstructured "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
"k8s.io/apimachinery/pkg/labels"
appsv1 "k8s.io/client-go/kubernetes/typed/apps/v1"
deployutil "k8s.io/kubernetes/pkg/controller/deployment/util"
)
func converLabelToSelector(labelMap map[string]string) (labels.Selector, error) {
ls := &metav1.LabelSelector{}
err := metav1.Convert_Map_string_To_string_To_v1_LabelSelector(&labelMap, ls, nil)
if err != nil {
return nil, err
}
policyViolationSelector, err := metav1.LabelSelectorAsSelector(ls)
if err != nil {
return nil, fmt.Errorf("invalid label selector: %v", err)
}
return policyViolationSelector, nil
}
func containsOwner(owners []kyverno.ResourceSpec, pvResourceSpec kyverno.ResourceSpec) bool {
curOwner := kyverno.ResourceSpec{
Kind: pvResourceSpec.Kind,
Namespace: pvResourceSpec.Namespace,
Name: pvResourceSpec.Name,
}
for _, targetOwner := range owners {
if reflect.DeepEqual(curOwner, targetOwner) {
return true
}
}
return false
}
// validDependantForDeployment checks if resource (pod) matches the intent of the given deployment
// explicitly handles deployment-replicaset-pod relationship
func validDependantForDeployment(client appsv1.AppsV1Interface, pvResourceSpec kyverno.ResourceSpec, resource unstructured.Unstructured) bool {
if resource.GetKind() != "Pod" {
return false
}
// only handles deploymeny-replicaset-pod relationship
if pvResourceSpec.Kind != "Deployment" {
return false
}
owner := kyverno.ResourceSpec{
Kind: pvResourceSpec.Kind,
Namespace: pvResourceSpec.Namespace,
Name: pvResourceSpec.Name,
}
start := time.Now()
deploy, err := client.Deployments(owner.Namespace).Get(owner.Name, metav1.GetOptions{})
if err != nil {
glog.Errorf("failed to get resourceOwner deployment %s/%s/%s: %v", owner.Kind, owner.Namespace, owner.Name, err)
return false
}
glog.V(4).Infof("Time getting deployment %v", time.Since(start))
// TODO(shuting): replace typed client AppsV1Interface
expectReplicaset, err := deployutil.GetNewReplicaSet(deploy, client)
if err != nil {
glog.Errorf("failed to get replicaset owned by %s/%s/%s: %v", owner.Kind, owner.Namespace, owner.Name, err)
return false
}
if reflect.DeepEqual(expectReplicaset, v1.ReplicaSet{}) {
glog.V(2).Infof("no replicaset found for deploy %s/%s/%s", owner.Namespace, owner.Kind, owner.Name)
return false
}
var actualReplicaset *v1.ReplicaSet
for _, podOwner := range resource.GetOwnerReferences() {
if podOwner.Kind != "ReplicaSet" {
continue
}
actualReplicaset, err = client.ReplicaSets(resource.GetNamespace()).Get(podOwner.Name, metav1.GetOptions{})
if err != nil {
glog.Errorf("failed to get replicaset from %s/%s/%s: %v", resource.GetKind(), resource.GetNamespace(), resource.GetName(), err)
return false
}
if reflect.DeepEqual(actualReplicaset, v1.ReplicaSet{}) {
glog.V(2).Infof("no replicaset found for Pod/%s/%s", resource.GetNamespace(), podOwner.Name)
return false
}
if expectReplicaset.Name == actualReplicaset.Name {
return true
}
}
return false
}