@@ -55,6 +55,7 @@ type CASBackend struct {
5555 CreatedAt , ValidatedAt * time.Time
5656 OrganizationID uuid.UUID
5757 ValidationStatus CASBackendValidationStatus
58+ ValidationError * string
5859 // OCI, S3, ...
5960 Provider CASBackendProvider
6061 // Whether this is the default cas backend for the organization
@@ -77,6 +78,8 @@ type CASBackendOpts struct {
7778 Location , SecretName , Description string
7879 Provider CASBackendProvider
7980 Default bool
81+ ValidationStatus CASBackendValidationStatus
82+ ValidationError * string
8083}
8184
8285type CASBackendCreateOpts struct {
@@ -98,10 +101,10 @@ type CASBackendRepo interface {
98101 FindByIDInOrg (ctx context.Context , OrgID , ID uuid.UUID ) (* CASBackend , error )
99102 FindByNameInOrg (ctx context.Context , OrgID uuid.UUID , name string ) (* CASBackend , error )
100103 List (ctx context.Context , orgID uuid.UUID ) ([]* CASBackend , error )
104+ UpdateValidationStatus (ctx context.Context , ID uuid.UUID , status CASBackendValidationStatus , validationError * string ) error
101105 // ListBackends returns CAS backends across all organizations
102106 // If onlyDefaults is true, only default backends are returned
103107 ListBackends (ctx context.Context , onlyDefaults bool ) ([]* CASBackend , error )
104- UpdateValidationStatus (ctx context.Context , ID uuid.UUID , status CASBackendValidationStatus ) error
105108 Create (context.Context , * CASBackendCreateOpts ) (* CASBackend , error )
106109 Update (context.Context , * CASBackendUpdateOpts ) (* CASBackend , error )
107110 Delete (ctx context.Context , ID uuid.UUID ) error
@@ -345,6 +348,8 @@ func (uc *CASBackendUseCase) Update(ctx context.Context, orgID, id, description
345348 ID : uuid ,
346349 CASBackendOpts : & CASBackendOpts {
347350 SecretName : secretName , Default : defaultB , Description : description , OrgID : orgUUID ,
351+ ValidationStatus : CASBackendValidationOK ,
352+ ValidationError : ToPtr ("" ),
348353 },
349354 })
350355 if err != nil {
@@ -530,6 +535,7 @@ func (CASBackendValidationStatus) Values() (kinds []string) {
530535// Validate that the repository is valid and reachable
531536func (uc * CASBackendUseCase ) PerformValidation (ctx context.Context , id string ) (err error ) {
532537 validationStatus := CASBackendValidationFailed
538+ var validationError * string
533539
534540 backendUUID , err := uuid .Parse (id )
535541 if err != nil {
@@ -559,16 +565,16 @@ func (uc *CASBackendUseCase) PerformValidation(ctx context.Context, id string) (
559565 return
560566 }
561567
562- // Store previous status for audit logging
563- previousStatus := backend .ValidationStatus
564-
565- // Update the validation status
566- uc .logger .Infow ("msg" , "updating validation status" , "ID" , id , "status" , validationStatus )
567- if err := uc .repo .UpdateValidationStatus (ctx , backendUUID , validationStatus ); err != nil {
568+ // Update the validation status and error
569+ uc .logger .Infow ("msg" , "updating validation status" , "ID" , id , "status" , validationStatus , "error" , validationError )
570+ if err := uc .repo .UpdateValidationStatus (ctx , backendUUID , validationStatus , validationError ); err != nil {
568571 uc .logger .Errorw ("msg" , "updating validation status" , "ID" , id , "error" , err )
569572 return
570573 }
571574
575+ // Store previous status for audit logging
576+ previousStatus := backend .ValidationStatus
577+
572578 // Log status change as an audit event if status has changed and auditor is available
573579 if uc .auditorUC != nil && previousStatus != validationStatus {
574580 uc .logger .Debugw ("msg" , "status changed, dispatching audit event" ,
@@ -579,6 +585,11 @@ func (uc *CASBackendUseCase) PerformValidation(ctx context.Context, id string) (
579585 // Check if this is a recovery event (going from failed to OK)
580586 isRecovery := previousStatus == CASBackendValidationFailed && validationStatus == CASBackendValidationOK
581587
588+ var validationErrorStr string
589+ if validationError != nil {
590+ validationErrorStr = * validationError
591+ }
592+
582593 // Create and send event for the status change
583594 uc .auditorUC .Dispatch (ctx , & events.CASBackendStatusChanged {
584595 CASBackendBase : & events.CASBackendBase {
@@ -590,6 +601,7 @@ func (uc *CASBackendUseCase) PerformValidation(ctx context.Context, id string) (
590601 },
591602 PreviousStatus : string (previousStatus ),
592603 NewStatus : string (validationStatus ),
604+ StatusError : validationErrorStr ,
593605 IsRecovery : isRecovery ,
594606 }, & backend .OrganizationID )
595607 }
@@ -598,25 +610,28 @@ func (uc *CASBackendUseCase) PerformValidation(ctx context.Context, id string) (
598610 // 1 - Retrieve the credentials from the external secrets manager
599611 var creds any
600612 if err := uc .credsRW .ReadCredentials (ctx , backend .SecretName , & creds ); err != nil {
601- uc .logger .Infow ("msg" , "credentials not found or invalid" , "ID" , id )
613+ uc .logger .Infow ("msg" , "credentials not found or invalid" , "ID" , id , "error" , err )
602614 return nil
603615 }
604616
605617 credsJSON , err := json .Marshal (creds )
606618 if err != nil {
607- uc .logger .Infow ("msg" , "credentials invalid" , "ID" , id )
619+ uc .logger .Infow ("msg" , "credentials invalid" , "ID" , id , "error" , err )
608620 return nil
609621 }
610622
611623 // 2 - run validation
612624 _ , err = provider .ValidateAndExtractCredentials (backend .Location , credsJSON )
613625 if err != nil {
614- uc .logger .Infow ("msg" , "permissions validation failed" , "ID" , id )
626+ errMsg := err .Error ()
627+ validationError = & errMsg
628+ uc .logger .Infow ("msg" , "permissions validation failed" , "ID" , id , "error" , err )
615629 return nil
616630 }
617631
618632 // If everything went well, update the validation status to OK
619633 validationStatus = CASBackendValidationOK
634+ validationError = nil
620635 uc .logger .Infow ("msg" , "validation OK" , "ID" , id )
621636
622637 return nil
0 commit comments