func()

in internal/loader/configuration_setting_loader.go [212:320]


func (csl *ConfigurationSettingLoader) CreateKeyValueSettings(ctx context.Context, secretReferenceResolver SecretReferenceResolver) (*RawSettings, error) {
	keyValueFilters := GetKeyValueFilters(csl.Spec)
	settingsClient := csl.SettingsClient
	if settingsClient == nil {
		settingsClient = &SelectorSettingsClient{
			selectors: keyValueFilters,
		}
	}
	settingsResponse, err := csl.ExecuteFailoverPolicy(ctx, settingsClient)
	if err != nil {
		return nil, err
	}

	rawSettings := &RawSettings{
		KeyValueSettings:     make(map[string]*string),
		IsJsonContentTypeMap: make(map[string]bool),
		SecretSettings:       make(map[string]corev1.Secret),
		K8sSecrets:           make(map[string]*TargetK8sSecretMetadata),
		KeyValueETags:        settingsResponse.Etags,
	}

	if csl.Spec.Secret != nil {
		rawSettings.K8sSecrets[csl.Spec.Secret.Target.SecretName] = &TargetK8sSecretMetadata{
			Type:                    corev1.SecretTypeOpaque,
			SecretsKeyVaultMetadata: make(map[string]KeyVaultSecretMetadata),
		}
	}

	resolver := secretReferenceResolver

	for _, setting := range settingsResponse.Settings {
		trimmedKey := trimPrefix(*setting.Key, csl.Spec.Configuration.TrimKeyPrefixes)
		if len(trimmedKey) == 0 {
			klog.Warningf("key of the setting '%s' is trimmed to the empty string, just ignore it", *setting.Key)
			continue
		}

		if setting.ContentType == nil {
			rawSettings.KeyValueSettings[trimmedKey] = setting.Value
			rawSettings.IsJsonContentTypeMap[trimmedKey] = false
			continue
		}
		switch *setting.ContentType {
		case FeatureFlagContentType:
			continue // ignore feature flag while getting key value settings
		case SecretReferenceContentType:
			if setting.Value == nil {
				return nil, fmt.Errorf("the value of Key Vault reference '%s' is null", *setting.Key)
			}

			if csl.Spec.Secret == nil {
				return nil, fmt.Errorf("a Key Vault reference is found in App Configuration, but 'spec.secret' was not configured in the Azure App Configuration provider '%s' in namespace '%s'", csl.Name, csl.Namespace)
			}

			var secretType corev1.SecretType = corev1.SecretTypeOpaque
			var err error
			if secretTypeTag, ok := setting.Tags[PreservedSecretTypeTag]; ok {
				secretType, err = parseSecretType(secretTypeTag)
				if err != nil {
					return nil, err
				}
			}

			if resolver == nil {
				if newResolver, err := csl.createSecretReferenceResolver(ctx); err != nil {
					return nil, err
				} else {
					resolver = newResolver
				}
			}

			currentUrl := *setting.Value
			secretMetadata, err := parse(currentUrl)
			if err != nil {
				return nil, err
			}

			secretName := trimmedKey
			// If the secret type is not specified, reside it to the Secret with name specified
			if secretType == corev1.SecretTypeOpaque {
				secretName = csl.Spec.Secret.Target.SecretName
			}

			if _, ok := rawSettings.K8sSecrets[secretName]; !ok {
				rawSettings.K8sSecrets[secretName] = &TargetK8sSecretMetadata{
					Type:                    secretType,
					SecretsKeyVaultMetadata: make(map[string]KeyVaultSecretMetadata),
				}
			}
			rawSettings.K8sSecrets[secretName].SecretsKeyVaultMetadata[trimmedKey] = *secretMetadata
		default:
			rawSettings.KeyValueSettings[trimmedKey] = setting.Value
			rawSettings.IsJsonContentTypeMap[trimmedKey] = isJsonContentType(setting.ContentType)
		}
	}

	// resolve the secret reference settings
	if resolvedSecret, err := csl.ResolveSecretReferences(ctx, rawSettings.K8sSecrets, resolver); err != nil {
		return nil, err
	} else {
		rawSettings.K8sSecrets = resolvedSecret.K8sSecrets
		err = MergeSecret(rawSettings.SecretSettings, resolvedSecret.SecretSettings)
		if err != nil {
			return nil, err
		}
	}

	return rawSettings, nil
}