forked from spinnaker/keel
/
NetworkResolver.kt
102 lines (92 loc) · 3.23 KB
/
NetworkResolver.kt
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
package com.netflix.spinnaker.keel.ec2.resolvers
import com.netflix.spinnaker.keel.api.Locatable
import com.netflix.spinnaker.keel.api.LocationConstants
import com.netflix.spinnaker.keel.api.Resource
import com.netflix.spinnaker.keel.api.SubnetAwareLocations
import com.netflix.spinnaker.keel.api.SubnetAwareRegionSpec
import com.netflix.spinnaker.keel.api.ec2.ApplicationLoadBalancerSpec
import com.netflix.spinnaker.keel.api.ec2.ClassicLoadBalancerSpec
import com.netflix.spinnaker.keel.api.ec2.ClusterSpec
import com.netflix.spinnaker.keel.api.ec2.EC2_APPLICATION_LOAD_BALANCER_V1_1
import com.netflix.spinnaker.keel.api.ec2.EC2_CLASSIC_LOAD_BALANCER_V1
import com.netflix.spinnaker.keel.api.ec2.EC2_CLUSTER_V1
import com.netflix.spinnaker.keel.api.plugins.Resolver
import com.netflix.spinnaker.keel.clouddriver.CloudDriverCache
import org.springframework.stereotype.Component
abstract class NetworkResolver<T : Locatable<SubnetAwareLocations>>(
private val cloudDriverCache: CloudDriverCache
) : Resolver<T> {
protected fun SubnetAwareLocations.withResolvedNetwork(): SubnetAwareLocations {
val resolvedSubnet = subnet ?: LocationConstants.DEFAULT_SUBNET_PURPOSE.format(vpc)
return copy(
vpc = vpc,
subnet = resolvedSubnet,
regions = regions.map { region ->
if (region.availabilityZones.isEmpty()) {
region.copy(
availabilityZones = cloudDriverCache.resolveAvailabilityZones(
account = account,
subnet = resolvedSubnet,
region = region
)
)
} else {
region
}
}.toSet()
)
}
}
@Component
class ClusterNetworkResolver(cloudDriverCache: CloudDriverCache) : NetworkResolver<ClusterSpec>(cloudDriverCache) {
override val supportedKind = EC2_CLUSTER_V1
override fun invoke(resource: Resource<ClusterSpec>): Resource<ClusterSpec> =
resource.run {
copy(
spec = spec.run {
copy(
locations = locations.withResolvedNetwork()
)
}
)
}
}
@Component
class ClassicLoadBalancerNetworkResolver(cloudDriverCache: CloudDriverCache) : NetworkResolver<ClassicLoadBalancerSpec>(cloudDriverCache) {
override val supportedKind = EC2_CLASSIC_LOAD_BALANCER_V1
override fun invoke(resource: Resource<ClassicLoadBalancerSpec>): Resource<ClassicLoadBalancerSpec> =
resource.run {
copy(
spec = spec.run {
copy(
locations = locations.withResolvedNetwork()
)
}
)
}
}
@Component
class ApplicationLoadBalancerNetworkResolver(cloudDriverCache: CloudDriverCache) : NetworkResolver<ApplicationLoadBalancerSpec>(cloudDriverCache) {
override val supportedKind = EC2_APPLICATION_LOAD_BALANCER_V1_1
override fun invoke(resource: Resource<ApplicationLoadBalancerSpec>): Resource<ApplicationLoadBalancerSpec> =
resource.run {
copy(
spec = spec.run {
copy(
locations = locations.withResolvedNetwork()
)
}
)
}
}
private fun CloudDriverCache.resolveAvailabilityZones(
account: String,
subnet: String,
region: SubnetAwareRegionSpec
) =
availabilityZonesBy(
account,
subnetBy(account, region.name, subnet).vpcId,
subnet,
region.name
).toSet()