mirror of
https://github.com/kyverno/kyverno.git
synced 2025-03-15 12:17:56 +00:00
code fixes
This commit is contained in:
parent
8cf5cd70fe
commit
a64789c59d
2 changed files with 95 additions and 89 deletions
|
@ -141,7 +141,7 @@ func IsRoleAuthorize(rbLister rbaclister.RoleBindingLister, crbLister rbaclister
|
||||||
for _, e := range clusterRoles {
|
for _, e := range clusterRoles {
|
||||||
if strings.Contains(e, "kyverno:") {
|
if strings.Contains(e, "kyverno:") {
|
||||||
return true, nil
|
return true, nil
|
||||||
} else {
|
}
|
||||||
role, err := crLister.Get(e)
|
role, err := crLister.Get(e)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return false, err
|
return false, err
|
||||||
|
@ -152,7 +152,6 @@ func IsRoleAuthorize(rbLister rbaclister.RoleBindingLister, crbLister rbaclister
|
||||||
return true, nil
|
return true, nil
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
for _, e := range roles {
|
for _, e := range roles {
|
||||||
roleData := strings.Split(e, ":")
|
roleData := strings.Split(e, ":")
|
||||||
role, err := rLister.Roles(roleData[0]).Get(roleData[1])
|
role, err := rLister.Roles(roleData[0]).Get(roleData[1])
|
||||||
|
@ -166,7 +165,7 @@ func IsRoleAuthorize(rbLister rbaclister.RoleBindingLister, crbLister rbaclister
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
}
|
||||||
// User or Group
|
// User or Group
|
||||||
excludeDevelopmentRole := []string{"minikube-user", "kubernetes-admin"}
|
excludeDevelopmentRole := []string{"minikube-user", "kubernetes-admin"}
|
||||||
for _, e := range excludeDevelopmentRole {
|
for _, e := range excludeDevelopmentRole {
|
||||||
|
@ -186,7 +185,6 @@ func IsRoleAuthorize(rbLister rbaclister.RoleBindingLister, crbLister rbaclister
|
||||||
if len(matchedRoles) == len(request.UserInfo.Groups) {
|
if len(matchedRoles) == len(request.UserInfo.Groups) {
|
||||||
return true, nil
|
return true, nil
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
return false, nil
|
return false, nil
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,13 +10,13 @@ import (
|
||||||
"net/http"
|
"net/http"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
apierrors "k8s.io/apimachinery/pkg/api/errors"
|
|
||||||
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
|
|
||||||
|
|
||||||
"github.com/go-logr/logr"
|
"github.com/go-logr/logr"
|
||||||
"github.com/julienschmidt/httprouter"
|
"github.com/julienschmidt/httprouter"
|
||||||
v1 "github.com/nirmata/kyverno/pkg/api/kyverno/v1"
|
v1 "github.com/nirmata/kyverno/pkg/api/kyverno/v1"
|
||||||
"github.com/nirmata/kyverno/pkg/checker"
|
"github.com/nirmata/kyverno/pkg/checker"
|
||||||
|
apierrors "k8s.io/apimachinery/pkg/api/errors"
|
||||||
|
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
|
||||||
|
|
||||||
kyvernoclient "github.com/nirmata/kyverno/pkg/client/clientset/versioned"
|
kyvernoclient "github.com/nirmata/kyverno/pkg/client/clientset/versioned"
|
||||||
kyvernoinformer "github.com/nirmata/kyverno/pkg/client/informers/externalversions/kyverno/v1"
|
kyvernoinformer "github.com/nirmata/kyverno/pkg/client/informers/externalversions/kyverno/v1"
|
||||||
kyvernolister "github.com/nirmata/kyverno/pkg/client/listers/kyverno/v1"
|
kyvernolister "github.com/nirmata/kyverno/pkg/client/listers/kyverno/v1"
|
||||||
|
@ -65,12 +65,18 @@ type WebhookServer struct {
|
||||||
// return true if role bining store has synced atleast once
|
// return true if role bining store has synced atleast once
|
||||||
rbSynced cache.InformerSynced
|
rbSynced cache.InformerSynced
|
||||||
|
|
||||||
|
// return true if role store has synced atleast once
|
||||||
|
rSynced cache.InformerSynced
|
||||||
|
|
||||||
// list/get cluster role binding resource
|
// list/get cluster role binding resource
|
||||||
crbLister rbaclister.ClusterRoleBindingLister
|
crbLister rbaclister.ClusterRoleBindingLister
|
||||||
|
|
||||||
// return true if cluster role binding store has synced atleast once
|
// return true if cluster role binding store has synced atleast once
|
||||||
crbSynced cache.InformerSynced
|
crbSynced cache.InformerSynced
|
||||||
|
|
||||||
|
// return true if cluster role store has synced atleast once
|
||||||
|
crSynced cache.InformerSynced
|
||||||
|
|
||||||
// generate events
|
// generate events
|
||||||
eventGen event.Interface
|
eventGen event.Interface
|
||||||
|
|
||||||
|
@ -151,11 +157,14 @@ func NewWebhookServer(
|
||||||
pLister: pInformer.Lister(),
|
pLister: pInformer.Lister(),
|
||||||
pSynced: pInformer.Informer().HasSynced,
|
pSynced: pInformer.Informer().HasSynced,
|
||||||
rbLister: rbInformer.Lister(),
|
rbLister: rbInformer.Lister(),
|
||||||
rLister: rInformer.Lister(),
|
|
||||||
rbSynced: rbInformer.Informer().HasSynced,
|
rbSynced: rbInformer.Informer().HasSynced,
|
||||||
|
rLister: rInformer.Lister(),
|
||||||
|
rSynced: rInformer.Informer().HasSynced,
|
||||||
|
|
||||||
crbLister: crbInformer.Lister(),
|
crbLister: crbInformer.Lister(),
|
||||||
crLister: crInformer.Lister(),
|
crLister: crInformer.Lister(),
|
||||||
crbSynced: crbInformer.Informer().HasSynced,
|
crbSynced: crbInformer.Informer().HasSynced,
|
||||||
|
crSynced: crInformer.Informer().HasSynced,
|
||||||
eventGen: eventGen,
|
eventGen: eventGen,
|
||||||
pCache: pCache,
|
pCache: pCache,
|
||||||
webhookRegistrationClient: webhookRegistrationClient,
|
webhookRegistrationClient: webhookRegistrationClient,
|
||||||
|
@ -374,37 +383,9 @@ func (ws *WebhookServer) resourceMutation(request *v1beta1.AdmissionRequest) *v1
|
||||||
|
|
||||||
func (ws *WebhookServer) resourceValidation(request *v1beta1.AdmissionRequest) *v1beta1.AdmissionResponse {
|
func (ws *WebhookServer) resourceValidation(request *v1beta1.AdmissionRequest) *v1beta1.AdmissionResponse {
|
||||||
logger := ws.log.WithName("resourceValidation").WithValues("uid", request.UID, "kind", request.Kind.Kind, "namespace", request.Namespace, "name", request.Name, "operation", request.Operation)
|
logger := ws.log.WithName("resourceValidation").WithValues("uid", request.UID, "kind", request.Kind.Kind, "namespace", request.Namespace, "name", request.Name, "operation", request.Operation)
|
||||||
checked, err := userinfo.IsRoleAuthorize(ws.rbLister, ws.crbLister, ws.rLister, ws.crLister, request)
|
|
||||||
if err != nil {
|
|
||||||
logger.Error(err, "failed to get RBAC infromation for request")
|
|
||||||
}
|
|
||||||
|
|
||||||
if !checked {
|
|
||||||
if request.Operation == v1beta1.Delete || request.Operation == v1beta1.Update {
|
if request.Operation == v1beta1.Delete || request.Operation == v1beta1.Update {
|
||||||
// convert RAW to unstructured
|
if err := ws.excludeKyvernoResources(request); err != nil {
|
||||||
var resource *unstructured.Unstructured
|
|
||||||
if request.Operation == v1beta1.Delete {
|
|
||||||
resource, err = enginutils.ConvertToUnstructured(request.OldObject.Raw)
|
|
||||||
} else {
|
|
||||||
resource, err = enginutils.ConvertToUnstructured(request.Object.Raw)
|
|
||||||
}
|
|
||||||
if err != nil {
|
|
||||||
//TODO: skip applying the admission control ?
|
|
||||||
logger.Error(err, "failed to convert RAR resource to unstructured format")
|
|
||||||
|
|
||||||
return &v1beta1.AdmissionResponse{
|
|
||||||
Allowed: false,
|
|
||||||
Result: &metav1.Status{
|
|
||||||
Status: "Failure",
|
|
||||||
Message: err.Error(),
|
|
||||||
},
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
oldResource, err := ws.client.GetResource(resource.GetKind(), resource.GetNamespace(), resource.GetName())
|
|
||||||
if err != nil {
|
|
||||||
if !apierrors.IsNotFound(err) {
|
|
||||||
logger.Error(err, "failed to get resource")
|
|
||||||
return &v1beta1.AdmissionResponse{
|
return &v1beta1.AdmissionResponse{
|
||||||
Allowed: false,
|
Allowed: false,
|
||||||
Result: &metav1.Status{
|
Result: &metav1.Status{
|
||||||
|
@ -414,21 +395,7 @@ func (ws *WebhookServer) resourceValidation(request *v1beta1.AdmissionRequest) *
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
labels := oldResource.GetLabels()
|
|
||||||
if labels != nil {
|
|
||||||
if labels["app.kubernetes.io/managed-by"] == "kyverno" && labels["app.kubernetes.io/synchronize"] == "enable" {
|
|
||||||
return &v1beta1.AdmissionResponse{
|
|
||||||
Allowed: false,
|
|
||||||
Result: &metav1.Status{
|
|
||||||
Status: "Failure",
|
|
||||||
Message: "You don't have permission to update resourses that is generated by kyverno",
|
|
||||||
},
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if !ws.supportMudateValidate {
|
if !ws.supportMudateValidate {
|
||||||
logger.Info("mutate and validate rules are not supported prior to Kubernetes 1.14.0")
|
logger.Info("mutate and validate rules are not supported prior to Kubernetes 1.14.0")
|
||||||
return &v1beta1.AdmissionResponse{
|
return &v1beta1.AdmissionResponse{
|
||||||
|
@ -458,6 +425,7 @@ func (ws *WebhookServer) resourceValidation(request *v1beta1.AdmissionRequest) *
|
||||||
}
|
}
|
||||||
|
|
||||||
var roles, clusterRoles []string
|
var roles, clusterRoles []string
|
||||||
|
var err error
|
||||||
// getRoleRef only if policy has roles/clusterroles defined
|
// getRoleRef only if policy has roles/clusterroles defined
|
||||||
if containRBACinfo(policies) {
|
if containRBACinfo(policies) {
|
||||||
roles, clusterRoles, err = userinfo.GetRoleRef(ws.rbLister, ws.crbLister, request)
|
roles, clusterRoles, err = userinfo.GetRoleRef(ws.rbLister, ws.crbLister, request)
|
||||||
|
@ -517,7 +485,7 @@ func (ws *WebhookServer) resourceValidation(request *v1beta1.AdmissionRequest) *
|
||||||
// RunAsync TLS server in separate thread and returns control immediately
|
// RunAsync TLS server in separate thread and returns control immediately
|
||||||
func (ws *WebhookServer) RunAsync(stopCh <-chan struct{}) {
|
func (ws *WebhookServer) RunAsync(stopCh <-chan struct{}) {
|
||||||
logger := ws.log
|
logger := ws.log
|
||||||
if !cache.WaitForCacheSync(stopCh, ws.pSynced, ws.rbSynced, ws.crbSynced) {
|
if !cache.WaitForCacheSync(stopCh, ws.pSynced, ws.rbSynced, ws.crbSynced, ws.rSynced, ws.crSynced) {
|
||||||
logger.Info("failed to sync informer cache")
|
logger.Info("failed to sync informer cache")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -584,3 +552,43 @@ func (ws *WebhookServer) bodyToAdmissionReview(request *http.Request, writer htt
|
||||||
|
|
||||||
return admissionReview
|
return admissionReview
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// excludeKyvernoResources will check resource can have acces or not
|
||||||
|
func (ws *WebhookServer) excludeKyvernoResources(request *v1beta1.AdmissionRequest) error {
|
||||||
|
logger := ws.log.WithName("resourceValidation").WithValues("uid", request.UID, "kind", request.Kind.Kind, "namespace", request.Namespace, "name", request.Name, "operation", request.Operation)
|
||||||
|
|
||||||
|
checked, err := userinfo.IsRoleAuthorize(ws.rbLister, ws.crbLister, ws.rLister, ws.crLister, request)
|
||||||
|
if err != nil {
|
||||||
|
logger.Error(err, "failed to get RBAC infromation for request")
|
||||||
|
}
|
||||||
|
|
||||||
|
if !checked {
|
||||||
|
// convert RAW to unstructured
|
||||||
|
var resource *unstructured.Unstructured
|
||||||
|
if request.Operation == v1beta1.Delete {
|
||||||
|
resource, err = enginutils.ConvertToUnstructured(request.OldObject.Raw)
|
||||||
|
} else {
|
||||||
|
resource, err = enginutils.ConvertToUnstructured(request.Object.Raw)
|
||||||
|
}
|
||||||
|
if err != nil {
|
||||||
|
logger.Error(err, "failed to convert RAR resource to unstructured format")
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
oldResource, err := ws.client.GetResource(resource.GetKind(), resource.GetNamespace(), resource.GetName())
|
||||||
|
if err != nil {
|
||||||
|
if !apierrors.IsNotFound(err) {
|
||||||
|
logger.Error(err, "failed to get resource")
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
labels := oldResource.GetLabels()
|
||||||
|
if labels != nil {
|
||||||
|
if labels["app.kubernetes.io/managed-by"] == "kyverno" && labels["app.kubernetes.io/synchronize"] == "enable" {
|
||||||
|
return fmt.Errorf("Resource is managed by Kyverno, can't be changed manually. You can edit generate policy to update this resource")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
Loading…
Add table
Reference in a new issue