Skip to content

Commit

Permalink
fix(k8s): handle normalization issue between numbers and strings in d…
Browse files Browse the repository at this point in the history
…iffs

Also improved the display of diffs when verbose logging, to make these
types of issues a little easier to debug.
  • Loading branch information
edvald committed Jun 5, 2019
1 parent ebcc54a commit d98ed6f
Show file tree
Hide file tree
Showing 4 changed files with 63 additions and 9 deletions.
52 changes: 52 additions & 0 deletions garden-service/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions garden-service/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@
"inquirer": "^6.3.1",
"joi": "^14.3.1",
"js-yaml": "^3.13.1",
"json-diff": "^0.5.4",
"json-merge-patch": "^0.2.3",
"json-stable-stringify": "^1.0.1",
"json-stringify-safe": "^5.0.1",
Expand Down
15 changes: 8 additions & 7 deletions garden-service/src/plugins/kubernetes/status.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,11 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*/

import { diffString } from "json-diff"
import { DeploymentError } from "../../exceptions"
import { PluginContext } from "../../plugin-context"
import { ServiceState, combineStates } from "../../types/service"
import { sleep, encodeYamlMulti } from "../../util/util"
import { sleep, encodeYamlMulti, deepMap } from "../../util/util"
import { KubeApi, KubernetesError } from "./api"
import { KUBECTL_DEFAULT_TIMEOUT, kubectl } from "./kubectl"
import { getAppNamespace } from "./namespace"
Expand Down Expand Up @@ -511,6 +512,10 @@ export async function compareDeployedObjects(
log.verbose(`Comparing expected and deployed resources...`)

for (let [newSpec, existingSpec] of zip(resources, deployedObjects) as KubernetesResource[][]) {
// to avoid normalization issues, we convert all numeric values to strings and then compare
newSpec = <KubernetesResource>deepMap(newSpec, v => typeof v === "number" ? v.toString() : v)
existingSpec = <KubernetesResource>deepMap(existingSpec, v => typeof v === "number" ? v.toString() : v)

// the API version may implicitly change when deploying
existingSpec.apiVersion = newSpec.apiVersion

Expand Down Expand Up @@ -546,12 +551,8 @@ export async function compareDeployedObjects(

if (!isSubset(existingSpec, newSpec)) {
if (newSpec) {
log.silly(`Resource ${newSpec.metadata.name} is not a superset of deployed resource`)
log.silly("----------------- Expected: -----------------------")
log.silly(JSON.stringify(newSpec, null, 4))
log.silly("------------------Deployed: -----------------------")
log.silly(JSON.stringify(existingSpec, null, 4))
log.silly("---------------------------------------------------")
log.verbose(`Resource ${newSpec.metadata.name} is not a superset of deployed resource:`)
log.verbose(diffString(existingSpec, newSpec))
}
// console.log(JSON.stringify(obj, null, 4))
// console.log(JSON.stringify(existingSpec, null, 4))
Expand Down
4 changes: 2 additions & 2 deletions garden-service/src/util/util.ts
Original file line number Diff line number Diff line change
Expand Up @@ -236,11 +236,11 @@ export function deepMap<T extends object, U extends object = T>(
value: T | Iterable<T>, fn: (value: any, key: string | number) => any,
): U | Iterable<U> {
if (isArray(value)) {
return value.map(fn)
return value.map(v => <U>deepMap(v, fn))
} else if (isPlainObject(value)) {
return <U>mapValues(value, v => deepMap(v, fn))
} else {
return <U>value
return <U>fn(value, 0)
}
}

Expand Down

0 comments on commit d98ed6f

Please sign in to comment.