@@ -385,6 +385,7 @@ func (azappcfg *AzureAppConfiguration) loadKeyValues(ctx context.Context, settin
385385 var useAIConfiguration , useAIChatCompletionConfiguration bool
386386 kvSettings := make (map [string ]any , len (settingsResponse .settings ))
387387 keyVaultRefs := make (map [string ]string )
388+ snapshotRefs := make (map [string ]string )
388389 for trimmedKey , setting := range rawSettings {
389390 if setting .ContentType == nil || setting .Value == nil {
390391 kvSettings [trimmedKey ] = setting .Value
@@ -396,6 +397,9 @@ func (azappcfg *AzureAppConfiguration) loadKeyValues(ctx context.Context, settin
396397 continue // ignore feature flag while getting key value settings
397398 case secretReferenceContentType :
398399 keyVaultRefs [trimmedKey ] = * setting .Value
400+ case snapshotReferenceContentType :
401+ snapshotRefs [trimmedKey ] = * setting .Value
402+ azappcfg .tracingOptions .UseSnapshotReference = true
399403 default :
400404 if isJsonContentType (setting .ContentType ) {
401405 var v any
@@ -424,6 +428,10 @@ func (azappcfg *AzureAppConfiguration) loadKeyValues(ctx context.Context, settin
424428 azappcfg .tracingOptions .UseAIConfiguration = useAIConfiguration
425429 azappcfg .tracingOptions .UseAIChatCompletionConfiguration = useAIChatCompletionConfiguration
426430
431+ if err := azappcfg .loadSettingsFromSnapshotRefs (ctx , settingsClient , snapshotRefs , kvSettings , keyVaultRefs ); err != nil {
432+ return err
433+ }
434+
427435 secrets , err := azappcfg .loadKeyVaultSecrets (ctx , keyVaultRefs )
428436 if err != nil {
429437 return fmt .Errorf ("failed to load Key Vault secrets: %w" , err )
@@ -437,6 +445,58 @@ func (azappcfg *AzureAppConfiguration) loadKeyValues(ctx context.Context, settin
437445 return nil
438446}
439447
448+ func (azappcfg * AzureAppConfiguration ) loadSettingsFromSnapshotRefs (ctx context.Context , settingsClient settingsClient , snapshotRefs map [string ]string , kvSettings map [string ]any , keyVaultRefs map [string ]string ) error {
449+ for key , snapshotRef := range snapshotRefs {
450+ // Parse the snapshot reference
451+ snapshotName , err := parseSnapshotReference (snapshotRef )
452+ if err != nil {
453+ return fmt .Errorf ("invalid format for Snapshot reference setting %s: %w" , key , err )
454+ }
455+
456+ if client , ok := settingsClient .(* selectorSettingsClient ); ok {
457+ // Load the snapshot settings
458+ settingsFromSnapshot , err := loadSnapshotSettings (ctx , client .client , snapshotName )
459+ if err != nil {
460+ return fmt .Errorf ("failed to load snapshot settings: key=%s, error=%s" , key , err .Error ())
461+ }
462+
463+ for _ , setting := range settingsFromSnapshot {
464+ if setting .ContentType == nil || setting .Value == nil || setting .Key == nil {
465+ continue
466+ }
467+
468+ if * setting .ContentType == featureFlagContentType {
469+ continue
470+ }
471+
472+ if * setting .ContentType == secretReferenceContentType {
473+ keyVaultRefs [* setting .Key ] = * setting .Value
474+ continue
475+ }
476+
477+ // Handle JSON content types (similar to regular key-value loading)
478+ if isJsonContentType (setting .ContentType ) {
479+ var v any
480+ if err := json .Unmarshal ([]byte (* setting .Value ), & v ); err != nil {
481+ // If the value is not valid JSON, try to remove comments and parse again
482+ if err := json .Unmarshal (jsonc .StripComments ([]byte (* setting .Value )), & v ); err != nil {
483+ // If still invalid, log the error and treat it as a plain string
484+ log .Printf ("Failed to unmarshal JSON value from snapshot: key=%s, error=%s" , * setting .Key , err .Error ())
485+ kvSettings [* setting .Key ] = setting .Value
486+ continue
487+ }
488+ }
489+ kvSettings [* setting .Key ] = v
490+ } else {
491+ kvSettings [* setting .Key ] = setting .Value
492+ }
493+ }
494+ }
495+ }
496+
497+ return nil
498+ }
499+
440500func (azappcfg * AzureAppConfiguration ) loadKeyVaultSecrets (ctx context.Context , keyVaultRefs map [string ]string ) (map [string ]any , error ) {
441501 secrets := make (map [string ]any )
442502 if len (keyVaultRefs ) == 0 {
@@ -1019,3 +1079,20 @@ func isFailoverable(err error) bool {
10191079
10201080 return false
10211081}
1082+
1083+ // "{\"snapshot_name\":\"referenced-snapshot\"}"
1084+ func parseSnapshotReference (ref string ) (string , error ) {
1085+ var snapshotRef struct {
1086+ SnapshotName string `json:"snapshot_name"`
1087+ }
1088+
1089+ if err := json .Unmarshal ([]byte (ref ), & snapshotRef ); err != nil {
1090+ return "" , fmt .Errorf ("failed to parse snapshot reference: %w" , err )
1091+ }
1092+
1093+ if snapshotRef .SnapshotName == "" {
1094+ return "" , fmt .Errorf ("snapshot_name is empty in snapshot reference" )
1095+ }
1096+
1097+ return snapshotRef .SnapshotName , nil
1098+ }
0 commit comments