mirror of https://github.com/kubernetes/kops.git
Merge pull request #10872 from timothyclarke/feature/NLB-EIP
Adding Elastic IP Allocations to NLB API
This commit is contained in:
commit
a424958e83
|
|
@ -97,6 +97,9 @@ func (m *MockELBV2) CreateLoadBalancer(request *elbv2.CreateLoadBalancerInput) (
|
||||||
if subnetMapping.PrivateIPv4Address != nil {
|
if subnetMapping.PrivateIPv4Address != nil {
|
||||||
lbAddrs = append(lbAddrs, &elbv2.LoadBalancerAddress{PrivateIPv4Address: subnetMapping.PrivateIPv4Address})
|
lbAddrs = append(lbAddrs, &elbv2.LoadBalancerAddress{PrivateIPv4Address: subnetMapping.PrivateIPv4Address})
|
||||||
}
|
}
|
||||||
|
if subnetMapping.AllocationId != nil {
|
||||||
|
lbAddrs = append(lbAddrs, &elbv2.LoadBalancerAddress{AllocationId: subnetMapping.AllocationId})
|
||||||
|
}
|
||||||
zones = append(zones, &elbv2.AvailabilityZone{
|
zones = append(zones, &elbv2.AvailabilityZone{
|
||||||
SubnetId: subnetMapping.SubnetId,
|
SubnetId: subnetMapping.SubnetId,
|
||||||
LoadBalancerAddresses: lbAddrs,
|
LoadBalancerAddresses: lbAddrs,
|
||||||
|
|
|
||||||
|
|
@ -137,6 +137,19 @@ spec:
|
||||||
|
|
||||||
The specified IPv4 addresses must be part of the subnets CIDR. They can not be changed after initial deployment.
|
The specified IPv4 addresses must be part of the subnets CIDR. They can not be changed after initial deployment.
|
||||||
|
|
||||||
|
If the `type` is `Public` and the `class` is `Network`, you can also specify an Elastic IP allocationID to bind a fixed public IP address per subnet. Pleae note only IPv4 addresses have been tested:
|
||||||
|
```yaml
|
||||||
|
spec:
|
||||||
|
api:
|
||||||
|
loadBalancer:
|
||||||
|
type: Public
|
||||||
|
subnets:
|
||||||
|
- name: utility-subnet-a
|
||||||
|
allocationID: eipalloc-222ghi789
|
||||||
|
```
|
||||||
|
|
||||||
|
The specified Allocation ID's must already be created manually or external infrastructure as code, eg Terraform. You will need to place the loadBalanacer in the utility subnets for external connectivity.
|
||||||
|
|
||||||
If you made a mistake or need to change subnets for any other reason, you're currently forced to manually delete the
|
If you made a mistake or need to change subnets for any other reason, you're currently forced to manually delete the
|
||||||
underlying ELB/NLB and re-run `kops update`.
|
underlying ELB/NLB and re-run `kops update`.
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -119,6 +119,10 @@ spec:
|
||||||
description: LoadBalancerSubnetSpec provides configuration
|
description: LoadBalancerSubnetSpec provides configuration
|
||||||
for subnets used for a load balancer
|
for subnets used for a load balancer
|
||||||
properties:
|
properties:
|
||||||
|
allocationId:
|
||||||
|
description: AllocationID specifies the Elastic IP Allocation
|
||||||
|
ID for use by a NLB
|
||||||
|
type: string
|
||||||
name:
|
name:
|
||||||
description: Name specifies the name of the cluster
|
description: Name specifies the name of the cluster
|
||||||
subnet
|
subnet
|
||||||
|
|
|
||||||
|
|
@ -383,6 +383,8 @@ type LoadBalancerSubnetSpec struct {
|
||||||
Name string `json:"name,omitempty"`
|
Name string `json:"name,omitempty"`
|
||||||
// PrivateIPv4Address specifies the private IPv4 address to use for a NLB
|
// PrivateIPv4Address specifies the private IPv4 address to use for a NLB
|
||||||
PrivateIPv4Address *string `json:"privateIPv4Address,omitempty"`
|
PrivateIPv4Address *string `json:"privateIPv4Address,omitempty"`
|
||||||
|
// AllocationID specifies the Elastic IP Allocation ID for use by a NLB
|
||||||
|
AllocationID *string `json:"allocationId,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// LoadBalancerAccessSpec provides configuration details related to API LoadBalancer and its access
|
// LoadBalancerAccessSpec provides configuration details related to API LoadBalancer and its access
|
||||||
|
|
|
||||||
|
|
@ -385,6 +385,8 @@ type LoadBalancerSubnetSpec struct {
|
||||||
Name string `json:"name,omitempty"`
|
Name string `json:"name,omitempty"`
|
||||||
// PrivateIPv4Address specifies the private IPv4 address to use for a NLB
|
// PrivateIPv4Address specifies the private IPv4 address to use for a NLB
|
||||||
PrivateIPv4Address *string `json:"privateIPv4Address,omitempty"`
|
PrivateIPv4Address *string `json:"privateIPv4Address,omitempty"`
|
||||||
|
// AllocationID specifies the Elastic IP Allocation ID for use by a NLB
|
||||||
|
AllocationID *string `json:"allocationId,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// LoadBalancerAccessSpec provides configuration details related to API LoadBalancer and its access
|
// LoadBalancerAccessSpec provides configuration details related to API LoadBalancer and its access
|
||||||
|
|
|
||||||
|
|
@ -5183,6 +5183,7 @@ func Convert_kops_LoadBalancerAccessSpec_To_v1alpha2_LoadBalancerAccessSpec(in *
|
||||||
func autoConvert_v1alpha2_LoadBalancerSubnetSpec_To_kops_LoadBalancerSubnetSpec(in *LoadBalancerSubnetSpec, out *kops.LoadBalancerSubnetSpec, s conversion.Scope) error {
|
func autoConvert_v1alpha2_LoadBalancerSubnetSpec_To_kops_LoadBalancerSubnetSpec(in *LoadBalancerSubnetSpec, out *kops.LoadBalancerSubnetSpec, s conversion.Scope) error {
|
||||||
out.Name = in.Name
|
out.Name = in.Name
|
||||||
out.PrivateIPv4Address = in.PrivateIPv4Address
|
out.PrivateIPv4Address = in.PrivateIPv4Address
|
||||||
|
out.AllocationID = in.AllocationID
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -5194,6 +5195,7 @@ func Convert_v1alpha2_LoadBalancerSubnetSpec_To_kops_LoadBalancerSubnetSpec(in *
|
||||||
func autoConvert_kops_LoadBalancerSubnetSpec_To_v1alpha2_LoadBalancerSubnetSpec(in *kops.LoadBalancerSubnetSpec, out *LoadBalancerSubnetSpec, s conversion.Scope) error {
|
func autoConvert_kops_LoadBalancerSubnetSpec_To_v1alpha2_LoadBalancerSubnetSpec(in *kops.LoadBalancerSubnetSpec, out *LoadBalancerSubnetSpec, s conversion.Scope) error {
|
||||||
out.Name = in.Name
|
out.Name = in.Name
|
||||||
out.PrivateIPv4Address = in.PrivateIPv4Address
|
out.PrivateIPv4Address = in.PrivateIPv4Address
|
||||||
|
out.AllocationID = in.AllocationID
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -3503,6 +3503,11 @@ func (in *LoadBalancerSubnetSpec) DeepCopyInto(out *LoadBalancerSubnetSpec) {
|
||||||
*out = new(string)
|
*out = new(string)
|
||||||
**out = **in
|
**out = **in
|
||||||
}
|
}
|
||||||
|
if in.AllocationID != nil {
|
||||||
|
in, out := &in.AllocationID, &out.AllocationID
|
||||||
|
*out = new(string)
|
||||||
|
**out = **in
|
||||||
|
}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -263,6 +263,16 @@ func awsValidateLoadBalancerSubnets(fieldPath *field.Path, spec kops.ClusterSpec
|
||||||
allErrs = append(allErrs, field.Forbidden(fieldPath.Index(i).Child("privateIPv4Address"), "privateIPv4Address only allowed for internal NLBs"))
|
allErrs = append(allErrs, field.Forbidden(fieldPath.Index(i).Child("privateIPv4Address"), "privateIPv4Address only allowed for internal NLBs"))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if subnet.AllocationID != nil {
|
||||||
|
if *subnet.AllocationID == "" {
|
||||||
|
allErrs = append(allErrs, field.Required(fieldPath.Index(i).Child("allocationID"), "allocationID can't be empty"))
|
||||||
|
}
|
||||||
|
|
||||||
|
if lbSpec.Class != kops.LoadBalancerClassNetwork || lbSpec.Type == kops.LoadBalancerTypeInternal {
|
||||||
|
allErrs = append(allErrs, field.Forbidden(fieldPath.Index(i).Child("allocationID"), "allocationID only allowed for Public NLBs"))
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return allErrs
|
return allErrs
|
||||||
|
|
|
||||||
|
|
@ -352,16 +352,18 @@ func TestLoadBalancerSubnets(t *testing.T) {
|
||||||
lbSubnets []kops.LoadBalancerSubnetSpec
|
lbSubnets []kops.LoadBalancerSubnetSpec
|
||||||
expected []string
|
expected []string
|
||||||
}{
|
}{
|
||||||
{ // valid (no privateIPv4Address)
|
{ // valid (no privateIPv4Address, no allocationID)
|
||||||
clusterSubnets: []string{"a", "b", "c"},
|
clusterSubnets: []string{"a", "b", "c"},
|
||||||
lbSubnets: []kops.LoadBalancerSubnetSpec{
|
lbSubnets: []kops.LoadBalancerSubnetSpec{
|
||||||
{
|
{
|
||||||
Name: "a",
|
Name: "a",
|
||||||
PrivateIPv4Address: nil,
|
PrivateIPv4Address: nil,
|
||||||
|
AllocationID: nil,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
Name: "b",
|
Name: "b",
|
||||||
PrivateIPv4Address: nil,
|
PrivateIPv4Address: nil,
|
||||||
|
AllocationID: nil,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|
@ -371,10 +373,12 @@ func TestLoadBalancerSubnets(t *testing.T) {
|
||||||
{
|
{
|
||||||
Name: "a",
|
Name: "a",
|
||||||
PrivateIPv4Address: fi.String("10.0.0.10"),
|
PrivateIPv4Address: fi.String("10.0.0.10"),
|
||||||
|
AllocationID: nil,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
Name: "b",
|
Name: "b",
|
||||||
PrivateIPv4Address: nil,
|
PrivateIPv4Address: nil,
|
||||||
|
AllocationID: nil,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|
@ -384,6 +388,7 @@ func TestLoadBalancerSubnets(t *testing.T) {
|
||||||
{
|
{
|
||||||
Name: "",
|
Name: "",
|
||||||
PrivateIPv4Address: nil,
|
PrivateIPv4Address: nil,
|
||||||
|
AllocationID: nil,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
expected: []string{"Required value::spec.api.loadBalancer.subnets[0].name"},
|
expected: []string{"Required value::spec.api.loadBalancer.subnets[0].name"},
|
||||||
|
|
@ -394,62 +399,103 @@ func TestLoadBalancerSubnets(t *testing.T) {
|
||||||
{
|
{
|
||||||
Name: "d",
|
Name: "d",
|
||||||
PrivateIPv4Address: nil,
|
PrivateIPv4Address: nil,
|
||||||
|
AllocationID: nil,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
expected: []string{"Not found::spec.api.loadBalancer.subnets[0].name"},
|
expected: []string{"Not found::spec.api.loadBalancer.subnets[0].name"},
|
||||||
},
|
},
|
||||||
{ // empty privateIPv4Address
|
{ // empty privateIPv4Address, no allocationID
|
||||||
clusterSubnets: []string{"a", "b", "c"},
|
clusterSubnets: []string{"a", "b", "c"},
|
||||||
lbSubnets: []kops.LoadBalancerSubnetSpec{
|
lbSubnets: []kops.LoadBalancerSubnetSpec{
|
||||||
{
|
{
|
||||||
Name: "a",
|
Name: "a",
|
||||||
PrivateIPv4Address: fi.String(""),
|
PrivateIPv4Address: fi.String(""),
|
||||||
|
AllocationID: nil,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
expected: []string{"Required value::spec.api.loadBalancer.subnets[0].privateIPv4Address"},
|
expected: []string{"Required value::spec.api.loadBalancer.subnets[0].privateIPv4Address"},
|
||||||
},
|
},
|
||||||
{ // invalid privateIPv4Address
|
{ // empty no privateIPv4Address, with allocationID
|
||||||
|
clusterSubnets: []string{"a", "b", "c"},
|
||||||
|
lbSubnets: []kops.LoadBalancerSubnetSpec{
|
||||||
|
{
|
||||||
|
Name: "a",
|
||||||
|
PrivateIPv4Address: nil,
|
||||||
|
AllocationID: fi.String(""),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
expected: []string{"Required value::spec.api.loadBalancer.subnets[0].allocationID"},
|
||||||
|
},
|
||||||
|
{ // invalid privateIPv4Address, no allocationID
|
||||||
clusterSubnets: []string{"a", "b", "c"},
|
clusterSubnets: []string{"a", "b", "c"},
|
||||||
lbSubnets: []kops.LoadBalancerSubnetSpec{
|
lbSubnets: []kops.LoadBalancerSubnetSpec{
|
||||||
{
|
{
|
||||||
Name: "a",
|
Name: "a",
|
||||||
PrivateIPv4Address: fi.String("invalidip"),
|
PrivateIPv4Address: fi.String("invalidip"),
|
||||||
|
AllocationID: nil,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
expected: []string{"Invalid value::spec.api.loadBalancer.subnets[0].privateIPv4Address"},
|
expected: []string{"Invalid value::spec.api.loadBalancer.subnets[0].privateIPv4Address"},
|
||||||
},
|
},
|
||||||
{ // privateIPv4Address not matching subnet cidr
|
{ // privateIPv4Address not matching subnet cidr, no allocationID
|
||||||
clusterSubnets: []string{"a", "b", "c"},
|
clusterSubnets: []string{"a", "b", "c"},
|
||||||
lbSubnets: []kops.LoadBalancerSubnetSpec{
|
lbSubnets: []kops.LoadBalancerSubnetSpec{
|
||||||
{
|
{
|
||||||
Name: "a",
|
Name: "a",
|
||||||
PrivateIPv4Address: fi.String("11.0.0.10"),
|
PrivateIPv4Address: fi.String("11.0.0.10"),
|
||||||
|
AllocationID: nil,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
expected: []string{"Invalid value::spec.api.loadBalancer.subnets[0].privateIPv4Address"},
|
expected: []string{"Invalid value::spec.api.loadBalancer.subnets[0].privateIPv4Address"},
|
||||||
},
|
},
|
||||||
{ // invalid class
|
{ // invalid class - with privateIPv4Address, no allocationID
|
||||||
class: fi.String(string(kops.LoadBalancerClassClassic)),
|
class: fi.String(string(kops.LoadBalancerClassClassic)),
|
||||||
clusterSubnets: []string{"a", "b", "c"},
|
clusterSubnets: []string{"a", "b", "c"},
|
||||||
lbSubnets: []kops.LoadBalancerSubnetSpec{
|
lbSubnets: []kops.LoadBalancerSubnetSpec{
|
||||||
{
|
{
|
||||||
Name: "a",
|
Name: "a",
|
||||||
PrivateIPv4Address: fi.String("10.0.0.10"),
|
PrivateIPv4Address: fi.String("10.0.0.10"),
|
||||||
|
AllocationID: nil,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
expected: []string{"Forbidden::spec.api.loadBalancer.subnets[0].privateIPv4Address"},
|
expected: []string{"Forbidden::spec.api.loadBalancer.subnets[0].privateIPv4Address"},
|
||||||
},
|
},
|
||||||
{ // invalid type
|
{ // invalid class - no privateIPv4Address, with allocationID
|
||||||
|
class: fi.String(string(kops.LoadBalancerClassClassic)),
|
||||||
|
clusterSubnets: []string{"a", "b", "c"},
|
||||||
|
lbSubnets: []kops.LoadBalancerSubnetSpec{
|
||||||
|
{
|
||||||
|
Name: "a",
|
||||||
|
PrivateIPv4Address: nil,
|
||||||
|
AllocationID: fi.String("eipalloc-222ghi789"),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
expected: []string{"Forbidden::spec.api.loadBalancer.subnets[0].allocationID"},
|
||||||
|
},
|
||||||
|
{ // invalid type external for private IP
|
||||||
lbType: fi.String(string(kops.LoadBalancerTypePublic)),
|
lbType: fi.String(string(kops.LoadBalancerTypePublic)),
|
||||||
clusterSubnets: []string{"a", "b", "c"},
|
clusterSubnets: []string{"a", "b", "c"},
|
||||||
lbSubnets: []kops.LoadBalancerSubnetSpec{
|
lbSubnets: []kops.LoadBalancerSubnetSpec{
|
||||||
{
|
{
|
||||||
Name: "a",
|
Name: "a",
|
||||||
PrivateIPv4Address: fi.String("10.0.0.10"),
|
PrivateIPv4Address: fi.String("10.0.0.10"),
|
||||||
|
AllocationID: nil,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
expected: []string{"Forbidden::spec.api.loadBalancer.subnets[0].privateIPv4Address"},
|
expected: []string{"Forbidden::spec.api.loadBalancer.subnets[0].privateIPv4Address"},
|
||||||
},
|
},
|
||||||
|
{ // invalid type Internal for public IP
|
||||||
|
lbType: fi.String(string(kops.LoadBalancerTypeInternal)),
|
||||||
|
clusterSubnets: []string{"a", "b", "c"},
|
||||||
|
lbSubnets: []kops.LoadBalancerSubnetSpec{
|
||||||
|
{
|
||||||
|
Name: "a",
|
||||||
|
PrivateIPv4Address: nil,
|
||||||
|
AllocationID: fi.String("eipalloc-222ghi789"),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
expected: []string{"Forbidden::spec.api.loadBalancer.subnets[0].allocationID"},
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, test := range tests {
|
for _, test := range tests {
|
||||||
|
|
|
||||||
|
|
@ -3701,6 +3701,11 @@ func (in *LoadBalancerSubnetSpec) DeepCopyInto(out *LoadBalancerSubnetSpec) {
|
||||||
*out = new(string)
|
*out = new(string)
|
||||||
**out = **in
|
**out = **in
|
||||||
}
|
}
|
||||||
|
if in.AllocationID != nil {
|
||||||
|
in, out := &in.AllocationID, &out.AllocationID
|
||||||
|
*out = new(string)
|
||||||
|
**out = **in
|
||||||
|
}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -79,6 +79,9 @@ func (b *APILoadBalancerBuilder) Build(c *fi.ModelBuilderContext) error {
|
||||||
if subnet.PrivateIPv4Address != nil {
|
if subnet.PrivateIPv4Address != nil {
|
||||||
nlbSubnetMapping.PrivateIPv4Address = subnet.PrivateIPv4Address
|
nlbSubnetMapping.PrivateIPv4Address = subnet.PrivateIPv4Address
|
||||||
}
|
}
|
||||||
|
if subnet.AllocationID != nil {
|
||||||
|
nlbSubnetMapping.AllocationID = subnet.AllocationID
|
||||||
|
}
|
||||||
nlbSubnetMappings = append(nlbSubnetMappings, nlbSubnetMapping)
|
nlbSubnetMappings = append(nlbSubnetMappings, nlbSubnetMapping)
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1272,7 +1272,8 @@
|
||||||
{
|
{
|
||||||
"SubnetId": {
|
"SubnetId": {
|
||||||
"Ref": "AWSEC2Subnetustest1acomplexexamplecom"
|
"Ref": "AWSEC2Subnetustest1acomplexexamplecom"
|
||||||
}
|
},
|
||||||
|
"AllocationId": "eipalloc-012345a678b9cdefa"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"Type": "network",
|
"Type": "network",
|
||||||
|
|
|
||||||
|
|
@ -14,6 +14,9 @@ spec:
|
||||||
class: Network
|
class: Network
|
||||||
sslCertificate: arn:aws:acm:us-test-1:000000000000:certificate/123456789012-1234-1234-1234-12345678
|
sslCertificate: arn:aws:acm:us-test-1:000000000000:certificate/123456789012-1234-1234-1234-12345678
|
||||||
sslPolicy: ELBSecurityPolicy-2016-08
|
sslPolicy: ELBSecurityPolicy-2016-08
|
||||||
|
subnets:
|
||||||
|
- name: us-test-1a
|
||||||
|
allocationId: eipalloc-012345a678b9cdefa
|
||||||
kubernetesApiAccess:
|
kubernetesApiAccess:
|
||||||
- 1.1.1.0/24
|
- 1.1.1.0/24
|
||||||
- 2001:0:8500::/40
|
- 2001:0:8500::/40
|
||||||
|
|
|
||||||
|
|
@ -13,7 +13,10 @@ spec:
|
||||||
crossZoneLoadBalancing: true
|
crossZoneLoadBalancing: true
|
||||||
class: Network
|
class: Network
|
||||||
sslCertificate: arn:aws:acm:us-test-1:000000000000:certificate/123456789012-1234-1234-1234-12345678
|
sslCertificate: arn:aws:acm:us-test-1:000000000000:certificate/123456789012-1234-1234-1234-12345678
|
||||||
sslPolicy: ELBSecurityPolicy-2016-08
|
sslPolicy: ELBSecurityPolicy-2016-08
|
||||||
|
subnets:
|
||||||
|
- name: us-test-1a
|
||||||
|
allocationId: eipalloc-012345a678b9cdefa
|
||||||
kubernetesApiAccess:
|
kubernetesApiAccess:
|
||||||
- 1.1.1.0/24
|
- 1.1.1.0/24
|
||||||
- 2001:0:8500::/40
|
- 2001:0:8500::/40
|
||||||
|
|
|
||||||
|
|
@ -541,7 +541,8 @@ resource "aws_lb" "api-complex-example-com" {
|
||||||
load_balancer_type = "network"
|
load_balancer_type = "network"
|
||||||
name = "api-complex-example-com-vd3t5n"
|
name = "api-complex-example-com-vd3t5n"
|
||||||
subnet_mapping {
|
subnet_mapping {
|
||||||
subnet_id = aws_subnet.us-test-1a-complex-example-com.id
|
allocation_id = "eipalloc-012345a678b9cdefa"
|
||||||
|
subnet_id = aws_subnet.us-test-1a-complex-example-com.id
|
||||||
}
|
}
|
||||||
tags = {
|
tags = {
|
||||||
"KubernetesCluster" = "complex.example.com"
|
"KubernetesCluster" = "complex.example.com"
|
||||||
|
|
|
||||||
|
|
@ -362,6 +362,12 @@ func (e *NetworkLoadBalancer) Find(c *fi.Context) (*NetworkLoadBalancer, error)
|
||||||
}
|
}
|
||||||
sm.PrivateIPv4Address = a.PrivateIPv4Address
|
sm.PrivateIPv4Address = a.PrivateIPv4Address
|
||||||
}
|
}
|
||||||
|
if a.AllocationId != nil {
|
||||||
|
if sm.AllocationID != nil {
|
||||||
|
return nil, fmt.Errorf("NLB has more then one AllocationID per subnet, which is unexpected. This is a bug in kOps, please open a GitHub issue.")
|
||||||
|
}
|
||||||
|
sm.AllocationID = a.AllocationId
|
||||||
|
}
|
||||||
}
|
}
|
||||||
actual.SubnetMappings = append(actual.SubnetMappings, sm)
|
actual.SubnetMappings = append(actual.SubnetMappings, sm)
|
||||||
}
|
}
|
||||||
|
|
@ -528,7 +534,13 @@ func (s *NetworkLoadBalancer) CheckChanges(a, e, changes *NetworkLoadBalancer) e
|
||||||
if len(changes.SubnetMappings) > 0 {
|
if len(changes.SubnetMappings) > 0 {
|
||||||
expectedSubnets := make(map[string]*string)
|
expectedSubnets := make(map[string]*string)
|
||||||
for _, s := range e.SubnetMappings {
|
for _, s := range e.SubnetMappings {
|
||||||
expectedSubnets[*s.Subnet.ID] = s.PrivateIPv4Address
|
//expectedSubnets[*s.Subnet.ID] = s
|
||||||
|
if s.AllocationID != nil {
|
||||||
|
expectedSubnets[*s.Subnet.ID] = s.AllocationID
|
||||||
|
}
|
||||||
|
if s.PrivateIPv4Address != nil {
|
||||||
|
expectedSubnets[*s.Subnet.ID] = s.PrivateIPv4Address
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, s := range a.SubnetMappings {
|
for _, s := range a.SubnetMappings {
|
||||||
|
|
@ -536,7 +548,7 @@ func (s *NetworkLoadBalancer) CheckChanges(a, e, changes *NetworkLoadBalancer) e
|
||||||
if !ok {
|
if !ok {
|
||||||
return fmt.Errorf("network load balancers do not support detaching subnets")
|
return fmt.Errorf("network load balancers do not support detaching subnets")
|
||||||
}
|
}
|
||||||
if fi.StringValue(eIP) != fi.StringValue(s.PrivateIPv4Address) {
|
if fi.StringValue(eIP) != fi.StringValue(s.PrivateIPv4Address) || fi.StringValue(eIP) != fi.StringValue(s.AllocationID) {
|
||||||
return fmt.Errorf("network load balancers do not support modifying address settings")
|
return fmt.Errorf("network load balancers do not support modifying address settings")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -573,6 +585,7 @@ func (_ *NetworkLoadBalancer) RenderAWS(t *awsup.AWSAPITarget, a, e, changes *Ne
|
||||||
for _, subnetMapping := range e.SubnetMappings {
|
for _, subnetMapping := range e.SubnetMappings {
|
||||||
request.SubnetMappings = append(request.SubnetMappings, &elbv2.SubnetMapping{
|
request.SubnetMappings = append(request.SubnetMappings, &elbv2.SubnetMapping{
|
||||||
SubnetId: subnetMapping.Subnet.ID,
|
SubnetId: subnetMapping.Subnet.ID,
|
||||||
|
AllocationId: subnetMapping.AllocationID,
|
||||||
PrivateIPv4Address: subnetMapping.PrivateIPv4Address,
|
PrivateIPv4Address: subnetMapping.PrivateIPv4Address,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
@ -623,18 +636,25 @@ func (_ *NetworkLoadBalancer) RenderAWS(t *awsup.AWSAPITarget, a, e, changes *Ne
|
||||||
if changes.SubnetMappings != nil {
|
if changes.SubnetMappings != nil {
|
||||||
actualSubnets := make(map[string]*string)
|
actualSubnets := make(map[string]*string)
|
||||||
for _, s := range a.SubnetMappings {
|
for _, s := range a.SubnetMappings {
|
||||||
actualSubnets[*s.Subnet.ID] = s.PrivateIPv4Address
|
//actualSubnets[*s.Subnet.ID] = s
|
||||||
|
if s.AllocationID != nil {
|
||||||
|
actualSubnets[*s.Subnet.ID] = s.AllocationID
|
||||||
|
}
|
||||||
|
if s.PrivateIPv4Address != nil {
|
||||||
|
actualSubnets[*s.Subnet.ID] = s.PrivateIPv4Address
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
var awsSubnetMappings []*elbv2.SubnetMapping
|
var awsSubnetMappings []*elbv2.SubnetMapping
|
||||||
hasChanges := false
|
hasChanges := false
|
||||||
for _, s := range e.SubnetMappings {
|
for _, s := range e.SubnetMappings {
|
||||||
aIP, ok := actualSubnets[*s.Subnet.ID]
|
aIP, ok := actualSubnets[*s.Subnet.ID]
|
||||||
if !ok || fi.StringValue(s.PrivateIPv4Address) != fi.StringValue(aIP) {
|
if !ok || (fi.StringValue(s.PrivateIPv4Address) != fi.StringValue(aIP) && fi.StringValue(s.AllocationID) != fi.StringValue(aIP)) {
|
||||||
hasChanges = true
|
hasChanges = true
|
||||||
}
|
}
|
||||||
awsSubnetMappings = append(awsSubnetMappings, &elbv2.SubnetMapping{
|
awsSubnetMappings = append(awsSubnetMappings, &elbv2.SubnetMapping{
|
||||||
SubnetId: s.Subnet.ID,
|
SubnetId: s.Subnet.ID,
|
||||||
|
AllocationId: s.AllocationID,
|
||||||
PrivateIPv4Address: s.PrivateIPv4Address,
|
PrivateIPv4Address: s.PrivateIPv4Address,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
@ -747,6 +767,7 @@ func (_ *NetworkLoadBalancer) RenderTerraform(t *terraform.TerraformTarget, a, e
|
||||||
for _, subnetMapping := range e.SubnetMappings {
|
for _, subnetMapping := range e.SubnetMappings {
|
||||||
nlbTF.SubnetMappings = append(nlbTF.SubnetMappings, terraformNetworkLoadBalancerSubnetMapping{
|
nlbTF.SubnetMappings = append(nlbTF.SubnetMappings, terraformNetworkLoadBalancerSubnetMapping{
|
||||||
Subnet: subnetMapping.Subnet.TerraformLink(),
|
Subnet: subnetMapping.Subnet.TerraformLink(),
|
||||||
|
AllocationID: subnetMapping.AllocationID,
|
||||||
PrivateIPv4Address: subnetMapping.PrivateIPv4Address,
|
PrivateIPv4Address: subnetMapping.PrivateIPv4Address,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
@ -844,6 +865,7 @@ func (_ *NetworkLoadBalancer) RenderCloudformation(t *cloudformation.Cloudformat
|
||||||
for _, subnetMapping := range e.SubnetMappings {
|
for _, subnetMapping := range e.SubnetMappings {
|
||||||
nlbCF.SubnetMappings = append(nlbCF.SubnetMappings, &cloudformationSubnetMapping{
|
nlbCF.SubnetMappings = append(nlbCF.SubnetMappings, &cloudformationSubnetMapping{
|
||||||
Subnet: subnetMapping.Subnet.CloudformationLink(),
|
Subnet: subnetMapping.Subnet.CloudformationLink(),
|
||||||
|
AllocationId: subnetMapping.AllocationID,
|
||||||
PrivateIPv4Address: subnetMapping.PrivateIPv4Address,
|
PrivateIPv4Address: subnetMapping.PrivateIPv4Address,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -26,6 +26,8 @@ type SubnetMapping struct {
|
||||||
|
|
||||||
// PrivateIPv4Address only valid for NLBs
|
// PrivateIPv4Address only valid for NLBs
|
||||||
PrivateIPv4Address *string
|
PrivateIPv4Address *string
|
||||||
|
// AllocationID only valid for NLBs
|
||||||
|
AllocationID *string
|
||||||
}
|
}
|
||||||
|
|
||||||
// OrderSubnetsById implements sort.Interface for []Subnet, based on ID
|
// OrderSubnetsById implements sort.Interface for []Subnet, based on ID
|
||||||
|
|
@ -37,7 +39,12 @@ func (a OrderSubnetMappingsByID) Less(i, j int) bool {
|
||||||
v1 := fi.StringValue(a[i].Subnet.ID)
|
v1 := fi.StringValue(a[i].Subnet.ID)
|
||||||
v2 := fi.StringValue(a[j].Subnet.ID)
|
v2 := fi.StringValue(a[j].Subnet.ID)
|
||||||
if v1 == v2 {
|
if v1 == v2 {
|
||||||
return fi.StringValue(a[i].PrivateIPv4Address) < fi.StringValue(a[j].PrivateIPv4Address)
|
if a[i].PrivateIPv4Address != nil && a[j].PrivateIPv4Address != nil {
|
||||||
|
return fi.StringValue(a[i].PrivateIPv4Address) < fi.StringValue(a[j].PrivateIPv4Address)
|
||||||
|
}
|
||||||
|
if a[i].AllocationID != nil && a[j].AllocationID != nil {
|
||||||
|
return fi.StringValue(a[i].AllocationID) < fi.StringValue(a[j].AllocationID)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return v1 < v2
|
return v1 < v2
|
||||||
}
|
}
|
||||||
|
|
@ -67,6 +74,9 @@ func subnetMappingSlicesEqualIgnoreOrder(l, r []*SubnetMapping) bool {
|
||||||
if fi.StringValue(s.PrivateIPv4Address) != fi.StringValue(s2.PrivateIPv4Address) {
|
if fi.StringValue(s.PrivateIPv4Address) != fi.StringValue(s2.PrivateIPv4Address) {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
if fi.StringValue(s.AllocationID) != fi.StringValue(s2.AllocationID) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue