mirror of
https://github.com/kyverno/kyverno.git
synced 2025-03-14 11:48:53 +00:00
merge the changes with policy-engine
This commit is contained in:
commit
6d83aa6b9e
19 changed files with 616 additions and 39 deletions
|
@ -206,7 +206,34 @@ var rMapper = map[string]getter{
|
||||||
"StatefulSet": statefulSetGetter,
|
"StatefulSet": statefulSetGetter,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var lMapper = map[string]lister{
|
||||||
|
"ConfigMap": configMapLister,
|
||||||
|
"Pods": podLister,
|
||||||
|
"Deployment": deploymentLister,
|
||||||
|
"CronJob": cronJobLister,
|
||||||
|
"Endpoints": endpointsLister,
|
||||||
|
"HorizontalPodAutoscaler": horizontalPodAutoscalerLister,
|
||||||
|
"Ingress": ingressLister,
|
||||||
|
"Job": jobLister,
|
||||||
|
"LimitRange": limitRangeLister,
|
||||||
|
"Namespace": namespaceLister,
|
||||||
|
"NetworkPolicy": networkPolicyLister,
|
||||||
|
"PersistentVolumeClaim": persistentVolumeClaimLister,
|
||||||
|
"PodDisruptionBudget": podDisruptionBudgetLister,
|
||||||
|
"PodTemplate": podTemplateLister,
|
||||||
|
"ResourceQuota": resourceQuotaLister,
|
||||||
|
"Secret": secretLister,
|
||||||
|
"Service": serviceLister,
|
||||||
|
"StatefulSet": statefulSetLister,
|
||||||
|
}
|
||||||
|
|
||||||
type getter func(*kubernetes.Clientset, string, string) (runtime.Object, error)
|
type getter func(*kubernetes.Clientset, string, string) (runtime.Object, error)
|
||||||
|
type lister func(*kubernetes.Clientset, string) ([]runtime.Object, error)
|
||||||
|
|
||||||
|
//ListResource to return resource list
|
||||||
|
func (kc *KubeClient) ListResource(kind string, namespace string) ([]runtime.Object, error) {
|
||||||
|
return lMapper[kind](kc.client, namespace)
|
||||||
|
}
|
||||||
|
|
||||||
//GetResource get the resource object
|
//GetResource get the resource object
|
||||||
func (kc *KubeClient) GetResource(kind string, resource string) (runtime.Object, error) {
|
func (kc *KubeClient) GetResource(kind string, resource string) (runtime.Object, error) {
|
||||||
|
@ -233,6 +260,19 @@ func configMapGetter(clientSet *kubernetes.Clientset, namespace string, name str
|
||||||
}
|
}
|
||||||
return obj, nil
|
return obj, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func configMapLister(clientSet *kubernetes.Clientset, namespace string) ([]runtime.Object, error) {
|
||||||
|
list, err := clientSet.CoreV1().ConfigMaps(namespace).List(metav1.ListOptions{})
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
objList := []runtime.Object{}
|
||||||
|
for _, obj := range list.Items {
|
||||||
|
objList = append(objList, &obj)
|
||||||
|
}
|
||||||
|
return objList, nil
|
||||||
|
}
|
||||||
|
|
||||||
func podsGetter(clientSet *kubernetes.Clientset, namespace string, name string) (runtime.Object, error) {
|
func podsGetter(clientSet *kubernetes.Clientset, namespace string, name string) (runtime.Object, error) {
|
||||||
obj, err := clientSet.CoreV1().Pods(namespace).Get(name, metav1.GetOptions{})
|
obj, err := clientSet.CoreV1().Pods(namespace).Get(name, metav1.GetOptions{})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -241,6 +281,18 @@ func podsGetter(clientSet *kubernetes.Clientset, namespace string, name string)
|
||||||
return obj, nil
|
return obj, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func podLister(clientSet *kubernetes.Clientset, namespace string) ([]runtime.Object, error) {
|
||||||
|
list, err := clientSet.CoreV1().Pods(namespace).List(metav1.ListOptions{})
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
objList := []runtime.Object{}
|
||||||
|
for _, obj := range list.Items {
|
||||||
|
objList = append(objList, &obj)
|
||||||
|
}
|
||||||
|
return objList, nil
|
||||||
|
}
|
||||||
|
|
||||||
func deploymentGetter(clientSet *kubernetes.Clientset, namespace string, name string) (runtime.Object, error) {
|
func deploymentGetter(clientSet *kubernetes.Clientset, namespace string, name string) (runtime.Object, error) {
|
||||||
obj, err := clientSet.AppsV1().Deployments(namespace).Get(name, metav1.GetOptions{})
|
obj, err := clientSet.AppsV1().Deployments(namespace).Get(name, metav1.GetOptions{})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -248,6 +300,17 @@ func deploymentGetter(clientSet *kubernetes.Clientset, namespace string, name st
|
||||||
}
|
}
|
||||||
return obj, nil
|
return obj, nil
|
||||||
}
|
}
|
||||||
|
func deploymentLister(clientSet *kubernetes.Clientset, namespace string) ([]runtime.Object, error) {
|
||||||
|
list, err := clientSet.AppsV1().Deployments(namespace).List(metav1.ListOptions{})
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
objList := []runtime.Object{}
|
||||||
|
for _, obj := range list.Items {
|
||||||
|
objList = append(objList, &obj)
|
||||||
|
}
|
||||||
|
return objList, nil
|
||||||
|
}
|
||||||
|
|
||||||
func cronJobGetter(clientSet *kubernetes.Clientset, namespace string, name string) (runtime.Object, error) {
|
func cronJobGetter(clientSet *kubernetes.Clientset, namespace string, name string) (runtime.Object, error) {
|
||||||
obj, err := clientSet.BatchV1beta1().CronJobs(namespace).Get(name, metav1.GetOptions{})
|
obj, err := clientSet.BatchV1beta1().CronJobs(namespace).Get(name, metav1.GetOptions{})
|
||||||
|
@ -257,6 +320,18 @@ func cronJobGetter(clientSet *kubernetes.Clientset, namespace string, name strin
|
||||||
return obj, nil
|
return obj, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func cronJobLister(clientSet *kubernetes.Clientset, namespace string) ([]runtime.Object, error) {
|
||||||
|
list, err := clientSet.BatchV1beta1().CronJobs(namespace).List(metav1.ListOptions{})
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
objList := []runtime.Object{}
|
||||||
|
for _, obj := range list.Items {
|
||||||
|
objList = append(objList, &obj)
|
||||||
|
}
|
||||||
|
return objList, nil
|
||||||
|
}
|
||||||
|
|
||||||
func endpointsbGetter(clientSet *kubernetes.Clientset, namespace string, name string) (runtime.Object, error) {
|
func endpointsbGetter(clientSet *kubernetes.Clientset, namespace string, name string) (runtime.Object, error) {
|
||||||
obj, err := clientSet.CoreV1().Endpoints(namespace).Get(name, metav1.GetOptions{})
|
obj, err := clientSet.CoreV1().Endpoints(namespace).Get(name, metav1.GetOptions{})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -265,6 +340,18 @@ func endpointsbGetter(clientSet *kubernetes.Clientset, namespace string, name st
|
||||||
return obj, nil
|
return obj, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func endpointsLister(clientSet *kubernetes.Clientset, namespace string) ([]runtime.Object, error) {
|
||||||
|
list, err := clientSet.CoreV1().Endpoints(namespace).List(metav1.ListOptions{})
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
objList := []runtime.Object{}
|
||||||
|
for _, obj := range list.Items {
|
||||||
|
objList = append(objList, &obj)
|
||||||
|
}
|
||||||
|
return objList, nil
|
||||||
|
}
|
||||||
|
|
||||||
func horizontalPodAutoscalerGetter(clientSet *kubernetes.Clientset, namespace string, name string) (runtime.Object, error) {
|
func horizontalPodAutoscalerGetter(clientSet *kubernetes.Clientset, namespace string, name string) (runtime.Object, error) {
|
||||||
obj, err := clientSet.AutoscalingV1().HorizontalPodAutoscalers(namespace).Get(name, metav1.GetOptions{})
|
obj, err := clientSet.AutoscalingV1().HorizontalPodAutoscalers(namespace).Get(name, metav1.GetOptions{})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -273,6 +360,18 @@ func horizontalPodAutoscalerGetter(clientSet *kubernetes.Clientset, namespace st
|
||||||
return obj, nil
|
return obj, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func horizontalPodAutoscalerLister(clientSet *kubernetes.Clientset, namespace string) ([]runtime.Object, error) {
|
||||||
|
list, err := clientSet.AutoscalingV1().HorizontalPodAutoscalers(namespace).List(metav1.ListOptions{})
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
objList := []runtime.Object{}
|
||||||
|
for _, obj := range list.Items {
|
||||||
|
objList = append(objList, &obj)
|
||||||
|
}
|
||||||
|
return objList, nil
|
||||||
|
}
|
||||||
|
|
||||||
func ingressGetter(clientSet *kubernetes.Clientset, namespace string, name string) (runtime.Object, error) {
|
func ingressGetter(clientSet *kubernetes.Clientset, namespace string, name string) (runtime.Object, error) {
|
||||||
obj, err := clientSet.ExtensionsV1beta1().Ingresses(namespace).Get(name, metav1.GetOptions{})
|
obj, err := clientSet.ExtensionsV1beta1().Ingresses(namespace).Get(name, metav1.GetOptions{})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -281,6 +380,18 @@ func ingressGetter(clientSet *kubernetes.Clientset, namespace string, name strin
|
||||||
return obj, nil
|
return obj, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func ingressLister(clientSet *kubernetes.Clientset, namespace string) ([]runtime.Object, error) {
|
||||||
|
list, err := clientSet.ExtensionsV1beta1().Ingresses(namespace).List(metav1.ListOptions{})
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
objList := []runtime.Object{}
|
||||||
|
for _, obj := range list.Items {
|
||||||
|
objList = append(objList, &obj)
|
||||||
|
}
|
||||||
|
return objList, nil
|
||||||
|
}
|
||||||
|
|
||||||
func jobGetter(clientSet *kubernetes.Clientset, namespace string, name string) (runtime.Object, error) {
|
func jobGetter(clientSet *kubernetes.Clientset, namespace string, name string) (runtime.Object, error) {
|
||||||
obj, err := clientSet.BatchV1().Jobs(namespace).Get(name, metav1.GetOptions{})
|
obj, err := clientSet.BatchV1().Jobs(namespace).Get(name, metav1.GetOptions{})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -289,6 +400,18 @@ func jobGetter(clientSet *kubernetes.Clientset, namespace string, name string) (
|
||||||
return obj, nil
|
return obj, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func jobLister(clientSet *kubernetes.Clientset, namespace string) ([]runtime.Object, error) {
|
||||||
|
list, err := clientSet.BatchV1().Jobs(namespace).List(metav1.ListOptions{})
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
objList := []runtime.Object{}
|
||||||
|
for _, obj := range list.Items {
|
||||||
|
objList = append(objList, &obj)
|
||||||
|
}
|
||||||
|
return objList, nil
|
||||||
|
}
|
||||||
|
|
||||||
func limitRangeGetter(clientSet *kubernetes.Clientset, namespace string, name string) (runtime.Object, error) {
|
func limitRangeGetter(clientSet *kubernetes.Clientset, namespace string, name string) (runtime.Object, error) {
|
||||||
obj, err := clientSet.CoreV1().LimitRanges(namespace).Get(name, metav1.GetOptions{})
|
obj, err := clientSet.CoreV1().LimitRanges(namespace).Get(name, metav1.GetOptions{})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -296,6 +419,17 @@ func limitRangeGetter(clientSet *kubernetes.Clientset, namespace string, name st
|
||||||
}
|
}
|
||||||
return obj, nil
|
return obj, nil
|
||||||
}
|
}
|
||||||
|
func limitRangeLister(clientSet *kubernetes.Clientset, namespace string) ([]runtime.Object, error) {
|
||||||
|
list, err := clientSet.CoreV1().LimitRanges(namespace).List(metav1.ListOptions{})
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
objList := []runtime.Object{}
|
||||||
|
for _, obj := range list.Items {
|
||||||
|
objList = append(objList, &obj)
|
||||||
|
}
|
||||||
|
return objList, nil
|
||||||
|
}
|
||||||
|
|
||||||
func namespaceGetter(clientSet *kubernetes.Clientset, namespace string, name string) (runtime.Object, error) {
|
func namespaceGetter(clientSet *kubernetes.Clientset, namespace string, name string) (runtime.Object, error) {
|
||||||
obj, err := clientSet.CoreV1().Namespaces().Get(name, metav1.GetOptions{})
|
obj, err := clientSet.CoreV1().Namespaces().Get(name, metav1.GetOptions{})
|
||||||
|
@ -305,6 +439,18 @@ func namespaceGetter(clientSet *kubernetes.Clientset, namespace string, name str
|
||||||
return obj, nil
|
return obj, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func namespaceLister(clientSet *kubernetes.Clientset, namespace string) ([]runtime.Object, error) {
|
||||||
|
list, err := clientSet.CoreV1().Namespaces().List(metav1.ListOptions{})
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
objList := []runtime.Object{}
|
||||||
|
for _, obj := range list.Items {
|
||||||
|
objList = append(objList, &obj)
|
||||||
|
}
|
||||||
|
return objList, nil
|
||||||
|
}
|
||||||
|
|
||||||
func networkPolicyGetter(clientSet *kubernetes.Clientset, namespace string, name string) (runtime.Object, error) {
|
func networkPolicyGetter(clientSet *kubernetes.Clientset, namespace string, name string) (runtime.Object, error) {
|
||||||
obj, err := clientSet.NetworkingV1().NetworkPolicies(namespace).Get(name, metav1.GetOptions{})
|
obj, err := clientSet.NetworkingV1().NetworkPolicies(namespace).Get(name, metav1.GetOptions{})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -313,6 +459,18 @@ func networkPolicyGetter(clientSet *kubernetes.Clientset, namespace string, name
|
||||||
return obj, nil
|
return obj, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func networkPolicyLister(clientSet *kubernetes.Clientset, namespace string) ([]runtime.Object, error) {
|
||||||
|
list, err := clientSet.NetworkingV1().NetworkPolicies(namespace).List(metav1.ListOptions{})
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
objList := []runtime.Object{}
|
||||||
|
for _, obj := range list.Items {
|
||||||
|
objList = append(objList, &obj)
|
||||||
|
}
|
||||||
|
return objList, nil
|
||||||
|
}
|
||||||
|
|
||||||
func persistentVolumeClaimGetter(clientSet *kubernetes.Clientset, namespace string, name string) (runtime.Object, error) {
|
func persistentVolumeClaimGetter(clientSet *kubernetes.Clientset, namespace string, name string) (runtime.Object, error) {
|
||||||
obj, err := clientSet.CoreV1().PersistentVolumeClaims(namespace).Get(name, metav1.GetOptions{})
|
obj, err := clientSet.CoreV1().PersistentVolumeClaims(namespace).Get(name, metav1.GetOptions{})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -321,6 +479,18 @@ func persistentVolumeClaimGetter(clientSet *kubernetes.Clientset, namespace stri
|
||||||
return obj, nil
|
return obj, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func persistentVolumeClaimLister(clientSet *kubernetes.Clientset, namespace string) ([]runtime.Object, error) {
|
||||||
|
list, err := clientSet.CoreV1().PersistentVolumeClaims(namespace).List(metav1.ListOptions{})
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
objList := []runtime.Object{}
|
||||||
|
for _, obj := range list.Items {
|
||||||
|
objList = append(objList, &obj)
|
||||||
|
}
|
||||||
|
return objList, nil
|
||||||
|
}
|
||||||
|
|
||||||
func podDisruptionBudgetGetter(clientSet *kubernetes.Clientset, namespace string, name string) (runtime.Object, error) {
|
func podDisruptionBudgetGetter(clientSet *kubernetes.Clientset, namespace string, name string) (runtime.Object, error) {
|
||||||
obj, err := clientSet.PolicyV1beta1().PodDisruptionBudgets(namespace).Get(name, metav1.GetOptions{})
|
obj, err := clientSet.PolicyV1beta1().PodDisruptionBudgets(namespace).Get(name, metav1.GetOptions{})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -329,6 +499,18 @@ func podDisruptionBudgetGetter(clientSet *kubernetes.Clientset, namespace string
|
||||||
return obj, nil
|
return obj, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func podDisruptionBudgetLister(clientSet *kubernetes.Clientset, namespace string) ([]runtime.Object, error) {
|
||||||
|
list, err := clientSet.PolicyV1beta1().PodDisruptionBudgets(namespace).List(metav1.ListOptions{})
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
objList := []runtime.Object{}
|
||||||
|
for _, obj := range list.Items {
|
||||||
|
objList = append(objList, &obj)
|
||||||
|
}
|
||||||
|
return objList, nil
|
||||||
|
}
|
||||||
|
|
||||||
func podTemplateGetter(clientSet *kubernetes.Clientset, namespace string, name string) (runtime.Object, error) {
|
func podTemplateGetter(clientSet *kubernetes.Clientset, namespace string, name string) (runtime.Object, error) {
|
||||||
obj, err := clientSet.CoreV1().PodTemplates(namespace).Get(name, metav1.GetOptions{})
|
obj, err := clientSet.CoreV1().PodTemplates(namespace).Get(name, metav1.GetOptions{})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -337,6 +519,18 @@ func podTemplateGetter(clientSet *kubernetes.Clientset, namespace string, name s
|
||||||
return obj, nil
|
return obj, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func podTemplateLister(clientSet *kubernetes.Clientset, namespace string) ([]runtime.Object, error) {
|
||||||
|
list, err := clientSet.CoreV1().PodTemplates(namespace).List(metav1.ListOptions{})
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
objList := []runtime.Object{}
|
||||||
|
for _, obj := range list.Items {
|
||||||
|
objList = append(objList, &obj)
|
||||||
|
}
|
||||||
|
return objList, nil
|
||||||
|
}
|
||||||
|
|
||||||
func resourceQuotaGetter(clientSet *kubernetes.Clientset, namespace string, name string) (runtime.Object, error) {
|
func resourceQuotaGetter(clientSet *kubernetes.Clientset, namespace string, name string) (runtime.Object, error) {
|
||||||
obj, err := clientSet.CoreV1().ResourceQuotas(namespace).Get(name, metav1.GetOptions{})
|
obj, err := clientSet.CoreV1().ResourceQuotas(namespace).Get(name, metav1.GetOptions{})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -345,6 +539,18 @@ func resourceQuotaGetter(clientSet *kubernetes.Clientset, namespace string, name
|
||||||
return obj, nil
|
return obj, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func resourceQuotaLister(clientSet *kubernetes.Clientset, namespace string) ([]runtime.Object, error) {
|
||||||
|
list, err := clientSet.CoreV1().ResourceQuotas(namespace).List(metav1.ListOptions{})
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
objList := []runtime.Object{}
|
||||||
|
for _, obj := range list.Items {
|
||||||
|
objList = append(objList, &obj)
|
||||||
|
}
|
||||||
|
return objList, nil
|
||||||
|
}
|
||||||
|
|
||||||
func secretGetter(clientSet *kubernetes.Clientset, namespace string, name string) (runtime.Object, error) {
|
func secretGetter(clientSet *kubernetes.Clientset, namespace string, name string) (runtime.Object, error) {
|
||||||
obj, err := clientSet.CoreV1().Secrets(namespace).Get(name, metav1.GetOptions{})
|
obj, err := clientSet.CoreV1().Secrets(namespace).Get(name, metav1.GetOptions{})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -353,6 +559,18 @@ func secretGetter(clientSet *kubernetes.Clientset, namespace string, name string
|
||||||
return obj, nil
|
return obj, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func secretLister(clientSet *kubernetes.Clientset, namespace string) ([]runtime.Object, error) {
|
||||||
|
list, err := clientSet.CoreV1().Secrets(namespace).List(metav1.ListOptions{})
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
objList := []runtime.Object{}
|
||||||
|
for _, obj := range list.Items {
|
||||||
|
objList = append(objList, &obj)
|
||||||
|
}
|
||||||
|
return objList, nil
|
||||||
|
}
|
||||||
|
|
||||||
func serviceGetter(clientSet *kubernetes.Clientset, namespace string, name string) (runtime.Object, error) {
|
func serviceGetter(clientSet *kubernetes.Clientset, namespace string, name string) (runtime.Object, error) {
|
||||||
obj, err := clientSet.CoreV1().Services(namespace).Get(name, metav1.GetOptions{})
|
obj, err := clientSet.CoreV1().Services(namespace).Get(name, metav1.GetOptions{})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -361,6 +579,18 @@ func serviceGetter(clientSet *kubernetes.Clientset, namespace string, name strin
|
||||||
return obj, nil
|
return obj, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func serviceLister(clientSet *kubernetes.Clientset, namespace string) ([]runtime.Object, error) {
|
||||||
|
list, err := clientSet.CoreV1().Services(namespace).List(metav1.ListOptions{})
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
objList := []runtime.Object{}
|
||||||
|
for _, obj := range list.Items {
|
||||||
|
objList = append(objList, &obj)
|
||||||
|
}
|
||||||
|
return objList, nil
|
||||||
|
}
|
||||||
|
|
||||||
func statefulSetGetter(clientSet *kubernetes.Clientset, namespace string, name string) (runtime.Object, error) {
|
func statefulSetGetter(clientSet *kubernetes.Clientset, namespace string, name string) (runtime.Object, error) {
|
||||||
obj, err := clientSet.AppsV1().StatefulSets(namespace).Get(name, metav1.GetOptions{})
|
obj, err := clientSet.AppsV1().StatefulSets(namespace).Get(name, metav1.GetOptions{})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -368,3 +598,15 @@ func statefulSetGetter(clientSet *kubernetes.Clientset, namespace string, name s
|
||||||
}
|
}
|
||||||
return obj, nil
|
return obj, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func statefulSetLister(clientSet *kubernetes.Clientset, namespace string) ([]runtime.Object, error) {
|
||||||
|
list, err := clientSet.AppsV1().StatefulSets(namespace).List(metav1.ListOptions{})
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
objList := []runtime.Object{}
|
||||||
|
for _, obj := range list.Items {
|
||||||
|
objList = append(objList, &obj)
|
||||||
|
}
|
||||||
|
return objList, nil
|
||||||
|
}
|
||||||
|
|
3
main.go
3
main.go
|
@ -11,6 +11,7 @@ import (
|
||||||
|
|
||||||
policyclientset "github.com/nirmata/kube-policy/pkg/client/clientset/versioned"
|
policyclientset "github.com/nirmata/kube-policy/pkg/client/clientset/versioned"
|
||||||
informers "github.com/nirmata/kube-policy/pkg/client/informers/externalversions"
|
informers "github.com/nirmata/kube-policy/pkg/client/informers/externalversions"
|
||||||
|
policyengine "github.com/nirmata/kube-policy/pkg/policyengine"
|
||||||
policyviolation "github.com/nirmata/kube-policy/pkg/policyviolation"
|
policyviolation "github.com/nirmata/kube-policy/pkg/policyviolation"
|
||||||
|
|
||||||
event "github.com/nirmata/kube-policy/pkg/event"
|
event "github.com/nirmata/kube-policy/pkg/event"
|
||||||
|
@ -45,9 +46,11 @@ func main() {
|
||||||
|
|
||||||
eventController := event.NewEventController(kubeclient, policyInformer.Lister(), nil)
|
eventController := event.NewEventController(kubeclient, policyInformer.Lister(), nil)
|
||||||
violationBuilder := policyviolation.NewPolicyViolationBuilder(kubeclient, policyInformer.Lister(), policyClientset, eventController, nil)
|
violationBuilder := policyviolation.NewPolicyViolationBuilder(kubeclient, policyInformer.Lister(), policyClientset, eventController, nil)
|
||||||
|
policyEngine := policyengine.NewPolicyEngine(kubeclient, nil)
|
||||||
|
|
||||||
policyController := policycontroller.NewPolicyController(policyClientset,
|
policyController := policycontroller.NewPolicyController(policyClientset,
|
||||||
policyInformer,
|
policyInformer,
|
||||||
|
policyEngine,
|
||||||
violationBuilder,
|
violationBuilder,
|
||||||
eventController,
|
eventController,
|
||||||
nil,
|
nil,
|
||||||
|
|
|
@ -92,6 +92,4 @@ type Violation struct {
|
||||||
Kind string `json:"kind,omitempty"`
|
Kind string `json:"kind,omitempty"`
|
||||||
Resource string `json:"resource,omitempty"`
|
Resource string `json:"resource,omitempty"`
|
||||||
Rule string `json:"rule,omitempty"`
|
Rule string `json:"rule,omitempty"`
|
||||||
Reason string `json:"reason,omitempty"`
|
|
||||||
Message string `json:"message,omitempty`
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -29,7 +29,7 @@ type controller struct {
|
||||||
|
|
||||||
//Generator to generate event
|
//Generator to generate event
|
||||||
type Generator interface {
|
type Generator interface {
|
||||||
Add(kind string, resource string, reason Reason, message MsgKey, args ...interface{})
|
Add(info Info)
|
||||||
}
|
}
|
||||||
|
|
||||||
//Controller api
|
//Controller api
|
||||||
|
@ -66,13 +66,8 @@ func initRecorder(kubeClient *kubeClient.KubeClient) record.EventRecorder {
|
||||||
return recorder
|
return recorder
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *controller) Add(kind string, resource string, reason Reason, message MsgKey, args ...interface{}) {
|
func (c *controller) Add(info Info) {
|
||||||
c.queue.Add(c.newEvent(
|
c.queue.Add(info)
|
||||||
kind,
|
|
||||||
resource,
|
|
||||||
reason,
|
|
||||||
message,
|
|
||||||
))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *controller) Run(stopCh <-chan struct{}) error {
|
func (c *controller) Run(stopCh <-chan struct{}) error {
|
||||||
|
@ -103,9 +98,9 @@ func (c *controller) processNextWorkItem() bool {
|
||||||
}
|
}
|
||||||
err := func(obj interface{}) error {
|
err := func(obj interface{}) error {
|
||||||
defer c.queue.Done(obj)
|
defer c.queue.Done(obj)
|
||||||
var key eventInfo
|
var key Info
|
||||||
var ok bool
|
var ok bool
|
||||||
if key, ok = obj.(eventInfo); !ok {
|
if key, ok = obj.(Info); !ok {
|
||||||
c.queue.Forget(obj)
|
c.queue.Forget(obj)
|
||||||
log.Printf("Expecting type info by got %v", obj)
|
log.Printf("Expecting type info by got %v", obj)
|
||||||
return nil
|
return nil
|
||||||
|
@ -124,7 +119,7 @@ func (c *controller) processNextWorkItem() bool {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *controller) SyncHandler(key eventInfo) error {
|
func (c *controller) SyncHandler(key Info) error {
|
||||||
var resource runtime.Object
|
var resource runtime.Object
|
||||||
var err error
|
var err error
|
||||||
switch key.Kind {
|
switch key.Kind {
|
||||||
|
@ -150,12 +145,13 @@ func (c *controller) SyncHandler(key eventInfo) error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *controller) newEvent(kind string, resource string, reason Reason, message MsgKey, args ...interface{}) eventInfo {
|
//NewEvent returns a new event
|
||||||
|
func NewEvent(kind string, resource string, reason Reason, message MsgKey, args ...interface{}) Info {
|
||||||
msgText, err := getEventMsg(message, args)
|
msgText, err := getEventMsg(message, args)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
utilruntime.HandleError(err)
|
utilruntime.HandleError(err)
|
||||||
}
|
}
|
||||||
return eventInfo{
|
return Info{
|
||||||
Kind: kind,
|
Kind: kind,
|
||||||
Resource: resource,
|
Resource: resource,
|
||||||
Reason: reason.String(),
|
Reason: reason.String(),
|
||||||
|
|
|
@ -6,7 +6,8 @@ const eventWorkQueueName = "policy-controller-events"
|
||||||
|
|
||||||
const eventWorkerThreadCount = 1
|
const eventWorkerThreadCount = 1
|
||||||
|
|
||||||
type eventInfo struct {
|
//Info defines the event details
|
||||||
|
type Info struct {
|
||||||
Kind string
|
Kind string
|
||||||
Resource string
|
Resource string
|
||||||
Reason string
|
Reason string
|
||||||
|
|
96
pkg/policyengine/mutation.go
Normal file
96
pkg/policyengine/mutation.go
Normal file
|
@ -0,0 +1,96 @@
|
||||||
|
package policyengine
|
||||||
|
|
||||||
|
import (
|
||||||
|
"errors"
|
||||||
|
"fmt"
|
||||||
|
|
||||||
|
types "github.com/nirmata/kube-policy/pkg/apis/policy/v1alpha1"
|
||||||
|
"github.com/nirmata/kube-policy/pkg/policyengine/mutation"
|
||||||
|
)
|
||||||
|
|
||||||
|
func (p *policyEngine) ProcessMutation(policy types.Policy, rawResource []byte) ([]mutation.PatchBytes, error) {
|
||||||
|
patchingSets := mutation.GetPolicyPatchingSets(policy)
|
||||||
|
var policyPatches []mutation.PatchBytes
|
||||||
|
|
||||||
|
for ruleIdx, rule := range policy.Spec.Rules {
|
||||||
|
err := rule.Validate()
|
||||||
|
if err != nil {
|
||||||
|
p.logger.Printf("Invalid rule detected: #%s in policy %s, err: %v\n", rule.Name, policy.ObjectMeta.Name, err)
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
if ok, err := mutation.IsRuleApplicableToResource(rawResource, rule.Resource); !ok {
|
||||||
|
p.logger.Printf("Rule %d of policy %s is not applicable to the request", ruleIdx, policy.Name)
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
err = p.applyRuleGenerators(rawResource, rule)
|
||||||
|
if err != nil && patchingSets == mutation.PatchingSetsStopOnError {
|
||||||
|
return nil, fmt.Errorf("Failed to apply generators from rule #%s: %v", rule.Name, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
rulePatchesProcessed, err := mutation.ProcessPatches(rule.Patches, rawResource, patchingSets)
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("Failed to process patches from rule #%s: %v", rule.Name, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if rulePatchesProcessed != nil {
|
||||||
|
policyPatches = append(policyPatches, rulePatchesProcessed...)
|
||||||
|
p.logger.Printf("Rule %d: prepared %d patches", ruleIdx, len(rulePatchesProcessed))
|
||||||
|
// TODO: add PolicyApplied events per rule for policy and resource
|
||||||
|
} else {
|
||||||
|
p.logger.Printf("Rule %d: no patches prepared", ruleIdx)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// empty patch, return error to deny resource creation
|
||||||
|
if policyPatches == nil {
|
||||||
|
return nil, fmt.Errorf("no patches prepared")
|
||||||
|
}
|
||||||
|
|
||||||
|
return policyPatches, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// Applies "configMapGenerator" and "secretGenerator" described in PolicyRule
|
||||||
|
func (p *policyEngine) applyRuleGenerators(rawResource []byte, rule types.PolicyRule) error {
|
||||||
|
kind := mutation.ParseKindFromObject(rawResource)
|
||||||
|
|
||||||
|
// configMapGenerator and secretGenerator can be applied only to namespaces
|
||||||
|
if kind == "Namespace" {
|
||||||
|
namespaceName := mutation.ParseNameFromObject(rawResource)
|
||||||
|
|
||||||
|
err := p.applyConfigGenerator(rule.ConfigMapGenerator, namespaceName, "ConfigMap")
|
||||||
|
if err == nil {
|
||||||
|
err = p.applyConfigGenerator(rule.SecretGenerator, namespaceName, "Secret")
|
||||||
|
}
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// Creates resourceKind (ConfigMap or Secret) with parameters specified in generator in cluster specified in request.
|
||||||
|
func (p *policyEngine) applyConfigGenerator(generator *types.PolicyConfigGenerator, namespace string, configKind string) error {
|
||||||
|
if generator == nil {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
err := generator.Validate()
|
||||||
|
if err != nil {
|
||||||
|
return errors.New(fmt.Sprintf("Generator for '%s' is invalid: %s", configKind, err))
|
||||||
|
}
|
||||||
|
|
||||||
|
switch configKind {
|
||||||
|
case "ConfigMap":
|
||||||
|
err = p.kubeClient.GenerateConfigMap(*generator, namespace)
|
||||||
|
case "Secret":
|
||||||
|
err = p.kubeClient.GenerateSecret(*generator, namespace)
|
||||||
|
default:
|
||||||
|
err = errors.New(fmt.Sprintf("Unsupported config Kind '%s'", configKind))
|
||||||
|
}
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
return errors.New(fmt.Sprintf("Unable to apply generator for %s '%s/%s' : %s", configKind, namespace, generator.Name, err))
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
|
@ -8,10 +8,11 @@ import (
|
||||||
|
|
||||||
// kind is the type of object being manipulated
|
// kind is the type of object being manipulated
|
||||||
// Checks requests kind, name and labels to fit the policy
|
// Checks requests kind, name and labels to fit the policy
|
||||||
func IsRuleApplicableToResource(kind string, resourceRaw []byte, policyResource types.PolicyResource) (bool, error) {
|
func IsRuleApplicableToResource(resourceRaw []byte, policyResource types.PolicyResource) (bool, error) {
|
||||||
if policyResource.Kind != kind {
|
// kind := ParseKindFromObject(resourceRaw)
|
||||||
return false, nil
|
// if policyResource.Kind != kind {
|
||||||
}
|
// return false, nil
|
||||||
|
// }
|
||||||
|
|
||||||
if resourceRaw != nil {
|
if resourceRaw != nil {
|
||||||
meta := ParseMetadataFromObject(resourceRaw)
|
meta := ParseMetadataFromObject(resourceRaw)
|
103
pkg/policyengine/policyengine.go
Normal file
103
pkg/policyengine/policyengine.go
Normal file
|
@ -0,0 +1,103 @@
|
||||||
|
package policyengine
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"log"
|
||||||
|
|
||||||
|
kubeClient "github.com/nirmata/kube-policy/kubeclient"
|
||||||
|
types "github.com/nirmata/kube-policy/pkg/apis/policy/v1alpha1"
|
||||||
|
event "github.com/nirmata/kube-policy/pkg/event"
|
||||||
|
"github.com/nirmata/kube-policy/pkg/policyengine/mutation"
|
||||||
|
policyviolation "github.com/nirmata/kube-policy/pkg/policyviolation"
|
||||||
|
)
|
||||||
|
|
||||||
|
type PolicyEngine interface {
|
||||||
|
// ProcessMutation should be called from admission contoller
|
||||||
|
// when there is an creation / update of the resource
|
||||||
|
// ProcessMutation(policy types.Policy, rawResource []byte) (patchBytes []byte, events []Events, err error)
|
||||||
|
ProcessMutation(policy types.Policy, rawResource []byte) ([]mutation.PatchBytes, error)
|
||||||
|
|
||||||
|
// ProcessValidation should be called from admission contoller
|
||||||
|
// when there is an creation / update of the resource
|
||||||
|
ProcessValidation(policy types.Policy, rawResource []byte)
|
||||||
|
|
||||||
|
// ProcessExisting should be called from policy controller
|
||||||
|
// when there is an create / update of the policy
|
||||||
|
// we should process the policy on matched resources, generate violations accordingly
|
||||||
|
ProcessExisting(policy types.Policy, rawResource []byte) ([]policyviolation.Info, []event.Info, error)
|
||||||
|
}
|
||||||
|
|
||||||
|
type policyEngine struct {
|
||||||
|
kubeClient *kubeClient.KubeClient
|
||||||
|
logger *log.Logger
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewPolicyEngine(kubeClient *kubeClient.KubeClient, logger *log.Logger) PolicyEngine {
|
||||||
|
return &policyEngine{
|
||||||
|
kubeClient: kubeClient,
|
||||||
|
logger: logger,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *policyEngine) ProcessExisting(policy types.Policy, rawResource []byte) ([]policyviolation.Info, []event.Info, error) {
|
||||||
|
var violations []policyviolation.Info
|
||||||
|
var events []event.Info
|
||||||
|
|
||||||
|
patchingSets := mutation.GetPolicyPatchingSets(policy)
|
||||||
|
|
||||||
|
for _, rule := range policy.Spec.Rules {
|
||||||
|
err := rule.Validate()
|
||||||
|
if err != nil {
|
||||||
|
p.logger.Printf("Invalid rule detected: #%s in policy %s, err: %v\n", rule.Name, policy.ObjectMeta.Name, err)
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
if ok, err := mutation.IsRuleApplicableToResource(rawResource, rule.Resource); !ok {
|
||||||
|
p.logger.Printf("Rule %s of policy %s is not applicable to the request", rule.Name, policy.Name)
|
||||||
|
return nil, nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
violation, eventInfos, err := p.processRuleOnResource(policy.Name, rule, rawResource, patchingSets)
|
||||||
|
if err != nil {
|
||||||
|
p.logger.Printf("Failed to process rule %s, err: %v\n", rule.Name, err)
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
// } else {
|
||||||
|
// policyPatches = append(policyPatches, processedPatches...)
|
||||||
|
// }
|
||||||
|
violations = append(violations, violation)
|
||||||
|
events = append(events, eventInfos...)
|
||||||
|
}
|
||||||
|
return violations, events, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *policyEngine) processRuleOnResource(policyName string, rule types.PolicyRule, rawResource []byte, patchingSets mutation.PatchingSets) (
|
||||||
|
policyviolation.Info, []event.Info, error) {
|
||||||
|
|
||||||
|
var violationInfo policyviolation.Info
|
||||||
|
var eventInfos []event.Info
|
||||||
|
|
||||||
|
resourceKind := mutation.ParseKindFromObject(rawResource)
|
||||||
|
resourceName := mutation.ParseNameFromObject(rawResource)
|
||||||
|
resourceNamespace := mutation.ParseNamespaceFromObject(rawResource)
|
||||||
|
|
||||||
|
rulePatchesProcessed, err := mutation.ProcessPatches(rule.Patches, nil, patchingSets)
|
||||||
|
if err != nil {
|
||||||
|
return violationInfo, eventInfos, fmt.Errorf("Failed to process patches from rule %s: %v", rule.Name, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if rulePatchesProcessed != nil {
|
||||||
|
log.Printf("Rule %s: prepared %d patches", rule.Name, len(rulePatchesProcessed))
|
||||||
|
|
||||||
|
violationInfo = policyviolation.NewViolation(policyName, resourceKind, resourceNamespace+"/"+resourceName, rule.Name)
|
||||||
|
// add a violation to queue
|
||||||
|
|
||||||
|
// add an event to policy
|
||||||
|
//TODO: event msg
|
||||||
|
eventInfos = append(eventInfos, event.NewEvent("Policy", policyName, event.PolicyViolation, event.FResourcePolcy))
|
||||||
|
// add an event to resource
|
||||||
|
eventInfos = append(eventInfos, event.NewEvent(resourceKind, resourceNamespace+"/"+resourceName, event.PolicyViolation, event.FResourcePolcy))
|
||||||
|
}
|
||||||
|
|
||||||
|
return violationInfo, eventInfos, nil
|
||||||
|
}
|
5
pkg/policyengine/validation.go
Normal file
5
pkg/policyengine/validation.go
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
package policyengine
|
||||||
|
|
||||||
|
import types "github.com/nirmata/kube-policy/pkg/apis/policy/v1alpha1"
|
||||||
|
|
||||||
|
func (p *policyEngine) ProcessValidation(policy types.Policy, rawResource []byte) {}
|
|
@ -15,7 +15,7 @@ import (
|
||||||
|
|
||||||
//Generator to generate policy violation
|
//Generator to generate policy violation
|
||||||
type Generator interface {
|
type Generator interface {
|
||||||
Add(info ViolationInfo) error
|
Add(info Info) error
|
||||||
}
|
}
|
||||||
|
|
||||||
type builder struct {
|
type builder struct {
|
||||||
|
@ -29,7 +29,7 @@ type builder struct {
|
||||||
//Builder is to build policy violations
|
//Builder is to build policy violations
|
||||||
type Builder interface {
|
type Builder interface {
|
||||||
Generator
|
Generator
|
||||||
processViolation(info ViolationInfo) error
|
processViolation(info Info) error
|
||||||
isActive(kind string, resource string) (bool, error)
|
isActive(kind string, resource string) (bool, error)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -51,11 +51,11 @@ func NewPolicyViolationBuilder(
|
||||||
return builder
|
return builder
|
||||||
}
|
}
|
||||||
|
|
||||||
func (b *builder) Add(info ViolationInfo) error {
|
func (b *builder) Add(info Info) error {
|
||||||
return b.processViolation(info)
|
return b.processViolation(info)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (b *builder) processViolation(info ViolationInfo) error {
|
func (b *builder) processViolation(info Info) error {
|
||||||
// Get the policy
|
// Get the policy
|
||||||
namespace, name, err := cache.SplitMetaNamespaceKey(info.Policy)
|
namespace, name, err := cache.SplitMetaNamespaceKey(info.Policy)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -71,13 +71,7 @@ func (b *builder) processViolation(info ViolationInfo) error {
|
||||||
modifiedViolations := []types.Violation{}
|
modifiedViolations := []types.Violation{}
|
||||||
|
|
||||||
// Create new violation
|
// Create new violation
|
||||||
newViolation := types.Violation{
|
newViolation := info.Violation
|
||||||
Kind: info.Kind,
|
|
||||||
Resource: info.Resource,
|
|
||||||
Rule: info.Rule,
|
|
||||||
Reason: info.Reason,
|
|
||||||
Message: info.Message,
|
|
||||||
}
|
|
||||||
|
|
||||||
for _, violation := range modifiedPolicy.Status.Violations {
|
for _, violation := range modifiedPolicy.Status.Violations {
|
||||||
ok, err := b.isActive(info.Kind, violation.Resource)
|
ok, err := b.isActive(info.Kind, violation.Resource)
|
||||||
|
@ -111,3 +105,11 @@ func (b *builder) isActive(kind string, resource string) (bool, error) {
|
||||||
}
|
}
|
||||||
return true, nil
|
return true, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//NewViolation return new policy violation
|
||||||
|
func NewViolation(policyName string, kind string, resource string, rule string) Info {
|
||||||
|
return Info{Policy: policyName,
|
||||||
|
Violation: types.Violation{
|
||||||
|
Kind: kind, Resource: resource, Rule: rule},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -12,7 +12,7 @@ const workqueueViolationName = "Policy-Violations"
|
||||||
const violationEventResrouce = "Violation"
|
const violationEventResrouce = "Violation"
|
||||||
|
|
||||||
//ViolationInfo describes the policyviolation details
|
//ViolationInfo describes the policyviolation details
|
||||||
type ViolationInfo struct {
|
type Info struct {
|
||||||
Policy string
|
Policy string
|
||||||
policytype.Violation
|
policytype.Violation
|
||||||
}
|
}
|
||||||
|
|
|
@ -11,8 +11,8 @@ import (
|
||||||
infomertypes "github.com/nirmata/kube-policy/pkg/client/informers/externalversions/policy/v1alpha1"
|
infomertypes "github.com/nirmata/kube-policy/pkg/client/informers/externalversions/policy/v1alpha1"
|
||||||
lister "github.com/nirmata/kube-policy/pkg/client/listers/policy/v1alpha1"
|
lister "github.com/nirmata/kube-policy/pkg/client/listers/policy/v1alpha1"
|
||||||
event "github.com/nirmata/kube-policy/pkg/event"
|
event "github.com/nirmata/kube-policy/pkg/event"
|
||||||
|
policyengine "github.com/nirmata/kube-policy/pkg/policyengine"
|
||||||
policyviolation "github.com/nirmata/kube-policy/pkg/policyviolation"
|
policyviolation "github.com/nirmata/kube-policy/pkg/policyviolation"
|
||||||
|
|
||||||
"k8s.io/apimachinery/pkg/api/errors"
|
"k8s.io/apimachinery/pkg/api/errors"
|
||||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||||
utilruntime "k8s.io/apimachinery/pkg/util/runtime"
|
utilruntime "k8s.io/apimachinery/pkg/util/runtime"
|
||||||
|
@ -27,6 +27,7 @@ type PolicyController struct {
|
||||||
policyLister lister.PolicyLister
|
policyLister lister.PolicyLister
|
||||||
policyInterface policyclientset.Interface
|
policyInterface policyclientset.Interface
|
||||||
policySynced cache.InformerSynced
|
policySynced cache.InformerSynced
|
||||||
|
policyEngine policyengine.PolicyEngine
|
||||||
violationBuilder policyviolation.Generator
|
violationBuilder policyviolation.Generator
|
||||||
eventBuilder event.Generator
|
eventBuilder event.Generator
|
||||||
logger *log.Logger
|
logger *log.Logger
|
||||||
|
@ -36,6 +37,7 @@ type PolicyController struct {
|
||||||
// NewPolicyController from cmd args
|
// NewPolicyController from cmd args
|
||||||
func NewPolicyController(policyInterface policyclientset.Interface,
|
func NewPolicyController(policyInterface policyclientset.Interface,
|
||||||
policyInformer infomertypes.PolicyInformer,
|
policyInformer infomertypes.PolicyInformer,
|
||||||
|
policyEngine policyengine.PolicyEngine,
|
||||||
violationBuilder policyviolation.Generator,
|
violationBuilder policyviolation.Generator,
|
||||||
eventController event.Generator,
|
eventController event.Generator,
|
||||||
logger *log.Logger,
|
logger *log.Logger,
|
||||||
|
@ -46,6 +48,7 @@ func NewPolicyController(policyInterface policyclientset.Interface,
|
||||||
policyLister: policyInformer.Lister(),
|
policyLister: policyInformer.Lister(),
|
||||||
policyInterface: policyInterface,
|
policyInterface: policyInterface,
|
||||||
policySynced: policyInformer.Informer().HasSynced,
|
policySynced: policyInformer.Informer().HasSynced,
|
||||||
|
policyEngine: policyEngine,
|
||||||
violationBuilder: violationBuilder,
|
violationBuilder: violationBuilder,
|
||||||
eventBuilder: eventController,
|
eventBuilder: eventController,
|
||||||
logger: logger,
|
logger: logger,
|
||||||
|
|
122
policycontroller/processPolicy.go
Normal file
122
policycontroller/processPolicy.go
Normal file
|
@ -0,0 +1,122 @@
|
||||||
|
package policycontroller
|
||||||
|
|
||||||
|
import (
|
||||||
|
"encoding/json"
|
||||||
|
"fmt"
|
||||||
|
|
||||||
|
types "github.com/nirmata/kube-policy/pkg/apis/policy/v1alpha1"
|
||||||
|
event "github.com/nirmata/kube-policy/pkg/event"
|
||||||
|
"github.com/nirmata/kube-policy/pkg/policyengine/mutation"
|
||||||
|
policyviolation "github.com/nirmata/kube-policy/pkg/policyviolation"
|
||||||
|
"k8s.io/apimachinery/pkg/labels"
|
||||||
|
"k8s.io/apimachinery/pkg/runtime"
|
||||||
|
utilruntime "k8s.io/apimachinery/pkg/util/runtime"
|
||||||
|
)
|
||||||
|
|
||||||
|
func (pc *PolicyController) runForPolicy(key string) {
|
||||||
|
|
||||||
|
policy, err := pc.getPolicyByKey(key)
|
||||||
|
if err != nil {
|
||||||
|
utilruntime.HandleError(fmt.Errorf("invalid resource key: %s, err: %v", key, err))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if policy == nil {
|
||||||
|
pc.logger.Printf("Counld not find policy by key %s", key)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
violations, events, err := pc.processPolicy(*policy)
|
||||||
|
if err != nil {
|
||||||
|
// add Error processing policy event
|
||||||
|
}
|
||||||
|
|
||||||
|
pc.logger.Printf("%v, %v", violations, events)
|
||||||
|
// TODO:
|
||||||
|
// create violations
|
||||||
|
// pc.violationBuilder.Add()
|
||||||
|
// create events
|
||||||
|
// pc.eventBuilder.Add()
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
// processPolicy process the policy to all the matched resources
|
||||||
|
func (pc *PolicyController) processPolicy(policy types.Policy) (
|
||||||
|
violations []policyviolation.Info, events []event.Info, err error) {
|
||||||
|
|
||||||
|
for _, rule := range policy.Spec.Rules {
|
||||||
|
resources, err := pc.filterResourceByRule(rule)
|
||||||
|
if err != nil {
|
||||||
|
pc.logger.Printf("Failed to filter resources by rule %s, err: %v\n", rule.Name, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, resource := range resources {
|
||||||
|
rawResource, err := json.Marshal(resource)
|
||||||
|
if err != nil {
|
||||||
|
pc.logger.Printf("Failed to marshal resources map to rule %s, err: %v\n", rule.Name, err)
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
violation, eventInfos, err := pc.policyEngine.ProcessExisting(policy, rawResource)
|
||||||
|
if err != nil {
|
||||||
|
pc.logger.Printf("Failed to process rule %s, err: %v\n", rule.Name, err)
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
violations = append(violations, violation...)
|
||||||
|
events = append(events, eventInfos...)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return violations, events, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (pc *PolicyController) filterResourceByRule(rule types.PolicyRule) ([]runtime.Object, error) {
|
||||||
|
var targetResources []runtime.Object
|
||||||
|
// TODO: make this namespace all
|
||||||
|
var namespace = "default"
|
||||||
|
if err := rule.Validate(); err != nil {
|
||||||
|
return nil, fmt.Errorf("invalid rule detected: %s, err: %v", rule.Name, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get the resource list from kind
|
||||||
|
resources, err := pc.kubeClient.ListResource(rule.Resource.Kind, namespace)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, resource := range resources {
|
||||||
|
// TODO:
|
||||||
|
rawResource, err := json.Marshal(resource)
|
||||||
|
// objKind := resource.GetObjectKind()
|
||||||
|
// codecFactory := serializer.NewCodecFactory(runtime.NewScheme())
|
||||||
|
// codecFactory.EncoderForVersion()
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
pc.logger.Printf("failed to marshal object %v", resource)
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
// filter the resource by name and label
|
||||||
|
if ok, _ := mutation.IsRuleApplicableToResource(rawResource, rule.Resource); ok {
|
||||||
|
targetResources = append(targetResources, resource)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return targetResources, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (pc *PolicyController) getPolicyByKey(key string) (*types.Policy, error) {
|
||||||
|
// Create nil Selector to grab all the policies
|
||||||
|
selector := labels.NewSelector()
|
||||||
|
cachedPolicies, err := pc.policyLister.List(selector)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, elem := range cachedPolicies {
|
||||||
|
if elem.Name == key {
|
||||||
|
return elem, nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil, nil
|
||||||
|
}
|
|
@ -3,7 +3,7 @@ package webhooks
|
||||||
import (
|
import (
|
||||||
kubeclient "github.com/nirmata/kube-policy/kubeclient"
|
kubeclient "github.com/nirmata/kube-policy/kubeclient"
|
||||||
types "github.com/nirmata/kube-policy/pkg/apis/policy/v1alpha1"
|
types "github.com/nirmata/kube-policy/pkg/apis/policy/v1alpha1"
|
||||||
mutation "github.com/nirmata/kube-policy/pkg/mutation"
|
mutation "github.com/nirmata/kube-policy/pkg/policyengine/mutation"
|
||||||
"k8s.io/api/admission/v1beta1"
|
"k8s.io/api/admission/v1beta1"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -24,5 +24,5 @@ func AdmissionIsRequired(request *v1beta1.AdmissionRequest) bool {
|
||||||
|
|
||||||
// Checks requests kind, name and labels to fit the policy
|
// Checks requests kind, name and labels to fit the policy
|
||||||
func IsRuleApplicableToRequest(policyResource types.PolicyResource, request *v1beta1.AdmissionRequest) (bool, error) {
|
func IsRuleApplicableToRequest(policyResource types.PolicyResource, request *v1beta1.AdmissionRequest) (bool, error) {
|
||||||
return mutation.IsRuleApplicableToResource(request.Kind.Kind, request.Object.Raw, policyResource)
|
return mutation.IsRuleApplicableToResource(request.Object.Raw, policyResource)
|
||||||
}
|
}
|
||||||
|
|
|
@ -11,7 +11,8 @@ import (
|
||||||
types "github.com/nirmata/kube-policy/pkg/apis/policy/v1alpha1"
|
types "github.com/nirmata/kube-policy/pkg/apis/policy/v1alpha1"
|
||||||
policylister "github.com/nirmata/kube-policy/pkg/client/listers/policy/v1alpha1"
|
policylister "github.com/nirmata/kube-policy/pkg/client/listers/policy/v1alpha1"
|
||||||
event "github.com/nirmata/kube-policy/pkg/event"
|
event "github.com/nirmata/kube-policy/pkg/event"
|
||||||
mutation "github.com/nirmata/kube-policy/pkg/mutation"
|
policyengine "github.com/nirmata/kube-policy/pkg/policyengine"
|
||||||
|
mutation "github.com/nirmata/kube-policy/pkg/policyengine/mutation"
|
||||||
policyviolation "github.com/nirmata/kube-policy/pkg/policyviolation"
|
policyviolation "github.com/nirmata/kube-policy/pkg/policyviolation"
|
||||||
v1beta1 "k8s.io/api/admission/v1beta1"
|
v1beta1 "k8s.io/api/admission/v1beta1"
|
||||||
|
|
||||||
|
@ -25,6 +26,7 @@ import (
|
||||||
// business logic for resource mutation
|
// business logic for resource mutation
|
||||||
type MutationWebhook struct {
|
type MutationWebhook struct {
|
||||||
kubeclient *kubeclient.KubeClient
|
kubeclient *kubeclient.KubeClient
|
||||||
|
policyEngine policyengine.PolicyEngine
|
||||||
policyLister policylister.PolicyLister
|
policyLister policylister.PolicyLister
|
||||||
registration *MutationWebhookRegistration
|
registration *MutationWebhookRegistration
|
||||||
violationBuilder policyviolation.Generator
|
violationBuilder policyviolation.Generator
|
||||||
|
@ -57,8 +59,11 @@ func CreateMutationWebhook(
|
||||||
if logger == nil {
|
if logger == nil {
|
||||||
logger = log.New(os.Stdout, "Mutation WebHook: ", log.LstdFlags|log.Lshortfile)
|
logger = log.New(os.Stdout, "Mutation WebHook: ", log.LstdFlags|log.Lshortfile)
|
||||||
}
|
}
|
||||||
|
policyengine := policyengine.NewPolicyEngine(kubeclient, logger)
|
||||||
|
|
||||||
return &MutationWebhook{
|
return &MutationWebhook{
|
||||||
kubeclient: kubeclient,
|
kubeclient: kubeclient,
|
||||||
|
policyEngine: policyengine,
|
||||||
policyLister: policyLister,
|
policyLister: policyLister,
|
||||||
registration: registration,
|
registration: registration,
|
||||||
violationBuilder: violationBuilder,
|
violationBuilder: violationBuilder,
|
||||||
|
@ -136,10 +141,10 @@ func (mw *MutationWebhook) Mutate(request *v1beta1.AdmissionRequest) *v1beta1.Ad
|
||||||
// May return nil patches if it is not necessary to create patches for requested object.
|
// May return nil patches if it is not necessary to create patches for requested object.
|
||||||
// Returns error ONLY in case when creation of resource should be denied.
|
// Returns error ONLY in case when creation of resource should be denied.
|
||||||
func (mw *MutationWebhook) applyPolicyRules(request *v1beta1.AdmissionRequest, policy types.Policy) ([]mutation.PatchBytes, error) {
|
func (mw *MutationWebhook) applyPolicyRules(request *v1beta1.AdmissionRequest, policy types.Policy) ([]mutation.PatchBytes, error) {
|
||||||
return mw.applyPolicyRulesOnResource(request.Kind.Kind, request.Object.Raw, policy)
|
return mw.policyEngine.ProcessMutation(policy, request.Object.Raw)
|
||||||
}
|
}
|
||||||
|
|
||||||
// kind is the type of object being manipulated
|
// kind is the type of object being manipulated, e.g. request.Kind.kind
|
||||||
func (mw *MutationWebhook) applyPolicyRulesOnResource(kind string, rawResource []byte, policy types.Policy) ([]mutation.PatchBytes, error) {
|
func (mw *MutationWebhook) applyPolicyRulesOnResource(kind string, rawResource []byte, policy types.Policy) ([]mutation.PatchBytes, error) {
|
||||||
patchingSets := mutation.GetPolicyPatchingSets(policy)
|
patchingSets := mutation.GetPolicyPatchingSets(policy)
|
||||||
var policyPatches []mutation.PatchBytes
|
var policyPatches []mutation.PatchBytes
|
||||||
|
@ -151,7 +156,7 @@ func (mw *MutationWebhook) applyPolicyRulesOnResource(kind string, rawResource [
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
if ok, err := mutation.IsRuleApplicableToResource(kind, rawResource, rule.Resource); !ok {
|
if ok, err := mutation.IsRuleApplicableToResource(rawResource, rule.Resource); !ok {
|
||||||
mw.logger.Printf("Rule %d of policy %s is not applicable to the request", ruleIdx, policy.Name)
|
mw.logger.Printf("Rule %d of policy %s is not applicable to the request", ruleIdx, policy.Name)
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Reference in a new issue