Skip to content

Commit

Permalink
WIP
Browse files Browse the repository at this point in the history
  • Loading branch information
nowNick committed Nov 7, 2024
1 parent 84c8c97 commit 73b25d6
Showing 1 changed file with 63 additions and 32 deletions.
95 changes: 63 additions & 32 deletions kong/utils.go
Original file line number Diff line number Diff line change
Expand Up @@ -924,44 +924,38 @@ func clearUnmatchingDeprecationsForGivenPath(
}
}

// same as ClearUnmatchingDeprecations but this function below is adjusted for recursive use (which is required
// when the schema contains nested records and they can have nested shorthands).
func clearUnmatchingDeprecationsHelper(
// clearCurrentLevelUnmatchingDeprecations compares the new and old plugin configurations to handle deprecated fields.
// For each deprecated field in the new configuration, it checks whether the corresponding field is present in
// the old configuration, and adjusts the old configuration if necessary. If the deprecated field is missing
// from the new configuration, it deletes it from the old configuration for consistency.
//
// Parameters:
//
// newPluginConfig - The updated configuration containing potential deprecated fields.
// oldPluginConfig - The original configuration that may contain deprecated fields.
// schema - A JSON schema representing the structure of the configuration, including deprecated fields.
//
// This function mutates the oldPluginConfig to align with the newPluginConfig in regard to deprecated fields.
func clearCurrentLevelUnmatchingDeprecations(
newPluginConfig Configuration,
oldPluginConfig Configuration,
schema *gjson.Result,
) {
configFields := schema.Get("fields")
// Fetch deprecated fields
shortHandFields := schema.Get("shorthand_fields")

shortHandFields.ForEach(func(_, value gjson.Result) bool {
field := value.Map()
for deprecatedFieldName, shorthandFieldConfig := range field {
if deprecatedFieldValue, ok := newPluginConfig[deprecatedFieldName]; ok {
replacements := shorthandFieldConfig.Get("deprecation.replaced_with.#.path")
// The new plugin configuration contains deprecated field. Verify if the oldPluginConfiguration needs
// to be adjusted in order to match newPluginConfiguration.
//
// Determine if we accept `null` values based on the deprecated field:
acceptNullValue := deprecatedFieldValue == nil
if replacements.Exists() {
replacements.ForEach(func(_, value gjson.Result) bool {
replacementPathAsStringArray := readStringArray(value)

clearUnmatchingDeprecationsForGivenPath(replacementPathAsStringArray,
newPluginConfig, oldPluginConfig, acceptNullValue)

return true
})
} else {
// for Kong 3.6 we don't have `"deprecation.replaced_with.#.path"`
// we need to fallback to `.translate_backwards` instead
backwardsTranslation := shorthandFieldConfig.Get("translate_backwards")
if backwardsTranslation.Exists() {
replacementPathAsStringArray := readStringArray(backwardsTranslation)
clearUnmatchingDeprecationsForGivenPath(replacementPathAsStringArray,
newPluginConfig, oldPluginConfig, acceptNullValue)
}
for _, path := range parseReplacedWithPaths(shorthandFieldConfig) {
clearUnmatchingDeprecationsForGivenPath(path, newPluginConfig, oldPluginConfig, acceptNullValue)
}

} else {
// The new plugin configuration does not contain deprecated fields.
// However, for backwards compatibility, Kong sends deprecated fields in the response.
Expand All @@ -973,24 +967,43 @@ func clearUnmatchingDeprecationsHelper(

return true
})
}

// traverseConfigurationsAndExecute iterates over the fields in two plugin configurations (configA and configB),
// and executes the provided function 'f' on nested fields of type "record" that exist in both configurations.
//
// Parameters:
//
// configA - The first configuration to compare.
// configB - The second configuration to compare.
// schema - The schema describing the fields of the configurations.
// f - A function that will be executed on each pair of matching nested fields of type "record" in configA and configB.
//
// This function supports recursively processing nested configuration records and applies the function 'f' to them.
func traverseConfigurationsAndExecute(
configA Configuration,
configB Configuration,
schema *gjson.Result,
f func(Configuration, Configuration, *gjson.Result),
) {
configFields := schema.Get("fields")
configFields.ForEach(func(_, value gjson.Result) bool {
field := value.Map()

for fieldName, fieldConfig := range field {
if fieldType := fieldConfig.Get("type"); fieldType.String() == "record" {
var nestedNewPluginConfig map[string]interface{}
if f, ok := newPluginConfig[fieldName].(map[string]interface{}); ok {
nestedNewPluginConfig = f
var nestedConfigA map[string]interface{}
if fieldA, ok := configA[fieldName].(map[string]interface{}); ok {
nestedConfigA = fieldA
}

var nestedOldPluginConfig map[string]interface{}
if f, ok := oldPluginConfig[fieldName].(map[string]interface{}); ok {
nestedOldPluginConfig = f
var nestedConfigB map[string]interface{}
if fieldB, ok := configB[fieldName].(map[string]interface{}); ok {
nestedConfigB = fieldB
}

if nestedNewPluginConfig != nil && nestedOldPluginConfig != nil {
clearUnmatchingDeprecationsHelper(nestedNewPluginConfig, nestedOldPluginConfig, &fieldConfig)
if nestedConfigA != nil && nestedConfigB != nil {
f(nestedConfigA, nestedConfigB, &fieldConfig)
}
}
}
Expand All @@ -999,6 +1012,24 @@ func clearUnmatchingDeprecationsHelper(
})
}

// same as ClearUnmatchingDeprecations but this function below is adjusted for recursive use (which is required
// when the schema contains nested records and they can have nested shorthands).
func clearUnmatchingDeprecationsHelper(
newPluginConfig Configuration,
oldPluginConfig Configuration,
schema *gjson.Result,
) {
clearCurrentLevelUnmatchingDeprecations(newPluginConfig, oldPluginConfig, schema)

// Recursively walk through configuration to clear any nested unmatching deprecations.
traverseConfigurationsAndExecute(
newPluginConfig,
oldPluginConfig,
schema,
clearUnmatchingDeprecationsHelper,
)
}

// ClearUnmatchingDeprecations is a function that go through a pair of
// configurations: newPlugin and oldPlugin, and by using schema it makes sure those two configurations
// are aligned.
Expand Down

0 comments on commit 73b25d6

Please sign in to comment.