fix(google): differentiate among autohealing health check kinds
MODIFY
clouddriver-google/src/main/groovy/com/netflix/spinnaker/clouddriver/google/deploy/GCEUtil.groovy
clouddriver-google/src/main/groovy/com/netflix/spinnaker/clouddriver/google/deploy/GCEUtil.groovy
@@ -272,28 +272,28 @@ class GCEUtil {
static def queryHealthCheck(String projectName,
String account,
String healthCheckName,
+ GoogleHealthCheck.HealthCheckKind healthCheckKind,
Compute compute,
Cache cacheView,
Task task,
String phase,
GoogleExecutorTraits executor) {
- task.updateStatus phase, "Looking up http(s) health check $healthCheckName..."
-
- def httpHealthCheckIdentifiers = cacheView.filterIdentifiers(HTTP_HEALTH_CHECKS.ns, Keys.getHttpHealthCheckKey(account, healthCheckName))
- def results = cacheView.getAll(HTTP_HEALTH_CHECKS.ns, httpHealthCheckIdentifiers, RelationshipCacheFilter.none())
+ task.updateStatus phase, "Looking up health check $healthCheckName..."
- if (results[0]?.attributes?.httpHealthCheck) {
- return results[0]?.attributes?.httpHealthCheck
- } else {
- try {
- // TODO(duftler): Update this to use the cache instead of a live call once we are caching https health checks.
- return executor.timeExecute(
- compute.httpsHealthChecks().get(projectName, healthCheckName),
- "compute.httpsHealthChecks.get",
- executor.TAG_SCOPE, executor.SCOPE_GLOBAL)
- } catch (GoogleJsonResponseException | SocketTimeoutException | SocketException _) {
- updateStatusAndThrowNotFoundException("Http(s) health check $healthCheckName not found.", task, phase)
- }
+ switch (healthCheckKind) {
+ case GoogleHealthCheck.HealthCheckKind.healthCheck:
+ return queryNestedHealthCheck(projectName, account, healthCheckName, compute, cacheView, task, phase, executor)
+ case GoogleHealthCheck.HealthCheckKind.httpHealthCheck:
+ return queryLegacyHttpHealthCheck(account, healthCheckName, cacheView, task, phase)
+ case GoogleHealthCheck.HealthCheckKind.httpsHealthCheck:
+ return queryLegacyHttpsHealthCheck(projectName, healthCheckName, compute, task, phase, executor)
+ default:
+ // Note: Cache queries for these health checks must occur in this order since queryLegacyHttpsHealthCheck() will make a live
+ // call that fails on a missing health check.
+ // todo(mneterval): return null instead of querying for each type once all health check payloads include `healthCheckKind`
+ return queryNestedHealthCheck(projectName, account, healthCheckName, compute, cacheView, task, phase, executor) ?:
+ queryLegacyHttpHealthCheck(account, healthCheckName, cacheView, task, phase) ?:
+ queryLegacyHttpsHealthCheck(projectName, healthCheckName, compute, task, phase, executor)
}
}
@@ -313,6 +313,36 @@ class GCEUtil {
return results[0]?.attributes?.healthCheck
}
+ static def queryLegacyHttpHealthCheck(String account,
+ String healthCheckName,
+ Cache cacheView,
+ Task task,
+ String phase) {
+ task.updateStatus phase, "Looking up http health check $healthCheckName..."
+
+ def httpHealthCheckIdentifiers = cacheView.filterIdentifiers(HTTP_HEALTH_CHECKS.ns, Keys.getHttpHealthCheckKey(account, healthCheckName))
+ def results = cacheView.getAll(HTTP_HEALTH_CHECKS.ns, httpHealthCheckIdentifiers, RelationshipCacheFilter.none())
+ return results[0]?.attributes?.httpHealthCheck
+ }
+
+ static def queryLegacyHttpsHealthCheck(String projectName,
+ String healthCheckName,
+ Compute compute,
+ Task task,
+ String phase,
+ GoogleExecutorTraits executor) {
+ task.updateStatus phase, "Looking up https health check $healthCheckName..."
+ try {
+ // TODO(duftler): Update this to use the cache instead of a live call once we are caching https health checks.
+ return executor.timeExecute(
+ compute.httpsHealthChecks().get(projectName, healthCheckName),
+ "compute.httpsHealthChecks.get",
+ executor.TAG_SCOPE, executor.SCOPE_GLOBAL)
+ } catch (GoogleJsonResponseException | SocketTimeoutException | SocketException _) {
+ updateStatusAndThrowNotFoundException("Https health check $healthCheckName not found.", task, phase)
+ }
+ }
+
static List<ForwardingRule> queryRegionalForwardingRules(String projectName,
String region,
List<String> forwardingRuleNames,

MODIFY
clouddriver-google/src/main/groovy/com/netflix/spinnaker/clouddriver/google/deploy/handlers/BasicGoogleDeployHandler.groovy
clouddriver-google/src/main/groovy/com/netflix/spinnaker/clouddriver/google/deploy/handlers/BasicGoogleDeployHandler.groovy
@@ -396,12 +396,9 @@ class BasicGoogleDeployHandler implements DeployHandler<BasicGoogleDeployDescrip
description.autoscalingPolicy = GCEUtil.buildAutoscalingPolicyDescriptionFromAutoscalingPolicy(ancestorServerGroup.autoscalingPolicy)
}
- // Note: Cache queries for these health checks must occur in this order since queryHealthCheck() will make a live
- // call that fails on a missing health check.
def autoHealingHealthCheck = null
if (description.autoHealingPolicy?.healthCheck) {
- autoHealingHealthCheck = GCEUtil.queryNestedHealthCheck(project, description.accountName, description.autoHealingPolicy.healthCheck, compute, cacheView, task, BASE_PHASE, this) ?:
- GCEUtil.queryHealthCheck(project, description.accountName, description.autoHealingPolicy.healthCheck, compute, cacheView, task, BASE_PHASE, this)
+ autoHealingHealthCheck = GCEUtil.queryHealthCheck(project, description.accountName, description.autoHealingPolicy.healthCheck, description.autoHealingPolicy.healthCheckKind, compute, cacheView, task, BASE_PHASE, this)
}
List<InstanceGroupManagerAutoHealingPolicy> autoHealingPolicy =

MODIFY
clouddriver-google/src/main/groovy/com/netflix/spinnaker/clouddriver/google/deploy/ops/UpsertGoogleAutoscalingPolicyAtomicOperation.groovy
clouddriver-google/src/main/groovy/com/netflix/spinnaker/clouddriver/google/deploy/ops/UpsertGoogleAutoscalingPolicyAtomicOperation.groovy
@@ -249,7 +249,7 @@ class UpsertGoogleAutoscalingPolicyAtomicOperation extends GoogleAtomicOperation
return newDescription
}
- ["healthCheck", "initialDelaySec"].each {
+ ["healthCheck", "initialDelaySec", "healthCheckKind"].each {
if (update[it] != null) {
newDescription[it] = update[it]
}
@@ -278,10 +278,7 @@ class UpsertGoogleAutoscalingPolicyAtomicOperation extends GoogleAtomicOperation
}
private buildAutoHealingPolicyFromAutoHealingPolicyDescription(GoogleAutoHealingPolicy autoHealingPolicyDescription, String project, Compute compute) {
- // Note: Cache queries for these health checks must occur in this order since queryHealthCheck() will make a live
- // call that fails on a missing health check.
- def autoHealingHealthCheck = GCEUtil.queryNestedHealthCheck(project, description.accountName, autoHealingPolicyDescription.healthCheck, compute, cacheView, task, BASE_PHASE, this) ?:
- GCEUtil.queryHealthCheck(project, description.accountName, autoHealingPolicyDescription.healthCheck, compute, cacheView, task, BASE_PHASE, this)
+ def autoHealingHealthCheck = GCEUtil.queryHealthCheck(project, description.accountName, autoHealingPolicyDescription.healthCheck, autoHealingPolicyDescription.healthCheckKind, compute, cacheView, task, BASE_PHASE, this)
List<InstanceGroupManagerAutoHealingPolicy> autoHealingPolicy = autoHealingPolicyDescription?.healthCheck
? [new InstanceGroupManagerAutoHealingPolicy(

MODIFY
clouddriver-google/src/main/groovy/com/netflix/spinnaker/clouddriver/google/model/GoogleAutoHealingPolicy.groovy
clouddriver-google/src/main/groovy/com/netflix/spinnaker/clouddriver/google/model/GoogleAutoHealingPolicy.groovy
@@ -25,6 +25,7 @@ import groovy.transform.ToString
@ToString(includeNames = true)
class GoogleAutoHealingPolicy {
String healthCheck
+ GoogleHealthCheck.HealthCheckKind healthCheckKind
Integer initialDelaySec
FixedOrPercent maxUnavailable

fix(google): differentiate among autohealing health check kinds (#3282)