mirror of
https://github.com/kyverno/kyverno.git
synced 2025-03-31 03:45:17 +00:00
767 tested prototype
This commit is contained in:
parent
1175fec22c
commit
4ae65497bf
7 changed files with 99 additions and 144 deletions
|
@ -219,22 +219,26 @@ func main() {
|
||||||
// -- annotations on resources with update details on mutation JSON patches
|
// -- annotations on resources with update details on mutation JSON patches
|
||||||
// -- generate policy violation resource
|
// -- generate policy violation resource
|
||||||
// -- generate events on policy and resource
|
// -- generate events on policy and resource
|
||||||
server, err := webhooks.NewWebhookServer(
|
server, err := webhooks.NewWebhookServer(&webhooks.WebhookServer{
|
||||||
pclient,
|
Client: client,
|
||||||
client,
|
KyvernoClient: pclient,
|
||||||
tlsPair,
|
PLister: pInformer.Kyverno().V1().ClusterPolicies().Lister(),
|
||||||
pInformer.Kyverno().V1().ClusterPolicies(),
|
PSynced: pInformer.Kyverno().V1().ClusterPolicies().Informer().HasSynced,
|
||||||
kubeInformer.Rbac().V1().RoleBindings(),
|
RbLister: kubeInformer.Rbac().V1().RoleBindings().Lister(),
|
||||||
kubeInformer.Rbac().V1().ClusterRoleBindings(),
|
RbSynced: kubeInformer.Rbac().V1().RoleBindings().Informer().HasSynced,
|
||||||
egen,
|
CrbLister: kubeInformer.Rbac().V1().ClusterRoleBindings().Lister(),
|
||||||
webhookRegistrationClient,
|
CrbSynced: kubeInformer.Rbac().V1().ClusterRoleBindings().Informer().HasSynced,
|
||||||
statusSync.Listener,
|
EventGen: egen,
|
||||||
configData,
|
WebhookRegistrationClient: webhookRegistrationClient,
|
||||||
policyMetaStore,
|
StatusListener: statusSync.Listener,
|
||||||
pvgen,
|
ConfigHandler: configData,
|
||||||
grgen,
|
CleanUp: cleanUp,
|
||||||
rWebhookWatcher,
|
LastReqTime: rWebhookWatcher.LastReqTime,
|
||||||
cleanUp)
|
PvGenerator: pvgen,
|
||||||
|
PMetaStore: policyMetaStore,
|
||||||
|
GrGenerator: grgen,
|
||||||
|
ResourceWebhookWatcher: rWebhookWatcher,
|
||||||
|
}, tlsPair)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
glog.Fatalf("Unable to create webhook server: %v\n", err)
|
glog.Fatalf("Unable to create webhook server: %v\n", err)
|
||||||
}
|
}
|
||||||
|
|
1
pkg/webhooks/generate/handler.go
Normal file
1
pkg/webhooks/generate/handler.go
Normal file
|
@ -0,0 +1 @@
|
||||||
|
package generate
|
|
@ -66,13 +66,13 @@ func (ws *WebhookServer) HandleGenerate(request *v1beta1.AdmissionRequest, polic
|
||||||
if len(engineResponse.PolicyResponse.Rules) > 0 {
|
if len(engineResponse.PolicyResponse.Rules) > 0 {
|
||||||
// some generate rules do apply to the resource
|
// some generate rules do apply to the resource
|
||||||
engineResponses = append(engineResponses, engineResponse)
|
engineResponses = append(engineResponses, engineResponse)
|
||||||
ws.statusListener.Send(generateStats{
|
ws.StatusListener.Send(generateStats{
|
||||||
resp: engineResponse,
|
resp: engineResponse,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Adds Generate Request to a channel(queue size 1000) to generators
|
// Adds Generate Request to a channel(queue size 1000) to generators
|
||||||
if err := createGenerateRequest(ws.grGenerator, userRequestInfo, engineResponses...); err != nil {
|
if err := createGenerateRequest(ws.GrGenerator, userRequestInfo, engineResponses...); err != nil {
|
||||||
//TODO: send appropriate error
|
//TODO: send appropriate error
|
||||||
return false, "Kyverno blocked: failed to create Generate Requests"
|
return false, "Kyverno blocked: failed to create Generate Requests"
|
||||||
}
|
}
|
||||||
|
|
|
@ -63,7 +63,7 @@ func (ws *WebhookServer) HandleMutation(request *v1beta1.AdmissionRequest, resou
|
||||||
policyContext.Policy = policy
|
policyContext.Policy = policy
|
||||||
engineResponse := engine.Mutate(policyContext)
|
engineResponse := engine.Mutate(policyContext)
|
||||||
engineResponses = append(engineResponses, engineResponse)
|
engineResponses = append(engineResponses, engineResponse)
|
||||||
ws.statusListener.Send(mutateStats{resp: engineResponse})
|
ws.StatusListener.Send(mutateStats{resp: engineResponse})
|
||||||
if !engineResponse.IsSuccesful() {
|
if !engineResponse.IsSuccesful() {
|
||||||
glog.V(4).Infof("Failed to apply policy %s on resource %s/%s\n", policy.Name, resource.GetNamespace(), resource.GetName())
|
glog.V(4).Infof("Failed to apply policy %s on resource %s/%s\n", policy.Name, resource.GetNamespace(), resource.GetName())
|
||||||
continue
|
continue
|
||||||
|
@ -91,7 +91,7 @@ func (ws *WebhookServer) HandleMutation(request *v1beta1.AdmissionRequest, resou
|
||||||
// AUDIT
|
// AUDIT
|
||||||
// generate violation when response fails
|
// generate violation when response fails
|
||||||
pvInfos := policyviolation.GeneratePVsFromEngineResponse(engineResponses)
|
pvInfos := policyviolation.GeneratePVsFromEngineResponse(engineResponses)
|
||||||
ws.pvGenerator.Add(pvInfos...)
|
ws.PvGenerator.Add(pvInfos...)
|
||||||
// REPORTING EVENTS
|
// REPORTING EVENTS
|
||||||
// Scenario 1:
|
// Scenario 1:
|
||||||
// some/all policies failed to apply on the resource. a policy volation is generated.
|
// some/all policies failed to apply on the resource. a policy volation is generated.
|
||||||
|
@ -101,7 +101,7 @@ func (ws *WebhookServer) HandleMutation(request *v1beta1.AdmissionRequest, resou
|
||||||
// create an event on the resource
|
// create an event on the resource
|
||||||
// ADD EVENTS
|
// ADD EVENTS
|
||||||
events := generateEvents(engineResponses, false, (request.Operation == v1beta1.Update))
|
events := generateEvents(engineResponses, false, (request.Operation == v1beta1.Update))
|
||||||
ws.eventGen.Add(events...)
|
ws.EventGen.Add(events...)
|
||||||
|
|
||||||
// debug info
|
// debug info
|
||||||
func() {
|
func() {
|
||||||
|
|
|
@ -39,7 +39,7 @@ func (ws *WebhookServer) handlePolicyValidation(request *v1beta1.AdmissionReques
|
||||||
if admissionResp.Allowed {
|
if admissionResp.Allowed {
|
||||||
// if the policy contains mutating & validation rules and it config does not exist we create one
|
// if the policy contains mutating & validation rules and it config does not exist we create one
|
||||||
// queue the request
|
// queue the request
|
||||||
ws.resourceWebhookWatcher.RegisterResourceWebhook()
|
ws.ResourceWebhookWatcher.RegisterResourceWebhook()
|
||||||
}
|
}
|
||||||
return admissionResp
|
return admissionResp
|
||||||
}
|
}
|
||||||
|
|
|
@ -13,7 +13,6 @@ import (
|
||||||
"github.com/golang/glog"
|
"github.com/golang/glog"
|
||||||
"github.com/nirmata/kyverno/pkg/checker"
|
"github.com/nirmata/kyverno/pkg/checker"
|
||||||
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"
|
|
||||||
kyvernolister "github.com/nirmata/kyverno/pkg/client/listers/kyverno/v1"
|
kyvernolister "github.com/nirmata/kyverno/pkg/client/listers/kyverno/v1"
|
||||||
"github.com/nirmata/kyverno/pkg/config"
|
"github.com/nirmata/kyverno/pkg/config"
|
||||||
client "github.com/nirmata/kyverno/pkg/dclient"
|
client "github.com/nirmata/kyverno/pkg/dclient"
|
||||||
|
@ -27,7 +26,6 @@ import (
|
||||||
"github.com/nirmata/kyverno/pkg/webhooks/generate"
|
"github.com/nirmata/kyverno/pkg/webhooks/generate"
|
||||||
v1beta1 "k8s.io/api/admission/v1beta1"
|
v1beta1 "k8s.io/api/admission/v1beta1"
|
||||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||||
rbacinformer "k8s.io/client-go/informers/rbac/v1"
|
|
||||||
rbaclister "k8s.io/client-go/listers/rbac/v1"
|
rbaclister "k8s.io/client-go/listers/rbac/v1"
|
||||||
"k8s.io/client-go/tools/cache"
|
"k8s.io/client-go/tools/cache"
|
||||||
)
|
)
|
||||||
|
@ -36,64 +34,50 @@ import (
|
||||||
// MutationWebhook gets policies from policyController and takes control of the cluster with kubeclient.
|
// MutationWebhook gets policies from policyController and takes control of the cluster with kubeclient.
|
||||||
type WebhookServer struct {
|
type WebhookServer struct {
|
||||||
server http.Server
|
server http.Server
|
||||||
client *client.Client
|
Client *client.Client
|
||||||
kyvernoClient *kyvernoclient.Clientset
|
KyvernoClient *kyvernoclient.Clientset
|
||||||
// list/get cluster policy resource
|
// list/get cluster policy resource
|
||||||
pLister kyvernolister.ClusterPolicyLister
|
PLister kyvernolister.ClusterPolicyLister
|
||||||
// returns true if the cluster policy store has synced atleast
|
// returns true if the cluster policy store has synced atleast
|
||||||
pSynced cache.InformerSynced
|
PSynced cache.InformerSynced
|
||||||
// list/get role binding resource
|
// list/get role binding resource
|
||||||
rbLister rbaclister.RoleBindingLister
|
RbLister rbaclister.RoleBindingLister
|
||||||
// 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
|
||||||
// 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
|
||||||
// generate events
|
// generate events
|
||||||
eventGen event.Interface
|
EventGen event.Interface
|
||||||
// webhook registration client
|
// webhook registration client
|
||||||
webhookRegistrationClient *webhookconfig.WebhookRegistrationClient
|
WebhookRegistrationClient *webhookconfig.WebhookRegistrationClient
|
||||||
// API to send policy stats for aggregation
|
// API to send policy stats for aggregation
|
||||||
statusListener policystatus.Listener
|
StatusListener policystatus.Listener
|
||||||
// helpers to validate against current loaded configuration
|
// helpers to validate against current loaded configuration
|
||||||
configHandler config.Interface
|
ConfigHandler config.Interface
|
||||||
// channel for cleanup notification
|
// channel for cleanup notification
|
||||||
cleanUp chan<- struct{}
|
CleanUp chan<- struct{}
|
||||||
// last request time
|
// last request time
|
||||||
lastReqTime *checker.LastReqTime
|
LastReqTime *checker.LastReqTime
|
||||||
// store to hold policy meta data for faster lookup
|
// store to hold policy meta data for faster lookup
|
||||||
pMetaStore policystore.LookupInterface
|
PMetaStore policystore.LookupInterface
|
||||||
// policy violation generator
|
// policy violation generator
|
||||||
pvGenerator policyviolation.GeneratorInterface
|
PvGenerator policyviolation.GeneratorInterface
|
||||||
// generate request generator
|
// generate request generator
|
||||||
grGenerator *generate.Generator
|
GrGenerator *generate.Generator
|
||||||
resourceWebhookWatcher *webhookconfig.ResourceWebhookRegister
|
ResourceWebhookWatcher *webhookconfig.ResourceWebhookRegister
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewWebhookServer creates new instance of WebhookServer accordingly to given configuration
|
// NewWebhookServer creates new instance of WebhookServer accordingly to given configuration
|
||||||
// Policy Controller and Kubernetes Client should be initialized in configuration
|
// Policy Controller and Kubernetes Client should be initialized in configuration
|
||||||
func NewWebhookServer(
|
func NewWebhookServer(
|
||||||
kyvernoClient *kyvernoclient.Clientset,
|
ws *WebhookServer,
|
||||||
client *client.Client,
|
tlsPair *tlsutils.TlsPemPair) (*WebhookServer, error) {
|
||||||
tlsPair *tlsutils.TlsPemPair,
|
|
||||||
pInformer kyvernoinformer.ClusterPolicyInformer,
|
|
||||||
rbInformer rbacinformer.RoleBindingInformer,
|
|
||||||
crbInformer rbacinformer.ClusterRoleBindingInformer,
|
|
||||||
eventGen event.Interface,
|
|
||||||
webhookRegistrationClient *webhookconfig.WebhookRegistrationClient,
|
|
||||||
statusSync policystatus.Listener,
|
|
||||||
configHandler config.Interface,
|
|
||||||
pMetaStore policystore.LookupInterface,
|
|
||||||
pvGenerator policyviolation.GeneratorInterface,
|
|
||||||
grGenerator *generate.Generator,
|
|
||||||
resourceWebhookWatcher *webhookconfig.ResourceWebhookRegister,
|
|
||||||
cleanUp chan<- struct{}) (*WebhookServer, error) {
|
|
||||||
|
|
||||||
if tlsPair == nil {
|
if tlsPair == nil {
|
||||||
return nil, errors.New("NewWebhookServer is not initialized properly")
|
return nil, errors.New("NewWebhookServer is not initialized properly")
|
||||||
}
|
}
|
||||||
|
|
||||||
var tlsConfig tls.Config
|
var tlsConfig tls.Config
|
||||||
pair, err := tls.X509KeyPair(tlsPair.Certificate, tlsPair.PrivateKey)
|
pair, err := tls.X509KeyPair(tlsPair.Certificate, tlsPair.PrivateKey)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -101,32 +85,12 @@ func NewWebhookServer(
|
||||||
}
|
}
|
||||||
tlsConfig.Certificates = []tls.Certificate{pair}
|
tlsConfig.Certificates = []tls.Certificate{pair}
|
||||||
|
|
||||||
ws := &WebhookServer{
|
|
||||||
client: client,
|
|
||||||
kyvernoClient: kyvernoClient,
|
|
||||||
pLister: pInformer.Lister(),
|
|
||||||
pSynced: pInformer.Informer().HasSynced,
|
|
||||||
rbLister: rbInformer.Lister(),
|
|
||||||
rbSynced: rbInformer.Informer().HasSynced,
|
|
||||||
crbLister: crbInformer.Lister(),
|
|
||||||
crbSynced: crbInformer.Informer().HasSynced,
|
|
||||||
eventGen: eventGen,
|
|
||||||
webhookRegistrationClient: webhookRegistrationClient,
|
|
||||||
statusListener: statusSync,
|
|
||||||
configHandler: configHandler,
|
|
||||||
cleanUp: cleanUp,
|
|
||||||
lastReqTime: resourceWebhookWatcher.LastReqTime,
|
|
||||||
pvGenerator: pvGenerator,
|
|
||||||
pMetaStore: pMetaStore,
|
|
||||||
grGenerator: grGenerator,
|
|
||||||
resourceWebhookWatcher: resourceWebhookWatcher,
|
|
||||||
}
|
|
||||||
mux := http.NewServeMux()
|
mux := http.NewServeMux()
|
||||||
mux.HandleFunc(config.MutatingWebhookServicePath, ws.serve)
|
mux.HandleFunc(config.MutatingWebhookServicePath, ws.handlerFunc(ws.handleMutateAdmissionRequest, true))
|
||||||
mux.HandleFunc(config.ValidatingWebhookServicePath, ws.serve)
|
mux.HandleFunc(config.ValidatingWebhookServicePath, ws.handlerFunc(ws.handleValidateAdmissionRequest, true))
|
||||||
mux.HandleFunc(config.VerifyMutatingWebhookServicePath, ws.serve)
|
mux.HandleFunc(config.PolicyMutatingWebhookServicePath, ws.handlerFunc(ws.handlePolicyMutation, true))
|
||||||
mux.HandleFunc(config.PolicyValidatingWebhookServicePath, ws.serve)
|
mux.HandleFunc(config.PolicyValidatingWebhookServicePath, ws.handlerFunc(ws.handlePolicyValidation, true))
|
||||||
mux.HandleFunc(config.PolicyMutatingWebhookServicePath, ws.serve)
|
mux.HandleFunc(config.VerifyMutatingWebhookServicePath, ws.handlerFunc(ws.handleVerifyRequest, false))
|
||||||
ws.server = http.Server{
|
ws.server = http.Server{
|
||||||
Addr: ":443", // Listen on port for HTTPS requests
|
Addr: ":443", // Listen on port for HTTPS requests
|
||||||
TLSConfig: &tlsConfig,
|
TLSConfig: &tlsConfig,
|
||||||
|
@ -138,64 +102,50 @@ func NewWebhookServer(
|
||||||
return ws, nil
|
return ws, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// Main server endpoint for all requests
|
func (ws *WebhookServer) handlerFunc(handler func(request *v1beta1.AdmissionRequest) *v1beta1.AdmissionResponse, filter bool) http.HandlerFunc {
|
||||||
func (ws *WebhookServer) serve(w http.ResponseWriter, r *http.Request) {
|
return func(w http.ResponseWriter, r *http.Request) {
|
||||||
startTime := time.Now()
|
startTime := time.Now()
|
||||||
// for every request received on the ep update last request time,
|
// for every request received on the ep update last request time,
|
||||||
// this is used to verify admission control
|
// this is used to verify admission control
|
||||||
ws.lastReqTime.SetTime(time.Now())
|
ws.LastReqTime.SetTime(time.Now())
|
||||||
admissionReview := ws.bodyToAdmissionReview(r, w)
|
admissionReview := ws.bodyToAdmissionReview(r, w)
|
||||||
if admissionReview == nil {
|
if admissionReview == nil {
|
||||||
return
|
return
|
||||||
}
|
|
||||||
defer func() {
|
|
||||||
glog.V(4).Infof("request: %v %s/%s/%s", time.Since(startTime), admissionReview.Request.Kind, admissionReview.Request.Namespace, admissionReview.Request.Name)
|
|
||||||
}()
|
|
||||||
|
|
||||||
admissionReview.Response = &v1beta1.AdmissionResponse{
|
|
||||||
Allowed: true,
|
|
||||||
}
|
|
||||||
|
|
||||||
// Do not process the admission requests for kinds that are in filterKinds for filtering
|
|
||||||
request := admissionReview.Request
|
|
||||||
switch r.URL.Path {
|
|
||||||
case config.VerifyMutatingWebhookServicePath:
|
|
||||||
// we do not apply filters as this endpoint is used explicitly
|
|
||||||
// to watch kyveno deployment and verify if admission control is enabled
|
|
||||||
admissionReview.Response = ws.handleVerifyRequest(request)
|
|
||||||
case config.MutatingWebhookServicePath:
|
|
||||||
if !ws.configHandler.ToFilter(request.Kind.Kind, request.Namespace, request.Name) {
|
|
||||||
admissionReview.Response = ws.handleMutateAdmissionRequest(request)
|
|
||||||
}
|
}
|
||||||
case config.ValidatingWebhookServicePath:
|
defer func() {
|
||||||
if !ws.configHandler.ToFilter(request.Kind.Kind, request.Namespace, request.Name) {
|
glog.V(4).Infof("request: %v %s/%s/%s", time.Since(startTime), admissionReview.Request.Kind, admissionReview.Request.Namespace, admissionReview.Request.Name)
|
||||||
admissionReview.Response = ws.handleValidateAdmissionRequest(request)
|
}()
|
||||||
}
|
|
||||||
case config.PolicyValidatingWebhookServicePath:
|
|
||||||
if !ws.configHandler.ToFilter(request.Kind.Kind, request.Namespace, request.Name) {
|
|
||||||
admissionReview.Response = ws.handlePolicyValidation(request)
|
|
||||||
}
|
|
||||||
case config.PolicyMutatingWebhookServicePath:
|
|
||||||
if !ws.configHandler.ToFilter(request.Kind.Kind, request.Namespace, request.Name) {
|
|
||||||
admissionReview.Response = ws.handlePolicyMutation(request)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
admissionReview.Response.UID = request.UID
|
|
||||||
|
|
||||||
responseJSON, err := json.Marshal(admissionReview)
|
admissionReview.Response = &v1beta1.AdmissionResponse{
|
||||||
if err != nil {
|
Allowed: true,
|
||||||
http.Error(w, fmt.Sprintf("Could not encode response: %v", err), http.StatusInternalServerError)
|
}
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
w.Header().Set("Content-Type", "application/json; charset=utf-8")
|
// Do not process the admission requests for kinds that are in filterKinds for filtering
|
||||||
if _, err := w.Write(responseJSON); err != nil {
|
request := admissionReview.Request
|
||||||
http.Error(w, fmt.Sprintf("could not write response: %v", err), http.StatusInternalServerError)
|
if filter {
|
||||||
|
if !ws.ConfigHandler.ToFilter(request.Kind.Kind, request.Namespace, request.Name) {
|
||||||
|
admissionReview.Response = handler(request)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
admissionReview.Response = handler(request)
|
||||||
|
}
|
||||||
|
admissionReview.Response.UID = request.UID
|
||||||
|
|
||||||
|
responseJSON, err := json.Marshal(admissionReview)
|
||||||
|
if err != nil {
|
||||||
|
http.Error(w, fmt.Sprintf("Could not encode response: %v", err), http.StatusInternalServerError)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
w.Header().Set("Content-Type", "application/json; charset=utf-8")
|
||||||
|
if _, err := w.Write(responseJSON); err != nil {
|
||||||
|
http.Error(w, fmt.Sprintf("could not write response: %v", err), http.StatusInternalServerError)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (ws *WebhookServer) handleMutateAdmissionRequest(request *v1beta1.AdmissionRequest) *v1beta1.AdmissionResponse {
|
func (ws *WebhookServer) handleMutateAdmissionRequest(request *v1beta1.AdmissionRequest) *v1beta1.AdmissionResponse {
|
||||||
policies, err := ws.pMetaStore.ListAll()
|
policies, err := ws.PMetaStore.ListAll()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
// Unable to connect to policy Lister to access policies
|
// Unable to connect to policy Lister to access policies
|
||||||
glog.Errorf("Unable to connect to policy controller to access policies. Policies are NOT being applied: %v", err)
|
glog.Errorf("Unable to connect to policy controller to access policies. Policies are NOT being applied: %v", err)
|
||||||
|
@ -207,7 +157,7 @@ func (ws *WebhookServer) handleMutateAdmissionRequest(request *v1beta1.Admission
|
||||||
// getRoleRef only if policy has roles/clusterroles defined
|
// getRoleRef only if policy has roles/clusterroles defined
|
||||||
startTime := time.Now()
|
startTime := time.Now()
|
||||||
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)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
// TODO(shuting): continue apply policy if error getting roleRef?
|
// TODO(shuting): continue apply policy if error getting roleRef?
|
||||||
glog.Errorf("Unable to get rbac information for request Kind=%s, Namespace=%s Name=%s UID=%s patchOperation=%s: %v",
|
glog.Errorf("Unable to get rbac information for request Kind=%s, Namespace=%s Name=%s UID=%s patchOperation=%s: %v",
|
||||||
|
@ -247,7 +197,7 @@ func (ws *WebhookServer) handleMutateAdmissionRequest(request *v1beta1.Admission
|
||||||
// patch the resource with patches before handling validation rules
|
// patch the resource with patches before handling validation rules
|
||||||
patchedResource := processResourceWithPatches(patches, request.Object.Raw)
|
patchedResource := processResourceWithPatches(patches, request.Object.Raw)
|
||||||
|
|
||||||
if ws.resourceWebhookWatcher != nil && ws.resourceWebhookWatcher.RunValidationInMutatingWebhook == "true" {
|
if ws.ResourceWebhookWatcher != nil && ws.ResourceWebhookWatcher.RunValidationInMutatingWebhook == "true" {
|
||||||
// VALIDATION
|
// VALIDATION
|
||||||
ok, msg := ws.HandleValidation(request, policies, patchedResource, roles, clusterRoles)
|
ok, msg := ws.HandleValidation(request, policies, patchedResource, roles, clusterRoles)
|
||||||
if !ok {
|
if !ok {
|
||||||
|
@ -292,7 +242,7 @@ func (ws *WebhookServer) handleMutateAdmissionRequest(request *v1beta1.Admission
|
||||||
}
|
}
|
||||||
|
|
||||||
func (ws *WebhookServer) handleValidateAdmissionRequest(request *v1beta1.AdmissionRequest) *v1beta1.AdmissionResponse {
|
func (ws *WebhookServer) handleValidateAdmissionRequest(request *v1beta1.AdmissionRequest) *v1beta1.AdmissionResponse {
|
||||||
policies, err := ws.pMetaStore.ListAll()
|
policies, err := ws.PMetaStore.ListAll()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
// Unable to connect to policy Lister to access policies
|
// Unable to connect to policy Lister to access policies
|
||||||
glog.Errorf("Unable to connect to policy controller to access policies. Policies are NOT being applied: %v", err)
|
glog.Errorf("Unable to connect to policy controller to access policies. Policies are NOT being applied: %v", err)
|
||||||
|
@ -304,7 +254,7 @@ func (ws *WebhookServer) handleValidateAdmissionRequest(request *v1beta1.Admissi
|
||||||
// getRoleRef only if policy has roles/clusterroles defined
|
// getRoleRef only if policy has roles/clusterroles defined
|
||||||
startTime := time.Now()
|
startTime := time.Now()
|
||||||
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)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
// TODO(shuting): continue apply policy if error getting roleRef?
|
// TODO(shuting): continue apply policy if error getting roleRef?
|
||||||
glog.Errorf("Unable to get rbac information for request Kind=%s, Namespace=%s Name=%s UID=%s patchOperation=%s: %v",
|
glog.Errorf("Unable to get rbac information for request Kind=%s, Namespace=%s Name=%s UID=%s patchOperation=%s: %v",
|
||||||
|
@ -336,7 +286,7 @@ func (ws *WebhookServer) handleValidateAdmissionRequest(request *v1beta1.Admissi
|
||||||
|
|
||||||
// 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{}) {
|
||||||
if !cache.WaitForCacheSync(stopCh, ws.pSynced, ws.rbSynced, ws.crbSynced) {
|
if !cache.WaitForCacheSync(stopCh, ws.PSynced, ws.RbSynced, ws.CrbSynced) {
|
||||||
glog.Error("webhook: failed to sync informer cache")
|
glog.Error("webhook: failed to sync informer cache")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -351,7 +301,7 @@ func (ws *WebhookServer) RunAsync(stopCh <-chan struct{}) {
|
||||||
// resync: 60 seconds
|
// resync: 60 seconds
|
||||||
// deadline: 60 seconds (send request)
|
// deadline: 60 seconds (send request)
|
||||||
// max deadline: deadline*3 (set the deployment annotation as false)
|
// max deadline: deadline*3 (set the deployment annotation as false)
|
||||||
go ws.lastReqTime.Run(ws.pLister, ws.eventGen, ws.client, checker.DefaultResync, checker.DefaultDeadline, stopCh)
|
go ws.LastReqTime.Run(ws.PLister, ws.EventGen, ws.Client, checker.DefaultResync, checker.DefaultDeadline, stopCh)
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -359,7 +309,7 @@ func (ws *WebhookServer) RunAsync(stopCh <-chan struct{}) {
|
||||||
func (ws *WebhookServer) Stop(ctx context.Context) {
|
func (ws *WebhookServer) Stop(ctx context.Context) {
|
||||||
// cleanUp
|
// cleanUp
|
||||||
// remove the static webhookconfigurations
|
// remove the static webhookconfigurations
|
||||||
go ws.webhookRegistrationClient.RemoveWebhookConfigurations(ws.cleanUp)
|
go ws.WebhookRegistrationClient.RemoveWebhookConfigurations(ws.CleanUp)
|
||||||
// shutdown http.Server with context timeout
|
// shutdown http.Server with context timeout
|
||||||
err := ws.server.Shutdown(ctx)
|
err := ws.server.Shutdown(ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
|
@ -71,7 +71,7 @@ func (ws *WebhookServer) HandleValidation(request *v1beta1.AdmissionRequest, pol
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
engineResponses = append(engineResponses, engineResponse)
|
engineResponses = append(engineResponses, engineResponse)
|
||||||
ws.statusListener.Send(validateStats{
|
ws.StatusListener.Send(validateStats{
|
||||||
resp: engineResponse,
|
resp: engineResponse,
|
||||||
})
|
})
|
||||||
if !engineResponse.IsSuccesful() {
|
if !engineResponse.IsSuccesful() {
|
||||||
|
@ -98,7 +98,7 @@ func (ws *WebhookServer) HandleValidation(request *v1beta1.AdmissionRequest, pol
|
||||||
// all policies were applied succesfully.
|
// all policies were applied succesfully.
|
||||||
// create an event on the resource
|
// create an event on the resource
|
||||||
events := generateEvents(engineResponses, blocked, (request.Operation == v1beta1.Update))
|
events := generateEvents(engineResponses, blocked, (request.Operation == v1beta1.Update))
|
||||||
ws.eventGen.Add(events...)
|
ws.EventGen.Add(events...)
|
||||||
if blocked {
|
if blocked {
|
||||||
glog.V(4).Infof("resource %s/%s/%s is blocked\n", newR.GetKind(), newR.GetNamespace(), newR.GetName())
|
glog.V(4).Infof("resource %s/%s/%s is blocked\n", newR.GetKind(), newR.GetNamespace(), newR.GetName())
|
||||||
return false, getEnforceFailureErrorMsg(engineResponses)
|
return false, getEnforceFailureErrorMsg(engineResponses)
|
||||||
|
@ -107,7 +107,7 @@ func (ws *WebhookServer) HandleValidation(request *v1beta1.AdmissionRequest, pol
|
||||||
// ADD POLICY VIOLATIONS
|
// ADD POLICY VIOLATIONS
|
||||||
// violations are created with resource on "audit"
|
// violations are created with resource on "audit"
|
||||||
pvInfos := policyviolation.GeneratePVsFromEngineResponse(engineResponses)
|
pvInfos := policyviolation.GeneratePVsFromEngineResponse(engineResponses)
|
||||||
ws.pvGenerator.Add(pvInfos...)
|
ws.PvGenerator.Add(pvInfos...)
|
||||||
// report time end
|
// report time end
|
||||||
glog.V(4).Infof("report: %v %s/%s/%s", time.Since(reportTime), request.Kind, request.Namespace, request.Name)
|
glog.V(4).Infof("report: %v %s/%s/%s", time.Since(reportTime), request.Kind, request.Namespace, request.Name)
|
||||||
return true, ""
|
return true, ""
|
||||||
|
|
Loading…
Add table
Reference in a new issue