@@ -221,6 +221,30 @@ func resourceRegistryEcrCreate(ctx context.Context, d *schema.ResourceData, m in
221221 return diag .FromErr (err )
222222 }
223223 d .SetId (uid )
224+
225+ // Wait for sync if requested and provider_type is helm (ECR supports helm only for wait_for_sync)
226+ if providerType == "helm" && d .Get ("wait_for_sync" ) != nil && d .Get ("wait_for_sync" ).(bool ) {
227+ diagnostics , isError := waitForOciEcrRegistrySync (ctx , d , uid , diags , c , schema .TimeoutCreate )
228+ if len (diagnostics ) > 0 {
229+ diags = append (diags , diagnostics ... )
230+ }
231+ // Fetch final sync status and set wait_for_status_message
232+ registry , statusErr := c .GetOciEcrRegistry (uid )
233+ if statusErr == nil && registry != nil && registry .Status != nil && registry .Status .SyncStatus != nil {
234+ statusMessage := ""
235+ if registry .Status .SyncStatus .Message != "" {
236+ statusMessage = registry .Status .SyncStatus .Message
237+ } else if registry .Status .SyncStatus .Status != "" {
238+ statusMessage = fmt .Sprintf ("Status: %s" , registry .Status .SyncStatus .Status )
239+ }
240+ if err := d .Set ("wait_for_status_message" , statusMessage ); err != nil {
241+ diags = append (diags , diag .FromErr (err )... )
242+ }
243+ }
244+ if isError {
245+ return diagnostics
246+ }
247+ }
224248 case "basic" :
225249 registry := toRegistryBasic (d )
226250 if err := validateRegistryCred (c , registryType , providerType , isSync , registry .Spec , nil ); err != nil {
@@ -325,7 +349,7 @@ func resourceRegistryEcrRead(ctx context.Context, d *schema.ResourceData, m inte
325349 }
326350 // tls configuration handling
327351 tlsConfig := make ([]interface {}, 0 , 1 )
328- if registry .Spec .TLS != nil && ( registry . Spec . TLS . Certificate != "" || registry . Spec . TLS . InsecureSkipVerify ) {
352+ if registry .Spec .TLS != nil {
329353 tls := make (map [string ]interface {})
330354 tls ["certificate" ] = registry .Spec .TLS .Certificate
331355 tls ["insecure_skip_verify" ] = registry .Spec .TLS .InsecureSkipVerify
@@ -451,6 +475,30 @@ func resourceRegistryEcrUpdate(ctx context.Context, d *schema.ResourceData, m in
451475 if err != nil {
452476 return diag .FromErr (err )
453477 }
478+
479+ // Wait for sync if requested and provider_type is helm
480+ if providerType == "helm" && d .Get ("wait_for_sync" ) != nil && d .Get ("wait_for_sync" ).(bool ) {
481+ diagnostics , isError := waitForOciEcrRegistrySync (ctx , d , d .Id (), diags , c , schema .TimeoutUpdate )
482+ if len (diagnostics ) > 0 {
483+ diags = append (diags , diagnostics ... )
484+ }
485+ // Fetch final sync status and set wait_for_status_message
486+ registry , statusErr := c .GetOciEcrRegistry (d .Id ())
487+ if statusErr == nil && registry != nil && registry .Status != nil && registry .Status .SyncStatus != nil {
488+ statusMessage := ""
489+ if registry .Status .SyncStatus .Message != "" {
490+ statusMessage = registry .Status .SyncStatus .Message
491+ } else if registry .Status .SyncStatus .Status != "" {
492+ statusMessage = fmt .Sprintf ("Status: %s" , registry .Status .SyncStatus .Status )
493+ }
494+ if err := d .Set ("wait_for_status_message" , statusMessage ); err != nil {
495+ diags = append (diags , diag .FromErr (err )... )
496+ }
497+ }
498+ if isError {
499+ return diagnostics
500+ }
501+ }
454502 case "basic" :
455503 registry := toRegistryBasic (d )
456504 if err := validateRegistryCred (c , registryType , providerType , isSync , registry .Spec , nil ); err != nil {
@@ -733,3 +781,108 @@ func resourceOciRegistrySyncRefreshFunc(c *client.V1Client, uid string) retry.St
733781 }
734782 }
735783}
784+
785+ // waitForOciEcrRegistrySync waits for an OCI ECR registry to complete its synchronization by polling GetOciEcrRegistry.
786+ func waitForOciEcrRegistrySync (ctx context.Context , d * schema.ResourceData , uid string , diags diag.Diagnostics , c * client.V1Client , timeoutType string ) (diag.Diagnostics , bool ) {
787+ stateConf := & retry.StateChangeConf {
788+ Pending : []string {
789+ "InProgress" ,
790+ "Pending" ,
791+ "Unknown" ,
792+ "" ,
793+ },
794+ Target : []string {
795+ "Success" ,
796+ "Completed" ,
797+ },
798+ Refresh : resourceOciEcrRegistrySyncRefreshFunc (c , uid ),
799+ Timeout : d .Timeout (timeoutType ) - 1 * time .Minute ,
800+ MinTimeout : 10 * time .Second ,
801+ Delay : 30 * time .Second ,
802+ }
803+
804+ _ , err := stateConf .WaitForStateContext (ctx )
805+ if err != nil {
806+ var timeoutErr * retry.TimeoutError
807+ if errors .As (err , & timeoutErr ) {
808+ currentStatus := timeoutErr .LastState
809+ statusMessage := ""
810+ registry , statusErr := c .GetOciEcrRegistry (uid )
811+ if statusErr == nil && registry != nil && registry .Status != nil && registry .Status .SyncStatus != nil {
812+ if registry .Status .SyncStatus .Status != "" {
813+ currentStatus = registry .Status .SyncStatus .Status
814+ }
815+ if registry .Status .SyncStatus .Message != "" {
816+ statusMessage = fmt .Sprintf (" Message: %s" , registry .Status .SyncStatus .Message )
817+ }
818+ }
819+ if currentStatus == "" {
820+ currentStatus = "Unknown"
821+ }
822+ diags = append (diags , diag.Diagnostic {
823+ Severity : diag .Warning ,
824+ Summary : "OCI ECR registry sync timeout" ,
825+ Detail : fmt .Sprintf (
826+ "OCI ECR registry synchronization timed out after waiting for %v. Current sync status is '%s'.%s " +
827+ "The registry sync may still be in progress. You may need to increase the timeout or wait for the sync to complete manually." ,
828+ d .Timeout (timeoutType )- 1 * time .Minute , currentStatus , statusMessage ),
829+ })
830+ return diags , false
831+ }
832+
833+ registry , statusErr := c .GetOciEcrRegistry (uid )
834+ if statusErr == nil && registry != nil && registry .Status != nil && registry .Status .SyncStatus != nil {
835+ status := registry .Status .SyncStatus .Status
836+ if status == "Failed" || status == "Error" || status == "failed" || status == "error" {
837+ errorDetail := fmt .Sprintf ("OCI ECR registry synchronization failed with status '%s'." , status )
838+ if registry .Status .SyncStatus .Message != "" {
839+ errorDetail += fmt .Sprintf ("\n \n Error details: %s" , registry .Status .SyncStatus .Message )
840+ }
841+ errorDetail += "\n \n Please check the registry configuration (endpoint, credentials) and try again."
842+ diags = append (diags , diag.Diagnostic {
843+ Severity : diag .Warning ,
844+ Summary : "OCI ECR registry sync failed" ,
845+ Detail : errorDetail ,
846+ })
847+ return diags , false
848+ }
849+ }
850+
851+ return diag .FromErr (err ), true
852+ }
853+ return nil , false
854+ }
855+
856+ // resourceOciEcrRegistrySyncRefreshFunc returns a retry.StateRefreshFunc that checks the sync status of an OCI ECR registry via GetOciEcrRegistry.
857+ func resourceOciEcrRegistrySyncRefreshFunc (c * client.V1Client , uid string ) retry.StateRefreshFunc {
858+ return func () (interface {}, string , error ) {
859+ registry , err := c .GetOciEcrRegistry (uid )
860+ if err != nil {
861+ return nil , "" , err
862+ }
863+ if registry == nil || registry .Status == nil || registry .Status .SyncStatus == nil {
864+ return nil , "" , nil
865+ }
866+ syncStatus := registry .Status .SyncStatus
867+ if ! syncStatus .IsSyncSupported {
868+ return syncStatus , "Success" , nil
869+ }
870+ status := syncStatus .Status
871+ if status == "" {
872+ return syncStatus , "" , nil
873+ }
874+ switch status {
875+ case "Success" , "Completed" , "success" , "completed" :
876+ return syncStatus , "Success" , nil
877+ case "Failed" , "Error" , "failed" , "error" :
878+ if syncStatus .Message != "" {
879+ return syncStatus , status , fmt .Errorf ("registry sync failed: %s" , syncStatus .Message )
880+ }
881+ return syncStatus , status , fmt .Errorf ("registry sync failed" )
882+ case "InProgress" , "Running" , "Syncing" , "inprogress" , "running" , "syncing" :
883+ return syncStatus , "InProgress" , nil
884+ default :
885+ return syncStatus , status , nil
886+ }
887+ }
888+ }
0 commit comments