diff --git a/common/actions.go b/common/actions.go index caa3331d..73d8ec52 100644 --- a/common/actions.go +++ b/common/actions.go @@ -54,7 +54,7 @@ func InitializeActionHandler(handler ActionHandler) { func ExecutePreAction(user *dataprovider.User, operation, filePath, virtualPath, protocol, ip string, fileSize int64, openFlags int, ) error { - plugin.Handler.NotifyFsEvent(time.Now(), operation, user.Username, filePath, "", "", protocol, ip, virtualPath, "", fileSize, nil) + plugin.Handler.NotifyFsEvent(time.Now().UnixNano(), operation, user.Username, filePath, "", "", protocol, ip, virtualPath, "", fileSize, nil) if !util.IsStringInSlice(operation, Config.Actions.ExecuteOn) { // for pre-delete we execute the internal handling on error, so we must return errUnconfiguredAction. // Other pre action will deny the operation on error so if we have no configuration we must return @@ -73,7 +73,7 @@ func ExecutePreAction(user *dataprovider.User, operation, filePath, virtualPath, func ExecuteActionNotification(user *dataprovider.User, operation, filePath, virtualPath, target, virtualTarget, sshCmd, protocol, ip string, fileSize int64, err error, ) { - plugin.Handler.NotifyFsEvent(time.Now(), operation, user.Username, filePath, target, sshCmd, protocol, ip, virtualPath, + plugin.Handler.NotifyFsEvent(time.Now().UnixNano(), operation, user.Username, filePath, target, sshCmd, protocol, ip, virtualPath, virtualTarget, fileSize, err) notification := newActionNotification(user, operation, filePath, virtualPath, target, virtualTarget, sshCmd, protocol, ip, fileSize, 0, err) @@ -139,9 +139,9 @@ func newActionNotification( } if err == ErrQuotaExceeded { - status = 2 + status = 3 } else if err != nil { - status = 0 + status = 2 } return &ActionNotification{ @@ -160,7 +160,7 @@ func newActionNotification( Protocol: protocol, IP: ip, OpenFlags: openFlags, - Timestamp: util.GetTimeAsMsSinceEpoch(time.Now()), + Timestamp: time.Now().UnixNano(), } } diff --git a/common/actions_test.go b/common/actions_test.go index 8cf7d803..4b2796a4 100644 --- a/common/actions_test.go +++ b/common/actions_test.go @@ -49,7 +49,7 @@ func TestNewActionNotification(t *testing.T) { assert.Equal(t, user.Username, a.Username) assert.Equal(t, 0, len(a.Bucket)) assert.Equal(t, 0, len(a.Endpoint)) - assert.Equal(t, 0, a.Status) + assert.Equal(t, 2, a.Status) user.FsConfig.Provider = sdk.S3FilesystemProvider a = newActionNotification(user, operationDownload, "path", "vpath", "target", "", "", ProtocolSSH, "", 123, 0, nil) @@ -61,7 +61,7 @@ func TestNewActionNotification(t *testing.T) { a = newActionNotification(user, operationDownload, "path", "vpath", "target", "", "", ProtocolSCP, "", 123, 0, ErrQuotaExceeded) assert.Equal(t, "gcsbucket", a.Bucket) assert.Equal(t, 0, len(a.Endpoint)) - assert.Equal(t, 2, a.Status) + assert.Equal(t, 3, a.Status) user.FsConfig.Provider = sdk.AzureBlobFilesystemProvider a = newActionNotification(user, operationDownload, "path", "vpath", "target", "", "", ProtocolSCP, "", 123, 0, nil) diff --git a/dataprovider/actions.go b/dataprovider/actions.go index 2708b123..e03d651b 100644 --- a/dataprovider/actions.go +++ b/dataprovider/actions.go @@ -32,7 +32,7 @@ const ( ) func executeAction(operation, executor, ip, objectType, objectName string, object plugin.Renderer) { - plugin.Handler.NotifyProviderEvent(time.Now(), operation, executor, objectType, objectName, ip, object) + plugin.Handler.NotifyProviderEvent(time.Now().UnixNano(), operation, executor, objectType, objectName, ip, object) if config.Actions.Hook == "" { return } @@ -60,7 +60,7 @@ func executeAction(operation, executor, ip, objectType, objectName string, objec q.Add("ip", ip) q.Add("object_type", objectType) q.Add("object_name", objectName) - q.Add("timestamp", fmt.Sprintf("%v", util.GetTimeAsMsSinceEpoch(time.Now()))) + q.Add("timestamp", fmt.Sprintf("%v", time.Now().UnixNano())) url.RawQuery = q.Encode() startTime := time.Now() resp, err := httpclient.RetryablePost(url.String(), "application/json", bytes.NewBuffer(dataAsJSON)) diff --git a/dataprovider/mysql.go b/dataprovider/mysql.go index 0f9970d8..416e9f1e 100644 --- a/dataprovider/mysql.go +++ b/dataprovider/mysql.go @@ -105,7 +105,7 @@ func getMySQLConnectionString(redactedPwd bool) string { if redactedPwd { password = "[redacted]" } - connectionString = fmt.Sprintf("%v:%v@tcp([%v]:%v)/%v?charset=utf8&interpolateParams=true&timeout=10s&tls=%v&writeTimeout=10s&readTimeout=10s", + connectionString = fmt.Sprintf("%v:%v@tcp([%v]:%v)/%v?charset=utf8mb4&interpolateParams=true&timeout=10s&parseTime=true&tls=%v&writeTimeout=10s&readTimeout=10s", config.Username, password, config.Host, config.Port, config.Name, getSSLMode()) } else { connectionString = config.ConnectionString diff --git a/docs/custom-actions.md b/docs/custom-actions.md index c8e82d33..38093970 100644 --- a/docs/custom-actions.md +++ b/docs/custom-actions.md @@ -42,11 +42,11 @@ If the `hook` defines a path to an external program, then this program can read - `SFTPGO_ACTION_FS_PROVIDER`, `0` for local filesystem, `1` for S3 backend, `2` for Google Cloud Storage (GCS) backend, `3` for Azure Blob Storage backend, `4` for local encrypted backend, `5` for SFTP backend - `SFTPGO_ACTION_BUCKET`, non-empty for S3, GCS and Azure backends - `SFTPGO_ACTION_ENDPOINT`, non-empty for S3, SFTP and Azure backend if configured. For Azure this is the endpoint, if configured -- `SFTPGO_ACTION_STATUS`, integer. Status for `upload`, `download` and `ssh_cmd` actions. 0 means a generic error occurred. 1 means no error, 2 means quota exceeded error +- `SFTPGO_ACTION_STATUS`, integer. Status for `upload`, `download` and `ssh_cmd` actions. 1 means no error, 2 means a generic error occurred, 3 means quota exceeded error - `SFTPGO_ACTION_PROTOCOL`, string. Possible values are `SSH`, `SFTP`, `SCP`, `FTP`, `DAV`, `HTTP`, `DataRetention` - `SFTPGO_ACTION_IP`, the action was executed from this IP address - `SFTPGO_ACTION_OPEN_FLAGS`, integer. File open flags, can be non-zero for `pre-upload` action. If `SFTPGO_ACTION_FILE_SIZE` is greater than zero and `SFTPGO_ACTION_OPEN_FLAGS&512 == 0` the target file will not be truncated -- `SFTPGO_ACTION_TIMESTAMP`, int64. Event timestamp as milliseconds since epoch +- `SFTPGO_ACTION_TIMESTAMP`, int64. Event timestamp as nanoseconds since epoch Previous global environment variables aren't cleared when the script is called. The program must finish within 30 seconds. @@ -64,11 +64,11 @@ If the `hook` defines an HTTP URL then this URL will be invoked as HTTP POST. Th - `fs_provider`, integer, `0` for local filesystem, `1` for S3 backend, `2` for Google Cloud Storage (GCS) backend, `3` for Azure Blob Storage backend, `4` for local encrypted backend, `5` for SFTP backend - `bucket`, string, inlcuded for S3, GCS and Azure backends - `endpoint`, string, included for S3, SFTP and Azure backend if configured -- `status`, integer. Status for `upload`, `download` and `ssh_cmd` actions. 0 means a generic error occurred. 1 means no error, 2 means quota exceeded error +- `status`, integer. Status for `upload`, `download` and `ssh_cmd` actions. 1 means no error, 2 means a generic error occurred, 3 means quota exceeded error - `protocol`, string. Possible values are `SSH`, `SFTP`, `SCP`, `FTP`, `DAV`, `HTTP`, `DataRetention` - `ip`, string. The action was executed from this IP address - `open_flags`, integer. File open flags, can be non-zero for `pre-upload` action. If `file_size` is greater than zero and `file_size&512 == 0` the target file will not be truncated -- `timestamp`, int64. Event timestamp as milliseconds since epoch +- `timestamp`, int64. Event timestamp as nanoseconds since epoch The HTTP hook will use the global configuration for HTTP clients and will respect the retry configurations. @@ -93,7 +93,7 @@ If the `hook` defines a path to an external program, then this program can read - `SFTPGO_PROVIDER_OBJECT_NAME`, unique identifier for the affected object, for example username or key id - `SFTPGO_PROVIDER_USERNAME`, the username that executed the action. There are two special usernames: `__self__` identifies a user/admin that updates itself and `__system__` identifies an action that does not have an explicit executor associated with it, for example users/admins can be added/updated by loading them from initial data - `SFTPGO_PROVIDER_IP`, the action was executed from this IP address -- `SFTPGO_PROVIDER_TIMESTAMP`, event timestamp as milliseconds since epoch +- `SFTPGO_PROVIDER_TIMESTAMP`, event timestamp as nanoseconds since epoch - `SFTPGO_PROVIDER_OBJECT`, object serialized as JSON with sensitive fields removed Previous global environment variables aren't cleared when the script is called. diff --git a/go.mod b/go.mod index 66f0299e..3097d2f8 100644 --- a/go.mod +++ b/go.mod @@ -3,11 +3,11 @@ module github.com/drakkan/sftpgo/v2 go 1.17 require ( - cloud.google.com/go/storage v1.18.1 + cloud.google.com/go/storage v1.18.2 github.com/Azure/azure-storage-blob-go v0.14.0 github.com/GehirnInc/crypt v0.0.0-20200316065508-bb7000b8a962 github.com/alexedwards/argon2id v0.0.0-20210511081203-7d35d68092b8 - github.com/aws/aws-sdk-go v1.41.4 + github.com/aws/aws-sdk-go v1.41.6 github.com/cockroachdb/cockroach-go/v2 v2.2.1 github.com/eikenb/pipeat v0.0.0-20210603033007-44fc3ffce52b github.com/fatih/color v1.13.0 // indirect @@ -33,7 +33,7 @@ require ( github.com/lib/pq v1.10.3 github.com/lithammer/shortuuid/v3 v3.0.7 github.com/mattn/go-isatty v0.0.14 // indirect - github.com/mattn/go-sqlite3 v1.14.8 + github.com/mattn/go-sqlite3 v1.14.9 github.com/mhale/smtpd v0.8.0 github.com/miekg/dns v1.1.43 // indirect github.com/minio/sio v0.3.0 @@ -44,7 +44,7 @@ require ( github.com/pkg/sftp v1.13.4 github.com/pquerna/otp v1.3.0 github.com/prometheus/client_golang v1.11.0 - github.com/prometheus/common v0.31.1 // indirect + github.com/prometheus/common v0.32.0 // indirect github.com/rs/cors v1.8.0 github.com/rs/xid v1.3.0 github.com/rs/zerolog v1.25.0 @@ -63,10 +63,10 @@ require ( gocloud.dev v0.24.0 golang.org/x/crypto v0.0.0-20210915214749-c084706c2272 golang.org/x/net v0.0.0-20211015210444-4f30a5c0130f - golang.org/x/sys v0.0.0-20211015200801-69063c4bb744 + golang.org/x/sys v0.0.0-20211020154033-fcb26fe61c20 golang.org/x/time v0.0.0-20210723032227-1f47c861a9ac - google.golang.org/api v0.58.0 - google.golang.org/genproto v0.0.0-20211013025323-ce878158c4d4 // indirect + google.golang.org/api v0.59.0 + google.golang.org/genproto v0.0.0-20211020151524-b7c3a969101a // indirect google.golang.org/grpc v1.41.0 google.golang.org/protobuf v1.27.1 gopkg.in/natefinch/lumberjack.v2 v2.0.0 diff --git a/go.sum b/go.sum index cbaaaa8d..805c39e4 100644 --- a/go.sum +++ b/go.sum @@ -60,8 +60,8 @@ cloud.google.com/go/storage v1.6.0/go.mod h1:N7U0C8pVQ/+NIKOBQyamJIeKQKkZ+mxpohl cloud.google.com/go/storage v1.8.0/go.mod h1:Wv1Oy7z6Yz3DshWRJFhqM/UCfaWIRTdp0RXyy7KQOVs= cloud.google.com/go/storage v1.10.0/go.mod h1:FLPqc6j+Ki4BU591ie1oL6qBQGu2Bl/tZ9ullr3+Kg0= cloud.google.com/go/storage v1.16.1/go.mod h1:LaNorbty3ehnU3rEjXSNV/NRgQA0O8Y+uh6bPe5UOk4= -cloud.google.com/go/storage v1.18.1 h1:hfXX1gE2mvuwoS/weBfgH1Vr+efX0uLdxX2ETJ9g1JQ= -cloud.google.com/go/storage v1.18.1/go.mod h1:FPalGc7eWSCKf26f2JwjrZhVibDE6pCDP19d1Pe2lB8= +cloud.google.com/go/storage v1.18.2 h1:5NQw6tOn3eMm0oE8vTkfjau18kjL79FlMjy/CHTpmoY= +cloud.google.com/go/storage v1.18.2/go.mod h1:AiIj7BWXyhO5gGVmYJ+S8tbkCx3yb0IMjua8Aw4naVM= cloud.google.com/go/trace v0.1.0/go.mod h1:wxEwsoeRVPbeSkt7ZC9nWCgmoKQRAoySN7XHW2AmI7g= contrib.go.opencensus.io/exporter/aws v0.0.0-20200617204711-c478e41e60e9/go.mod h1:uu1P0UCM/6RbsMrgPa98ll8ZcHM858i/AD06a9aLRCA= contrib.go.opencensus.io/exporter/stackdriver v0.13.8/go.mod h1:huNtlWx75MwO7qMs0KrMxPZXzNNWebav1Sq/pm02JdQ= @@ -137,8 +137,8 @@ github.com/aws/aws-sdk-go v1.15.27/go.mod h1:mFuSZ37Z9YOHbQEwBWztmVzqXrEkub65tZo github.com/aws/aws-sdk-go v1.37.0/go.mod h1:hcU610XS61/+aQV88ixoOzUoG7v3b31pl2zKMmprdro= github.com/aws/aws-sdk-go v1.38.68/go.mod h1:hcU610XS61/+aQV88ixoOzUoG7v3b31pl2zKMmprdro= github.com/aws/aws-sdk-go v1.40.34/go.mod h1:585smgzpB/KqRA+K3y/NL/oYRqQvpNJYvLm+LY1U59Q= -github.com/aws/aws-sdk-go v1.41.4 h1:5xRzZp8LfBFfowMPxmoNsxLBZOY/NTH4EeI7q2F5eWE= -github.com/aws/aws-sdk-go v1.41.4/go.mod h1:585smgzpB/KqRA+K3y/NL/oYRqQvpNJYvLm+LY1U59Q= +github.com/aws/aws-sdk-go v1.41.6 h1:ojO1jWhE3lkJlTFQOq0rlWZ11q18LIdsZNtGJ07FFEA= +github.com/aws/aws-sdk-go v1.41.6/go.mod h1:585smgzpB/KqRA+K3y/NL/oYRqQvpNJYvLm+LY1U59Q= github.com/aws/aws-sdk-go-v2 v1.7.0/go.mod h1:tb9wi5s61kTDA5qCkcDbt3KRVV74GGslQkl/DRdX/P4= github.com/aws/aws-sdk-go-v2 v1.9.0/go.mod h1:cK/D0BBs0b/oWPIcX/Z/obahJK1TT7IPVjy53i/mX/4= github.com/aws/aws-sdk-go-v2/config v1.7.0/go.mod h1:w9+nMZ7soXCe5nT46Ri354SNhXDQ6v+V5wqDjnZE+GY= @@ -592,8 +592,8 @@ github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Ky github.com/mattn/go-isatty v0.0.14 h1:yVuAays6BHfxijgZPzw+3Zlu5yQgKGP2/hcQbHb7S9Y= github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94= github.com/mattn/go-sqlite3 v1.14.6/go.mod h1:NyWgC/yNuGj7Q9rpYnZvas74GogHl5/Z4A/KQRfk6bU= -github.com/mattn/go-sqlite3 v1.14.8 h1:gDp86IdQsN/xWjIEmr9MF6o9mpksUgh0fu+9ByFxzIU= -github.com/mattn/go-sqlite3 v1.14.8/go.mod h1:NyWgC/yNuGj7Q9rpYnZvas74GogHl5/Z4A/KQRfk6bU= +github.com/mattn/go-sqlite3 v1.14.9 h1:10HX2Td0ocZpYEjhilsuo6WWtUqttj2Kb0KtD86/KYA= +github.com/mattn/go-sqlite3 v1.14.9/go.mod h1:NyWgC/yNuGj7Q9rpYnZvas74GogHl5/Z4A/KQRfk6bU= github.com/matttproud/golang_protobuf_extensions v1.0.1 h1:4hp9jkHxhMHkqkrB3Ix0jegS5sx/RkqARlsWZ6pIwiU= github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0= github.com/mhale/smtpd v0.8.0 h1:5JvdsehCg33PQrZBvFyDMMUDQmvbzVpZgKob7eYBJc0= @@ -688,8 +688,8 @@ github.com/prometheus/client_model v0.2.0/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6T github.com/prometheus/common v0.4.1/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4= github.com/prometheus/common v0.10.0/go.mod h1:Tlit/dnDKsSWFlCLTWaA1cyBgKHSMdTB80sz/V91rCo= github.com/prometheus/common v0.26.0/go.mod h1:M7rCNAaPfAosfx8veZJCuw84e35h3Cfd9VFqTh1DIvc= -github.com/prometheus/common v0.31.1 h1:d18hG4PkHnNAKNMOmFuXFaiY8Us0nird/2m60uS1AMs= -github.com/prometheus/common v0.31.1/go.mod h1:vu+V0TpY+O6vW9J44gczi3Ap/oXXR10b+M/gUGO4Hls= +github.com/prometheus/common v0.32.0 h1:HRmM4uANZDAjdvbsdfOoqI5UDbjz0faKeMs/cGPKKI0= +github.com/prometheus/common v0.32.0/go.mod h1:vu+V0TpY+O6vW9J44gczi3Ap/oXXR10b+M/gUGO4Hls= github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= github.com/prometheus/procfs v0.0.2/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA= github.com/prometheus/procfs v0.1.3/go.mod h1:lV6e/gmhEcM9IjHGsFOCxxuZ+z1YqCvr4OA4YeYWdaU= @@ -964,8 +964,9 @@ golang.org/x/sys v0.0.0-20210831042530-f4d43177bf5e/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.0.0-20210908233432-aa78b53d3365/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210917161153-d61c044b1678/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210927094055-39ccf1dd6fa6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20211015200801-69063c4bb744 h1:KzbpndAYEM+4oHRp9JmB2ewj0NHHxO3Z0g7Gus2O1kk= -golang.org/x/sys v0.0.0-20211015200801-69063c4bb744/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20211007075335-d3039528d8ac/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20211020154033-fcb26fe61c20 h1:NPtIbR2t8Mhg6UCbkTQMNMejkPpH6IvV4PdZnh1Mqpk= +golang.org/x/sys v0.0.0-20211020154033-fcb26fe61c20/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1 h1:v+OssWQX+hTHEmOBgwxdZxK4zHq3yOs8F9J7mk0PY8E= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= @@ -1090,8 +1091,9 @@ google.golang.org/api v0.54.0/go.mod h1:7C4bFFOvVDGXjfDTAsgGwDgAxRDeQ4X8NvUedIt6 google.golang.org/api v0.55.0/go.mod h1:38yMfeP1kfjsl8isn0tliTjIb1rJXcQi4UXlbqivdVE= google.golang.org/api v0.56.0/go.mod h1:38yMfeP1kfjsl8isn0tliTjIb1rJXcQi4UXlbqivdVE= google.golang.org/api v0.57.0/go.mod h1:dVPlbZyBo2/OjBpmvNdpn2GRm6rPy75jyU7bmhdrMgI= -google.golang.org/api v0.58.0 h1:MDkAbYIB1JpSgCTOCYYoIec/coMlKK4oVbpnBLLcyT0= google.golang.org/api v0.58.0/go.mod h1:cAbP2FsxoGVNwtgNAmmn3y5G1TWAiVYRmg4yku3lv+E= +google.golang.org/api v0.59.0 h1:fPfFO7gttlXYo2ALuD3HxJzh8vaF++4youI0BkFL6GE= +google.golang.org/api v0.59.0/go.mod h1:sT2boj7M9YJxZzgeZqXogmhfmRWDtPzT31xkieUbuZU= google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= google.golang.org/appengine v1.5.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= @@ -1165,8 +1167,10 @@ google.golang.org/genproto v0.0.0-20210903162649-d08c68adba83/go.mod h1:eFjDcFEc google.golang.org/genproto v0.0.0-20210909211513-a8c4777a87af/go.mod h1:eFjDcFEctNawg4eG61bRv87N7iHBWyVhJu7u1kqDUXY= google.golang.org/genproto v0.0.0-20210917145530-b395a37504d4/go.mod h1:eFjDcFEctNawg4eG61bRv87N7iHBWyVhJu7u1kqDUXY= google.golang.org/genproto v0.0.0-20210924002016-3dee208752a0/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= -google.golang.org/genproto v0.0.0-20211013025323-ce878158c4d4 h1:NBxB1XxiWpGqkPUiJ9PoBXkHV5A9+GohMOA+EmWoPbU= -google.golang.org/genproto v0.0.0-20211013025323-ce878158c4d4/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= +google.golang.org/genproto v0.0.0-20211008145708-270636b82663/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= +google.golang.org/genproto v0.0.0-20211016002631-37fc39342514/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= +google.golang.org/genproto v0.0.0-20211020151524-b7c3a969101a h1:8maMHMQp9NroHXhc3HelFX9Ay2lWlXLcdH5mw5Biz0s= +google.golang.org/genproto v0.0.0-20211020151524-b7c3a969101a/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= google.golang.org/grpc v1.8.0/go.mod h1:yo6s7OP7yaDglbqo1J04qKzAhqBH6lvTonzMVmEdcZw= google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38= diff --git a/httpd/schema/openapi.yaml b/httpd/schema/openapi.yaml index 61d02fc3..da2793d6 100644 --- a/httpd/schema/openapi.yaml +++ b/httpd/schema/openapi.yaml @@ -10,12 +10,13 @@ tags: - name: quota - name: folders - name: users - - name: users API - name: data retention + - name: events + - name: users API info: title: SFTPGo description: | - SFTPGo allows to securely share your files over SFTP and optionally FTP/S and WebDAV too. + SFTPGo allows to securely share your files over SFTP and optionally FTP/S and WebDAV as well. Several storage backends are supported and they are configurable per user, so you can serve a local directory for a user and an S3 bucket (or part of it) for another one. SFTPGo also supports virtual folders, a virtual folder can use any of the supported storage backends. So you can have, for example, an S3 user that exposes a GCS bucket (or part of it) on a specified path and an encrypted local filesystem on another one. Virtual folders can be private or shared among multiple users, for shared virtual folders you can define different quota limits for each user. @@ -1485,6 +1486,251 @@ paths: $ref: '#/components/responses/InternalServerError' default: $ref: '#/components/responses/DefaultResponse' + /events/fs: + get: + tags: + - events + summary: Get filesystem events + description: 'Returns an array with one or more filesystem events applying the specified filters. This API is only available if you configure an "eventsearcher" plugin' + operationId: get_fs_events + parameters: + - in: query + name: start_timestamp + schema: + type: integer + format: int64 + minimum: 0 + default: 0 + required: false + description: 'the event timestamp, unix timestamp in nanoseconds, must be greater than or equal to the specified one. 0 or missing means omit this filter' + - in: query + name: end_timestamp + schema: + type: integer + format: int64 + minimum: 0 + default: 0 + required: false + description: 'the event timestamp, unix timestamp in nanoseconds, must be less than or equal to the specified one. 0 or missing means omit this filter' + - in: query + name: actions + schema: + type: array + items: + $ref: '#/components/schemas/FsEventAction' + description: 'the event action must be included among those specified. Empty or missing means omit this filter. Actions must be specified comma separated' + explode: false + required: false + - in: query + name: username + schema: + type: string + description: 'the event username must be the same as the one specified. Empty or missing means omit this filter' + required: false + - in: query + name: ip + schema: + type: string + description: 'the event IP must be the same as the one specified. Empty or missing means omit this filter' + required: false + - in: query + name: ssh_cmd + schema: + type: string + description: 'the event SSH command must be the same as the one specified. Empty or missing means omit this filter' + required: false + - in: query + name: protocols + schema: + type: array + items: + $ref: '#/components/schemas/EventProtocols' + description: 'the event protocol must be included among those specified. Empty or missing means omit this filter. Values must be specified comma separated' + explode: false + required: false + - in: query + name: statuses + schema: + type: array + items: + $ref: '#/components/schemas/FsEventStatus' + description: 'the event status must be included among those specified. Empty or missing means omit this filter. Values must be specified comma separated' + explode: false + required: false + - in: query + name: instance_ids + schema: + type: array + items: + type: string + description: 'the event instance id must be included among those specified. Empty or missing means omit this filter. Values must be specified comma separated' + explode: false + required: false + - in: query + name: exclude_ids + schema: + type: array + items: + type: string + description: 'the event id must not be included among those specified. This is useful for cursor based pagination. Empty or missing means omit this filter. Values must be specified comma separated' + explode: false + required: false + - in: query + name: limit + schema: + type: integer + minimum: 1 + maximum: 1000 + default: 100 + required: false + description: 'The maximum number of items to return. Max value is 500, default is 100' + - in: query + name: order + required: false + description: Ordering events by timestamp. Default DESC + schema: + type: string + enum: + - ASC + - DESC + example: DESC + responses: + '200': + description: successful operation + content: + application/json: + schema: + type: array + items: + $ref: '#/components/schemas/FsEvent' + '400': + $ref: '#/components/responses/BadRequest' + '401': + $ref: '#/components/responses/Unauthorized' + '403': + $ref: '#/components/responses/Forbidden' + '500': + $ref: '#/components/responses/InternalServerError' + default: + $ref: '#/components/responses/DefaultResponse' + /events/provider: + get: + tags: + - events + summary: Get provider events + description: 'Returns an array with one or more provider events applying the specified filters. This API is only available if you configure an "eventsearcher" plugin' + operationId: get_provider_events + parameters: + - in: query + name: start_timestamp + schema: + type: integer + format: int64 + minimum: 0 + default: 0 + required: false + description: 'the event timestamp, unix timestamp in nanoseconds, must be greater than or equal to the specified one. 0 or missing means omit this filter' + - in: query + name: end_timestamp + schema: + type: integer + format: int64 + minimum: 0 + default: 0 + required: false + description: 'the event timestamp, unix timestamp in nanoseconds, must be less than or equal to the specified one. 0 or missing means omit this filter' + - in: query + name: actions + schema: + type: array + items: + $ref: '#/components/schemas/ProviderEventAction' + description: 'the event action must be included among those specified. Empty or missing means omit this filter. Actions must be specified comma separated' + explode: false + required: false + - in: query + name: username + schema: + type: string + description: 'the event username must be the same as the one specified. Empty or missing means omit this filter' + required: false + - in: query + name: ip + schema: + type: string + description: 'the event IP must be the same as the one specified. Empty or missing means omit this filter' + required: false + - in: query + name: object_name + schema: + type: string + description: 'the event object name must be the same as the one specified. Empty or missing means omit this filter' + required: false + - in: query + name: object_types + schema: + type: array + items: + $ref: '#/components/schemas/ProviderEventObjectType' + description: 'the event object type must be included among those specified. Empty or missing means omit this filter. Values must be specified comma separated' + explode: false + required: false + - in: query + name: instance_ids + schema: + type: array + items: + type: string + description: 'the event instance id must be included among those specified. Empty or missing means omit this filter. Values must be specified comma separated' + explode: false + required: false + - in: query + name: exclude_ids + schema: + type: array + items: + type: string + description: 'the event id must not be included among those specified. This is useful for cursor based pagination. Empty or missing means omit this filter. Values must be specified comma separated' + explode: false + required: false + - in: query + name: limit + schema: + type: integer + minimum: 1 + maximum: 1000 + default: 100 + required: false + description: 'The maximum number of items to return. Max value is 500, default is 100' + - in: query + name: order + required: false + description: Ordering events by timestamp. Default DESC + schema: + type: string + enum: + - ASC + - DESC + example: DESC + responses: + '200': + description: successful operation + content: + application/json: + schema: + type: array + items: + $ref: '#/components/schemas/ProviderEvent' + '400': + $ref: '#/components/responses/BadRequest' + '401': + $ref: '#/components/responses/Unauthorized' + '403': + $ref: '#/components/responses/Forbidden' + '500': + $ref: '#/components/responses/InternalServerError' + default: + $ref: '#/components/responses/DefaultResponse' /apikeys: get: security: @@ -3214,6 +3460,24 @@ components: * `SSH` - includes both SFTP and SSH commands * `FTP` - plain FTP and FTPES/FTPS * `HTTP` - WebClient/REST API + EventProtocols: + type: string + enum: + - SSH + - SFTP + - SCP + - FTP + - DAV + - HTTP + - DataRetention + description: | + Protocols: + * `SSH` - SSH commands + * `SFTP` - SFTP protocol + * `FTP` - plain FTP and FTPES/FTPS + * `DAV` - WebDAV + * `HTTP` - WebClient/REST API + * `DataRetention` - the event is generated by a data retention check WebClientOptions: type: string enum: @@ -3263,6 +3527,39 @@ components: - LDAPUser - OSUser description: This is an hint for authentication plugins. It is ignored when using SFTPGo internal authentication + FsEventStatus: + type: integer + enum: + - 1 + - 2 + - 3 + description: > + Event status: + * `1` - no error + * `2` - generic error + * `3` - quota exceeded error + FsEventAction: + type: string + enum: + - download + - upload + - delete + - rename + - mkdir + - rmdir + - ssh_cmd + ProviderEventAction: + type: string + enum: + - add + - update + - delete + ProviderEventObjectType: + type: string + enum: + - user + - admin + - api_key TOTPConfig: type: object properties: @@ -4254,6 +4551,61 @@ components: last_modified: type: string format: date-time + FsEvent: + type: object + properties: + id: + type: string + timestamp: + type: integer + format: int64 + description: 'unix timestamp in nanoseconds' + action: + $ref: '#/components/schemas/FsEventAction' + username: + type: string + fs_path: + type: string + fs_target_path: + type: string + virtual_path: + type: string + virtual_target_path: + type: string + ssh_cmd: + type: string + file_size: + type: integer + format: int64 + status: + $ref: '#/components/schemas/FsEventStatus' + protocol: + $ref: '#/components/schemas/EventProtocols' + ip: + type: string + instance_id: + type: string + ProviderEvent: + type: object + properties: + id: + type: string + timestamp: + type: integer + format: int64 + description: 'unix timestamp in nanoseconds' + action: + $ref: '#/components/schemas/ProviderEventAction' + username: + type: string + ip: + type: string + object_type: + $ref: '#/components/schemas/ProviderEventObjectType' + object_name: + type: string + instance_id: + type: string ApiResponse: type: object properties: diff --git a/sdk/plugin/eventsearcher/eventsearcher.go b/sdk/plugin/eventsearcher/eventsearcher.go index ffee56bb..eed4d8c7 100644 --- a/sdk/plugin/eventsearcher/eventsearcher.go +++ b/sdk/plugin/eventsearcher/eventsearcher.go @@ -4,7 +4,6 @@ package eventsearcher import ( "context" - "time" "github.com/hashicorp/go-plugin" "google.golang.org/grpc" @@ -31,10 +30,10 @@ var PluginMap = map[string]plugin.Plugin{ // Searcher defines the interface for events search plugins type Searcher interface { - SearchFsEvents(startTimestamp, endTimestamp time.Time, action, username, ip, sshCmd, protocol, - instanceID, continuationToken string, status, limit int) (string, []byte, error) - SearchProviderEvents(startTimestamp, endTimestamp time.Time, action, username, ip, objectType, - objectName, instanceID, continuationToken string, limit int) (string, []byte, error) + SearchFsEvents(startTimestamp, endTimestamp int64, username, ip, sshCmd string, actions, protocols, + instanceIDs, excludeIDs []string, statuses []int32, limit, order int) ([]byte, []string, []string, error) + SearchProviderEvents(startTimestamp, endTimestamp int64, username, ip, objectName string, + limit, order int, actions, objectTypes, instanceIDs, excludeIDs []string) ([]byte, []string, []string, error) } // Plugin defines the implementation to serve/connect to a notifier plugin diff --git a/sdk/plugin/eventsearcher/grpc.go b/sdk/plugin/eventsearcher/grpc.go index aba211a4..ab7d3c3e 100644 --- a/sdk/plugin/eventsearcher/grpc.go +++ b/sdk/plugin/eventsearcher/grpc.go @@ -4,13 +4,11 @@ import ( "context" "time" - "google.golang.org/protobuf/types/known/timestamppb" - "github.com/drakkan/sftpgo/v2/sdk/plugin/eventsearcher/proto" ) const ( - rpcTimeout = 30 * time.Second + rpcTimeout = 20 * time.Second ) // GRPCClient is an implementation of Notifier interface that talks over RPC. @@ -19,54 +17,58 @@ type GRPCClient struct { } // SearchFsEvents implements the Searcher interface -func (c *GRPCClient) SearchFsEvents(startTimestamp, endTimestamp time.Time, action, username, ip, sshCmd, protocol, - instanceID, continuationToken string, status, limit int) (string, []byte, error) { +func (c *GRPCClient) SearchFsEvents(startTimestamp, endTimestamp int64, username, ip, sshCmd string, actions, + protocols, instanceIDs, excludeIDs []string, statuses []int32, limit, order int, +) ([]byte, error) { ctx, cancel := context.WithTimeout(context.Background(), rpcTimeout) defer cancel() resp, err := c.client.SearchFsEvents(ctx, &proto.FsEventsFilter{ - StartTimestamp: timestamppb.New(startTimestamp), - EndTimestamp: timestamppb.New(endTimestamp), - Action: action, - Username: username, - Ip: ip, - SshCmd: sshCmd, - Protocol: protocol, - InstanceId: instanceID, - ContinuationToken: continuationToken, - Status: int32(status), - Limit: int32(limit), + StartTimestamp: startTimestamp, + EndTimestamp: endTimestamp, + Actions: actions, + Username: username, + Ip: ip, + SshCmd: sshCmd, + Protocols: protocols, + InstanceIds: instanceIDs, + Statuses: statuses, + Limit: int32(limit), + Order: proto.FsEventsFilter_Order(order), + ExcludeIds: excludeIDs, }) if err != nil { - return "", nil, err + return nil, err } - return resp.ContinuationToken, resp.ResponseData, nil + return resp.Data, nil } // SearchProviderEvents implements the Searcher interface -func (c *GRPCClient) SearchProviderEvents(startTimestamp, endTimestamp time.Time, action, username, ip, objectType, - objectName, instanceID, continuationToken string, limit int) (string, []byte, error) { +func (c *GRPCClient) SearchProviderEvents(startTimestamp, endTimestamp int64, username, ip, objectName string, + limit, order int, actions, objectTypes, instanceIDs, excludeIDs []string, +) ([]byte, error) { ctx, cancel := context.WithTimeout(context.Background(), rpcTimeout) defer cancel() resp, err := c.client.SearchProviderEvents(ctx, &proto.ProviderEventsFilter{ - StartTimestamp: timestamppb.New(startTimestamp), - EndTimestamp: timestamppb.New(endTimestamp), - Action: action, - Username: username, - Ip: ip, - ObjectType: objectType, - ObjectName: objectName, - InstanceId: instanceID, - ContinuationToken: continuationToken, - Limit: int32(limit), + StartTimestamp: startTimestamp, + EndTimestamp: endTimestamp, + Actions: actions, + Username: username, + Ip: ip, + ObjectTypes: objectTypes, + ObjectName: objectName, + InstanceIds: instanceIDs, + Limit: int32(limit), + Order: proto.ProviderEventsFilter_Order(order), + ExcludeIds: excludeIDs, }) if err != nil { - return "", nil, err + return nil, err } - return resp.ContinuationToken, resp.ResponseData, nil + return resp.Data, nil } // GRPCServer defines the gRPC server that GRPCClient talks to. @@ -76,24 +78,26 @@ type GRPCServer struct { // SearchFsEvents implement the server side fs events search method func (s *GRPCServer) SearchFsEvents(ctx context.Context, req *proto.FsEventsFilter) (*proto.SearchResponse, error) { - continuationToken, responseData, err := s.Impl.SearchFsEvents(req.StartTimestamp.AsTime(), - req.EndTimestamp.AsTime(), req.Action, req.Username, req.Ip, req.SshCmd, req.Protocol, req.InstanceId, - req.ContinuationToken, int(req.Status), int(req.Limit)) + responseData, sameTsAtStart, sameTsAtEnd, err := s.Impl.SearchFsEvents(req.StartTimestamp, + req.EndTimestamp, req.Username, req.Ip, req.SshCmd, req.Actions, req.Protocols, req.InstanceIds, + req.ExcludeIds, req.Statuses, int(req.Limit), int(req.Order)) return &proto.SearchResponse{ - ContinuationToken: continuationToken, - ResponseData: responseData, + Data: responseData, + SameTsAtStart: sameTsAtStart, + SameTsAtEnd: sameTsAtEnd, }, err } // SearchProviderEvents implement the server side provider events search method func (s *GRPCServer) SearchProviderEvents(ctx context.Context, req *proto.ProviderEventsFilter) (*proto.SearchResponse, error) { - continuationToken, responseData, err := s.Impl.SearchProviderEvents(req.StartTimestamp.AsTime(), - req.EndTimestamp.AsTime(), req.Action, req.Username, req.Ip, req.ObjectType, req.ObjectName, - req.InstanceId, req.ContinuationToken, int(req.Limit)) + responseData, sameTsAtStart, sameTsAtEnd, err := s.Impl.SearchProviderEvents(req.StartTimestamp, + req.EndTimestamp, req.Username, req.Ip, req.ObjectName, int(req.Limit), + int(req.Order), req.Actions, req.ObjectTypes, req.InstanceIds, req.ExcludeIds) return &proto.SearchResponse{ - ContinuationToken: continuationToken, - ResponseData: responseData, + Data: responseData, + SameTsAtStart: sameTsAtStart, + SameTsAtEnd: sameTsAtEnd, }, err } diff --git a/sdk/plugin/eventsearcher/proto/search.pb.go b/sdk/plugin/eventsearcher/proto/search.pb.go index d2a4ec18..bdcfde11 100644 --- a/sdk/plugin/eventsearcher/proto/search.pb.go +++ b/sdk/plugin/eventsearcher/proto/search.pb.go @@ -13,7 +13,6 @@ import ( status "google.golang.org/grpc/status" protoreflect "google.golang.org/protobuf/reflect/protoreflect" protoimpl "google.golang.org/protobuf/runtime/protoimpl" - timestamppb "google.golang.org/protobuf/types/known/timestamppb" reflect "reflect" sync "sync" ) @@ -25,22 +24,115 @@ const ( _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) ) +type FsEventsFilter_Order int32 + +const ( + FsEventsFilter_DESC FsEventsFilter_Order = 0 + FsEventsFilter_ASC FsEventsFilter_Order = 1 +) + +// Enum value maps for FsEventsFilter_Order. +var ( + FsEventsFilter_Order_name = map[int32]string{ + 0: "DESC", + 1: "ASC", + } + FsEventsFilter_Order_value = map[string]int32{ + "DESC": 0, + "ASC": 1, + } +) + +func (x FsEventsFilter_Order) Enum() *FsEventsFilter_Order { + p := new(FsEventsFilter_Order) + *p = x + return p +} + +func (x FsEventsFilter_Order) String() string { + return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x)) +} + +func (FsEventsFilter_Order) Descriptor() protoreflect.EnumDescriptor { + return file_eventsearcher_proto_search_proto_enumTypes[0].Descriptor() +} + +func (FsEventsFilter_Order) Type() protoreflect.EnumType { + return &file_eventsearcher_proto_search_proto_enumTypes[0] +} + +func (x FsEventsFilter_Order) Number() protoreflect.EnumNumber { + return protoreflect.EnumNumber(x) +} + +// Deprecated: Use FsEventsFilter_Order.Descriptor instead. +func (FsEventsFilter_Order) EnumDescriptor() ([]byte, []int) { + return file_eventsearcher_proto_search_proto_rawDescGZIP(), []int{0, 0} +} + +type ProviderEventsFilter_Order int32 + +const ( + ProviderEventsFilter_DESC ProviderEventsFilter_Order = 0 + ProviderEventsFilter_ASC ProviderEventsFilter_Order = 1 +) + +// Enum value maps for ProviderEventsFilter_Order. +var ( + ProviderEventsFilter_Order_name = map[int32]string{ + 0: "DESC", + 1: "ASC", + } + ProviderEventsFilter_Order_value = map[string]int32{ + "DESC": 0, + "ASC": 1, + } +) + +func (x ProviderEventsFilter_Order) Enum() *ProviderEventsFilter_Order { + p := new(ProviderEventsFilter_Order) + *p = x + return p +} + +func (x ProviderEventsFilter_Order) String() string { + return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x)) +} + +func (ProviderEventsFilter_Order) Descriptor() protoreflect.EnumDescriptor { + return file_eventsearcher_proto_search_proto_enumTypes[1].Descriptor() +} + +func (ProviderEventsFilter_Order) Type() protoreflect.EnumType { + return &file_eventsearcher_proto_search_proto_enumTypes[1] +} + +func (x ProviderEventsFilter_Order) Number() protoreflect.EnumNumber { + return protoreflect.EnumNumber(x) +} + +// Deprecated: Use ProviderEventsFilter_Order.Descriptor instead. +func (ProviderEventsFilter_Order) EnumDescriptor() ([]byte, []int) { + return file_eventsearcher_proto_search_proto_rawDescGZIP(), []int{1, 0} +} + type FsEventsFilter struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - StartTimestamp *timestamppb.Timestamp `protobuf:"bytes,1,opt,name=start_timestamp,json=startTimestamp,proto3" json:"start_timestamp,omitempty"` - EndTimestamp *timestamppb.Timestamp `protobuf:"bytes,2,opt,name=end_timestamp,json=endTimestamp,proto3" json:"end_timestamp,omitempty"` - Action string `protobuf:"bytes,3,opt,name=action,proto3" json:"action,omitempty"` - Username string `protobuf:"bytes,4,opt,name=username,proto3" json:"username,omitempty"` - Ip string `protobuf:"bytes,5,opt,name=ip,proto3" json:"ip,omitempty"` - SshCmd string `protobuf:"bytes,6,opt,name=ssh_cmd,json=sshCmd,proto3" json:"ssh_cmd,omitempty"` - Protocol string `protobuf:"bytes,7,opt,name=protocol,proto3" json:"protocol,omitempty"` - Status int32 `protobuf:"varint,8,opt,name=status,proto3" json:"status,omitempty"` - InstanceId string `protobuf:"bytes,9,opt,name=instance_id,json=instanceId,proto3" json:"instance_id,omitempty"` - Limit int32 `protobuf:"varint,10,opt,name=limit,proto3" json:"limit,omitempty"` - ContinuationToken string `protobuf:"bytes,11,opt,name=continuation_token,json=continuationToken,proto3" json:"continuation_token,omitempty"` + StartTimestamp int64 `protobuf:"varint,1,opt,name=start_timestamp,json=startTimestamp,proto3" json:"start_timestamp,omitempty"` + EndTimestamp int64 `protobuf:"varint,2,opt,name=end_timestamp,json=endTimestamp,proto3" json:"end_timestamp,omitempty"` + Actions []string `protobuf:"bytes,3,rep,name=actions,proto3" json:"actions,omitempty"` + Username string `protobuf:"bytes,4,opt,name=username,proto3" json:"username,omitempty"` + Ip string `protobuf:"bytes,5,opt,name=ip,proto3" json:"ip,omitempty"` + SshCmd string `protobuf:"bytes,6,opt,name=ssh_cmd,json=sshCmd,proto3" json:"ssh_cmd,omitempty"` + Protocols []string `protobuf:"bytes,7,rep,name=protocols,proto3" json:"protocols,omitempty"` + Statuses []int32 `protobuf:"varint,8,rep,packed,name=statuses,proto3" json:"statuses,omitempty"` + InstanceIds []string `protobuf:"bytes,9,rep,name=instance_ids,json=instanceIds,proto3" json:"instance_ids,omitempty"` + Limit int32 `protobuf:"varint,10,opt,name=limit,proto3" json:"limit,omitempty"` + ExcludeIds []string `protobuf:"bytes,11,rep,name=exclude_ids,json=excludeIds,proto3" json:"exclude_ids,omitempty"` + Order FsEventsFilter_Order `protobuf:"varint,12,opt,name=order,proto3,enum=proto.FsEventsFilter_Order" json:"order,omitempty"` } func (x *FsEventsFilter) Reset() { @@ -75,25 +167,25 @@ func (*FsEventsFilter) Descriptor() ([]byte, []int) { return file_eventsearcher_proto_search_proto_rawDescGZIP(), []int{0} } -func (x *FsEventsFilter) GetStartTimestamp() *timestamppb.Timestamp { +func (x *FsEventsFilter) GetStartTimestamp() int64 { if x != nil { return x.StartTimestamp } - return nil + return 0 } -func (x *FsEventsFilter) GetEndTimestamp() *timestamppb.Timestamp { +func (x *FsEventsFilter) GetEndTimestamp() int64 { if x != nil { return x.EndTimestamp } - return nil + return 0 } -func (x *FsEventsFilter) GetAction() string { +func (x *FsEventsFilter) GetActions() []string { if x != nil { - return x.Action + return x.Actions } - return "" + return nil } func (x *FsEventsFilter) GetUsername() string { @@ -117,25 +209,25 @@ func (x *FsEventsFilter) GetSshCmd() string { return "" } -func (x *FsEventsFilter) GetProtocol() string { +func (x *FsEventsFilter) GetProtocols() []string { if x != nil { - return x.Protocol + return x.Protocols } - return "" + return nil } -func (x *FsEventsFilter) GetStatus() int32 { +func (x *FsEventsFilter) GetStatuses() []int32 { if x != nil { - return x.Status + return x.Statuses } - return 0 + return nil } -func (x *FsEventsFilter) GetInstanceId() string { +func (x *FsEventsFilter) GetInstanceIds() []string { if x != nil { - return x.InstanceId + return x.InstanceIds } - return "" + return nil } func (x *FsEventsFilter) GetLimit() int32 { @@ -145,11 +237,18 @@ func (x *FsEventsFilter) GetLimit() int32 { return 0 } -func (x *FsEventsFilter) GetContinuationToken() string { +func (x *FsEventsFilter) GetExcludeIds() []string { if x != nil { - return x.ContinuationToken + return x.ExcludeIds } - return "" + return nil +} + +func (x *FsEventsFilter) GetOrder() FsEventsFilter_Order { + if x != nil { + return x.Order + } + return FsEventsFilter_DESC } type ProviderEventsFilter struct { @@ -157,16 +256,17 @@ type ProviderEventsFilter struct { sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - StartTimestamp *timestamppb.Timestamp `protobuf:"bytes,1,opt,name=start_timestamp,json=startTimestamp,proto3" json:"start_timestamp,omitempty"` - EndTimestamp *timestamppb.Timestamp `protobuf:"bytes,2,opt,name=end_timestamp,json=endTimestamp,proto3" json:"end_timestamp,omitempty"` - Action string `protobuf:"bytes,3,opt,name=action,proto3" json:"action,omitempty"` - Username string `protobuf:"bytes,4,opt,name=username,proto3" json:"username,omitempty"` - Ip string `protobuf:"bytes,5,opt,name=ip,proto3" json:"ip,omitempty"` - ObjectType string `protobuf:"bytes,6,opt,name=object_type,json=objectType,proto3" json:"object_type,omitempty"` - ObjectName string `protobuf:"bytes,7,opt,name=object_name,json=objectName,proto3" json:"object_name,omitempty"` - InstanceId string `protobuf:"bytes,8,opt,name=instance_id,json=instanceId,proto3" json:"instance_id,omitempty"` - Limit int32 `protobuf:"varint,9,opt,name=limit,proto3" json:"limit,omitempty"` - ContinuationToken string `protobuf:"bytes,10,opt,name=continuation_token,json=continuationToken,proto3" json:"continuation_token,omitempty"` + StartTimestamp int64 `protobuf:"varint,1,opt,name=start_timestamp,json=startTimestamp,proto3" json:"start_timestamp,omitempty"` + EndTimestamp int64 `protobuf:"varint,2,opt,name=end_timestamp,json=endTimestamp,proto3" json:"end_timestamp,omitempty"` + Actions []string `protobuf:"bytes,3,rep,name=actions,proto3" json:"actions,omitempty"` + Username string `protobuf:"bytes,4,opt,name=username,proto3" json:"username,omitempty"` + Ip string `protobuf:"bytes,5,opt,name=ip,proto3" json:"ip,omitempty"` + ObjectTypes []string `protobuf:"bytes,6,rep,name=object_types,json=objectTypes,proto3" json:"object_types,omitempty"` + ObjectName string `protobuf:"bytes,7,opt,name=object_name,json=objectName,proto3" json:"object_name,omitempty"` + InstanceIds []string `protobuf:"bytes,8,rep,name=instance_ids,json=instanceIds,proto3" json:"instance_ids,omitempty"` + Limit int32 `protobuf:"varint,9,opt,name=limit,proto3" json:"limit,omitempty"` + Order ProviderEventsFilter_Order `protobuf:"varint,10,opt,name=order,proto3,enum=proto.ProviderEventsFilter_Order" json:"order,omitempty"` + ExcludeIds []string `protobuf:"bytes,11,rep,name=exclude_ids,json=excludeIds,proto3" json:"exclude_ids,omitempty"` } func (x *ProviderEventsFilter) Reset() { @@ -201,25 +301,25 @@ func (*ProviderEventsFilter) Descriptor() ([]byte, []int) { return file_eventsearcher_proto_search_proto_rawDescGZIP(), []int{1} } -func (x *ProviderEventsFilter) GetStartTimestamp() *timestamppb.Timestamp { +func (x *ProviderEventsFilter) GetStartTimestamp() int64 { if x != nil { return x.StartTimestamp } - return nil + return 0 } -func (x *ProviderEventsFilter) GetEndTimestamp() *timestamppb.Timestamp { +func (x *ProviderEventsFilter) GetEndTimestamp() int64 { if x != nil { return x.EndTimestamp } - return nil + return 0 } -func (x *ProviderEventsFilter) GetAction() string { +func (x *ProviderEventsFilter) GetActions() []string { if x != nil { - return x.Action + return x.Actions } - return "" + return nil } func (x *ProviderEventsFilter) GetUsername() string { @@ -236,11 +336,11 @@ func (x *ProviderEventsFilter) GetIp() string { return "" } -func (x *ProviderEventsFilter) GetObjectType() string { +func (x *ProviderEventsFilter) GetObjectTypes() []string { if x != nil { - return x.ObjectType + return x.ObjectTypes } - return "" + return nil } func (x *ProviderEventsFilter) GetObjectName() string { @@ -250,11 +350,11 @@ func (x *ProviderEventsFilter) GetObjectName() string { return "" } -func (x *ProviderEventsFilter) GetInstanceId() string { +func (x *ProviderEventsFilter) GetInstanceIds() []string { if x != nil { - return x.InstanceId + return x.InstanceIds } - return "" + return nil } func (x *ProviderEventsFilter) GetLimit() int32 { @@ -264,11 +364,18 @@ func (x *ProviderEventsFilter) GetLimit() int32 { return 0 } -func (x *ProviderEventsFilter) GetContinuationToken() string { +func (x *ProviderEventsFilter) GetOrder() ProviderEventsFilter_Order { if x != nil { - return x.ContinuationToken + return x.Order } - return "" + return ProviderEventsFilter_DESC +} + +func (x *ProviderEventsFilter) GetExcludeIds() []string { + if x != nil { + return x.ExcludeIds + } + return nil } type SearchResponse struct { @@ -276,8 +383,9 @@ type SearchResponse struct { sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - ContinuationToken string `protobuf:"bytes,1,opt,name=continuation_token,json=continuationToken,proto3" json:"continuation_token,omitempty"` - ResponseData []byte `protobuf:"bytes,2,opt,name=response_data,json=responseData,proto3" json:"response_data,omitempty"` // JSON serialized response to return + Data []byte `protobuf:"bytes,1,opt,name=data,proto3" json:"data,omitempty"` // JSON serialized response to return + SameTsAtStart []string `protobuf:"bytes,2,rep,name=same_ts_at_start,json=sameTsAtStart,proto3" json:"same_ts_at_start,omitempty"` + SameTsAtEnd []string `protobuf:"bytes,3,rep,name=same_ts_at_end,json=sameTsAtEnd,proto3" json:"same_ts_at_end,omitempty"` } func (x *SearchResponse) Reset() { @@ -312,16 +420,23 @@ func (*SearchResponse) Descriptor() ([]byte, []int) { return file_eventsearcher_proto_search_proto_rawDescGZIP(), []int{2} } -func (x *SearchResponse) GetContinuationToken() string { +func (x *SearchResponse) GetData() []byte { if x != nil { - return x.ContinuationToken + return x.Data } - return "" + return nil } -func (x *SearchResponse) GetResponseData() []byte { +func (x *SearchResponse) GetSameTsAtStart() []string { if x != nil { - return x.ResponseData + return x.SameTsAtStart + } + return nil +} + +func (x *SearchResponse) GetSameTsAtEnd() []string { + if x != nil { + return x.SameTsAtEnd } return nil } @@ -331,77 +446,79 @@ var File_eventsearcher_proto_search_proto protoreflect.FileDescriptor var file_eventsearcher_proto_search_proto_rawDesc = []byte{ 0x0a, 0x20, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x73, 0x65, 0x61, 0x72, 0x63, 0x68, 0x65, 0x72, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x73, 0x65, 0x61, 0x72, 0x63, 0x68, 0x2e, 0x70, 0x72, 0x6f, - 0x74, 0x6f, 0x12, 0x05, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x1f, 0x67, 0x6f, 0x6f, 0x67, 0x6c, - 0x65, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2f, 0x74, 0x69, 0x6d, 0x65, 0x73, - 0x74, 0x61, 0x6d, 0x70, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0x8d, 0x03, 0x0a, 0x0e, 0x46, - 0x73, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x73, 0x46, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x12, 0x43, 0x0a, - 0x0f, 0x73, 0x74, 0x61, 0x72, 0x74, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, - 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, - 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, - 0x6d, 0x70, 0x52, 0x0e, 0x73, 0x74, 0x61, 0x72, 0x74, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, - 0x6d, 0x70, 0x12, 0x3f, 0x0a, 0x0d, 0x65, 0x6e, 0x64, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, - 0x61, 0x6d, 0x70, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, - 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, - 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x0c, 0x65, 0x6e, 0x64, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, - 0x61, 0x6d, 0x70, 0x12, 0x16, 0x0a, 0x06, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x03, 0x20, - 0x01, 0x28, 0x09, 0x52, 0x06, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x1a, 0x0a, 0x08, 0x75, - 0x73, 0x65, 0x72, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x75, - 0x73, 0x65, 0x72, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x70, 0x18, 0x05, 0x20, - 0x01, 0x28, 0x09, 0x52, 0x02, 0x69, 0x70, 0x12, 0x17, 0x0a, 0x07, 0x73, 0x73, 0x68, 0x5f, 0x63, - 0x6d, 0x64, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x73, 0x73, 0x68, 0x43, 0x6d, 0x64, - 0x12, 0x1a, 0x0a, 0x08, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x18, 0x07, 0x20, 0x01, - 0x28, 0x09, 0x52, 0x08, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x12, 0x16, 0x0a, 0x06, - 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x18, 0x08, 0x20, 0x01, 0x28, 0x05, 0x52, 0x06, 0x73, 0x74, - 0x61, 0x74, 0x75, 0x73, 0x12, 0x1f, 0x0a, 0x0b, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, - 0x5f, 0x69, 0x64, 0x18, 0x09, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x69, 0x6e, 0x73, 0x74, 0x61, - 0x6e, 0x63, 0x65, 0x49, 0x64, 0x12, 0x14, 0x0a, 0x05, 0x6c, 0x69, 0x6d, 0x69, 0x74, 0x18, 0x0a, - 0x20, 0x01, 0x28, 0x05, 0x52, 0x05, 0x6c, 0x69, 0x6d, 0x69, 0x74, 0x12, 0x2d, 0x0a, 0x12, 0x63, - 0x6f, 0x6e, 0x74, 0x69, 0x6e, 0x75, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x74, 0x6f, 0x6b, 0x65, - 0x6e, 0x18, 0x0b, 0x20, 0x01, 0x28, 0x09, 0x52, 0x11, 0x63, 0x6f, 0x6e, 0x74, 0x69, 0x6e, 0x75, - 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x22, 0x88, 0x03, 0x0a, 0x14, 0x50, - 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x73, 0x46, 0x69, 0x6c, - 0x74, 0x65, 0x72, 0x12, 0x43, 0x0a, 0x0f, 0x73, 0x74, 0x61, 0x72, 0x74, 0x5f, 0x74, 0x69, 0x6d, - 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, - 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, - 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x0e, 0x73, 0x74, 0x61, 0x72, 0x74, 0x54, - 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x12, 0x3f, 0x0a, 0x0d, 0x65, 0x6e, 0x64, 0x5f, - 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, - 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, - 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x0c, 0x65, 0x6e, 0x64, - 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x12, 0x16, 0x0a, 0x06, 0x61, 0x63, 0x74, - 0x69, 0x6f, 0x6e, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x61, 0x63, 0x74, 0x69, 0x6f, - 0x6e, 0x12, 0x1a, 0x0a, 0x08, 0x75, 0x73, 0x65, 0x72, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x04, 0x20, - 0x01, 0x28, 0x09, 0x52, 0x08, 0x75, 0x73, 0x65, 0x72, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x0e, 0x0a, - 0x02, 0x69, 0x70, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x69, 0x70, 0x12, 0x1f, 0x0a, - 0x0b, 0x6f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x18, 0x06, 0x20, 0x01, - 0x28, 0x09, 0x52, 0x0a, 0x6f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x54, 0x79, 0x70, 0x65, 0x12, 0x1f, - 0x0a, 0x0b, 0x6f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x07, 0x20, - 0x01, 0x28, 0x09, 0x52, 0x0a, 0x6f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x4e, 0x61, 0x6d, 0x65, 0x12, - 0x1f, 0x0a, 0x0b, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x5f, 0x69, 0x64, 0x18, 0x08, - 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x49, 0x64, + 0x74, 0x6f, 0x12, 0x05, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0xa0, 0x03, 0x0a, 0x0e, 0x46, 0x73, + 0x45, 0x76, 0x65, 0x6e, 0x74, 0x73, 0x46, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x12, 0x27, 0x0a, 0x0f, + 0x73, 0x74, 0x61, 0x72, 0x74, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x18, + 0x01, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0e, 0x73, 0x74, 0x61, 0x72, 0x74, 0x54, 0x69, 0x6d, 0x65, + 0x73, 0x74, 0x61, 0x6d, 0x70, 0x12, 0x23, 0x0a, 0x0d, 0x65, 0x6e, 0x64, 0x5f, 0x74, 0x69, 0x6d, + 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x18, 0x02, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0c, 0x65, 0x6e, + 0x64, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x12, 0x18, 0x0a, 0x07, 0x61, 0x63, + 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x09, 0x52, 0x07, 0x61, 0x63, 0x74, + 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x1a, 0x0a, 0x08, 0x75, 0x73, 0x65, 0x72, 0x6e, 0x61, 0x6d, 0x65, + 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x75, 0x73, 0x65, 0x72, 0x6e, 0x61, 0x6d, 0x65, + 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x70, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x69, 0x70, + 0x12, 0x17, 0x0a, 0x07, 0x73, 0x73, 0x68, 0x5f, 0x63, 0x6d, 0x64, 0x18, 0x06, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x06, 0x73, 0x73, 0x68, 0x43, 0x6d, 0x64, 0x12, 0x1c, 0x0a, 0x09, 0x70, 0x72, 0x6f, + 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x73, 0x18, 0x07, 0x20, 0x03, 0x28, 0x09, 0x52, 0x09, 0x70, 0x72, + 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x73, 0x12, 0x1a, 0x0a, 0x08, 0x73, 0x74, 0x61, 0x74, 0x75, + 0x73, 0x65, 0x73, 0x18, 0x08, 0x20, 0x03, 0x28, 0x05, 0x52, 0x08, 0x73, 0x74, 0x61, 0x74, 0x75, + 0x73, 0x65, 0x73, 0x12, 0x21, 0x0a, 0x0c, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x5f, + 0x69, 0x64, 0x73, 0x18, 0x09, 0x20, 0x03, 0x28, 0x09, 0x52, 0x0b, 0x69, 0x6e, 0x73, 0x74, 0x61, + 0x6e, 0x63, 0x65, 0x49, 0x64, 0x73, 0x12, 0x14, 0x0a, 0x05, 0x6c, 0x69, 0x6d, 0x69, 0x74, 0x18, + 0x0a, 0x20, 0x01, 0x28, 0x05, 0x52, 0x05, 0x6c, 0x69, 0x6d, 0x69, 0x74, 0x12, 0x1f, 0x0a, 0x0b, + 0x65, 0x78, 0x63, 0x6c, 0x75, 0x64, 0x65, 0x5f, 0x69, 0x64, 0x73, 0x18, 0x0b, 0x20, 0x03, 0x28, + 0x09, 0x52, 0x0a, 0x65, 0x78, 0x63, 0x6c, 0x75, 0x64, 0x65, 0x49, 0x64, 0x73, 0x12, 0x31, 0x0a, + 0x05, 0x6f, 0x72, 0x64, 0x65, 0x72, 0x18, 0x0c, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x1b, 0x2e, 0x70, + 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x46, 0x73, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x73, 0x46, 0x69, 0x6c, + 0x74, 0x65, 0x72, 0x2e, 0x4f, 0x72, 0x64, 0x65, 0x72, 0x52, 0x05, 0x6f, 0x72, 0x64, 0x65, 0x72, + 0x22, 0x1a, 0x0a, 0x05, 0x4f, 0x72, 0x64, 0x65, 0x72, 0x12, 0x08, 0x0a, 0x04, 0x44, 0x45, 0x53, + 0x43, 0x10, 0x00, 0x12, 0x07, 0x0a, 0x03, 0x41, 0x53, 0x43, 0x10, 0x01, 0x22, 0x9d, 0x03, 0x0a, + 0x14, 0x50, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x73, 0x46, + 0x69, 0x6c, 0x74, 0x65, 0x72, 0x12, 0x27, 0x0a, 0x0f, 0x73, 0x74, 0x61, 0x72, 0x74, 0x5f, 0x74, + 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x18, 0x01, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0e, + 0x73, 0x74, 0x61, 0x72, 0x74, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x12, 0x23, + 0x0a, 0x0d, 0x65, 0x6e, 0x64, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x18, + 0x02, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0c, 0x65, 0x6e, 0x64, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, + 0x61, 0x6d, 0x70, 0x12, 0x18, 0x0a, 0x07, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x03, + 0x20, 0x03, 0x28, 0x09, 0x52, 0x07, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x1a, 0x0a, + 0x08, 0x75, 0x73, 0x65, 0x72, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x08, 0x75, 0x73, 0x65, 0x72, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x70, 0x18, + 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x69, 0x70, 0x12, 0x21, 0x0a, 0x0c, 0x6f, 0x62, 0x6a, + 0x65, 0x63, 0x74, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x73, 0x18, 0x06, 0x20, 0x03, 0x28, 0x09, 0x52, + 0x0b, 0x6f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x54, 0x79, 0x70, 0x65, 0x73, 0x12, 0x1f, 0x0a, 0x0b, + 0x6f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x07, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x0a, 0x6f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x21, 0x0a, + 0x0c, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x5f, 0x69, 0x64, 0x73, 0x18, 0x08, 0x20, + 0x03, 0x28, 0x09, 0x52, 0x0b, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x49, 0x64, 0x73, 0x12, 0x14, 0x0a, 0x05, 0x6c, 0x69, 0x6d, 0x69, 0x74, 0x18, 0x09, 0x20, 0x01, 0x28, 0x05, 0x52, - 0x05, 0x6c, 0x69, 0x6d, 0x69, 0x74, 0x12, 0x2d, 0x0a, 0x12, 0x63, 0x6f, 0x6e, 0x74, 0x69, 0x6e, - 0x75, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x18, 0x0a, 0x20, 0x01, - 0x28, 0x09, 0x52, 0x11, 0x63, 0x6f, 0x6e, 0x74, 0x69, 0x6e, 0x75, 0x61, 0x74, 0x69, 0x6f, 0x6e, - 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x22, 0x64, 0x0a, 0x0e, 0x53, 0x65, 0x61, 0x72, 0x63, 0x68, 0x52, - 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x2d, 0x0a, 0x12, 0x63, 0x6f, 0x6e, 0x74, 0x69, - 0x6e, 0x75, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x18, 0x01, 0x20, - 0x01, 0x28, 0x09, 0x52, 0x11, 0x63, 0x6f, 0x6e, 0x74, 0x69, 0x6e, 0x75, 0x61, 0x74, 0x69, 0x6f, - 0x6e, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x12, 0x23, 0x0a, 0x0d, 0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e, - 0x73, 0x65, 0x5f, 0x64, 0x61, 0x74, 0x61, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0c, 0x72, - 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x44, 0x61, 0x74, 0x61, 0x32, 0x96, 0x01, 0x0a, 0x08, - 0x53, 0x65, 0x61, 0x72, 0x63, 0x68, 0x65, 0x72, 0x12, 0x3e, 0x0a, 0x0e, 0x53, 0x65, 0x61, 0x72, - 0x63, 0x68, 0x46, 0x73, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x73, 0x12, 0x15, 0x2e, 0x70, 0x72, 0x6f, - 0x74, 0x6f, 0x2e, 0x46, 0x73, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x73, 0x46, 0x69, 0x6c, 0x74, 0x65, - 0x72, 0x1a, 0x15, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x53, 0x65, 0x61, 0x72, 0x63, 0x68, - 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x4a, 0x0a, 0x14, 0x53, 0x65, 0x61, 0x72, - 0x63, 0x68, 0x50, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x73, - 0x12, 0x1b, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x50, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, - 0x72, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x73, 0x46, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x1a, 0x15, 0x2e, - 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x53, 0x65, 0x61, 0x72, 0x63, 0x68, 0x52, 0x65, 0x73, 0x70, - 0x6f, 0x6e, 0x73, 0x65, 0x42, 0x20, 0x5a, 0x1e, 0x73, 0x64, 0x6b, 0x2f, 0x70, 0x6c, 0x75, 0x67, - 0x69, 0x6e, 0x2f, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x73, 0x65, 0x61, 0x72, 0x63, 0x68, 0x65, 0x72, - 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, + 0x05, 0x6c, 0x69, 0x6d, 0x69, 0x74, 0x12, 0x37, 0x0a, 0x05, 0x6f, 0x72, 0x64, 0x65, 0x72, 0x18, + 0x0a, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x21, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x50, 0x72, + 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x73, 0x46, 0x69, 0x6c, 0x74, + 0x65, 0x72, 0x2e, 0x4f, 0x72, 0x64, 0x65, 0x72, 0x52, 0x05, 0x6f, 0x72, 0x64, 0x65, 0x72, 0x12, + 0x1f, 0x0a, 0x0b, 0x65, 0x78, 0x63, 0x6c, 0x75, 0x64, 0x65, 0x5f, 0x69, 0x64, 0x73, 0x18, 0x0b, + 0x20, 0x03, 0x28, 0x09, 0x52, 0x0a, 0x65, 0x78, 0x63, 0x6c, 0x75, 0x64, 0x65, 0x49, 0x64, 0x73, + 0x22, 0x1a, 0x0a, 0x05, 0x4f, 0x72, 0x64, 0x65, 0x72, 0x12, 0x08, 0x0a, 0x04, 0x44, 0x45, 0x53, + 0x43, 0x10, 0x00, 0x12, 0x07, 0x0a, 0x03, 0x41, 0x53, 0x43, 0x10, 0x01, 0x22, 0x72, 0x0a, 0x0e, + 0x53, 0x65, 0x61, 0x72, 0x63, 0x68, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x12, + 0x0a, 0x04, 0x64, 0x61, 0x74, 0x61, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x04, 0x64, 0x61, + 0x74, 0x61, 0x12, 0x27, 0x0a, 0x10, 0x73, 0x61, 0x6d, 0x65, 0x5f, 0x74, 0x73, 0x5f, 0x61, 0x74, + 0x5f, 0x73, 0x74, 0x61, 0x72, 0x74, 0x18, 0x02, 0x20, 0x03, 0x28, 0x09, 0x52, 0x0d, 0x73, 0x61, + 0x6d, 0x65, 0x54, 0x73, 0x41, 0x74, 0x53, 0x74, 0x61, 0x72, 0x74, 0x12, 0x23, 0x0a, 0x0e, 0x73, + 0x61, 0x6d, 0x65, 0x5f, 0x74, 0x73, 0x5f, 0x61, 0x74, 0x5f, 0x65, 0x6e, 0x64, 0x18, 0x03, 0x20, + 0x03, 0x28, 0x09, 0x52, 0x0b, 0x73, 0x61, 0x6d, 0x65, 0x54, 0x73, 0x41, 0x74, 0x45, 0x6e, 0x64, + 0x32, 0x96, 0x01, 0x0a, 0x08, 0x53, 0x65, 0x61, 0x72, 0x63, 0x68, 0x65, 0x72, 0x12, 0x3e, 0x0a, + 0x0e, 0x53, 0x65, 0x61, 0x72, 0x63, 0x68, 0x46, 0x73, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x73, 0x12, + 0x15, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x46, 0x73, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x73, + 0x46, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x1a, 0x15, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x53, + 0x65, 0x61, 0x72, 0x63, 0x68, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x4a, 0x0a, + 0x14, 0x53, 0x65, 0x61, 0x72, 0x63, 0x68, 0x50, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x45, + 0x76, 0x65, 0x6e, 0x74, 0x73, 0x12, 0x1b, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x50, 0x72, + 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x73, 0x46, 0x69, 0x6c, 0x74, + 0x65, 0x72, 0x1a, 0x15, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x53, 0x65, 0x61, 0x72, 0x63, + 0x68, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x42, 0x20, 0x5a, 0x1e, 0x73, 0x64, 0x6b, + 0x2f, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x2f, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x73, 0x65, 0x61, + 0x72, 0x63, 0x68, 0x65, 0x72, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x06, 0x70, 0x72, 0x6f, + 0x74, 0x6f, 0x33, } var ( @@ -416,27 +533,27 @@ func file_eventsearcher_proto_search_proto_rawDescGZIP() []byte { return file_eventsearcher_proto_search_proto_rawDescData } +var file_eventsearcher_proto_search_proto_enumTypes = make([]protoimpl.EnumInfo, 2) var file_eventsearcher_proto_search_proto_msgTypes = make([]protoimpl.MessageInfo, 3) var file_eventsearcher_proto_search_proto_goTypes = []interface{}{ - (*FsEventsFilter)(nil), // 0: proto.FsEventsFilter - (*ProviderEventsFilter)(nil), // 1: proto.ProviderEventsFilter - (*SearchResponse)(nil), // 2: proto.SearchResponse - (*timestamppb.Timestamp)(nil), // 3: google.protobuf.Timestamp + (FsEventsFilter_Order)(0), // 0: proto.FsEventsFilter.Order + (ProviderEventsFilter_Order)(0), // 1: proto.ProviderEventsFilter.Order + (*FsEventsFilter)(nil), // 2: proto.FsEventsFilter + (*ProviderEventsFilter)(nil), // 3: proto.ProviderEventsFilter + (*SearchResponse)(nil), // 4: proto.SearchResponse } var file_eventsearcher_proto_search_proto_depIdxs = []int32{ - 3, // 0: proto.FsEventsFilter.start_timestamp:type_name -> google.protobuf.Timestamp - 3, // 1: proto.FsEventsFilter.end_timestamp:type_name -> google.protobuf.Timestamp - 3, // 2: proto.ProviderEventsFilter.start_timestamp:type_name -> google.protobuf.Timestamp - 3, // 3: proto.ProviderEventsFilter.end_timestamp:type_name -> google.protobuf.Timestamp - 0, // 4: proto.Searcher.SearchFsEvents:input_type -> proto.FsEventsFilter - 1, // 5: proto.Searcher.SearchProviderEvents:input_type -> proto.ProviderEventsFilter - 2, // 6: proto.Searcher.SearchFsEvents:output_type -> proto.SearchResponse - 2, // 7: proto.Searcher.SearchProviderEvents:output_type -> proto.SearchResponse - 6, // [6:8] is the sub-list for method output_type - 4, // [4:6] is the sub-list for method input_type - 4, // [4:4] is the sub-list for extension type_name - 4, // [4:4] is the sub-list for extension extendee - 0, // [0:4] is the sub-list for field type_name + 0, // 0: proto.FsEventsFilter.order:type_name -> proto.FsEventsFilter.Order + 1, // 1: proto.ProviderEventsFilter.order:type_name -> proto.ProviderEventsFilter.Order + 2, // 2: proto.Searcher.SearchFsEvents:input_type -> proto.FsEventsFilter + 3, // 3: proto.Searcher.SearchProviderEvents:input_type -> proto.ProviderEventsFilter + 4, // 4: proto.Searcher.SearchFsEvents:output_type -> proto.SearchResponse + 4, // 5: proto.Searcher.SearchProviderEvents:output_type -> proto.SearchResponse + 4, // [4:6] is the sub-list for method output_type + 2, // [2:4] is the sub-list for method input_type + 2, // [2:2] is the sub-list for extension type_name + 2, // [2:2] is the sub-list for extension extendee + 0, // [0:2] is the sub-list for field type_name } func init() { file_eventsearcher_proto_search_proto_init() } @@ -487,13 +604,14 @@ func file_eventsearcher_proto_search_proto_init() { File: protoimpl.DescBuilder{ GoPackagePath: reflect.TypeOf(x{}).PkgPath(), RawDescriptor: file_eventsearcher_proto_search_proto_rawDesc, - NumEnums: 0, + NumEnums: 2, NumMessages: 3, NumExtensions: 0, NumServices: 1, }, GoTypes: file_eventsearcher_proto_search_proto_goTypes, DependencyIndexes: file_eventsearcher_proto_search_proto_depIdxs, + EnumInfos: file_eventsearcher_proto_search_proto_enumTypes, MessageInfos: file_eventsearcher_proto_search_proto_msgTypes, }.Build() File_eventsearcher_proto_search_proto = out.File diff --git a/sdk/plugin/eventsearcher/proto/search.proto b/sdk/plugin/eventsearcher/proto/search.proto index 5686cc85..71b1e1e5 100644 --- a/sdk/plugin/eventsearcher/proto/search.proto +++ b/sdk/plugin/eventsearcher/proto/search.proto @@ -1,40 +1,49 @@ syntax = "proto3"; package proto; -import "google/protobuf/timestamp.proto"; - option go_package = "sdk/plugin/eventsearcher/proto"; message FsEventsFilter { - google.protobuf.Timestamp start_timestamp = 1; - google.protobuf.Timestamp end_timestamp = 2; - string action = 3; + int64 start_timestamp = 1; + int64 end_timestamp = 2; + repeated string actions = 3; string username = 4; string ip = 5; string ssh_cmd = 6; - string protocol = 7; - int32 status = 8; - string instance_id = 9; + repeated string protocols = 7; + repeated int32 statuses = 8; + repeated string instance_ids = 9; int32 limit = 10; - string continuation_token = 11; + repeated string exclude_ids = 11; + enum Order { + DESC = 0; + ASC = 1; + } + Order order = 12; } message ProviderEventsFilter { - google.protobuf.Timestamp start_timestamp = 1; - google.protobuf.Timestamp end_timestamp = 2; - string action = 3; + int64 start_timestamp = 1; + int64 end_timestamp = 2; + repeated string actions = 3; string username = 4; string ip = 5; - string object_type = 6; + repeated string object_types = 6; string object_name = 7; - string instance_id = 8; + repeated string instance_ids = 8; int32 limit = 9; - string continuation_token = 10; + enum Order { + DESC = 0; + ASC = 1; + } + Order order = 10; + repeated string exclude_ids = 11; } message SearchResponse { - string continuation_token = 1; - bytes response_data = 2; // JSON serialized response to return + bytes data = 1; // JSON serialized response to return + repeated string same_ts_at_start = 2; + repeated string same_ts_at_end = 3; } service Searcher { diff --git a/sdk/plugin/notifier.go b/sdk/plugin/notifier.go index e41981f5..1af6a05d 100644 --- a/sdk/plugin/notifier.go +++ b/sdk/plugin/notifier.go @@ -10,7 +10,6 @@ import ( "github.com/hashicorp/go-hclog" "github.com/hashicorp/go-plugin" - "google.golang.org/protobuf/types/known/timestamppb" "github.com/drakkan/sftpgo/v2/logger" "github.com/drakkan/sftpgo/v2/sdk/plugin/notifier" @@ -43,14 +42,14 @@ type eventsQueue struct { providerEvents []*proto.ProviderEvent } -func (q *eventsQueue) addFsEvent(timestamp time.Time, action, username, fsPath, fsTargetPath, sshCmd, protocol, ip string, +func (q *eventsQueue) addFsEvent(timestamp int64, action, username, fsPath, fsTargetPath, sshCmd, protocol, ip string, fileSize int64, status int, ) { q.Lock() defer q.Unlock() q.fsEvents = append(q.fsEvents, &proto.FsEvent{ - Timestamp: timestamppb.New(timestamp), + Timestamp: timestamp, Action: action, Username: username, FsPath: fsPath, @@ -63,14 +62,14 @@ func (q *eventsQueue) addFsEvent(timestamp time.Time, action, username, fsPath, }) } -func (q *eventsQueue) addProviderEvent(timestamp time.Time, action, username, objectType, objectName, ip string, +func (q *eventsQueue) addProviderEvent(timestamp int64, action, username, objectType, objectName, ip string, objectAsJSON []byte, ) { q.Lock() defer q.Unlock() q.providerEvents = append(q.providerEvents, &proto.ProviderEvent{ - Timestamp: timestamppb.New(timestamp), + Timestamp: timestamp, Action: action, ObjectType: objectType, Username: username, @@ -191,11 +190,11 @@ func (p *notifierPlugin) initialize() error { return nil } -func (p *notifierPlugin) canQueueEvent(timestamp time.Time) bool { +func (p *notifierPlugin) canQueueEvent(timestamp int64) bool { if p.config.NotifierOptions.RetryMaxTime == 0 { return false } - if time.Now().After(timestamp.Add(time.Duration(p.config.NotifierOptions.RetryMaxTime) * time.Second)) { + if time.Now().After(util.GetTimeFromMsecSinceEpoch(timestamp).Add(time.Duration(p.config.NotifierOptions.RetryMaxTime) * time.Second)) { return false } if p.config.NotifierOptions.RetryQueueMaxSize > 0 { @@ -204,7 +203,7 @@ func (p *notifierPlugin) canQueueEvent(timestamp time.Time) bool { return true } -func (p *notifierPlugin) notifyFsAction(timestamp time.Time, action, username, fsPath, fsTargetPath, sshCmd, +func (p *notifierPlugin) notifyFsAction(timestamp int64, action, username, fsPath, fsTargetPath, sshCmd, protocol, ip, virtualPath, virtualTargetPath string, fileSize int64, errAction error) { if !util.IsStringInSlice(action, p.config.NotifierOptions.FsEvents) { return @@ -220,7 +219,7 @@ func (p *notifierPlugin) notifyFsAction(timestamp time.Time, action, username, f }() } -func (p *notifierPlugin) notifyProviderAction(timestamp time.Time, action, username, objectType, objectName, ip string, +func (p *notifierPlugin) notifyProviderAction(timestamp int64, action, username, objectType, objectName, ip string, object Renderer, ) { if !util.IsStringInSlice(action, p.config.NotifierOptions.ProviderEvents) || @@ -238,7 +237,7 @@ func (p *notifierPlugin) notifyProviderAction(timestamp time.Time, action, usern }() } -func (p *notifierPlugin) sendFsEvent(timestamp time.Time, action, username, fsPath, fsTargetPath, sshCmd, +func (p *notifierPlugin) sendFsEvent(timestamp int64, action, username, fsPath, fsTargetPath, sshCmd, protocol, ip, virtualPath, virtualTargetPath string, fileSize int64, status int) { if err := p.notifier.NotifyFsEvent(timestamp, action, username, fsPath, fsTargetPath, sshCmd, protocol, ip, virtualPath, virtualTargetPath, fileSize, status); err != nil { @@ -249,7 +248,7 @@ func (p *notifierPlugin) sendFsEvent(timestamp time.Time, action, username, fsPa } } -func (p *notifierPlugin) sendProviderEvent(timestamp time.Time, action, username, objectType, objectName, ip string, +func (p *notifierPlugin) sendProviderEvent(timestamp int64, action, username, objectType, objectName, ip string, objectAsJSON []byte, ) { if err := p.notifier.NotifyProviderEvent(timestamp, action, username, objectType, objectName, ip, objectAsJSON); err != nil { @@ -268,14 +267,14 @@ func (p *notifierPlugin) sendQueuedEvents() { logger.Debug(logSender, "", "check queued events for notifier %#v, events size: %v", p.config.Cmd, queueSize) fsEv := p.queue.popFsEvent() for fsEv != nil { - go p.sendFsEvent(fsEv.Timestamp.AsTime(), fsEv.Action, fsEv.Username, fsEv.FsPath, fsEv.FsTargetPath, + go p.sendFsEvent(fsEv.Timestamp, fsEv.Action, fsEv.Username, fsEv.FsPath, fsEv.FsTargetPath, fsEv.SshCmd, fsEv.Protocol, fsEv.Ip, fsEv.VirtualPath, fsEv.VirtualTargetPath, fsEv.FileSize, int(fsEv.Status)) fsEv = p.queue.popFsEvent() } providerEv := p.queue.popProviderEvent() for providerEv != nil { - go p.sendProviderEvent(providerEv.Timestamp.AsTime(), providerEv.Action, providerEv.Username, providerEv.ObjectType, + go p.sendProviderEvent(providerEv.Timestamp, providerEv.Action, providerEv.Username, providerEv.ObjectType, providerEv.ObjectName, providerEv.Ip, providerEv.ObjectData) providerEv = p.queue.popProviderEvent() } diff --git a/sdk/plugin/notifier/grpc.go b/sdk/plugin/notifier/grpc.go index cfe1f149..62652022 100644 --- a/sdk/plugin/notifier/grpc.go +++ b/sdk/plugin/notifier/grpc.go @@ -5,7 +5,6 @@ import ( "time" "google.golang.org/protobuf/types/known/emptypb" - "google.golang.org/protobuf/types/known/timestamppb" "github.com/drakkan/sftpgo/v2/sdk/plugin/notifier/proto" ) @@ -20,14 +19,14 @@ type GRPCClient struct { } // NotifyFsEvent implements the Notifier interface -func (c *GRPCClient) NotifyFsEvent(timestamp time.Time, action, username, fsPath, fsTargetPath, sshCmd, protocol, ip, +func (c *GRPCClient) NotifyFsEvent(timestamp int64, action, username, fsPath, fsTargetPath, sshCmd, protocol, ip, virtualPath, virtualTargetPath string, fileSize int64, status int, ) error { ctx, cancel := context.WithTimeout(context.Background(), rpcTimeout) defer cancel() _, err := c.client.SendFsEvent(ctx, &proto.FsEvent{ - Timestamp: timestamppb.New(timestamp), + Timestamp: timestamp, Action: action, Username: username, FsPath: fsPath, @@ -45,12 +44,12 @@ func (c *GRPCClient) NotifyFsEvent(timestamp time.Time, action, username, fsPath } // NotifyProviderEvent implements the Notifier interface -func (c *GRPCClient) NotifyProviderEvent(timestamp time.Time, action, username, objectType, objectName, ip string, object []byte) error { +func (c *GRPCClient) NotifyProviderEvent(timestamp int64, action, username, objectType, objectName, ip string, object []byte) error { ctx, cancel := context.WithTimeout(context.Background(), rpcTimeout) defer cancel() _, err := c.client.SendProviderEvent(ctx, &proto.ProviderEvent{ - Timestamp: timestamppb.New(timestamp), + Timestamp: timestamp, Action: action, ObjectType: objectType, Username: username, @@ -69,14 +68,14 @@ type GRPCServer struct { // SendFsEvent implements the serve side fs notify method func (s *GRPCServer) SendFsEvent(ctx context.Context, req *proto.FsEvent) (*emptypb.Empty, error) { - err := s.Impl.NotifyFsEvent(req.Timestamp.AsTime(), req.Action, req.Username, req.FsPath, req.FsTargetPath, req.SshCmd, + err := s.Impl.NotifyFsEvent(req.Timestamp, req.Action, req.Username, req.FsPath, req.FsTargetPath, req.SshCmd, req.Protocol, req.Ip, req.VirtualPath, req.VirtualTargetPath, req.FileSize, int(req.Status)) return &emptypb.Empty{}, err } // SendProviderEvent implements the serve side provider event notify method func (s *GRPCServer) SendProviderEvent(ctx context.Context, req *proto.ProviderEvent) (*emptypb.Empty, error) { - err := s.Impl.NotifyProviderEvent(req.Timestamp.AsTime(), req.Action, req.Username, req.ObjectType, req.ObjectName, + err := s.Impl.NotifyProviderEvent(req.Timestamp, req.Action, req.Username, req.ObjectType, req.ObjectName, req.Ip, req.ObjectData) return &emptypb.Empty{}, err } diff --git a/sdk/plugin/notifier/notifier.go b/sdk/plugin/notifier/notifier.go index f195b6d7..78fb9766 100644 --- a/sdk/plugin/notifier/notifier.go +++ b/sdk/plugin/notifier/notifier.go @@ -6,7 +6,6 @@ package notifier import ( "context" - "time" "github.com/hashicorp/go-plugin" "google.golang.org/grpc" @@ -33,9 +32,9 @@ var PluginMap = map[string]plugin.Plugin{ // Notifier defines the interface for notifiers plugins type Notifier interface { - NotifyFsEvent(timestamp time.Time, action, username, fsPath, fsTargetPath, sshCmd, protocol, ip, + NotifyFsEvent(timestamp int64, action, username, fsPath, fsTargetPath, sshCmd, protocol, ip, virtualPath, virtualTargetPath string, fileSize int64, status int) error - NotifyProviderEvent(timestamp time.Time, action, username, objectType, objectName, ip string, object []byte) error + NotifyProviderEvent(timestamp int64, action, username, objectType, objectName, ip string, object []byte) error } // Plugin defines the implementation to serve/connect to a notifier plugin diff --git a/sdk/plugin/notifier/proto/notifier.pb.go b/sdk/plugin/notifier/proto/notifier.pb.go index 362c2589..505e265c 100644 --- a/sdk/plugin/notifier/proto/notifier.pb.go +++ b/sdk/plugin/notifier/proto/notifier.pb.go @@ -14,7 +14,6 @@ import ( protoreflect "google.golang.org/protobuf/reflect/protoreflect" protoimpl "google.golang.org/protobuf/runtime/protoimpl" emptypb "google.golang.org/protobuf/types/known/emptypb" - timestamppb "google.golang.org/protobuf/types/known/timestamppb" reflect "reflect" sync "sync" ) @@ -31,18 +30,18 @@ type FsEvent struct { sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - Timestamp *timestamppb.Timestamp `protobuf:"bytes,1,opt,name=timestamp,proto3" json:"timestamp,omitempty"` - Action string `protobuf:"bytes,2,opt,name=action,proto3" json:"action,omitempty"` - Username string `protobuf:"bytes,3,opt,name=username,proto3" json:"username,omitempty"` - FsPath string `protobuf:"bytes,4,opt,name=fs_path,json=fsPath,proto3" json:"fs_path,omitempty"` - FsTargetPath string `protobuf:"bytes,5,opt,name=fs_target_path,json=fsTargetPath,proto3" json:"fs_target_path,omitempty"` - SshCmd string `protobuf:"bytes,6,opt,name=ssh_cmd,json=sshCmd,proto3" json:"ssh_cmd,omitempty"` - FileSize int64 `protobuf:"varint,7,opt,name=file_size,json=fileSize,proto3" json:"file_size,omitempty"` - Protocol string `protobuf:"bytes,8,opt,name=protocol,proto3" json:"protocol,omitempty"` - Status int32 `protobuf:"varint,9,opt,name=status,proto3" json:"status,omitempty"` - Ip string `protobuf:"bytes,10,opt,name=ip,proto3" json:"ip,omitempty"` - VirtualPath string `protobuf:"bytes,11,opt,name=virtual_path,json=virtualPath,proto3" json:"virtual_path,omitempty"` - VirtualTargetPath string `protobuf:"bytes,12,opt,name=virtual_target_path,json=virtualTargetPath,proto3" json:"virtual_target_path,omitempty"` + Timestamp int64 `protobuf:"varint,1,opt,name=timestamp,proto3" json:"timestamp,omitempty"` + Action string `protobuf:"bytes,2,opt,name=action,proto3" json:"action,omitempty"` + Username string `protobuf:"bytes,3,opt,name=username,proto3" json:"username,omitempty"` + FsPath string `protobuf:"bytes,4,opt,name=fs_path,json=fsPath,proto3" json:"fs_path,omitempty"` + FsTargetPath string `protobuf:"bytes,5,opt,name=fs_target_path,json=fsTargetPath,proto3" json:"fs_target_path,omitempty"` + SshCmd string `protobuf:"bytes,6,opt,name=ssh_cmd,json=sshCmd,proto3" json:"ssh_cmd,omitempty"` + FileSize int64 `protobuf:"varint,7,opt,name=file_size,json=fileSize,proto3" json:"file_size,omitempty"` + Protocol string `protobuf:"bytes,8,opt,name=protocol,proto3" json:"protocol,omitempty"` + Status int32 `protobuf:"varint,9,opt,name=status,proto3" json:"status,omitempty"` + Ip string `protobuf:"bytes,10,opt,name=ip,proto3" json:"ip,omitempty"` + VirtualPath string `protobuf:"bytes,11,opt,name=virtual_path,json=virtualPath,proto3" json:"virtual_path,omitempty"` + VirtualTargetPath string `protobuf:"bytes,12,opt,name=virtual_target_path,json=virtualTargetPath,proto3" json:"virtual_target_path,omitempty"` } func (x *FsEvent) Reset() { @@ -77,11 +76,11 @@ func (*FsEvent) Descriptor() ([]byte, []int) { return file_notifier_proto_notifier_proto_rawDescGZIP(), []int{0} } -func (x *FsEvent) GetTimestamp() *timestamppb.Timestamp { +func (x *FsEvent) GetTimestamp() int64 { if x != nil { return x.Timestamp } - return nil + return 0 } func (x *FsEvent) GetAction() string { @@ -166,13 +165,13 @@ type ProviderEvent struct { sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - Timestamp *timestamppb.Timestamp `protobuf:"bytes,1,opt,name=timestamp,proto3" json:"timestamp,omitempty"` - Action string `protobuf:"bytes,2,opt,name=action,proto3" json:"action,omitempty"` - ObjectType string `protobuf:"bytes,3,opt,name=object_type,json=objectType,proto3" json:"object_type,omitempty"` - Username string `protobuf:"bytes,4,opt,name=username,proto3" json:"username,omitempty"` - Ip string `protobuf:"bytes,5,opt,name=ip,proto3" json:"ip,omitempty"` - ObjectName string `protobuf:"bytes,6,opt,name=object_name,json=objectName,proto3" json:"object_name,omitempty"` - ObjectData []byte `protobuf:"bytes,7,opt,name=object_data,json=objectData,proto3" json:"object_data,omitempty"` // object JSON serialized + Timestamp int64 `protobuf:"varint,1,opt,name=timestamp,proto3" json:"timestamp,omitempty"` + Action string `protobuf:"bytes,2,opt,name=action,proto3" json:"action,omitempty"` + ObjectType string `protobuf:"bytes,3,opt,name=object_type,json=objectType,proto3" json:"object_type,omitempty"` + Username string `protobuf:"bytes,4,opt,name=username,proto3" json:"username,omitempty"` + Ip string `protobuf:"bytes,5,opt,name=ip,proto3" json:"ip,omitempty"` + ObjectName string `protobuf:"bytes,6,opt,name=object_name,json=objectName,proto3" json:"object_name,omitempty"` + ObjectData []byte `protobuf:"bytes,7,opt,name=object_data,json=objectData,proto3" json:"object_data,omitempty"` // object JSON serialized } func (x *ProviderEvent) Reset() { @@ -207,11 +206,11 @@ func (*ProviderEvent) Descriptor() ([]byte, []int) { return file_notifier_proto_notifier_proto_rawDescGZIP(), []int{1} } -func (x *ProviderEvent) GetTimestamp() *timestamppb.Timestamp { +func (x *ProviderEvent) GetTimestamp() int64 { if x != nil { return x.Timestamp } - return nil + return 0 } func (x *ProviderEvent) GetAction() string { @@ -261,61 +260,55 @@ var File_notifier_proto_notifier_proto protoreflect.FileDescriptor var file_notifier_proto_notifier_proto_rawDesc = []byte{ 0x0a, 0x1d, 0x6e, 0x6f, 0x74, 0x69, 0x66, 0x69, 0x65, 0x72, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x6e, 0x6f, 0x74, 0x69, 0x66, 0x69, 0x65, 0x72, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, - 0x05, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x1f, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x70, - 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2f, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, - 0x70, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x1b, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, - 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2f, 0x65, 0x6d, 0x70, 0x74, 0x79, 0x2e, 0x70, - 0x72, 0x6f, 0x74, 0x6f, 0x22, 0x83, 0x03, 0x0a, 0x07, 0x46, 0x73, 0x45, 0x76, 0x65, 0x6e, 0x74, - 0x12, 0x38, 0x0a, 0x09, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x18, 0x01, 0x20, - 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, - 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, - 0x09, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x12, 0x16, 0x0a, 0x06, 0x61, 0x63, - 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x61, 0x63, 0x74, 0x69, - 0x6f, 0x6e, 0x12, 0x1a, 0x0a, 0x08, 0x75, 0x73, 0x65, 0x72, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x03, - 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x75, 0x73, 0x65, 0x72, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x17, - 0x0a, 0x07, 0x66, 0x73, 0x5f, 0x70, 0x61, 0x74, 0x68, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, - 0x06, 0x66, 0x73, 0x50, 0x61, 0x74, 0x68, 0x12, 0x24, 0x0a, 0x0e, 0x66, 0x73, 0x5f, 0x74, 0x61, - 0x72, 0x67, 0x65, 0x74, 0x5f, 0x70, 0x61, 0x74, 0x68, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, - 0x0c, 0x66, 0x73, 0x54, 0x61, 0x72, 0x67, 0x65, 0x74, 0x50, 0x61, 0x74, 0x68, 0x12, 0x17, 0x0a, - 0x07, 0x73, 0x73, 0x68, 0x5f, 0x63, 0x6d, 0x64, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, - 0x73, 0x73, 0x68, 0x43, 0x6d, 0x64, 0x12, 0x1b, 0x0a, 0x09, 0x66, 0x69, 0x6c, 0x65, 0x5f, 0x73, - 0x69, 0x7a, 0x65, 0x18, 0x07, 0x20, 0x01, 0x28, 0x03, 0x52, 0x08, 0x66, 0x69, 0x6c, 0x65, 0x53, - 0x69, 0x7a, 0x65, 0x12, 0x1a, 0x0a, 0x08, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x18, - 0x08, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x12, - 0x16, 0x0a, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x18, 0x09, 0x20, 0x01, 0x28, 0x05, 0x52, - 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x70, 0x18, 0x0a, 0x20, - 0x01, 0x28, 0x09, 0x52, 0x02, 0x69, 0x70, 0x12, 0x21, 0x0a, 0x0c, 0x76, 0x69, 0x72, 0x74, 0x75, - 0x61, 0x6c, 0x5f, 0x70, 0x61, 0x74, 0x68, 0x18, 0x0b, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x76, - 0x69, 0x72, 0x74, 0x75, 0x61, 0x6c, 0x50, 0x61, 0x74, 0x68, 0x12, 0x2e, 0x0a, 0x13, 0x76, 0x69, - 0x72, 0x74, 0x75, 0x61, 0x6c, 0x5f, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x5f, 0x70, 0x61, 0x74, - 0x68, 0x18, 0x0c, 0x20, 0x01, 0x28, 0x09, 0x52, 0x11, 0x76, 0x69, 0x72, 0x74, 0x75, 0x61, 0x6c, - 0x54, 0x61, 0x72, 0x67, 0x65, 0x74, 0x50, 0x61, 0x74, 0x68, 0x22, 0xf0, 0x01, 0x0a, 0x0d, 0x50, - 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x12, 0x38, 0x0a, 0x09, - 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, - 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, - 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x09, 0x74, 0x69, 0x6d, - 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x12, 0x16, 0x0a, 0x06, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, - 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x1f, - 0x0a, 0x0b, 0x6f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x18, 0x03, 0x20, - 0x01, 0x28, 0x09, 0x52, 0x0a, 0x6f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x54, 0x79, 0x70, 0x65, 0x12, - 0x1a, 0x0a, 0x08, 0x75, 0x73, 0x65, 0x72, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, - 0x09, 0x52, 0x08, 0x75, 0x73, 0x65, 0x72, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x0e, 0x0a, 0x02, 0x69, - 0x70, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x69, 0x70, 0x12, 0x1f, 0x0a, 0x0b, 0x6f, - 0x62, 0x6a, 0x65, 0x63, 0x74, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, - 0x52, 0x0a, 0x6f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x1f, 0x0a, 0x0b, - 0x6f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x5f, 0x64, 0x61, 0x74, 0x61, 0x18, 0x07, 0x20, 0x01, 0x28, - 0x0c, 0x52, 0x0a, 0x6f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x44, 0x61, 0x74, 0x61, 0x32, 0x84, 0x01, - 0x0a, 0x08, 0x4e, 0x6f, 0x74, 0x69, 0x66, 0x69, 0x65, 0x72, 0x12, 0x35, 0x0a, 0x0b, 0x53, 0x65, - 0x6e, 0x64, 0x46, 0x73, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x12, 0x0e, 0x2e, 0x70, 0x72, 0x6f, 0x74, - 0x6f, 0x2e, 0x46, 0x73, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x1a, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, - 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, - 0x79, 0x12, 0x41, 0x0a, 0x11, 0x53, 0x65, 0x6e, 0x64, 0x50, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, - 0x72, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x12, 0x14, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x50, - 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x1a, 0x16, 0x2e, 0x67, - 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, - 0x6d, 0x70, 0x74, 0x79, 0x42, 0x1b, 0x5a, 0x19, 0x73, 0x64, 0x6b, 0x2f, 0x70, 0x6c, 0x75, 0x67, - 0x69, 0x6e, 0x2f, 0x6e, 0x6f, 0x74, 0x69, 0x66, 0x69, 0x65, 0x72, 0x2f, 0x70, 0x72, 0x6f, 0x74, - 0x6f, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, + 0x05, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x1b, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x70, + 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2f, 0x65, 0x6d, 0x70, 0x74, 0x79, 0x2e, 0x70, 0x72, + 0x6f, 0x74, 0x6f, 0x22, 0xe7, 0x02, 0x0a, 0x07, 0x46, 0x73, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x12, + 0x1c, 0x0a, 0x09, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x18, 0x01, 0x20, 0x01, + 0x28, 0x03, 0x52, 0x09, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x12, 0x16, 0x0a, + 0x06, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x61, + 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x1a, 0x0a, 0x08, 0x75, 0x73, 0x65, 0x72, 0x6e, 0x61, 0x6d, + 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x75, 0x73, 0x65, 0x72, 0x6e, 0x61, 0x6d, + 0x65, 0x12, 0x17, 0x0a, 0x07, 0x66, 0x73, 0x5f, 0x70, 0x61, 0x74, 0x68, 0x18, 0x04, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x06, 0x66, 0x73, 0x50, 0x61, 0x74, 0x68, 0x12, 0x24, 0x0a, 0x0e, 0x66, 0x73, + 0x5f, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x5f, 0x70, 0x61, 0x74, 0x68, 0x18, 0x05, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x0c, 0x66, 0x73, 0x54, 0x61, 0x72, 0x67, 0x65, 0x74, 0x50, 0x61, 0x74, 0x68, + 0x12, 0x17, 0x0a, 0x07, 0x73, 0x73, 0x68, 0x5f, 0x63, 0x6d, 0x64, 0x18, 0x06, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x06, 0x73, 0x73, 0x68, 0x43, 0x6d, 0x64, 0x12, 0x1b, 0x0a, 0x09, 0x66, 0x69, 0x6c, + 0x65, 0x5f, 0x73, 0x69, 0x7a, 0x65, 0x18, 0x07, 0x20, 0x01, 0x28, 0x03, 0x52, 0x08, 0x66, 0x69, + 0x6c, 0x65, 0x53, 0x69, 0x7a, 0x65, 0x12, 0x1a, 0x0a, 0x08, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x63, + 0x6f, 0x6c, 0x18, 0x08, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x63, + 0x6f, 0x6c, 0x12, 0x16, 0x0a, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x18, 0x09, 0x20, 0x01, + 0x28, 0x05, 0x52, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x70, + 0x18, 0x0a, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x69, 0x70, 0x12, 0x21, 0x0a, 0x0c, 0x76, 0x69, + 0x72, 0x74, 0x75, 0x61, 0x6c, 0x5f, 0x70, 0x61, 0x74, 0x68, 0x18, 0x0b, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x0b, 0x76, 0x69, 0x72, 0x74, 0x75, 0x61, 0x6c, 0x50, 0x61, 0x74, 0x68, 0x12, 0x2e, 0x0a, + 0x13, 0x76, 0x69, 0x72, 0x74, 0x75, 0x61, 0x6c, 0x5f, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x5f, + 0x70, 0x61, 0x74, 0x68, 0x18, 0x0c, 0x20, 0x01, 0x28, 0x09, 0x52, 0x11, 0x76, 0x69, 0x72, 0x74, + 0x75, 0x61, 0x6c, 0x54, 0x61, 0x72, 0x67, 0x65, 0x74, 0x50, 0x61, 0x74, 0x68, 0x22, 0xd4, 0x01, + 0x0a, 0x0d, 0x50, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x12, + 0x1c, 0x0a, 0x09, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x18, 0x01, 0x20, 0x01, + 0x28, 0x03, 0x52, 0x09, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x12, 0x16, 0x0a, + 0x06, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x61, + 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x1f, 0x0a, 0x0b, 0x6f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x5f, + 0x74, 0x79, 0x70, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x6f, 0x62, 0x6a, 0x65, + 0x63, 0x74, 0x54, 0x79, 0x70, 0x65, 0x12, 0x1a, 0x0a, 0x08, 0x75, 0x73, 0x65, 0x72, 0x6e, 0x61, + 0x6d, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x75, 0x73, 0x65, 0x72, 0x6e, 0x61, + 0x6d, 0x65, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x70, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, + 0x69, 0x70, 0x12, 0x1f, 0x0a, 0x0b, 0x6f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x5f, 0x6e, 0x61, 0x6d, + 0x65, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x6f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x4e, + 0x61, 0x6d, 0x65, 0x12, 0x1f, 0x0a, 0x0b, 0x6f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x5f, 0x64, 0x61, + 0x74, 0x61, 0x18, 0x07, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0a, 0x6f, 0x62, 0x6a, 0x65, 0x63, 0x74, + 0x44, 0x61, 0x74, 0x61, 0x32, 0x84, 0x01, 0x0a, 0x08, 0x4e, 0x6f, 0x74, 0x69, 0x66, 0x69, 0x65, + 0x72, 0x12, 0x35, 0x0a, 0x0b, 0x53, 0x65, 0x6e, 0x64, 0x46, 0x73, 0x45, 0x76, 0x65, 0x6e, 0x74, + 0x12, 0x0e, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x46, 0x73, 0x45, 0x76, 0x65, 0x6e, 0x74, + 0x1a, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, + 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x12, 0x41, 0x0a, 0x11, 0x53, 0x65, 0x6e, 0x64, + 0x50, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x12, 0x14, 0x2e, + 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x50, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x45, 0x76, + 0x65, 0x6e, 0x74, 0x1a, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, + 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x42, 0x1b, 0x5a, 0x19, 0x73, + 0x64, 0x6b, 0x2f, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x2f, 0x6e, 0x6f, 0x74, 0x69, 0x66, 0x69, + 0x65, 0x72, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, } var ( @@ -332,23 +325,20 @@ func file_notifier_proto_notifier_proto_rawDescGZIP() []byte { var file_notifier_proto_notifier_proto_msgTypes = make([]protoimpl.MessageInfo, 2) var file_notifier_proto_notifier_proto_goTypes = []interface{}{ - (*FsEvent)(nil), // 0: proto.FsEvent - (*ProviderEvent)(nil), // 1: proto.ProviderEvent - (*timestamppb.Timestamp)(nil), // 2: google.protobuf.Timestamp - (*emptypb.Empty)(nil), // 3: google.protobuf.Empty + (*FsEvent)(nil), // 0: proto.FsEvent + (*ProviderEvent)(nil), // 1: proto.ProviderEvent + (*emptypb.Empty)(nil), // 2: google.protobuf.Empty } var file_notifier_proto_notifier_proto_depIdxs = []int32{ - 2, // 0: proto.FsEvent.timestamp:type_name -> google.protobuf.Timestamp - 2, // 1: proto.ProviderEvent.timestamp:type_name -> google.protobuf.Timestamp - 0, // 2: proto.Notifier.SendFsEvent:input_type -> proto.FsEvent - 1, // 3: proto.Notifier.SendProviderEvent:input_type -> proto.ProviderEvent - 3, // 4: proto.Notifier.SendFsEvent:output_type -> google.protobuf.Empty - 3, // 5: proto.Notifier.SendProviderEvent:output_type -> google.protobuf.Empty - 4, // [4:6] is the sub-list for method output_type - 2, // [2:4] is the sub-list for method input_type - 2, // [2:2] is the sub-list for extension type_name - 2, // [2:2] is the sub-list for extension extendee - 0, // [0:2] is the sub-list for field type_name + 0, // 0: proto.Notifier.SendFsEvent:input_type -> proto.FsEvent + 1, // 1: proto.Notifier.SendProviderEvent:input_type -> proto.ProviderEvent + 2, // 2: proto.Notifier.SendFsEvent:output_type -> google.protobuf.Empty + 2, // 3: proto.Notifier.SendProviderEvent:output_type -> google.protobuf.Empty + 2, // [2:4] is the sub-list for method output_type + 0, // [0:2] is the sub-list for method input_type + 0, // [0:0] is the sub-list for extension type_name + 0, // [0:0] is the sub-list for extension extendee + 0, // [0:0] is the sub-list for field type_name } func init() { file_notifier_proto_notifier_proto_init() } diff --git a/sdk/plugin/notifier/proto/notifier.proto b/sdk/plugin/notifier/proto/notifier.proto index 5f7e77f8..9a09d135 100644 --- a/sdk/plugin/notifier/proto/notifier.proto +++ b/sdk/plugin/notifier/proto/notifier.proto @@ -1,13 +1,12 @@ syntax = "proto3"; package proto; -import "google/protobuf/timestamp.proto"; import "google/protobuf/empty.proto"; option go_package = "sdk/plugin/notifier/proto"; message FsEvent { - google.protobuf.Timestamp timestamp = 1; + int64 timestamp = 1; string action = 2; string username = 3; string fs_path = 4; @@ -22,7 +21,7 @@ message FsEvent { } message ProviderEvent { - google.protobuf.Timestamp timestamp = 1; + int64 timestamp = 1; string action = 2; string object_type = 3; string username = 4; diff --git a/sdk/plugin/plugin.go b/sdk/plugin/plugin.go index 415f27d8..7fd70d31 100644 --- a/sdk/plugin/plugin.go +++ b/sdk/plugin/plugin.go @@ -28,7 +28,8 @@ var ( // Handler defines the plugins manager Handler Manager pluginsLogLevel = hclog.Debug - errNoSearcher = errors.New("no events searcher plugin defined") + // ErrNoSearcher defines the error to return for events searches if no plugin is configured + ErrNoSearcher = errors.New("no events searcher plugin defined") ) // Renderer defines the interface for generic objects rendering @@ -184,7 +185,7 @@ func (m *Manager) validateConfigs() error { } // NotifyFsEvent sends the fs event notifications using any defined notifier plugins -func (m *Manager) NotifyFsEvent(timestamp time.Time, action, username, fsPath, fsTargetPath, sshCmd, protocol, ip, +func (m *Manager) NotifyFsEvent(timestamp int64, action, username, fsPath, fsTargetPath, sshCmd, protocol, ip, virtualPath, virtualTargetPath string, fileSize int64, err error, ) { m.notifLock.RLock() @@ -197,7 +198,7 @@ func (m *Manager) NotifyFsEvent(timestamp time.Time, action, username, fsPath, f } // NotifyProviderEvent sends the provider event notifications using any defined notifier plugins -func (m *Manager) NotifyProviderEvent(timestamp time.Time, action, username, objectType, objectName, ip string, +func (m *Manager) NotifyProviderEvent(timestamp int64, action, username, objectType, objectName, ip string, object Renderer, ) { m.notifLock.RLock() @@ -210,34 +211,34 @@ func (m *Manager) NotifyProviderEvent(timestamp time.Time, action, username, obj // SearchFsEvents returns the filesystem events matching the specified filter and a continuation token // to use for cursor based pagination -func (m *Manager) SearchFsEvents(startTimestamp, endTimestamp time.Time, action, username, ip, sshCmd, protocol, - instanceID, continuationToken string, status, limit int) (string, []byte, error, -) { +func (m *Manager) SearchFsEvents(startTimestamp, endTimestamp int64, username, ip, sshCmd string, actions, + protocols, instanceIDs, excludeIDs []string, statuses []int32, limit, order int, +) ([]byte, []string, []string, error) { if !m.hasSearcher { - return "", nil, errNoSearcher + return nil, nil, nil, ErrNoSearcher } m.searcherLock.RLock() plugin := m.searcher m.searcherLock.RUnlock() - return plugin.searchear.SearchFsEvents(startTimestamp, endTimestamp, action, username, ip, sshCmd, protocol, - instanceID, continuationToken, status, limit) + return plugin.searchear.SearchFsEvents(startTimestamp, endTimestamp, username, ip, sshCmd, actions, protocols, + instanceIDs, excludeIDs, statuses, limit, order) } // SearchProviderEvents returns the provider events matching the specified filter and a continuation token // to use for cursor based pagination -func (m *Manager) SearchProviderEvents(startTimestamp, endTimestamp time.Time, action, username, ip, objectType, - objectName, instanceID, continuationToken string, limit int, -) (string, []byte, error) { +func (m *Manager) SearchProviderEvents(startTimestamp, endTimestamp int64, username, ip, objectName string, + limit, order int, actions, objectTypes, instanceIDs, excludeIDs []string, +) ([]byte, []string, []string, error) { if !m.hasSearcher { - return "", nil, errNoSearcher + return nil, nil, nil, ErrNoSearcher } m.searcherLock.RLock() plugin := m.searcher m.searcherLock.RUnlock() - return plugin.searchear.SearchProviderEvents(startTimestamp, endTimestamp, action, username, ip, objectType, objectName, - instanceID, continuationToken, limit) + return plugin.searchear.SearchProviderEvents(startTimestamp, endTimestamp, username, ip, objectName, limit, + order, actions, objectTypes, instanceIDs, excludeIDs) } func (m *Manager) kmsEncrypt(secret kms.BaseSecret, url string, masterKey string, kmsID int) (string, string, int32, error) {