make ws admin aware of anything happened in its workspace.

Signed-off-by: wanjunlei <wanjunlei@yunify.com>
This commit is contained in:
wanjunlei
2020-07-27 22:53:53 +08:00
parent 388729e9b1
commit 713c646bfd
7 changed files with 150 additions and 30 deletions

View File

@@ -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

View File

@@ -12,9 +12,13 @@ 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"
resourcesv1alpha3 "kubesphere.io/kubesphere/pkg/models/resources/v1alpha3/resource"
"kubesphere.io/kubesphere/pkg/utils/iputil"
"net"
"net/http"
@@ -37,16 +41,18 @@ type Auditing interface {
}
type auditing struct {
lister v1alpha1.WebhookLister
cache chan *auditv1alpha1.EventList
backend *Backend
lister v1alpha1.WebhookLister
resourceGetter *resourcesv1alpha3.ResourceGetter
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),
lister: informers.KubeSphereSharedInformerFactory().Auditing().V1alpha1().Webhooks().Lister(),
resourceGetter: resourcesv1alpha3.NewResourceGetter(informers),
cache: make(chan *auditv1alpha1.EventList, DefaultCacheCapacity),
}
a.backend = NewBackend(url, ChannelCapacity, a.cache, SendTimeout, stopCh)
@@ -115,7 +121,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,
@@ -141,6 +147,25 @@ func (a *auditing) LogRequestObject(req *http.Request, info *request.RequestInfo
if len(info.Parts) >= 4 {
e.ObjectRef.Name = info.Parts[3]
}
// Get the workspace which the devops project be in.
if len(e.Workspace) == 0 {
res, err := a.resourceGetter.List(devopsv1alpha3.ResourcePluralDevOpsProject, "", query.New())
if err != nil {
klog.Error(err)
}
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
}
}
}
}
ips := make([]string, 1)
@@ -185,7 +210,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()}

View File

@@ -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(),
lister: 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(),
lister: 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(),
lister: 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(),
lister: 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(),
lister: 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)
}