Merge pull request #80003 from wongma7/cloudprovider-authoritative-hostname

Fix cloud reported hostname being overridden if nodeIP set
This commit is contained in:
Kubernetes Prow Robot 2019-08-21 20:50:32 -07:00 committed by GitHub
commit ebf15029da
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 72 additions and 14 deletions

View File

@ -90,40 +90,52 @@ func NodeAddress(nodeIP net.IP, // typically Kubelet.nodeIP
}
}
if cloud != nil {
nodeAddresses, err := nodeAddressesFunc()
cloudNodeAddresses, err := nodeAddressesFunc()
if err != nil {
return err
}
var nodeAddresses []v1.NodeAddress
// For every address supplied by the cloud provider that matches nodeIP, nodeIP is the enforced node address for
// that address Type (like InternalIP and ExternalIP), meaning other addresses of the same Type are discarded.
// See #61921 for more information: some cloud providers may supply secondary IPs, so nodeIP serves as a way to
// ensure that the correct IPs show up on a Node object.
if nodeIP != nil {
enforcedNodeAddresses := []v1.NodeAddress{}
nodeIPTypes := make(map[v1.NodeAddressType]bool)
for _, nodeAddress := range nodeAddresses {
for _, nodeAddress := range cloudNodeAddresses {
if nodeAddress.Address == nodeIP.String() {
enforcedNodeAddresses = append(enforcedNodeAddresses, v1.NodeAddress{Type: nodeAddress.Type, Address: nodeAddress.Address})
nodeIPTypes[nodeAddress.Type] = true
}
}
if len(enforcedNodeAddresses) > 0 {
for _, nodeAddress := range nodeAddresses {
if !nodeIPTypes[nodeAddress.Type] && nodeAddress.Type != v1.NodeHostName {
enforcedNodeAddresses = append(enforcedNodeAddresses, v1.NodeAddress{Type: nodeAddress.Type, Address: nodeAddress.Address})
}
}
enforcedNodeAddresses = append(enforcedNodeAddresses, v1.NodeAddress{Type: v1.NodeHostName, Address: hostname})
node.Status.Addresses = enforcedNodeAddresses
return nil
// nodeIP must be among the addresses supplied by the cloud provider
if len(enforcedNodeAddresses) == 0 {
return fmt.Errorf("failed to get node address from cloud provider that matches ip: %v", nodeIP)
}
return fmt.Errorf("failed to get node address from cloud provider that matches ip: %v", nodeIP)
// nodeIP was found, now use all other addresses supplied by the cloud provider NOT of the same Type as nodeIP.
for _, nodeAddress := range cloudNodeAddresses {
if !nodeIPTypes[nodeAddress.Type] {
enforcedNodeAddresses = append(enforcedNodeAddresses, v1.NodeAddress{Type: nodeAddress.Type, Address: nodeAddress.Address})
}
}
nodeAddresses = enforcedNodeAddresses
} else {
// If nodeIP is unset, just use the addresses provided by the cloud provider as-is
nodeAddresses = cloudNodeAddresses
}
switch {
case len(nodeAddresses) == 0:
case len(cloudNodeAddresses) == 0:
// the cloud provider didn't specify any addresses
nodeAddresses = append(nodeAddresses, v1.NodeAddress{Type: v1.NodeHostName, Address: hostname})
case !hasAddressType(nodeAddresses, v1.NodeHostName) && hasAddressValue(nodeAddresses, hostname):
case !hasAddressType(cloudNodeAddresses, v1.NodeHostName) && hasAddressValue(cloudNodeAddresses, hostname):
// the cloud provider didn't specify an address of type Hostname,
// but the auto-detected hostname matched an address reported by the cloud provider,
// so we can add it and count on the value being verifiable via cloud provider metadata

View File

@ -179,6 +179,21 @@ func TestNodeAddress(t *testing.T) {
},
shouldError: false,
},
{
name: "cloud reports hostname, nodeIP is set, no override",
nodeIP: net.ParseIP("10.1.1.1"),
nodeAddresses: []v1.NodeAddress{
{Type: v1.NodeInternalIP, Address: "10.1.1.1"},
{Type: v1.NodeExternalIP, Address: "55.55.55.55"},
{Type: v1.NodeHostName, Address: "cloud-host"},
},
expectedAddresses: []v1.NodeAddress{
{Type: v1.NodeInternalIP, Address: "10.1.1.1"},
{Type: v1.NodeExternalIP, Address: "55.55.55.55"},
{Type: v1.NodeHostName, Address: "cloud-host"}, // cloud-reported hostname wins over detected hostname
},
shouldError: false,
},
{
name: "cloud reports hostname, overridden",
nodeAddresses: []v1.NodeAddress{
@ -233,6 +248,37 @@ func TestNodeAddress(t *testing.T) {
},
shouldError: false,
},
{
name: "cloud doesn't report hostname, nodeIP is set, no override, detected hostname match",
nodeIP: net.ParseIP("10.1.1.1"),
nodeAddresses: []v1.NodeAddress{
{Type: v1.NodeInternalIP, Address: "10.1.1.1"},
{Type: v1.NodeExternalIP, Address: "55.55.55.55"},
{Type: v1.NodeExternalDNS, Address: testKubeletHostname}, // cloud-reported address value matches detected hostname
},
expectedAddresses: []v1.NodeAddress{
{Type: v1.NodeInternalIP, Address: "10.1.1.1"},
{Type: v1.NodeExternalIP, Address: "55.55.55.55"},
{Type: v1.NodeExternalDNS, Address: testKubeletHostname},
{Type: v1.NodeHostName, Address: testKubeletHostname}, // detected hostname gets auto-added
},
shouldError: false,
},
{
name: "cloud doesn't report hostname, nodeIP is set, no override, detected hostname match with same type as nodeIP",
nodeIP: net.ParseIP("10.1.1.1"),
nodeAddresses: []v1.NodeAddress{
{Type: v1.NodeInternalIP, Address: "10.1.1.1"},
{Type: v1.NodeInternalIP, Address: testKubeletHostname}, // cloud-reported address value matches detected hostname
{Type: v1.NodeExternalIP, Address: "55.55.55.55"},
},
expectedAddresses: []v1.NodeAddress{
{Type: v1.NodeInternalIP, Address: "10.1.1.1"},
{Type: v1.NodeExternalIP, Address: "55.55.55.55"},
{Type: v1.NodeHostName, Address: testKubeletHostname}, // detected hostname gets auto-added
},
shouldError: false,
},
{
name: "cloud doesn't report hostname, hostname override, hostname mismatch",
nodeAddresses: []v1.NodeAddress{