未验证 提交 52abbeb3 编写于 作者: K KubeSphere CI Bot 提交者: GitHub

Merge pull request #2227 from wanjunlei/master

process audit information for resource creating requests
...@@ -86,12 +86,14 @@ func (b *Backend) worker() { ...@@ -86,12 +86,14 @@ func (b *Backend) worker() {
<-b.semCh <-b.semCh
}() }()
bs, err := json.Marshal(event) bs, err := b.eventToBytes(event)
if err != nil { if err != nil {
klog.Errorf("json marshal error, %s", err) klog.V(6).Infof("json marshal error, %s", err)
return return
} }
klog.V(8).Infof("%s", string(bs))
response, err := b.client.Post(b.url, "application/json", bytes.NewBuffer(bs)) response, err := b.client.Post(b.url, "application/json", bytes.NewBuffer(bs))
if err != nil { if err != nil {
klog.Errorf("send audit event[%s] error, %s", event.Items[0].AuditID, err) klog.Errorf("send audit event[%s] error, %s", event.Items[0].AuditID, err)
...@@ -107,3 +109,21 @@ func (b *Backend) worker() { ...@@ -107,3 +109,21 @@ func (b *Backend) worker() {
go send(event) go send(event)
} }
} }
func (b *Backend) eventToBytes(event *v1alpha1.EventList) ([]byte, error) {
bs, err := json.Marshal(event)
if err != nil {
// Normally, the serialization failure is caused by the failure of ResponseObject serialization.
// To ensure the integrity of the auditing event to the greatest extent,
// it is necessary to delete ResponseObject and and then try to serialize again.
if event.Items[0].ResponseObject != nil {
event.Items[0].ResponseObject = nil
return json.Marshal(event)
}
return nil, err
}
return bs, err
}
...@@ -122,6 +122,19 @@ func (a *auditing) LogRequestObject(req *http.Request, info *request.RequestInfo ...@@ -122,6 +122,19 @@ 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]
// 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]
}
}
ips := make([]string, 1) ips := make([]string, 1)
ips[0] = iputil.RemoteIp(req) ips[0] = iputil.RemoteIp(req)
e.SourceIPs = ips e.SourceIPs = ips
...@@ -137,7 +150,7 @@ func (a *auditing) LogRequestObject(req *http.Request, info *request.RequestInfo ...@@ -137,7 +150,7 @@ func (a *auditing) LogRequestObject(req *http.Request, info *request.RequestInfo
} }
} }
if e.Level.GreaterOrEqual(audit.LevelRequest) && req.ContentLength > 0 { if (e.Level.GreaterOrEqual(audit.LevelRequest) || e.Verb == "create") && req.ContentLength > 0 {
body, err := ioutil.ReadAll(req.Body) body, err := ioutil.ReadAll(req.Body)
if err != nil { if err != nil {
klog.Error(err) klog.Error(err)
...@@ -145,19 +158,25 @@ func (a *auditing) LogRequestObject(req *http.Request, info *request.RequestInfo ...@@ -145,19 +158,25 @@ func (a *auditing) LogRequestObject(req *http.Request, info *request.RequestInfo
} }
_ = req.Body.Close() _ = req.Body.Close()
req.Body = ioutil.NopCloser(bytes.NewBuffer(body)) req.Body = ioutil.NopCloser(bytes.NewBuffer(body))
if e.Level.GreaterOrEqual(audit.LevelRequest) {
e.RequestObject = &runtime.Unknown{Raw: body} e.RequestObject = &runtime.Unknown{Raw: body}
} }
// For resource creating request, get resource name from the request body.
if info.Verb == "create" {
obj := &auditv1alpha1.Object{}
if err := json.Unmarshal(body, obj); err == nil {
e.ObjectRef.Name = obj.Name
}
}
}
return e return e
} }
func (a *auditing) LogResponseObject(e *auditv1alpha1.Event, resp *ResponseCapture, info *request.RequestInfo) { func (a *auditing) LogResponseObject(e *auditv1alpha1.Event, resp *ResponseCapture, info *request.RequestInfo) {
// Auditing should igonre k8s request when k8s auditing is enabled.
if info.IsKubernetesRequest && a.K8sAuditingEnabled() {
return
}
e.StageTimestamp = v1.NewMicroTime(time.Now()) e.StageTimestamp = v1.NewMicroTime(time.Now())
e.ResponseStatus = &v1.Status{Code: int32(resp.StatusCode())} e.ResponseStatus = &v1.Status{Code: int32(resp.StatusCode())}
if e.Level.GreaterOrEqual(audit.LevelRequestResponse) { if e.Level.GreaterOrEqual(audit.LevelRequestResponse) {
...@@ -168,10 +187,6 @@ func (a *auditing) LogResponseObject(e *auditv1alpha1.Event, resp *ResponseCaptu ...@@ -168,10 +187,6 @@ func (a *auditing) LogResponseObject(e *auditv1alpha1.Event, resp *ResponseCaptu
} }
func (a *auditing) cacheEvent(e auditv1alpha1.Event) { func (a *auditing) cacheEvent(e auditv1alpha1.Event) {
if klog.V(8) {
bs, _ := json.Marshal(e)
klog.Infof("%s", string(bs))
}
eventList := &auditv1alpha1.EventList{} eventList := &auditv1alpha1.EventList{}
eventList.Items = append(eventList.Items, e) eventList.Items = append(eventList.Items, e)
......
package v1alpha1 package v1alpha1
import "k8s.io/apiserver/pkg/apis/audit" import (
"k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apiserver/pkg/apis/audit"
)
type Event struct { type Event struct {
// Devops project // Devops project
...@@ -18,3 +21,7 @@ type Event struct { ...@@ -18,3 +21,7 @@ type Event struct {
type EventList struct { type EventList struct {
Items []Event Items []Event
} }
type Object struct {
v1.ObjectMeta `json:"metadata,omitempty" protobuf:"bytes,1,opt,name=metadata"`
}
...@@ -26,6 +26,12 @@ func WithAuditing(handler http.Handler, a auditing.Auditing) http.Handler { ...@@ -26,6 +26,12 @@ func WithAuditing(handler http.Handler, a auditing.Auditing) http.Handler {
return return
} }
// Auditing should igonre k8s request when k8s auditing is enabled.
if info.IsKubernetesRequest && a.K8sAuditingEnabled() {
handler.ServeHTTP(w, req)
return
}
e := a.LogRequestObject(req, info) e := a.LogRequestObject(req, info)
req = req.WithContext(request.WithAuditEvent(req.Context(), e)) req = req.WithContext(request.WithAuditEvent(req.Context(), e))
resp := auditing.NewResponseCapture(w) resp := auditing.NewResponseCapture(w)
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册