mirror of
https://github.com/kyverno/kyverno.git
synced 2024-12-14 11:57:48 +00:00
code fixes
This commit is contained in:
parent
8cf5cd70fe
commit
a64789c59d
2 changed files with 95 additions and 89 deletions
|
@ -141,16 +141,15 @@ func IsRoleAuthorize(rbLister rbaclister.RoleBindingLister, crbLister rbaclister
|
|||
for _, e := range clusterRoles {
|
||||
if strings.Contains(e, "kyverno:") {
|
||||
return true, nil
|
||||
} else {
|
||||
role, err := crLister.Get(e)
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
labels := role.GetLabels()
|
||||
}
|
||||
role, err := crLister.Get(e)
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
labels := role.GetLabels()
|
||||
|
||||
if labels["kubernetes.io/bootstrapping"] == "rbac-defaults" {
|
||||
return true, nil
|
||||
}
|
||||
if labels["kubernetes.io/bootstrapping"] == "rbac-defaults" {
|
||||
return true, nil
|
||||
}
|
||||
}
|
||||
for _, e := range roles {
|
||||
|
@ -166,26 +165,25 @@ func IsRoleAuthorize(rbLister rbaclister.RoleBindingLister, crbLister rbaclister
|
|||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// User or Group
|
||||
excludeDevelopmentRole := []string{"minikube-user", "kubernetes-admin"}
|
||||
for _, e := range excludeDevelopmentRole {
|
||||
if strings.Contains(request.UserInfo.Username, e) {
|
||||
return false, nil
|
||||
}
|
||||
// User or Group
|
||||
excludeDevelopmentRole := []string{"minikube-user", "kubernetes-admin"}
|
||||
for _, e := range excludeDevelopmentRole {
|
||||
if strings.Contains(request.UserInfo.Username, e) {
|
||||
return false, nil
|
||||
}
|
||||
}
|
||||
var matchedRoles []bool
|
||||
for _, e := range request.UserInfo.Groups {
|
||||
for _, defaultSuffix := range defaultSuffixs {
|
||||
if strings.Contains(e, defaultSuffix) {
|
||||
matchedRoles = append(matchedRoles, true)
|
||||
break
|
||||
}
|
||||
}
|
||||
var matchedRoles []bool
|
||||
for _, e := range request.UserInfo.Groups {
|
||||
for _, defaultSuffix := range defaultSuffixs {
|
||||
if strings.Contains(e, defaultSuffix) {
|
||||
matchedRoles = append(matchedRoles, true)
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
if len(matchedRoles) == len(request.UserInfo.Groups) {
|
||||
return true, nil
|
||||
}
|
||||
}
|
||||
if len(matchedRoles) == len(request.UserInfo.Groups) {
|
||||
return true, nil
|
||||
}
|
||||
|
||||
return false, nil
|
||||
|
|
|
@ -10,13 +10,13 @@ import (
|
|||
"net/http"
|
||||
"time"
|
||||
|
||||
apierrors "k8s.io/apimachinery/pkg/api/errors"
|
||||
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
|
||||
|
||||
"github.com/go-logr/logr"
|
||||
"github.com/julienschmidt/httprouter"
|
||||
v1 "github.com/nirmata/kyverno/pkg/api/kyverno/v1"
|
||||
"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"
|
||||
kyvernoinformer "github.com/nirmata/kyverno/pkg/client/informers/externalversions/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
|
||||
rbSynced cache.InformerSynced
|
||||
|
||||
// return true if role store has synced atleast once
|
||||
rSynced cache.InformerSynced
|
||||
|
||||
// list/get cluster role binding resource
|
||||
crbLister rbaclister.ClusterRoleBindingLister
|
||||
|
||||
// return true if cluster role binding store has synced atleast once
|
||||
crbSynced cache.InformerSynced
|
||||
|
||||
// return true if cluster role store has synced atleast once
|
||||
crSynced cache.InformerSynced
|
||||
|
||||
// generate events
|
||||
eventGen event.Interface
|
||||
|
||||
|
@ -146,16 +152,19 @@ func NewWebhookServer(
|
|||
tlsConfig.Certificates = []tls.Certificate{pair}
|
||||
|
||||
ws := &WebhookServer{
|
||||
client: client,
|
||||
kyvernoClient: kyvernoClient,
|
||||
pLister: pInformer.Lister(),
|
||||
pSynced: pInformer.Informer().HasSynced,
|
||||
rbLister: rbInformer.Lister(),
|
||||
rLister: rInformer.Lister(),
|
||||
rbSynced: rbInformer.Informer().HasSynced,
|
||||
client: client,
|
||||
kyvernoClient: kyvernoClient,
|
||||
pLister: pInformer.Lister(),
|
||||
pSynced: pInformer.Informer().HasSynced,
|
||||
rbLister: rbInformer.Lister(),
|
||||
rbSynced: rbInformer.Informer().HasSynced,
|
||||
rLister: rInformer.Lister(),
|
||||
rSynced: rInformer.Informer().HasSynced,
|
||||
|
||||
crbLister: crbInformer.Lister(),
|
||||
crLister: crInformer.Lister(),
|
||||
crbSynced: crbInformer.Informer().HasSynced,
|
||||
crSynced: crInformer.Informer().HasSynced,
|
||||
eventGen: eventGen,
|
||||
pCache: pCache,
|
||||
webhookRegistrationClient: webhookRegistrationClient,
|
||||
|
@ -374,61 +383,19 @@ func (ws *WebhookServer) resourceMutation(request *v1beta1.AdmissionRequest) *v1
|
|||
|
||||
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)
|
||||
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 {
|
||||
// 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 request.Operation == v1beta1.Delete || request.Operation == v1beta1.Update {
|
||||
if err := ws.excludeKyvernoResources(request); err != nil {
|
||||
return &v1beta1.AdmissionResponse{
|
||||
Allowed: false,
|
||||
Result: &metav1.Status{
|
||||
Status: "Failure",
|
||||
Message: err.Error(),
|
||||
},
|
||||
}
|
||||
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{
|
||||
Allowed: false,
|
||||
Result: &metav1.Status{
|
||||
Status: "Failure",
|
||||
Message: err.Error(),
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
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 {
|
||||
logger.Info("mutate and validate rules are not supported prior to Kubernetes 1.14.0")
|
||||
return &v1beta1.AdmissionResponse{
|
||||
|
@ -458,6 +425,7 @@ func (ws *WebhookServer) resourceValidation(request *v1beta1.AdmissionRequest) *
|
|||
}
|
||||
|
||||
var roles, clusterRoles []string
|
||||
var err error
|
||||
// getRoleRef only if policy has roles/clusterroles defined
|
||||
if containRBACinfo(policies) {
|
||||
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
|
||||
func (ws *WebhookServer) RunAsync(stopCh <-chan struct{}) {
|
||||
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")
|
||||
}
|
||||
|
||||
|
@ -584,3 +552,43 @@ func (ws *WebhookServer) bodyToAdmissionReview(request *http.Request, writer htt
|
|||
|
||||
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…
Reference in a new issue