diff --git a/orca-clouddriver/src/main/groovy/com/netflix/spinnaker/orca/clouddriver/config/tasks/CheckIfApplicationExistsTaskConfig.java b/orca-clouddriver/src/main/groovy/com/netflix/spinnaker/orca/clouddriver/config/tasks/CheckIfApplicationExistsTaskConfig.java index a29c5082cf..98f67011f9 100644 --- a/orca-clouddriver/src/main/groovy/com/netflix/spinnaker/orca/clouddriver/config/tasks/CheckIfApplicationExistsTaskConfig.java +++ b/orca-clouddriver/src/main/groovy/com/netflix/spinnaker/orca/clouddriver/config/tasks/CheckIfApplicationExistsTaskConfig.java @@ -23,6 +23,9 @@ public class CheckIfApplicationExistsTaskConfig { // controls whether clouddriver should be queried for an application or not. Defaults to true boolean checkClouddriver = true; + // controls whether the task should fail or simply log a warning + boolean auditModeEnabled = true; + // front50 specific retry config. This is only applicable when services.front50.enabled: true private RetryConfig front50Retries = new RetryConfig(); diff --git a/orca-clouddriver/src/main/groovy/com/netflix/spinnaker/orca/clouddriver/tasks/AbstractCheckIfApplicationExistsTask.java b/orca-clouddriver/src/main/groovy/com/netflix/spinnaker/orca/clouddriver/tasks/AbstractCheckIfApplicationExistsTask.java index 1bff447a09..816549cd2d 100644 --- a/orca-clouddriver/src/main/groovy/com/netflix/spinnaker/orca/clouddriver/tasks/AbstractCheckIfApplicationExistsTask.java +++ b/orca-clouddriver/src/main/groovy/com/netflix/spinnaker/orca/clouddriver/tasks/AbstractCheckIfApplicationExistsTask.java @@ -46,10 +46,12 @@ *
If the application doesn't exist, the task fails. * *
The motivation for adding such a task is to prevent creation of any ad-hoc applications in - * amazon deployment pipeline stages. Depending on what is the application value set in the moniker - * and/or the cluster keys in such stages, any application that didn't previously exist can be - * created on demand. This can have an adverse effect on the security of such applications since - * these applications aren't created via a controlled process. + * amazon and kubernetes deployment pipeline stages. + * + *
Depending on what is the application value set in the moniker and/or the cluster keys in such
+ * stages, any application that isn't known to front50 can be created by clouddriver on demand. This
+ * can have an adverse effect on the security of such applications since these applications aren't
+ * created via a controlled process.
*/
@Slf4j
@Component
@@ -90,13 +92,27 @@ public TaskResult execute(@Nonnull StageExecution stage) {
log.info("querying clouddriver for application: {}", applicationName);
fetchedApplication = getApplicationFromClouddriver(applicationName);
if (fetchedApplication == null) {
- errorMessage += " and in clouddriver.";
+ errorMessage += " and in clouddriver";
}
}
}
if (fetchedApplication == null) {
- log.error(errorMessage);
- throw new NotFoundException(errorMessage);
+ if (this.config.isAuditModeEnabled()) {
+ String pipelineName = "unknown";
+ if (stage.getParent() != null) {
+ pipelineName = stage.getParent().getName();
+ }
+ log.warn(
+ "Warning: stage: {}, pipeline: {}, message: {}. "
+ + "This will be a terminal failure in the near future.",
+ errorMessage,
+ stage.getName(),
+ pipelineName);
+ outputs.put("checkIfApplicationExistsWarning", errorMessage);
+ } else {
+ log.error(errorMessage);
+ throw new NotFoundException(errorMessage);
+ }
}
return TaskResult.builder(ExecutionStatus.SUCCEEDED).outputs(outputs).build();
}
diff --git a/orca-clouddriver/src/test/java/com/netflix/spinnaker/orca/clouddriver/tasks/servergroup/CheckIfApplicationExistsForServerGroupTaskTest.java b/orca-clouddriver/src/test/java/com/netflix/spinnaker/orca/clouddriver/tasks/servergroup/CheckIfApplicationExistsForServerGroupTaskTest.java
index c123c4a144..aeb05311f7 100644
--- a/orca-clouddriver/src/test/java/com/netflix/spinnaker/orca/clouddriver/tasks/servergroup/CheckIfApplicationExistsForServerGroupTaskTest.java
+++ b/orca-clouddriver/src/test/java/com/netflix/spinnaker/orca/clouddriver/tasks/servergroup/CheckIfApplicationExistsForServerGroupTaskTest.java
@@ -46,7 +46,6 @@
import org.apache.commons.io.IOUtils;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.DisplayName;
-import org.junit.jupiter.api.Test;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.ValueSource;
import org.springframework.http.HttpStatus;
@@ -135,10 +134,14 @@ public void testSuccessfulRetrievalOfApplicationFromClouddriverIfFront50IsDisabl
assertEquals(result.getStatus(), ExecutionStatus.SUCCEEDED);
}
- @Test
- public void testIfApplicationCannotBeRetrievedFromFront50AndCheckClouddriverIsFalse() {
+ @ParameterizedTest
+ @ValueSource(booleans = {true, false})
+ public void testIfApplicationCannotBeRetrievedFromFront50AndCheckClouddriverIsFalse(
+ boolean auditModeEnabled) {
TaskConfigurationProperties configurationProperties = new TaskConfigurationProperties();
configurationProperties.getCheckIfApplicationExistsTask().setCheckClouddriver(false);
+ configurationProperties.getCheckIfApplicationExistsTask().setAuditModeEnabled(auditModeEnabled);
+ final String expectedErrorMessage = "did not find application: testapp in front50";
// setup:
task =
new CheckIfApplicationExistsForServerGroupTask(
@@ -147,22 +150,34 @@ public void testIfApplicationCannotBeRetrievedFromFront50AndCheckClouddriverIsFa
stageExecution.setContext(getStageContext("application"));
// then
- NotFoundException thrown =
- assertThrows(NotFoundException.class, () -> task.execute(stageExecution));
-
- assertThat(thrown.getMessage()).contains("did not find application: testapp in front50");
+ if (auditModeEnabled) {
+ TaskResult result = task.execute(stageExecution);
+ assertEquals(result.getStatus(), ExecutionStatus.SUCCEEDED);
+ assertEquals(
+ expectedErrorMessage, result.getOutputs().get("checkIfApplicationExistsWarning"));
+ } else {
+ NotFoundException thrown =
+ assertThrows(NotFoundException.class, () -> task.execute(stageExecution));
+
+ assertThat(thrown.getMessage()).contains(expectedErrorMessage);
+ }
verifyNoInteractions(front50Service);
verifyNoInteractions(oortService);
}
- @Test
- public void testAnApplicationWhichDoesNotExistInBothFront50AndClouddriver() {
+ @ParameterizedTest
+ @ValueSource(booleans = {true, false})
+ public void testAnApplicationWhichDoesNotExistInBothFront50AndClouddriver(
+ boolean auditModeEnabled) {
// setup:
task =
new CheckIfApplicationExistsForServerGroupTask(
null, oortService, objectMapper, retrySupport, configurationProperties);
+ configurationProperties.getCheckIfApplicationExistsTask().setAuditModeEnabled(auditModeEnabled);
+ final String expectedErrorMessage =
+ "did not find application: invalid app in front50 and in clouddriver";
when(oortService.getApplication("invalid app"))
.thenReturn(
new Response(
@@ -175,13 +190,19 @@ public void testAnApplicationWhichDoesNotExistInBothFront50AndClouddriver() {
Map