Files
pmg/internal/audit/cloud_sink.go
T
Abhisek DattaGitHubdevin-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>
e67735c1c3 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>
2026-04-11 12:33:27 +05:30

126 lines
3.2 KiB
Go

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...)
}