mirror of
https://github.com/safedep/pmg.git
synced 2026-08-03 07:24:09 +02:00
feat: Add cloud sync event emit (#212)
* feat: Add cloud sync event emit * fix: Linter fixes * fix: Include malysis metadata in confirmed event * fix: Code review fixes * fix: Emit session complet event * fix: Code review fixes * chore: Add comment * chore: Add cloud info in setup info command * fix: Proxy flow must call install started * fix: Code review fixes * fix: Code review fixes * Update internal/audit/cloud_sink.go Co-authored-by: devin-ai-integration[bot] <158243242+devin-ai-integration[bot]@users.noreply.github.com> Signed-off-by: Abhisek Datta <abhisek.datta@gmail.com> * fix: Code review fixes --------- Signed-off-by: Abhisek Datta <abhisek.datta@gmail.com> Co-authored-by: devin-ai-integration[bot] <158243242+devin-ai-integration[bot]@users.noreply.github.com>
This commit is contained in:
co-authored by
devin-ai-integration[bot] <158243242+devin-ai-integration[bot]@users.noreply.github.com>
devin-ai-integration[bot] <158243242+devin-ai-integration[bot]@users.noreply.github.com>
parent
0355a5d4fd
commit
e67735c1c3
@@ -0,0 +1,125 @@
|
||||
package audit
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"fmt"
|
||||
|
||||
"github.com/google/uuid"
|
||||
"github.com/safedep/dry/cloud"
|
||||
"github.com/safedep/dry/cloud/endpointsync"
|
||||
"github.com/safedep/dry/log"
|
||||
"github.com/safedep/pmg/config"
|
||||
appVersion "github.com/safedep/pmg/internal/version"
|
||||
)
|
||||
|
||||
type cloudSink struct {
|
||||
syncClient *endpointsync.SyncClient
|
||||
cloudClient *cloud.Client
|
||||
invocationID string
|
||||
}
|
||||
|
||||
func newCloudSink(cfg *config.RuntimeConfig) (*cloudSink, error) {
|
||||
resolver, err := cloud.NewEnvCredentialResolver()
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to create credential resolver: %w", err)
|
||||
}
|
||||
|
||||
creds, err := resolver.Resolve()
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to resolve cloud credentials: %w", err)
|
||||
}
|
||||
|
||||
cloudClient, err := cloud.NewDataPlaneClient("pmg", creds)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to create data plane client: %w", err)
|
||||
}
|
||||
|
||||
transport := endpointsync.NewGrpcTransport(cloudClient.Connection())
|
||||
|
||||
sink, err := newCloudSinkWithTransport(transport, cfg.Config.Cloud.EndpointID, cfg.CloudSyncDBPath())
|
||||
if err != nil {
|
||||
if closeErr := cloudClient.Close(); closeErr != nil {
|
||||
log.Warnf("failed to close cloud client after sink init failure: %v", closeErr)
|
||||
}
|
||||
return nil, err
|
||||
}
|
||||
|
||||
sink.cloudClient = cloudClient
|
||||
return sink, nil
|
||||
}
|
||||
|
||||
func newCloudSinkWithTransport(transport endpointsync.EventTransport, endpointID, walPath string) (*cloudSink, error) {
|
||||
var identityOpts []endpointsync.EndpointIdentityOption
|
||||
if endpointID != "" {
|
||||
identityOpts = append(identityOpts, endpointsync.WithEndpointID(endpointID))
|
||||
}
|
||||
|
||||
identity := endpointsync.NewEndpointIdentityResolver(identityOpts...)
|
||||
|
||||
toolVersion := appVersion.Version
|
||||
if toolVersion == "" {
|
||||
toolVersion = "dev"
|
||||
}
|
||||
|
||||
syncClient, err := endpointsync.NewSyncClient("pmg", toolVersion, transport, identity,
|
||||
endpointsync.WithWALPath(walPath))
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to create sync client: %w", err)
|
||||
}
|
||||
|
||||
invocationID, err := uuid.NewRandom()
|
||||
if err != nil {
|
||||
if closeErr := syncClient.Close(); closeErr != nil {
|
||||
log.Warnf("failed to close sync client after invocation ID generation failure: %v", closeErr)
|
||||
}
|
||||
return nil, fmt.Errorf("failed to generate invocation ID: %w", err)
|
||||
}
|
||||
|
||||
return &cloudSink{
|
||||
syncClient: syncClient,
|
||||
invocationID: invocationID.String(),
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (s *cloudSink) Handle(ctx context.Context, event AuditEvent) error {
|
||||
pmgEvents := s.translateToPmgEvents(event)
|
||||
if len(pmgEvents) == 0 {
|
||||
return nil
|
||||
}
|
||||
|
||||
for _, pmgEvent := range pmgEvents {
|
||||
toolEvent, err := s.syncClient.NewEvent()
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to create tool event: %w", err)
|
||||
}
|
||||
|
||||
toolEvent.SetPmgEvent(pmgEvent)
|
||||
toolEvent.SetInvocationId(s.invocationID)
|
||||
|
||||
if err := s.syncClient.Emit(ctx, toolEvent); err != nil {
|
||||
if errors.Is(err, endpointsync.ErrWALFull) {
|
||||
log.Warnf("Cloud sync WAL is full, dropping event: %v", err)
|
||||
return nil
|
||||
}
|
||||
return fmt.Errorf("failed to emit cloud event: %w", err)
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s *cloudSink) Close() error {
|
||||
var errs []error
|
||||
if s.syncClient != nil {
|
||||
if err := s.syncClient.Close(); err != nil {
|
||||
errs = append(errs, err)
|
||||
}
|
||||
}
|
||||
if s.cloudClient != nil {
|
||||
if err := s.cloudClient.Close(); err != nil {
|
||||
errs = append(errs, err)
|
||||
}
|
||||
}
|
||||
return errors.Join(errs...)
|
||||
}
|
||||
Reference in New Issue
Block a user