Unverified Commit 2feb0937 authored by Kubernetes Submit Queue's avatar Kubernetes Submit Queue Committed by GitHub

Merge pull request #64180 from feiskyer/verbose

Automatic merge from submit-queue (batch tested with PRs 63434, 64172, 63975, 64180, 63755). If you want to cherry-pick this change to another branch, please follow the instructions <a href="https://github.com/kubernetes/community/blob/master/contributors/devel/cherry-picks.md">here</a>. Check SessionAffinity for Azure load balancer **What this PR does / why we need it**: Currently azure load balance rule comparing is based on name which does not have affinity information. So during updating, the loadDistribution property is not updated. This PR fixes this and adds some verbose logs for better understanding what's happening. **Which issue(s) this PR fixes** *(optional, in `fixes #<issue number>(, fixes #<issue_number>, ...)` format, will close the issue(s) when PR gets merged)*: Fixes #63908 **Special notes for your reviewer**: Cherry pick to 1.10. **Release note**: ```release-note Fix SessionAffinity not updated issue for Azure load balancer ```
parents b8dff0b4 a50ac290
...@@ -55,10 +55,10 @@ func (az *Cloud) GetVirtualMachineWithRetry(name types.NodeName) (compute.Virtua ...@@ -55,10 +55,10 @@ func (az *Cloud) GetVirtualMachineWithRetry(name types.NodeName) (compute.Virtua
return true, cloudprovider.InstanceNotFound return true, cloudprovider.InstanceNotFound
} }
if retryErr != nil { if retryErr != nil {
glog.Errorf("backoff: failure, will retry,err=%v", retryErr) glog.Errorf("GetVirtualMachineWithRetry(%s): backoff failure, will retry, err=%v", name, retryErr)
return false, nil return false, nil
} }
glog.V(2).Info("backoff: success") glog.V(2).Infof("GetVirtualMachineWithRetry(%s): backoff success", name)
return true, nil return true, nil
}) })
if err == wait.ErrWaitTimeout { if err == wait.ErrWaitTimeout {
...@@ -99,10 +99,10 @@ func (az *Cloud) GetIPForMachineWithRetry(name types.NodeName) (string, string, ...@@ -99,10 +99,10 @@ func (az *Cloud) GetIPForMachineWithRetry(name types.NodeName) (string, string,
var retryErr error var retryErr error
ip, publicIP, retryErr = az.getIPForMachine(name) ip, publicIP, retryErr = az.getIPForMachine(name)
if retryErr != nil { if retryErr != nil {
glog.Errorf("backoff: failure, will retry,err=%v", retryErr) glog.Errorf("GetIPForMachineWithRetry(%s): backoff failure, will retry,err=%v", name, retryErr)
return false, nil return false, nil
} }
glog.V(2).Info("backoff: success") glog.V(2).Infof("GetIPForMachineWithRetry(%s): backoff success", name)
return true, nil return true, nil
}) })
return ip, publicIP, err return ip, publicIP, err
...@@ -304,11 +304,11 @@ func (az *Cloud) UpdateVmssVMWithRetry(ctx context.Context, resourceGroupName st ...@@ -304,11 +304,11 @@ func (az *Cloud) UpdateVmssVMWithRetry(ctx context.Context, resourceGroupName st
// A wait.ConditionFunc function to deal with common HTTP backoff response conditions // A wait.ConditionFunc function to deal with common HTTP backoff response conditions
func processRetryResponse(resp autorest.Response, err error) (bool, error) { func processRetryResponse(resp autorest.Response, err error) (bool, error) {
if isSuccessHTTPResponse(resp) { if isSuccessHTTPResponse(resp) {
glog.V(2).Infof("backoff: success, HTTP response=%d", resp.StatusCode) glog.V(2).Infof("processRetryResponse: backoff success, HTTP response=%d", resp.StatusCode)
return true, nil return true, nil
} }
if shouldRetryAPIRequest(resp, err) { if shouldRetryAPIRequest(resp, err) {
glog.Errorf("backoff: failure, will retry, HTTP response=%d, err=%v", resp.StatusCode, err) glog.Errorf("processRetryResponse: backoff failure, will retry, HTTP response=%d, err=%v", resp.StatusCode, err)
// suppress the error object so that backoff process continues // suppress the error object so that backoff process continues
return false, nil return false, nil
} }
...@@ -361,7 +361,7 @@ func processHTTPRetryResponse(resp *http.Response, err error) (bool, error) { ...@@ -361,7 +361,7 @@ func processHTTPRetryResponse(resp *http.Response, err error) (bool, error) {
} }
if shouldRetryHTTPRequest(resp, err) { if shouldRetryHTTPRequest(resp, err) {
glog.Errorf("backoff: failure, will retry, HTTP response=%d, err=%v", resp.StatusCode, err) glog.Errorf("processHTTPRetryResponse: backoff failure, will retry, HTTP response=%d, err=%v", resp.StatusCode, err)
// suppress the error object so that backoff process continues // suppress the error object so that backoff process continues
return false, nil return false, nil
} }
......
...@@ -33,7 +33,7 @@ func (az *Cloud) NodeAddresses(ctx context.Context, name types.NodeName) ([]v1.N ...@@ -33,7 +33,7 @@ func (az *Cloud) NodeAddresses(ctx context.Context, name types.NodeName) ([]v1.N
addressGetter := func(nodeName types.NodeName) ([]v1.NodeAddress, error) { addressGetter := func(nodeName types.NodeName) ([]v1.NodeAddress, error) {
ip, publicIP, err := az.GetIPForMachineWithRetry(nodeName) ip, publicIP, err := az.GetIPForMachineWithRetry(nodeName)
if err != nil { if err != nil {
glog.V(2).Infof("NodeAddresses(%s) abort backoff", nodeName) glog.V(2).Infof("NodeAddresses(%s) abort backoff: %v", nodeName, err)
return nil, err return nil, err
} }
......
...@@ -97,3 +97,116 @@ func TestFindProbe(t *testing.T) { ...@@ -97,3 +97,116 @@ func TestFindProbe(t *testing.T) {
assert.Equal(t, test.expected, findResult, fmt.Sprintf("TestCase[%d]: %s", i, test.msg)) assert.Equal(t, test.expected, findResult, fmt.Sprintf("TestCase[%d]: %s", i, test.msg))
} }
} }
func TestFindRule(t *testing.T) {
tests := []struct {
msg string
existingRule []network.LoadBalancingRule
curRule network.LoadBalancingRule
expected bool
}{
{
msg: "empty existing rules should return false",
expected: false,
},
{
msg: "rule names unmatch should return false",
existingRule: []network.LoadBalancingRule{
{
Name: to.StringPtr("httpProbe1"),
LoadBalancingRulePropertiesFormat: &network.LoadBalancingRulePropertiesFormat{
FrontendPort: to.Int32Ptr(1),
},
},
},
curRule: network.LoadBalancingRule{
Name: to.StringPtr("httpProbe2"),
LoadBalancingRulePropertiesFormat: &network.LoadBalancingRulePropertiesFormat{
FrontendPort: to.Int32Ptr(1),
},
},
expected: false,
},
{
msg: "rule names match while frontend ports unmatch should return false",
existingRule: []network.LoadBalancingRule{
{
Name: to.StringPtr("httpProbe"),
LoadBalancingRulePropertiesFormat: &network.LoadBalancingRulePropertiesFormat{
FrontendPort: to.Int32Ptr(1),
},
},
},
curRule: network.LoadBalancingRule{
Name: to.StringPtr("httpProbe"),
LoadBalancingRulePropertiesFormat: &network.LoadBalancingRulePropertiesFormat{
FrontendPort: to.Int32Ptr(2),
},
},
expected: false,
},
{
msg: "rule names match while backend ports unmatch should return false",
existingRule: []network.LoadBalancingRule{
{
Name: to.StringPtr("httpProbe"),
LoadBalancingRulePropertiesFormat: &network.LoadBalancingRulePropertiesFormat{
BackendPort: to.Int32Ptr(1),
},
},
},
curRule: network.LoadBalancingRule{
Name: to.StringPtr("httpProbe"),
LoadBalancingRulePropertiesFormat: &network.LoadBalancingRulePropertiesFormat{
BackendPort: to.Int32Ptr(2),
},
},
expected: false,
},
{
msg: "rule names match while LoadDistribution unmatch should return false",
existingRule: []network.LoadBalancingRule{
{
Name: to.StringPtr("probe1"),
LoadBalancingRulePropertiesFormat: &network.LoadBalancingRulePropertiesFormat{
LoadDistribution: network.Default,
},
},
},
curRule: network.LoadBalancingRule{
Name: to.StringPtr("probe2"),
LoadBalancingRulePropertiesFormat: &network.LoadBalancingRulePropertiesFormat{
LoadDistribution: network.SourceIP,
},
},
expected: false,
},
{
msg: "both rule names and LoadBalancingRulePropertiesFormats match should return true",
existingRule: []network.LoadBalancingRule{
{
Name: to.StringPtr("matchName"),
LoadBalancingRulePropertiesFormat: &network.LoadBalancingRulePropertiesFormat{
BackendPort: to.Int32Ptr(2),
FrontendPort: to.Int32Ptr(2),
LoadDistribution: network.SourceIP,
},
},
},
curRule: network.LoadBalancingRule{
Name: to.StringPtr("matchName"),
LoadBalancingRulePropertiesFormat: &network.LoadBalancingRulePropertiesFormat{
BackendPort: to.Int32Ptr(2),
FrontendPort: to.Int32Ptr(2),
LoadDistribution: network.SourceIP,
},
},
expected: true,
},
}
for i, test := range tests {
findResult := findRule(test.existingRule, test.curRule)
assert.Equal(t, test.expected, findResult, fmt.Sprintf("TestCase[%d]: %s", i, test.msg))
}
}
...@@ -30,7 +30,7 @@ import ( ...@@ -30,7 +30,7 @@ import (
// ListRoutes lists all managed routes that belong to the specified clusterName // ListRoutes lists all managed routes that belong to the specified clusterName
func (az *Cloud) ListRoutes(ctx context.Context, clusterName string) ([]*cloudprovider.Route, error) { func (az *Cloud) ListRoutes(ctx context.Context, clusterName string) ([]*cloudprovider.Route, error) {
glog.V(10).Infof("list: START clusterName=%q", clusterName) glog.V(10).Infof("ListRoutes: START clusterName=%q", clusterName)
routeTable, existsRouteTable, err := az.getRouteTable() routeTable, existsRouteTable, err := az.getRouteTable()
return processRoutes(routeTable, existsRouteTable, err) return processRoutes(routeTable, existsRouteTable, err)
} }
...@@ -50,7 +50,7 @@ func processRoutes(routeTable network.RouteTable, exists bool, err error) ([]*cl ...@@ -50,7 +50,7 @@ func processRoutes(routeTable network.RouteTable, exists bool, err error) ([]*cl
for i, route := range *routeTable.Routes { for i, route := range *routeTable.Routes {
instance := mapRouteNameToNodeName(*route.Name) instance := mapRouteNameToNodeName(*route.Name)
cidr := *route.AddressPrefix cidr := *route.AddressPrefix
glog.V(10).Infof("list: * instance=%q, cidr=%q", instance, cidr) glog.V(10).Infof("ListRoutes: * instance=%q, cidr=%q", instance, cidr)
kubeRoutes[i] = &cloudprovider.Route{ kubeRoutes[i] = &cloudprovider.Route{
Name: *route.Name, Name: *route.Name,
...@@ -60,13 +60,13 @@ func processRoutes(routeTable network.RouteTable, exists bool, err error) ([]*cl ...@@ -60,13 +60,13 @@ func processRoutes(routeTable network.RouteTable, exists bool, err error) ([]*cl
} }
} }
glog.V(10).Info("list: FINISH") glog.V(10).Info("ListRoutes: FINISH")
return kubeRoutes, nil return kubeRoutes, nil
} }
func (az *Cloud) createRouteTableIfNotExists(clusterName string, kubeRoute *cloudprovider.Route) error { func (az *Cloud) createRouteTableIfNotExists(clusterName string, kubeRoute *cloudprovider.Route) error {
if _, existsRouteTable, err := az.getRouteTable(); err != nil { if _, existsRouteTable, err := az.getRouteTable(); err != nil {
glog.V(2).Infof("create error: couldn't get routetable. clusterName=%q instance=%q cidr=%q", clusterName, kubeRoute.TargetNode, kubeRoute.DestinationCIDR) glog.V(2).Infof("createRouteTableIfNotExists error: couldn't get routetable. clusterName=%q instance=%q cidr=%q", clusterName, kubeRoute.TargetNode, kubeRoute.DestinationCIDR)
return err return err
} else if existsRouteTable { } else if existsRouteTable {
return nil return nil
...@@ -81,17 +81,17 @@ func (az *Cloud) createRouteTable() error { ...@@ -81,17 +81,17 @@ func (az *Cloud) createRouteTable() error {
RouteTablePropertiesFormat: &network.RouteTablePropertiesFormat{}, RouteTablePropertiesFormat: &network.RouteTablePropertiesFormat{},
} }
glog.V(3).Infof("create: creating routetable. routeTableName=%q", az.RouteTableName) glog.V(3).Infof("createRouteTableIfNotExists: creating routetable. routeTableName=%q", az.RouteTableName)
ctx, cancel := getContextWithCancel() ctx, cancel := getContextWithCancel()
defer cancel() defer cancel()
resp, err := az.RouteTablesClient.CreateOrUpdate(ctx, az.ResourceGroup, az.RouteTableName, routeTable) resp, err := az.RouteTablesClient.CreateOrUpdate(ctx, az.ResourceGroup, az.RouteTableName, routeTable)
glog.V(10).Infof("RouteTablesClient.CreateOrUpdate(%q): end", az.RouteTableName) glog.V(10).Infof("RouteTablesClient.CreateOrUpdate(%q): end", az.RouteTableName)
if az.CloudProviderBackoff && shouldRetryHTTPRequest(resp, err) { if az.CloudProviderBackoff && shouldRetryHTTPRequest(resp, err) {
glog.V(2).Infof("create backing off: creating routetable. routeTableName=%q", az.RouteTableName) glog.V(2).Infof("createRouteTableIfNotExists backing off: creating routetable. routeTableName=%q", az.RouteTableName)
retryErr := az.CreateOrUpdateRouteTableWithRetry(routeTable) retryErr := az.CreateOrUpdateRouteTableWithRetry(routeTable)
if retryErr != nil { if retryErr != nil {
err = retryErr err = retryErr
glog.V(2).Infof("create abort backoff: creating routetable. routeTableName=%q", az.RouteTableName) glog.V(2).Infof("createRouteTableIfNotExists abort backoff: creating routetable. routeTableName=%q", az.RouteTableName)
} }
} }
if err != nil { if err != nil {
...@@ -107,7 +107,7 @@ func (az *Cloud) createRouteTable() error { ...@@ -107,7 +107,7 @@ func (az *Cloud) createRouteTable() error {
// route.Name will be ignored, although the cloud-provider may use nameHint // route.Name will be ignored, although the cloud-provider may use nameHint
// to create a more user-meaningful name. // to create a more user-meaningful name.
func (az *Cloud) CreateRoute(ctx context.Context, clusterName string, nameHint string, kubeRoute *cloudprovider.Route) error { func (az *Cloud) CreateRoute(ctx context.Context, clusterName string, nameHint string, kubeRoute *cloudprovider.Route) error {
glog.V(2).Infof("create: creating route. clusterName=%q instance=%q cidr=%q", clusterName, kubeRoute.TargetNode, kubeRoute.DestinationCIDR) glog.V(2).Infof("CreateRoute: creating route. clusterName=%q instance=%q cidr=%q", clusterName, kubeRoute.TargetNode, kubeRoute.DestinationCIDR)
if err := az.createRouteTableIfNotExists(clusterName, kubeRoute); err != nil { if err := az.createRouteTableIfNotExists(clusterName, kubeRoute); err != nil {
return err return err
} }
...@@ -126,31 +126,31 @@ func (az *Cloud) CreateRoute(ctx context.Context, clusterName string, nameHint s ...@@ -126,31 +126,31 @@ func (az *Cloud) CreateRoute(ctx context.Context, clusterName string, nameHint s
}, },
} }
glog.V(3).Infof("create: creating route: instance=%q cidr=%q", kubeRoute.TargetNode, kubeRoute.DestinationCIDR) glog.V(3).Infof("CreateRoute: creating route: instance=%q cidr=%q", kubeRoute.TargetNode, kubeRoute.DestinationCIDR)
ctx, cancel := getContextWithCancel() ctx, cancel := getContextWithCancel()
defer cancel() defer cancel()
resp, err := az.RoutesClient.CreateOrUpdate(ctx, az.ResourceGroup, az.RouteTableName, *route.Name, route) resp, err := az.RoutesClient.CreateOrUpdate(ctx, az.ResourceGroup, az.RouteTableName, *route.Name, route)
glog.V(10).Infof("RoutesClient.CreateOrUpdate(%q): end", az.RouteTableName) glog.V(10).Infof("RoutesClient.CreateOrUpdate(%q): end", az.RouteTableName)
if az.CloudProviderBackoff && shouldRetryHTTPRequest(resp, err) { if az.CloudProviderBackoff && shouldRetryHTTPRequest(resp, err) {
glog.V(2).Infof("create backing off: creating route: instance=%q cidr=%q", kubeRoute.TargetNode, kubeRoute.DestinationCIDR) glog.V(2).Infof("CreateRoute backing off: creating route: instance=%q cidr=%q", kubeRoute.TargetNode, kubeRoute.DestinationCIDR)
retryErr := az.CreateOrUpdateRouteWithRetry(route) retryErr := az.CreateOrUpdateRouteWithRetry(route)
if retryErr != nil { if retryErr != nil {
err = retryErr err = retryErr
glog.V(2).Infof("create abort backoff: creating route: instance=%q cidr=%q", kubeRoute.TargetNode, kubeRoute.DestinationCIDR) glog.V(2).Infof("CreateRoute abort backoff: creating route: instance=%q cidr=%q", kubeRoute.TargetNode, kubeRoute.DestinationCIDR)
} }
} }
if err != nil { if err != nil {
return err return err
} }
glog.V(2).Infof("create: route created. clusterName=%q instance=%q cidr=%q", clusterName, kubeRoute.TargetNode, kubeRoute.DestinationCIDR) glog.V(2).Infof("CreateRoute: route created. clusterName=%q instance=%q cidr=%q", clusterName, kubeRoute.TargetNode, kubeRoute.DestinationCIDR)
return nil return nil
} }
// DeleteRoute deletes the specified managed route // DeleteRoute deletes the specified managed route
// Route should be as returned by ListRoutes // Route should be as returned by ListRoutes
func (az *Cloud) DeleteRoute(ctx context.Context, clusterName string, kubeRoute *cloudprovider.Route) error { func (az *Cloud) DeleteRoute(ctx context.Context, clusterName string, kubeRoute *cloudprovider.Route) error {
glog.V(2).Infof("delete: deleting route. clusterName=%q instance=%q cidr=%q", clusterName, kubeRoute.TargetNode, kubeRoute.DestinationCIDR) glog.V(2).Infof("DeleteRoute: deleting route. clusterName=%q instance=%q cidr=%q", clusterName, kubeRoute.TargetNode, kubeRoute.DestinationCIDR)
ctx, cancel := getContextWithCancel() ctx, cancel := getContextWithCancel()
defer cancel() defer cancel()
...@@ -159,18 +159,18 @@ func (az *Cloud) DeleteRoute(ctx context.Context, clusterName string, kubeRoute ...@@ -159,18 +159,18 @@ func (az *Cloud) DeleteRoute(ctx context.Context, clusterName string, kubeRoute
glog.V(10).Infof("RoutesClient.Delete(%q): end", az.RouteTableName) glog.V(10).Infof("RoutesClient.Delete(%q): end", az.RouteTableName)
if az.CloudProviderBackoff && shouldRetryHTTPRequest(resp, err) { if az.CloudProviderBackoff && shouldRetryHTTPRequest(resp, err) {
glog.V(2).Infof("delete backing off: deleting route. clusterName=%q instance=%q cidr=%q", clusterName, kubeRoute.TargetNode, kubeRoute.DestinationCIDR) glog.V(2).Infof("DeleteRoute backing off: deleting route. clusterName=%q instance=%q cidr=%q", clusterName, kubeRoute.TargetNode, kubeRoute.DestinationCIDR)
retryErr := az.DeleteRouteWithRetry(routeName) retryErr := az.DeleteRouteWithRetry(routeName)
if retryErr != nil { if retryErr != nil {
err = retryErr err = retryErr
glog.V(2).Infof("delete abort backoff: deleting route. clusterName=%q instance=%q cidr=%q", clusterName, kubeRoute.TargetNode, kubeRoute.DestinationCIDR) glog.V(2).Infof("DeleteRoute abort backoff: deleting route. clusterName=%q instance=%q cidr=%q", clusterName, kubeRoute.TargetNode, kubeRoute.DestinationCIDR)
} }
} }
if err != nil { if err != nil {
return err return err
} }
glog.V(2).Infof("delete: route deleted. clusterName=%q instance=%q cidr=%q", clusterName, kubeRoute.TargetNode, kubeRoute.DestinationCIDR) glog.V(2).Infof("DeleteRoute: route deleted. clusterName=%q instance=%q cidr=%q", clusterName, kubeRoute.TargetNode, kubeRoute.DestinationCIDR)
return nil return nil
} }
......
...@@ -173,7 +173,7 @@ func getProtocolsFromKubernetesProtocol(protocol v1.Protocol) (*network.Transpor ...@@ -173,7 +173,7 @@ func getProtocolsFromKubernetesProtocol(protocol v1.Protocol) (*network.Transpor
securityProto = network.SecurityRuleProtocolUDP securityProto = network.SecurityRuleProtocolUDP
return &transportProto, &securityProto, nil, nil return &transportProto, &securityProto, nil, nil
default: default:
return &transportProto, &securityProto, &probeProto, fmt.Errorf("Only TCP and UDP are supported for Azure LoadBalancers") return &transportProto, &securityProto, &probeProto, fmt.Errorf("only TCP and UDP are supported for Azure LoadBalancers")
} }
} }
...@@ -285,7 +285,7 @@ outer: ...@@ -285,7 +285,7 @@ outer:
return smallest, nil return smallest, nil
} }
return -1, fmt.Errorf("SecurityGroup priorities are exhausted") return -1, fmt.Errorf("securityGroup priorities are exhausted")
} }
func (az *Cloud) getIPForMachine(nodeName types.NodeName) (string, string, error) { func (az *Cloud) getIPForMachine(nodeName types.NodeName) (string, string, error) {
...@@ -372,10 +372,10 @@ func (as *availabilitySet) GetInstanceIDByNodeName(name string) (string, error) ...@@ -372,10 +372,10 @@ func (as *availabilitySet) GetInstanceIDByNodeName(name string) (string, error)
} }
if err != nil { if err != nil {
if as.CloudProviderBackoff { if as.CloudProviderBackoff {
glog.V(2).Infof("InstanceID(%s) backing off", name) glog.V(2).Infof("GetInstanceIDByNodeName(%s) backing off", name)
machine, err = as.GetVirtualMachineWithRetry(types.NodeName(name)) machine, err = as.GetVirtualMachineWithRetry(types.NodeName(name))
if err != nil { if err != nil {
glog.V(2).Infof("InstanceID(%s) abort backoff", name) glog.V(2).Infof("GetInstanceIDByNodeName(%s) abort backoff", name)
return "", err return "", err
} }
} else { } else {
...@@ -400,7 +400,7 @@ func (as *availabilitySet) GetNodeNameByProviderID(providerID string) (types.Nod ...@@ -400,7 +400,7 @@ func (as *availabilitySet) GetNodeNameByProviderID(providerID string) (types.Nod
func (as *availabilitySet) GetInstanceTypeByNodeName(name string) (string, error) { func (as *availabilitySet) GetInstanceTypeByNodeName(name string) (string, error) {
machine, err := as.getVirtualMachine(types.NodeName(name)) machine, err := as.getVirtualMachine(types.NodeName(name))
if err != nil { if err != nil {
glog.Errorf("error: as.GetInstanceTypeByNodeName(%s), as.getVirtualMachine(%s) err=%v", name, name, err) glog.Errorf("as.GetInstanceTypeByNodeName(%s) failed: as.getVirtualMachine(%s) err=%v", name, name, err)
return "", err return "", err
} }
...@@ -437,7 +437,7 @@ func (as *availabilitySet) GetIPByNodeName(name string) (string, string, error) ...@@ -437,7 +437,7 @@ func (as *availabilitySet) GetIPByNodeName(name string) (string, string, error)
ipConfig, err := getPrimaryIPConfig(nic) ipConfig, err := getPrimaryIPConfig(nic)
if err != nil { if err != nil {
glog.Errorf("error: as.GetIPByNodeName(%s), getPrimaryIPConfig(%v), err=%v", name, nic, err) glog.Errorf("as.GetIPByNodeName(%s) failed: getPrimaryIPConfig(%v), err=%v", name, nic, err)
return "", "", err return "", "", err
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment