Skip to content

Commit

Permalink
fix(kubernetes): teach deployManifest stages to handle label selector…
Browse files Browse the repository at this point in the history
…s with generateName (#6265)

This fixes:

java.lang.NullPointerException: Cannot invoke "com.netflix.spinnaker.clouddriver.kubernetes.description.manifest.KubernetesManifest.getNamespace()" because "manifest" is null
	at com.netflix.spinnaker.clouddriver.kubernetes.op.OperationResult.addManifest(OperationResult.java:46)
	at com.netflix.spinnaker.clouddriver.kubernetes.op.handler.CanDeploy.deploy(CanDeploy.java:44)
	at com.netflix.spinnaker.clouddriver.kubernetes.op.manifest.KubernetesDeployManifestOperation.lambda$operate$3(KubernetesDeployManifestOperation.java:174)
	at java.base/java.util.ArrayList.forEach(ArrayList.java:1511)
	at com.netflix.spinnaker.clouddriver.kubernetes.op.manifest.KubernetesDeployManifestOperation.operate(KubernetesDeployManifestOperation.java:162)
	at com.netflix.spinnaker.clouddriver.kubernetes.op.manifest.KubernetesDeployManifestOperation.operate(KubernetesDeployManifestOperation.java:48)
	at com.netflix.spinnaker.clouddriver.orchestration.AtomicOperation$operate.call(Unknown Source)
	at com.netflix.spinnaker.clouddriver.orchestration.DefaultOrchestrationProcessor$_process_closure1$_closure2.doCall(DefaultOrchestrationProcessor.groovy:120)
	at com.netflix.spinnaker.clouddriver.orchestration.DefaultOrchestrationProcessor$_process_closure1$_closure2.doCall(DefaultOrchestrationProcessor.groovy)
	at jdk.internal.reflect.GeneratedMethodAccessor373.invoke(Unknown Source)
	at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.base/java.lang.reflect.Method.invoke(Method.java:568)
	at org.codehaus.groovy.reflection.CachedMethod.invoke(CachedMethod.java:107)
	at groovy.lang.MetaMethod.doMethodInvoke(MetaMethod.java:323)
	at org.codehaus.groovy.runtime.metaclass.ClosureMetaClass.invokeMethod(ClosureMetaClass.java:274)
	at groovy.lang.MetaClassImpl.invokeMethod(MetaClassImpl.java:1035)
	at groovy.lang.Closure.call(Closure.java:412)
	at groovy.lang.Closure.call(Closure.java:406)
	at com.netflix.spinnaker.clouddriver.metrics.TimedCallable$CallableWrapper.call(TimedCallable.java:81)
	at com.netflix.spinnaker.clouddriver.metrics.TimedCallable.call(TimedCallable.java:45)
	at java_util_concurrent_Callable$call.call(Unknown Source)
	at com.netflix.spinnaker.clouddriver.orchestration.DefaultOrchestrationProcessor$_process_closure1.doCall(DefaultOrchestrationProcessor.groovy:119)
	at com.netflix.spinnaker.clouddriver.orchestration.DefaultOrchestrationProcessor$_process_closure1.doCall(DefaultOrchestrationProcessor.groovy)
	at jdk.internal.reflect.GeneratedMethodAccessor367.invoke(Unknown Source)
	at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.base/java.lang.reflect.Method.invoke(Method.java:568)
	at org.codehaus.groovy.reflection.CachedMethod.invoke(CachedMethod.java:107)
	at groovy.lang.MetaMethod.doMethodInvoke(MetaMethod.java:323)
	at org.codehaus.groovy.runtime.metaclass.ClosureMetaClass.invokeMethod(ClosureMetaClass.java:274)
	at groovy.lang.MetaClassImpl.invokeMethod(MetaClassImpl.java:1035)
	at groovy.lang.Closure.call(Closure.java:412)
	at groovy.lang.Closure.call(Closure.java:406)
	at com.netflix.spinnaker.security.AuthenticatedRequest.lambda$wrapCallableForPrincipal$0(AuthenticatedRequest.java:272)
	at com.netflix.spinnaker.clouddriver.metrics.TimedCallable.call(TimedCallable.java:45)
	at java.base/java.util.concurrent.FutureTask.run(FutureTask.java:264)
	at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1136)
	at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:635)
	at java.base/java.lang.Thread.run(Thread.java:840)
  • Loading branch information
dbyron-sf authored Aug 16, 2024
1 parent 80f67d6 commit 53606c1
Show file tree
Hide file tree
Showing 2 changed files with 31 additions and 1 deletion.
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,11 @@ default OperationResult deploy(
// require looking up a manifest by name, which will fail.
if (manifest.hasGenerateName()) {
KubernetesManifest result = credentials.create(manifest, task, opName, labelSelectors);
return new OperationResult().addManifest(result);
OperationResult operationResult = new OperationResult();
if (result != null) {
operationResult.addManifest(result);
}
return operationResult;
}

KubernetesManifest deployedManifest;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -267,4 +267,30 @@ void nullManifest() {
verify(credentials).deploy(manifest, task, OP_NAME, selectorList);
assertThat(result.getManifests()).isEmpty();
}

@Test
void nullManifestWithGenerateName() {
KubernetesCredentials credentials = mock(KubernetesCredentials.class);
KubernetesManifest manifest =
ManifestFetcher.getManifest("candeploy/deployment-generate-name.yml");
assertThat(manifest.getGenerateName()).isNotBlank();

KubernetesSelectorList selectorList = new KubernetesSelectorList();
when(credentials.create(manifest, task, OP_NAME, selectorList)).thenReturn(null);

// DeployStrategy.APPLY and ServerSideApplyStrategy.DEFAULT are arbitrary
// too since they're ignored for manifests with generateName.
OperationResult result =
handler.deploy(
credentials,
manifest,
DeployStrategy.APPLY,
ServerSideApplyStrategy.DEFAULT,
task,
OP_NAME,
selectorList);

verify(credentials).create(manifest, task, OP_NAME, selectorList);
assertThat(result.getManifests()).isEmpty();
}
}

0 comments on commit 53606c1

Please sign in to comment.