Merge pull request #2672 from wanjunlei/auditing-log
make ws admin can be aware of anything happened in its workspace.
This commit is contained in:
@@ -260,8 +260,7 @@ func (s *APIServer) buildHandlerChain(stopCh <-chan struct{}) {
|
||||
|
||||
if s.Config.AuditingOptions.Enable {
|
||||
handler = filters.WithAuditing(handler,
|
||||
audit.NewAuditing(s.InformerFactory.KubeSphereSharedInformerFactory().Auditing().V1alpha1().Webhooks().Lister(),
|
||||
s.Config.AuditingOptions.WebhookUrl, stopCh))
|
||||
audit.NewAuditing(s.InformerFactory, s.Config.AuditingOptions.WebhookUrl, stopCh))
|
||||
}
|
||||
|
||||
var authorizers authorizer.Authorizer
|
||||
|
||||
@@ -12,9 +12,14 @@ import (
|
||||
"k8s.io/apimachinery/pkg/types"
|
||||
"k8s.io/apiserver/pkg/apis/audit"
|
||||
"k8s.io/klog"
|
||||
devopsv1alpha3 "kubesphere.io/kubesphere/pkg/apis/devops/v1alpha3"
|
||||
auditv1alpha1 "kubesphere.io/kubesphere/pkg/apiserver/auditing/v1alpha1"
|
||||
"kubesphere.io/kubesphere/pkg/apiserver/query"
|
||||
"kubesphere.io/kubesphere/pkg/apiserver/request"
|
||||
"kubesphere.io/kubesphere/pkg/client/listers/auditing/v1alpha1"
|
||||
"kubesphere.io/kubesphere/pkg/informers"
|
||||
"kubesphere.io/kubesphere/pkg/models/resources/v1alpha3"
|
||||
"kubesphere.io/kubesphere/pkg/models/resources/v1alpha3/devops"
|
||||
"kubesphere.io/kubesphere/pkg/utils/iputil"
|
||||
"net"
|
||||
"net/http"
|
||||
@@ -37,16 +42,18 @@ type Auditing interface {
|
||||
}
|
||||
|
||||
type auditing struct {
|
||||
lister v1alpha1.WebhookLister
|
||||
cache chan *auditv1alpha1.EventList
|
||||
backend *Backend
|
||||
webhookLister v1alpha1.WebhookLister
|
||||
devopsGetter v1alpha3.Interface
|
||||
cache chan *auditv1alpha1.EventList
|
||||
backend *Backend
|
||||
}
|
||||
|
||||
func NewAuditing(lister v1alpha1.WebhookLister, url string, stopCh <-chan struct{}) Auditing {
|
||||
func NewAuditing(informers informers.InformerFactory, url string, stopCh <-chan struct{}) Auditing {
|
||||
|
||||
a := &auditing{
|
||||
lister: lister,
|
||||
cache: make(chan *auditv1alpha1.EventList, DefaultCacheCapacity),
|
||||
webhookLister: informers.KubeSphereSharedInformerFactory().Auditing().V1alpha1().Webhooks().Lister(),
|
||||
devopsGetter: devops.New(informers.KubeSphereSharedInformerFactory()),
|
||||
cache: make(chan *auditv1alpha1.EventList, DefaultCacheCapacity),
|
||||
}
|
||||
|
||||
a.backend = NewBackend(url, ChannelCapacity, a.cache, SendTimeout, stopCh)
|
||||
@@ -54,7 +61,7 @@ func NewAuditing(lister v1alpha1.WebhookLister, url string, stopCh <-chan struct
|
||||
}
|
||||
|
||||
func (a *auditing) getAuditLevel() audit.Level {
|
||||
wh, err := a.lister.Get(DefaultWebhook)
|
||||
wh, err := a.webhookLister.Get(DefaultWebhook)
|
||||
if err != nil {
|
||||
klog.V(8).Info(err)
|
||||
return audit.LevelNone
|
||||
@@ -73,7 +80,7 @@ func (a *auditing) Enabled() bool {
|
||||
}
|
||||
|
||||
func (a *auditing) K8sAuditingEnabled() bool {
|
||||
wh, err := a.lister.Get(DefaultWebhook)
|
||||
wh, err := a.webhookLister.Get(DefaultWebhook)
|
||||
if err != nil {
|
||||
klog.V(8).Info(err)
|
||||
return false
|
||||
@@ -105,6 +112,7 @@ func (a *auditing) LogRequestObject(req *http.Request, info *request.RequestInfo
|
||||
}
|
||||
|
||||
e := &auditv1alpha1.Event{
|
||||
Devops: info.DevOps,
|
||||
Workspace: info.Workspace,
|
||||
Cluster: info.Cluster,
|
||||
Event: audit.Event{
|
||||
@@ -115,7 +123,7 @@ func (a *auditing) LogRequestObject(req *http.Request, info *request.RequestInfo
|
||||
Stage: audit.StageResponseComplete,
|
||||
ImpersonatedUser: nil,
|
||||
UserAgent: req.UserAgent(),
|
||||
RequestReceivedTimestamp: v1.NewMicroTime(time.Now()),
|
||||
RequestReceivedTimestamp: v1.NowMicro(),
|
||||
Annotations: nil,
|
||||
ObjectRef: &audit.ObjectReference{
|
||||
Resource: info.Resource,
|
||||
@@ -130,16 +138,22 @@ func (a *auditing) LogRequestObject(req *http.Request, info *request.RequestInfo
|
||||
},
|
||||
}
|
||||
|
||||
// Handle the devops request which request url matched /devops/{devops}/kind.
|
||||
if len(info.Parts) >= 3 && info.Parts[0] == "devops" {
|
||||
e.ObjectRef.Subresource = ""
|
||||
e.Devops = info.Parts[1]
|
||||
// set resource as kind
|
||||
e.ObjectRef.Resource = info.Parts[2]
|
||||
// Get the workspace which the devops project be in.
|
||||
if len(e.Devops) > 0 && len(e.Workspace) == 0 {
|
||||
res, err := a.devopsGetter.List("", query.New())
|
||||
if err != nil {
|
||||
klog.Error(err)
|
||||
}
|
||||
|
||||
// If the request url matched /devops/{devops}/kind/{kind}, set resource name as {kind}
|
||||
if len(info.Parts) >= 4 {
|
||||
e.ObjectRef.Name = info.Parts[3]
|
||||
for _, obj := range res.Items {
|
||||
d := obj.(*devopsv1alpha3.DevOpsProject)
|
||||
|
||||
if d.Name == e.Devops {
|
||||
e.Workspace = d.Labels["kubesphere.io/workspace"]
|
||||
} else if d.Status.AdminNamespace == e.Devops {
|
||||
e.Workspace = d.Labels["kubesphere.io/workspace"]
|
||||
e.Devops = d.Name
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -185,7 +199,7 @@ func (a *auditing) LogRequestObject(req *http.Request, info *request.RequestInfo
|
||||
|
||||
func (a *auditing) LogResponseObject(e *auditv1alpha1.Event, resp *ResponseCapture) {
|
||||
|
||||
e.StageTimestamp = v1.NewMicroTime(time.Now())
|
||||
e.StageTimestamp = v1.NowMicro()
|
||||
e.ResponseStatus = &v1.Status{Code: int32(resp.StatusCode())}
|
||||
if e.Level.GreaterOrEqual(audit.LevelRequestResponse) {
|
||||
e.ResponseObject = &runtime.Unknown{Raw: resp.Bytes()}
|
||||
|
||||
@@ -9,11 +9,12 @@ import (
|
||||
"k8s.io/apiserver/pkg/apis/audit"
|
||||
"k8s.io/apiserver/pkg/authentication/user"
|
||||
k8srequest "k8s.io/apiserver/pkg/endpoints/request"
|
||||
fakek8s "k8s.io/client-go/kubernetes/fake"
|
||||
auditingv1alpha1 "kubesphere.io/kubesphere/pkg/apis/auditing/v1alpha1"
|
||||
v1alpha12 "kubesphere.io/kubesphere/pkg/apiserver/auditing/v1alpha1"
|
||||
"kubesphere.io/kubesphere/pkg/apiserver/request"
|
||||
"kubesphere.io/kubesphere/pkg/client/clientset/versioned/fake"
|
||||
ksinformers "kubesphere.io/kubesphere/pkg/client/informers/externalversions"
|
||||
"kubesphere.io/kubesphere/pkg/informers"
|
||||
"kubesphere.io/kubesphere/pkg/utils/iputil"
|
||||
"net/http"
|
||||
"net/http/httptest"
|
||||
@@ -37,13 +38,15 @@ func TestGetAuditLevel(t *testing.T) {
|
||||
},
|
||||
}
|
||||
|
||||
informer := ksinformers.NewSharedInformerFactory(fake.NewSimpleClientset(), noResyncPeriodFunc())
|
||||
ksClient := fake.NewSimpleClientset()
|
||||
k8sClient := fakek8s.NewSimpleClientset()
|
||||
fakeInformerFactory := informers.NewInformerFactories(k8sClient, ksClient, nil, nil, nil, nil)
|
||||
|
||||
a := auditing{
|
||||
lister: informer.Auditing().V1alpha1().Webhooks().Lister(),
|
||||
webhookLister: fakeInformerFactory.KubeSphereSharedInformerFactory().Auditing().V1alpha1().Webhooks().Lister(),
|
||||
}
|
||||
|
||||
err := informer.Auditing().V1alpha1().Webhooks().Informer().GetIndexer().Add(webhook)
|
||||
err := fakeInformerFactory.KubeSphereSharedInformerFactory().Auditing().V1alpha1().Webhooks().Informer().GetIndexer().Add(webhook)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
@@ -64,13 +67,15 @@ func TestAuditing_Enabled(t *testing.T) {
|
||||
},
|
||||
}
|
||||
|
||||
informer := ksinformers.NewSharedInformerFactory(fake.NewSimpleClientset(), noResyncPeriodFunc())
|
||||
ksClient := fake.NewSimpleClientset()
|
||||
k8sClient := fakek8s.NewSimpleClientset()
|
||||
fakeInformerFactory := informers.NewInformerFactories(k8sClient, ksClient, nil, nil, nil, nil)
|
||||
|
||||
a := auditing{
|
||||
lister: informer.Auditing().V1alpha1().Webhooks().Lister(),
|
||||
webhookLister: fakeInformerFactory.KubeSphereSharedInformerFactory().Auditing().V1alpha1().Webhooks().Lister(),
|
||||
}
|
||||
|
||||
err := informer.Auditing().V1alpha1().Webhooks().Informer().GetIndexer().Add(webhook)
|
||||
err := fakeInformerFactory.KubeSphereSharedInformerFactory().Auditing().V1alpha1().Webhooks().Informer().GetIndexer().Add(webhook)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
@@ -92,13 +97,15 @@ func TestAuditing_K8sAuditingEnabled(t *testing.T) {
|
||||
},
|
||||
}
|
||||
|
||||
informer := ksinformers.NewSharedInformerFactory(fake.NewSimpleClientset(), noResyncPeriodFunc())
|
||||
ksClient := fake.NewSimpleClientset()
|
||||
k8sClient := fakek8s.NewSimpleClientset()
|
||||
fakeInformerFactory := informers.NewInformerFactories(k8sClient, ksClient, nil, nil, nil, nil)
|
||||
|
||||
a := auditing{
|
||||
lister: informer.Auditing().V1alpha1().Webhooks().Lister(),
|
||||
webhookLister: fakeInformerFactory.KubeSphereSharedInformerFactory().Auditing().V1alpha1().Webhooks().Lister(),
|
||||
}
|
||||
|
||||
err := informer.Auditing().V1alpha1().Webhooks().Informer().GetIndexer().Add(webhook)
|
||||
err := fakeInformerFactory.KubeSphereSharedInformerFactory().Auditing().V1alpha1().Webhooks().Informer().GetIndexer().Add(webhook)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
@@ -120,13 +127,15 @@ func TestAuditing_LogRequestObject(t *testing.T) {
|
||||
},
|
||||
}
|
||||
|
||||
informer := ksinformers.NewSharedInformerFactory(fake.NewSimpleClientset(), noResyncPeriodFunc())
|
||||
ksClient := fake.NewSimpleClientset()
|
||||
k8sClient := fakek8s.NewSimpleClientset()
|
||||
fakeInformerFactory := informers.NewInformerFactories(k8sClient, ksClient, nil, nil, nil, nil)
|
||||
|
||||
a := auditing{
|
||||
lister: informer.Auditing().V1alpha1().Webhooks().Lister(),
|
||||
webhookLister: fakeInformerFactory.KubeSphereSharedInformerFactory().Auditing().V1alpha1().Webhooks().Lister(),
|
||||
}
|
||||
|
||||
err := informer.Auditing().V1alpha1().Webhooks().Informer().GetIndexer().Add(webhook)
|
||||
err := fakeInformerFactory.KubeSphereSharedInformerFactory().Auditing().V1alpha1().Webhooks().Informer().GetIndexer().Add(webhook)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
@@ -208,13 +217,15 @@ func TestAuditing_LogResponseObject(t *testing.T) {
|
||||
},
|
||||
}
|
||||
|
||||
informer := ksinformers.NewSharedInformerFactory(fake.NewSimpleClientset(), noResyncPeriodFunc())
|
||||
ksClient := fake.NewSimpleClientset()
|
||||
k8sClient := fakek8s.NewSimpleClientset()
|
||||
fakeInformerFactory := informers.NewInformerFactories(k8sClient, ksClient, nil, nil, nil, nil)
|
||||
|
||||
a := auditing{
|
||||
lister: informer.Auditing().V1alpha1().Webhooks().Lister(),
|
||||
webhookLister: fakeInformerFactory.KubeSphereSharedInformerFactory().Auditing().V1alpha1().Webhooks().Lister(),
|
||||
}
|
||||
|
||||
err := informer.Auditing().V1alpha1().Webhooks().Informer().GetIndexer().Add(webhook)
|
||||
err := fakeInformerFactory.KubeSphereSharedInformerFactory().Auditing().V1alpha1().Webhooks().Informer().GetIndexer().Add(webhook)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user