Add sourceInfo to NotificationEvent (#3937)

This change adds information like host, port and user-agent of the
client whose request triggered an event notification.

E.g, if someone uploads an object to a bucket using mc. If notifications
were configured on that bucket, the host, port and user-agent of mc
would be sent as part of event notification data.

Sample output:
```
"source": {
          "host": "127.0.0.1",
          "port": "55808",
          "userAgent": "Minio (linux; amd64) minio-go/2.0.4 mc ..."
}
```
master
Krishnan Parthasarathi 8 years ago committed by Harshavardhana
parent 7f5a5b5e9d
commit 607c8a9611
  1. 20
      cmd/bucket-handlers.go
  2. 9
      cmd/bucket-notification-datatypes.go
  3. 14
      cmd/event-notifier.go
  4. 37
      cmd/object-handlers.go

@ -20,6 +20,7 @@ import (
"encoding/base64" "encoding/base64"
"encoding/xml" "encoding/xml"
"io" "io"
"net"
"net/http" "net/http"
"net/url" "net/url"
"path" "path"
@ -322,6 +323,13 @@ func (api objectAPIHandlers) DeleteMultipleObjectsHandler(w http.ResponseWriter,
// Write success response. // Write success response.
writeSuccessResponseXML(w, encodedSuccessResponse) writeSuccessResponseXML(w, encodedSuccessResponse)
// Get host and port from Request.RemoteAddr failing which
// fill them with empty strings.
host, port, err := net.SplitHostPort(r.RemoteAddr)
if err != nil {
host, port = "", ""
}
// Notify deleted event for objects. // Notify deleted event for objects.
for _, dobj := range deletedObjects { for _, dobj := range deletedObjects {
eventNotify(eventData{ eventNotify(eventData{
@ -331,6 +339,9 @@ func (api objectAPIHandlers) DeleteMultipleObjectsHandler(w http.ResponseWriter,
Name: dobj.ObjectName, Name: dobj.ObjectName,
}, },
ReqParams: extractReqParams(r), ReqParams: extractReqParams(r),
UserAgent: r.UserAgent(),
Host: host,
Port: port,
}) })
} }
} }
@ -520,12 +531,21 @@ func (api objectAPIHandlers) PostPolicyBucketHandler(w http.ResponseWriter, r *h
w.Header().Set("ETag", `"`+objInfo.MD5Sum+`"`) w.Header().Set("ETag", `"`+objInfo.MD5Sum+`"`)
w.Header().Set("Location", getObjectLocation(bucket, object)) w.Header().Set("Location", getObjectLocation(bucket, object))
// Get host and port from Request.RemoteAddr.
host, port, err := net.SplitHostPort(r.RemoteAddr)
if err != nil {
host, port = "", ""
}
// Notify object created event. // Notify object created event.
defer eventNotify(eventData{ defer eventNotify(eventData{
Type: ObjectCreatedPost, Type: ObjectCreatedPost,
Bucket: objInfo.Bucket, Bucket: objInfo.Bucket,
ObjInfo: objInfo, ObjInfo: objInfo,
ReqParams: extractReqParams(r), ReqParams: extractReqParams(r),
UserAgent: r.UserAgent(),
Host: host,
Port: port,
}) })
if successRedirect != "" { if successRedirect != "" {

@ -176,6 +176,14 @@ const (
eventVersion = "2.0" eventVersion = "2.0"
) )
// sourceInfo represents information on the client that triggered the
// event notification.
type sourceInfo struct {
Host string `json:"host"`
Port string `json:"port"`
UserAgent string `json:"userAgent"`
}
// NotificationEvent represents an Amazon an S3 bucket notification event. // NotificationEvent represents an Amazon an S3 bucket notification event.
type NotificationEvent struct { type NotificationEvent struct {
EventVersion string `json:"eventVersion"` EventVersion string `json:"eventVersion"`
@ -187,6 +195,7 @@ type NotificationEvent struct {
RequestParameters map[string]string `json:"requestParameters"` RequestParameters map[string]string `json:"requestParameters"`
ResponseElements map[string]string `json:"responseElements"` ResponseElements map[string]string `json:"responseElements"`
S3 eventMeta `json:"s3"` S3 eventMeta `json:"s3"`
Source sourceInfo `json:"source"`
} }
// Represents the minio sqs type and account id's. // Represents the minio sqs type and account id's.

@ -29,6 +29,10 @@ import (
"github.com/Sirupsen/logrus" "github.com/Sirupsen/logrus"
) )
const (
minioEventSource = "minio:s3"
)
type externalNotifier struct { type externalNotifier struct {
// Per-bucket notification config. This is updated via // Per-bucket notification config. This is updated via
// PutBucketNotification API. // PutBucketNotification API.
@ -82,6 +86,9 @@ type eventData struct {
Bucket string Bucket string
ObjInfo ObjectInfo ObjInfo ObjectInfo
ReqParams map[string]string ReqParams map[string]string
Host string
Port string
UserAgent string
} }
// New notification event constructs a new notification event message from // New notification event constructs a new notification event message from
@ -114,7 +121,7 @@ func newNotificationEvent(event eventData) NotificationEvent {
// http://docs.aws.amazon.com/AmazonS3/latest/dev/notification-content-structure.html // http://docs.aws.amazon.com/AmazonS3/latest/dev/notification-content-structure.html
nEvent := NotificationEvent{ nEvent := NotificationEvent{
EventVersion: eventVersion, EventVersion: eventVersion,
EventSource: eventSource, EventSource: minioEventSource,
AwsRegion: region, AwsRegion: region,
EventTime: eventTime.Format(timeFormatAMZ), EventTime: eventTime.Format(timeFormatAMZ),
EventName: event.Type.String(), EventName: event.Type.String(),
@ -135,6 +142,11 @@ func newNotificationEvent(event eventData) NotificationEvent {
ARN: bucketARNPrefix + event.Bucket, ARN: bucketARNPrefix + event.Bucket,
}, },
}, },
Source: sourceInfo{
Host: event.Host,
Port: event.Port,
UserAgent: event.UserAgent,
},
} }
// Escape the object name. For example "red flower.jpg" becomes "red+flower.jpg". // Escape the object name. For example "red flower.jpg" becomes "red+flower.jpg".

@ -20,6 +20,7 @@ import (
"encoding/hex" "encoding/hex"
"encoding/xml" "encoding/xml"
"io/ioutil" "io/ioutil"
"net"
"net/http" "net/http"
"net/url" "net/url"
"path" "path"
@ -372,12 +373,21 @@ func (api objectAPIHandlers) CopyObjectHandler(w http.ResponseWriter, r *http.Re
// Write success response. // Write success response.
writeSuccessResponseXML(w, encodedSuccessResponse) writeSuccessResponseXML(w, encodedSuccessResponse)
// Get host and port from Request.RemoteAddr.
host, port, err := net.SplitHostPort(r.RemoteAddr)
if err != nil {
host, port = "", ""
}
// Notify object created event. // Notify object created event.
eventNotify(eventData{ eventNotify(eventData{
Type: ObjectCreatedCopy, Type: ObjectCreatedCopy,
Bucket: dstBucket, Bucket: dstBucket,
ObjInfo: objInfo, ObjInfo: objInfo,
ReqParams: extractReqParams(r), ReqParams: extractReqParams(r),
UserAgent: r.UserAgent(),
Host: host,
Port: port,
}) })
} }
@ -503,12 +513,21 @@ func (api objectAPIHandlers) PutObjectHandler(w http.ResponseWriter, r *http.Req
w.Header().Set("ETag", "\""+objInfo.MD5Sum+"\"") w.Header().Set("ETag", "\""+objInfo.MD5Sum+"\"")
writeSuccessResponseHeadersOnly(w) writeSuccessResponseHeadersOnly(w)
// Get host and port from Request.RemoteAddr.
host, port, err := net.SplitHostPort(r.RemoteAddr)
if err != nil {
host, port = "", ""
}
// Notify object created event. // Notify object created event.
eventNotify(eventData{ eventNotify(eventData{
Type: ObjectCreatedPut, Type: ObjectCreatedPut,
Bucket: bucket, Bucket: bucket,
ObjInfo: objInfo, ObjInfo: objInfo,
ReqParams: extractReqParams(r), ReqParams: extractReqParams(r),
UserAgent: r.UserAgent(),
Host: host,
Port: port,
}) })
} }
@ -930,12 +949,21 @@ func (api objectAPIHandlers) CompleteMultipartUploadHandler(w http.ResponseWrite
// Write success response. // Write success response.
writeSuccessResponseXML(w, encodedSuccessResponse) writeSuccessResponseXML(w, encodedSuccessResponse)
// Get host and port from Request.RemoteAddr.
host, port, err := net.SplitHostPort(r.RemoteAddr)
if err != nil {
host, port = "", ""
}
// Notify object created event. // Notify object created event.
eventNotify(eventData{ eventNotify(eventData{
Type: ObjectCreatedCompleteMultipartUpload, Type: ObjectCreatedCompleteMultipartUpload,
Bucket: bucket, Bucket: bucket,
ObjInfo: objInfo, ObjInfo: objInfo,
ReqParams: extractReqParams(r), ReqParams: extractReqParams(r),
UserAgent: r.UserAgent(),
Host: host,
Port: port,
}) })
} }
@ -971,6 +999,12 @@ func (api objectAPIHandlers) DeleteObjectHandler(w http.ResponseWriter, r *http.
} }
writeSuccessNoContent(w) writeSuccessNoContent(w)
// Get host and port from Request.RemoteAddr.
host, port, err := net.SplitHostPort(r.RemoteAddr)
if err != nil {
host, port = "", ""
}
// Notify object deleted event. // Notify object deleted event.
eventNotify(eventData{ eventNotify(eventData{
Type: ObjectRemovedDelete, Type: ObjectRemovedDelete,
@ -979,5 +1013,8 @@ func (api objectAPIHandlers) DeleteObjectHandler(w http.ResponseWriter, r *http.
Name: object, Name: object,
}, },
ReqParams: extractReqParams(r), ReqParams: extractReqParams(r),
UserAgent: r.UserAgent(),
Host: host,
Port: port,
}) })
} }

Loading…
Cancel
Save