Skip to content

Commit

Permalink
fix(k8s): skip kubectl diff for container type
Browse files Browse the repository at this point in the history
  • Loading branch information
thsig committed Apr 8, 2019
1 parent f4281af commit 8dfb6a7
Show file tree
Hide file tree
Showing 5 changed files with 32 additions and 28 deletions.
2 changes: 1 addition & 1 deletion garden-service/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -196,4 +196,4 @@
},
"snyk": true,
"gitHead": "b0647221a4d2ff06952bae58000b104215aed922"
}
}
2 changes: 1 addition & 1 deletion garden-service/src/plugins/kubernetes/container/status.ts
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ export async function getContainerServiceStatus(

// FIXME: [objects, matched] and ingresses can be run in parallel
const objects = await createContainerObjects(k8sCtx, service, runtimeContext, hotReload)
const { state, remoteObjects } = await compareDeployedObjects(k8sCtx, api, namespace, objects, log)
const { state, remoteObjects } = await compareDeployedObjects(k8sCtx, api, namespace, objects, log, true)
const ingresses = await getIngresses(service, api, provider)

return {
Expand Down
2 changes: 1 addition & 1 deletion garden-service/src/plugins/kubernetes/helm/status.ts
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ export async function getServiceStatus(
const provider = k8sCtx.provider
const api = new KubeApi(provider.config.context)
const namespace = await getAppNamespace(k8sCtx, provider)
let { state, remoteObjects } = await compareDeployedObjects(k8sCtx, api, namespace, chartResources, log)
let { state, remoteObjects } = await compareDeployedObjects(k8sCtx, api, namespace, chartResources, log, false)
const detail = { remoteObjects }

return {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ async function getServiceStatus(
const api = new KubeApi(context)
const manifests = await getManifests(module)

const { state, remoteObjects } = await compareDeployedObjects(k8sCtx, api, namespace, manifests, log)
const { state, remoteObjects } = await compareDeployedObjects(k8sCtx, api, namespace, manifests, log, false)

return {
state,
Expand Down
52 changes: 28 additions & 24 deletions garden-service/src/plugins/kubernetes/status.ts
Original file line number Diff line number Diff line change
Expand Up @@ -422,6 +422,7 @@ interface ComparisonResult {
*/
export async function compareDeployedObjects(
ctx: KubernetesPluginContext, api: KubeApi, namespace: string, resources: KubernetesResource[], log: LogEntry,
skipDiff: boolean,
): Promise<ComparisonResult> {

// First check if any resources are missing from the cluster.
Expand Down Expand Up @@ -453,33 +454,36 @@ export async function compareDeployedObjects(

// From here, the state can only be "ready" or "outdated", so we proceed to compare the old & new specs.

// First we try using `kubectl diff`, to avoid potential normalization issues (i.e. false negatives). This errors
// with exit code 1 if there is a mismatch, but may also fail with the same exit code for a number of other reasons,
// including the cluster not supporting dry-runs, certain CRDs not supporting dry-runs etc.
const yamlResources = await encodeYamlMulti(resources)
// TODO: The skipDiff parameter is a temporary workaround until we finish implementing diffing in a more reliable way.
if (!skipDiff) {
// First we try using `kubectl diff`, to avoid potential normalization issues (i.e. false negatives). This errors
// with exit code 1 if there is a mismatch, but may also fail with the same exit code for a number of other reasons,
// including the cluster not supporting dry-runs, certain CRDs not supporting dry-runs etc.
const yamlResources = await encodeYamlMulti(resources)

try {
await kubectl(ctx.provider.config.context, namespace)
.call(["diff", "-f", "-"], { data: Buffer.from(yamlResources) })
try {
await kubectl(ctx.provider.config.context, namespace)
.call(["diff", "-f", "-"], { data: Buffer.from(yamlResources) })

// If the commands exits succesfully, the check was successful and the diff is empty.
log.verbose(`kubectl diff indicates all resources match the deployed resources.`)
result.state = "ready"
return result
} catch (err) {
// Exited with non-zero code. Check for error messages on stderr. If one is there, the command was unable to
// complete the check, so we fall back to our own mechanism. Otherwise the command worked, but one or more resources
// are missing or outdated.
if (
!err.detail || !err.detail.result
|| (!!err.detail.result.stderr && err.detail.result.stderr.trim() !== "exit status 1")
) {
log.verbose(`kubectl diff failed: ${err.message}`)
} else {
log.verbose(`kubectl diff indicates one or more resources are outdated.`)
log.silly(err.detail.result.stdout)
result.state = "outdated"
// If the commands exits succesfully, the check was successful and the diff is empty.
log.verbose(`kubectl diff indicates all resources match the deployed resources.`)
result.state = "ready"
return result
} catch (err) {
// Exited with non-zero code. Check for error messages on stderr. If one is there, the command was unable to
// complete the check, so we fall back to our own mechanism. Otherwise the command worked, but one or more
// resources are missing or outdated.
if (
!err.detail || !err.detail.result
|| (!!err.detail.result.stderr && err.detail.result.stderr.trim() !== "exit status 1")
) {
log.verbose(`kubectl diff failed: ${err.message}`)
} else {
log.verbose(`kubectl diff indicates one or more resources are outdated.`)
log.silly(err.detail.result.stdout)
result.state = "outdated"
return result
}
}
}

Expand Down

0 comments on commit 8dfb6a7

Please sign in to comment.