mirror of
https://github.com/k3s-io/kubernetes.git
synced 2025-07-23 03:41:45 +00:00
Merge pull request #84865 from deads2k/feature-gate-fail
panic in featuregate if a requested feature is unknown
This commit is contained in:
commit
bae8f56bb1
@ -87,14 +87,10 @@ func getAzureTestCloud(t *testing.T) *azure.Cloud {
|
|||||||
"aadClientSecret": "--aad-client-secret--"
|
"aadClientSecret": "--aad-client-secret--"
|
||||||
}`
|
}`
|
||||||
configReader := strings.NewReader(config)
|
configReader := strings.NewReader(config)
|
||||||
cloud, err := azure.NewCloud(configReader)
|
azureCloud, err := azure.NewCloudWithoutFeatureGates(configReader)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Error(err)
|
t.Error(err)
|
||||||
}
|
}
|
||||||
azureCloud, ok := cloud.(*azure.Cloud)
|
|
||||||
if !ok {
|
|
||||||
t.Error("NewCloud returned incorrect type")
|
|
||||||
}
|
|
||||||
return azureCloud
|
return azureCloud
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -7,6 +7,7 @@ go_library(
|
|||||||
importpath = "k8s.io/component-base/featuregate",
|
importpath = "k8s.io/component-base/featuregate",
|
||||||
visibility = ["//visibility:public"],
|
visibility = ["//visibility:public"],
|
||||||
deps = [
|
deps = [
|
||||||
|
"//staging/src/k8s.io/apimachinery/pkg/util/naming:go_default_library",
|
||||||
"//vendor/github.com/spf13/pflag:go_default_library",
|
"//vendor/github.com/spf13/pflag:go_default_library",
|
||||||
"//vendor/k8s.io/klog:go_default_library",
|
"//vendor/k8s.io/klog:go_default_library",
|
||||||
],
|
],
|
||||||
|
@ -25,6 +25,8 @@ import (
|
|||||||
"sync/atomic"
|
"sync/atomic"
|
||||||
|
|
||||||
"github.com/spf13/pflag"
|
"github.com/spf13/pflag"
|
||||||
|
|
||||||
|
"k8s.io/apimachinery/pkg/util/naming"
|
||||||
"k8s.io/klog"
|
"k8s.io/klog"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -103,6 +105,8 @@ type MutableFeatureGate interface {
|
|||||||
|
|
||||||
// featureGate implements FeatureGate as well as pflag.Value for flag parsing.
|
// featureGate implements FeatureGate as well as pflag.Value for flag parsing.
|
||||||
type featureGate struct {
|
type featureGate struct {
|
||||||
|
featureGateName string
|
||||||
|
|
||||||
special map[Feature]func(map[Feature]FeatureSpec, map[Feature]bool, bool)
|
special map[Feature]func(map[Feature]FeatureSpec, map[Feature]bool, bool)
|
||||||
|
|
||||||
// lock guards writes to known, enabled, and reads/writes of closed
|
// lock guards writes to known, enabled, and reads/writes of closed
|
||||||
@ -128,6 +132,10 @@ func setUnsetAlphaGates(known map[Feature]FeatureSpec, enabled map[Feature]bool,
|
|||||||
// Set, String, and Type implement pflag.Value
|
// Set, String, and Type implement pflag.Value
|
||||||
var _ pflag.Value = &featureGate{}
|
var _ pflag.Value = &featureGate{}
|
||||||
|
|
||||||
|
// internalPackages are packages that ignored when creating a name for featureGates. These packages are in the common
|
||||||
|
// call chains, so they'd be unhelpful as names.
|
||||||
|
var internalPackages = []string{"k8s.io/component-base/featuregate/feature_gate.go"}
|
||||||
|
|
||||||
func NewFeatureGate() *featureGate {
|
func NewFeatureGate() *featureGate {
|
||||||
known := map[Feature]FeatureSpec{}
|
known := map[Feature]FeatureSpec{}
|
||||||
for k, v := range defaultFeatures {
|
for k, v := range defaultFeatures {
|
||||||
@ -142,6 +150,7 @@ func NewFeatureGate() *featureGate {
|
|||||||
enabledValue.Store(enabled)
|
enabledValue.Store(enabled)
|
||||||
|
|
||||||
f := &featureGate{
|
f := &featureGate{
|
||||||
|
featureGateName: naming.GetNameFromCallsite(internalPackages...),
|
||||||
known: knownValue,
|
known: knownValue,
|
||||||
special: specialFeatures,
|
special: specialFeatures,
|
||||||
enabled: enabledValue,
|
enabled: enabledValue,
|
||||||
@ -263,12 +272,16 @@ func (f *featureGate) Add(features map[Feature]FeatureSpec) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// Enabled returns true if the key is enabled.
|
// Enabled returns true if the key is enabled. If the key is not known, this call will panic.
|
||||||
func (f *featureGate) Enabled(key Feature) bool {
|
func (f *featureGate) Enabled(key Feature) bool {
|
||||||
if v, ok := f.enabled.Load().(map[Feature]bool)[key]; ok {
|
if v, ok := f.enabled.Load().(map[Feature]bool)[key]; ok {
|
||||||
return v
|
return v
|
||||||
}
|
}
|
||||||
return f.known.Load().(map[Feature]FeatureSpec)[key].Default
|
if v, ok := f.known.Load().(map[Feature]FeatureSpec)[key]; ok {
|
||||||
|
return v.Default
|
||||||
|
}
|
||||||
|
|
||||||
|
panic(fmt.Errorf("feature %q is not registered in FeatureGate %q", key, f.featureGateName))
|
||||||
}
|
}
|
||||||
|
|
||||||
// AddFlag adds a flag for setting global feature gates to the specified FlagSet.
|
// AddFlag adds a flag for setting global feature gates to the specified FlagSet.
|
||||||
|
@ -34,6 +34,7 @@ import (
|
|||||||
v1 "k8s.io/api/core/v1"
|
v1 "k8s.io/api/core/v1"
|
||||||
"k8s.io/apimachinery/pkg/util/sets"
|
"k8s.io/apimachinery/pkg/util/sets"
|
||||||
"k8s.io/apimachinery/pkg/util/wait"
|
"k8s.io/apimachinery/pkg/util/wait"
|
||||||
|
utilfeature "k8s.io/apiserver/pkg/util/feature"
|
||||||
"k8s.io/client-go/informers"
|
"k8s.io/client-go/informers"
|
||||||
clientset "k8s.io/client-go/kubernetes"
|
clientset "k8s.io/client-go/kubernetes"
|
||||||
"k8s.io/client-go/kubernetes/scheme"
|
"k8s.io/client-go/kubernetes/scheme"
|
||||||
@ -202,6 +203,8 @@ type Cloud struct {
|
|||||||
metadata *InstanceMetadataService
|
metadata *InstanceMetadataService
|
||||||
vmSet VMSet
|
vmSet VMSet
|
||||||
|
|
||||||
|
// ipv6DualStack allows overriding for unit testing. It's normally initialized from featuregates
|
||||||
|
ipv6DualStackEnabled bool
|
||||||
// Lock for access to node caches, includes nodeZones, nodeResourceGroups, and unmanagedNodes.
|
// Lock for access to node caches, includes nodeZones, nodeResourceGroups, and unmanagedNodes.
|
||||||
nodeCachesLock sync.Mutex
|
nodeCachesLock sync.Mutex
|
||||||
// nodeZones is a mapping from Zone to a sets.String of Node's names in the Zone
|
// nodeZones is a mapping from Zone to a sets.String of Node's names in the Zone
|
||||||
@ -260,6 +263,18 @@ func init() {
|
|||||||
|
|
||||||
// NewCloud returns a Cloud with initialized clients
|
// NewCloud returns a Cloud with initialized clients
|
||||||
func NewCloud(configReader io.Reader) (cloudprovider.Interface, error) {
|
func NewCloud(configReader io.Reader) (cloudprovider.Interface, error) {
|
||||||
|
az, err := NewCloudWithoutFeatureGates(configReader)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
az.ipv6DualStackEnabled = utilfeature.DefaultFeatureGate.Enabled(IPv6DualStack)
|
||||||
|
|
||||||
|
return az, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewCloudWithoutFeatureGates returns a Cloud without trying to wire the feature gates. This is used by the unit tests
|
||||||
|
// that don't load the actual features being used in the cluster.
|
||||||
|
func NewCloudWithoutFeatureGates(configReader io.Reader) (*Cloud, error) {
|
||||||
config, err := parseConfig(configReader)
|
config, err := parseConfig(configReader)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
@ -271,6 +286,7 @@ func NewCloud(configReader io.Reader) (cloudprovider.Interface, error) {
|
|||||||
unmanagedNodes: sets.NewString(),
|
unmanagedNodes: sets.NewString(),
|
||||||
routeCIDRs: map[string]string{},
|
routeCIDRs: map[string]string{},
|
||||||
}
|
}
|
||||||
|
|
||||||
err = az.InitializeCloudFromConfig(config, false)
|
err = az.InitializeCloudFromConfig(config, false)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
|
@ -35,8 +35,6 @@ import (
|
|||||||
cloudprovider "k8s.io/cloud-provider"
|
cloudprovider "k8s.io/cloud-provider"
|
||||||
servicehelpers "k8s.io/cloud-provider/service/helpers"
|
servicehelpers "k8s.io/cloud-provider/service/helpers"
|
||||||
"k8s.io/klog"
|
"k8s.io/klog"
|
||||||
|
|
||||||
utilfeature "k8s.io/apiserver/pkg/util/feature"
|
|
||||||
utilnet "k8s.io/utils/net"
|
utilnet "k8s.io/utils/net"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -563,7 +561,7 @@ func (az *Cloud) ensurePublicIPExists(service *v1.Service, pipName string, domai
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if utilfeature.DefaultFeatureGate.Enabled(IPv6DualStack) {
|
if az.ipv6DualStackEnabled {
|
||||||
// TODO: (khenidak) if we ever enable IPv6 single stack, then we should
|
// TODO: (khenidak) if we ever enable IPv6 single stack, then we should
|
||||||
// not wrap the following in a feature gate
|
// not wrap the following in a feature gate
|
||||||
ipv6 := utilnet.IsIPv6String(service.Spec.ClusterIP)
|
ipv6 := utilnet.IsIPv6String(service.Spec.ClusterIP)
|
||||||
@ -697,7 +695,7 @@ func (az *Cloud) reconcileLoadBalancer(clusterName string, service *v1.Service,
|
|||||||
klog.V(2).Infof("reconcileLoadBalancer for service(%s): lb(%s) wantLb(%t) resolved load balancer name", serviceName, lbName, wantLb)
|
klog.V(2).Infof("reconcileLoadBalancer for service(%s): lb(%s) wantLb(%t) resolved load balancer name", serviceName, lbName, wantLb)
|
||||||
lbFrontendIPConfigName := az.getFrontendIPConfigName(service, subnet(service))
|
lbFrontendIPConfigName := az.getFrontendIPConfigName(service, subnet(service))
|
||||||
lbFrontendIPConfigID := az.getFrontendIPConfigID(lbName, lbFrontendIPConfigName)
|
lbFrontendIPConfigID := az.getFrontendIPConfigID(lbName, lbFrontendIPConfigName)
|
||||||
lbBackendPoolName := getBackendPoolName(clusterName, service)
|
lbBackendPoolName := getBackendPoolName(az.ipv6DualStackEnabled, clusterName, service)
|
||||||
lbBackendPoolID := az.getBackendPoolID(lbName, lbBackendPoolName)
|
lbBackendPoolID := az.getBackendPoolID(lbName, lbBackendPoolName)
|
||||||
|
|
||||||
lbIdleTimeout, err := getIdleTimeout(service)
|
lbIdleTimeout, err := getIdleTimeout(service)
|
||||||
|
@ -30,10 +30,6 @@ import (
|
|||||||
cloudprovider "k8s.io/cloud-provider"
|
cloudprovider "k8s.io/cloud-provider"
|
||||||
"k8s.io/klog"
|
"k8s.io/klog"
|
||||||
utilnet "k8s.io/utils/net"
|
utilnet "k8s.io/utils/net"
|
||||||
|
|
||||||
// Azure route controller changes behavior if ipv6dual stack feature is turned on
|
|
||||||
// remove this once the feature graduates
|
|
||||||
utilfeature "k8s.io/apiserver/pkg/util/feature"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// copied to minimize the number of cross reference
|
// copied to minimize the number of cross reference
|
||||||
@ -47,7 +43,7 @@ const (
|
|||||||
func (az *Cloud) ListRoutes(ctx context.Context, clusterName string) ([]*cloudprovider.Route, error) {
|
func (az *Cloud) ListRoutes(ctx context.Context, clusterName string) ([]*cloudprovider.Route, error) {
|
||||||
klog.V(10).Infof("ListRoutes: START clusterName=%q", clusterName)
|
klog.V(10).Infof("ListRoutes: START clusterName=%q", clusterName)
|
||||||
routeTable, existsRouteTable, err := az.getRouteTable(cacheReadTypeDefault)
|
routeTable, existsRouteTable, err := az.getRouteTable(cacheReadTypeDefault)
|
||||||
routes, err := processRoutes(routeTable, existsRouteTable, err)
|
routes, err := processRoutes(az.ipv6DualStackEnabled, routeTable, existsRouteTable, err)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@ -63,7 +59,7 @@ func (az *Cloud) ListRoutes(ctx context.Context, clusterName string) ([]*cloudpr
|
|||||||
if cidr, ok := az.routeCIDRs[nodeName]; ok {
|
if cidr, ok := az.routeCIDRs[nodeName]; ok {
|
||||||
routes = append(routes, &cloudprovider.Route{
|
routes = append(routes, &cloudprovider.Route{
|
||||||
Name: nodeName,
|
Name: nodeName,
|
||||||
TargetNode: mapRouteNameToNodeName(nodeName),
|
TargetNode: mapRouteNameToNodeName(az.ipv6DualStackEnabled, nodeName),
|
||||||
DestinationCIDR: cidr,
|
DestinationCIDR: cidr,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@ -73,7 +69,7 @@ func (az *Cloud) ListRoutes(ctx context.Context, clusterName string) ([]*cloudpr
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Injectable for testing
|
// Injectable for testing
|
||||||
func processRoutes(routeTable network.RouteTable, exists bool, err error) ([]*cloudprovider.Route, error) {
|
func processRoutes(ipv6DualStackEnabled bool, routeTable network.RouteTable, exists bool, err error) ([]*cloudprovider.Route, error) {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@ -85,7 +81,7 @@ func processRoutes(routeTable network.RouteTable, exists bool, err error) ([]*cl
|
|||||||
if routeTable.RouteTablePropertiesFormat != nil && routeTable.Routes != nil {
|
if routeTable.RouteTablePropertiesFormat != nil && routeTable.Routes != nil {
|
||||||
kubeRoutes = make([]*cloudprovider.Route, len(*routeTable.Routes))
|
kubeRoutes = make([]*cloudprovider.Route, len(*routeTable.Routes))
|
||||||
for i, route := range *routeTable.Routes {
|
for i, route := range *routeTable.Routes {
|
||||||
instance := mapRouteNameToNodeName(*route.Name)
|
instance := mapRouteNameToNodeName(ipv6DualStackEnabled, *route.Name)
|
||||||
cidr := *route.AddressPrefix
|
cidr := *route.AddressPrefix
|
||||||
klog.V(10).Infof("ListRoutes: * instance=%q, cidr=%q", instance, cidr)
|
klog.V(10).Infof("ListRoutes: * instance=%q, cidr=%q", instance, cidr)
|
||||||
|
|
||||||
@ -141,7 +137,7 @@ func (az *Cloud) CreateRoute(ctx context.Context, clusterName string, nameHint s
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
if unmanaged {
|
if unmanaged {
|
||||||
if utilfeature.DefaultFeatureGate.Enabled(IPv6DualStack) {
|
if az.ipv6DualStackEnabled {
|
||||||
//TODO (khenidak) add support for unmanaged nodes when the feature reaches beta
|
//TODO (khenidak) add support for unmanaged nodes when the feature reaches beta
|
||||||
return fmt.Errorf("unmanaged nodes are not supported in dual stack mode")
|
return fmt.Errorf("unmanaged nodes are not supported in dual stack mode")
|
||||||
}
|
}
|
||||||
@ -156,7 +152,7 @@ func (az *Cloud) CreateRoute(ctx context.Context, clusterName string, nameHint s
|
|||||||
if err := az.createRouteTableIfNotExists(clusterName, kubeRoute); err != nil {
|
if err := az.createRouteTableIfNotExists(clusterName, kubeRoute); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
if !utilfeature.DefaultFeatureGate.Enabled(IPv6DualStack) {
|
if !az.ipv6DualStackEnabled {
|
||||||
targetIP, _, err = az.getIPForMachine(kubeRoute.TargetNode)
|
targetIP, _, err = az.getIPForMachine(kubeRoute.TargetNode)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
@ -178,7 +174,7 @@ func (az *Cloud) CreateRoute(ctx context.Context, clusterName string, nameHint s
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
routeName := mapNodeNameToRouteName(kubeRoute.TargetNode, string(kubeRoute.DestinationCIDR))
|
routeName := mapNodeNameToRouteName(az.ipv6DualStackEnabled, kubeRoute.TargetNode, string(kubeRoute.DestinationCIDR))
|
||||||
route := network.Route{
|
route := network.Route{
|
||||||
Name: to.StringPtr(routeName),
|
Name: to.StringPtr(routeName),
|
||||||
RoutePropertiesFormat: &network.RoutePropertiesFormat{
|
RoutePropertiesFormat: &network.RoutePropertiesFormat{
|
||||||
@ -217,7 +213,7 @@ func (az *Cloud) DeleteRoute(ctx context.Context, clusterName string, kubeRoute
|
|||||||
|
|
||||||
klog.V(2).Infof("DeleteRoute: deleting route. clusterName=%q instance=%q cidr=%q", clusterName, kubeRoute.TargetNode, kubeRoute.DestinationCIDR)
|
klog.V(2).Infof("DeleteRoute: deleting route. clusterName=%q instance=%q cidr=%q", clusterName, kubeRoute.TargetNode, kubeRoute.DestinationCIDR)
|
||||||
|
|
||||||
routeName := mapNodeNameToRouteName(kubeRoute.TargetNode, string(kubeRoute.DestinationCIDR))
|
routeName := mapNodeNameToRouteName(az.ipv6DualStackEnabled, kubeRoute.TargetNode, string(kubeRoute.DestinationCIDR))
|
||||||
err = az.DeleteRouteWithName(routeName)
|
err = az.DeleteRouteWithName(routeName)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
@ -231,16 +227,16 @@ func (az *Cloud) DeleteRoute(ctx context.Context, clusterName string, kubeRoute
|
|||||||
// These two functions enable stashing the instance name in the route
|
// These two functions enable stashing the instance name in the route
|
||||||
// and then retrieving it later when listing. This is needed because
|
// and then retrieving it later when listing. This is needed because
|
||||||
// Azure does not let you put tags/descriptions on the Route itself.
|
// Azure does not let you put tags/descriptions on the Route itself.
|
||||||
func mapNodeNameToRouteName(nodeName types.NodeName, cidr string) string {
|
func mapNodeNameToRouteName(ipv6DualStackEnabled bool, nodeName types.NodeName, cidr string) string {
|
||||||
if !utilfeature.DefaultFeatureGate.Enabled(IPv6DualStack) {
|
if !ipv6DualStackEnabled {
|
||||||
return fmt.Sprintf("%s", nodeName)
|
return fmt.Sprintf("%s", nodeName)
|
||||||
}
|
}
|
||||||
return fmt.Sprintf(routeNameFmt, nodeName, cidrtoRfc1035(cidr))
|
return fmt.Sprintf(routeNameFmt, nodeName, cidrtoRfc1035(cidr))
|
||||||
}
|
}
|
||||||
|
|
||||||
// Used with mapNodeNameToRouteName. See comment on mapNodeNameToRouteName.
|
// Used with mapNodeNameToRouteName. See comment on mapNodeNameToRouteName.
|
||||||
func mapRouteNameToNodeName(routeName string) types.NodeName {
|
func mapRouteNameToNodeName(ipv6DualStackEnabled bool, routeName string) types.NodeName {
|
||||||
if !utilfeature.DefaultFeatureGate.Enabled(IPv6DualStack) {
|
if !ipv6DualStackEnabled {
|
||||||
return types.NodeName(fmt.Sprintf("%s", routeName))
|
return types.NodeName(fmt.Sprintf("%s", routeName))
|
||||||
}
|
}
|
||||||
parts := strings.Split(routeName, routeNameSeparator)
|
parts := strings.Split(routeName, routeNameSeparator)
|
||||||
|
@ -47,7 +47,7 @@ func TestDeleteRoute(t *testing.T) {
|
|||||||
nodeInformerSynced: func() bool { return true },
|
nodeInformerSynced: func() bool { return true },
|
||||||
}
|
}
|
||||||
route := cloudprovider.Route{TargetNode: "node", DestinationCIDR: "1.2.3.4/24"}
|
route := cloudprovider.Route{TargetNode: "node", DestinationCIDR: "1.2.3.4/24"}
|
||||||
routeName := mapNodeNameToRouteName(route.TargetNode, route.DestinationCIDR)
|
routeName := mapNodeNameToRouteName(false, route.TargetNode, route.DestinationCIDR)
|
||||||
|
|
||||||
fakeRoutes.FakeStore = map[string]map[string]network.Route{
|
fakeRoutes.FakeStore = map[string]map[string]network.Route{
|
||||||
cloud.RouteTableName: {
|
cloud.RouteTableName: {
|
||||||
@ -80,7 +80,7 @@ func TestDeleteRoute(t *testing.T) {
|
|||||||
nodeName: nodeCIDR,
|
nodeName: nodeCIDR,
|
||||||
}
|
}
|
||||||
route1 := cloudprovider.Route{
|
route1 := cloudprovider.Route{
|
||||||
TargetNode: mapRouteNameToNodeName(nodeName),
|
TargetNode: mapRouteNameToNodeName(false, nodeName),
|
||||||
DestinationCIDR: nodeCIDR,
|
DestinationCIDR: nodeCIDR,
|
||||||
}
|
}
|
||||||
err = cloud.DeleteRoute(context.TODO(), "cluster", &route1)
|
err = cloud.DeleteRoute(context.TODO(), "cluster", &route1)
|
||||||
@ -138,7 +138,7 @@ func TestCreateRoute(t *testing.T) {
|
|||||||
t.Errorf("unexpected calls create if not exists, exists: %v", fakeTable.Calls)
|
t.Errorf("unexpected calls create if not exists, exists: %v", fakeTable.Calls)
|
||||||
}
|
}
|
||||||
|
|
||||||
routeName := mapNodeNameToRouteName(route.TargetNode, string(route.DestinationCIDR))
|
routeName := mapNodeNameToRouteName(false, route.TargetNode, string(route.DestinationCIDR))
|
||||||
routeInfo, found := fakeRoutes.FakeStore[cloud.RouteTableName][routeName]
|
routeInfo, found := fakeRoutes.FakeStore[cloud.RouteTableName][routeName]
|
||||||
if !found {
|
if !found {
|
||||||
t.Errorf("could not find route: %v in %v", routeName, fakeRoutes.FakeStore)
|
t.Errorf("could not find route: %v in %v", routeName, fakeRoutes.FakeStore)
|
||||||
@ -160,7 +160,7 @@ func TestCreateRoute(t *testing.T) {
|
|||||||
cloud.unmanagedNodes.Insert(nodeName)
|
cloud.unmanagedNodes.Insert(nodeName)
|
||||||
cloud.routeCIDRs = map[string]string{}
|
cloud.routeCIDRs = map[string]string{}
|
||||||
route1 := cloudprovider.Route{
|
route1 := cloudprovider.Route{
|
||||||
TargetNode: mapRouteNameToNodeName(nodeName),
|
TargetNode: mapRouteNameToNodeName(false, nodeName),
|
||||||
DestinationCIDR: nodeCIDR,
|
DestinationCIDR: nodeCIDR,
|
||||||
}
|
}
|
||||||
err = cloud.CreateRoute(context.TODO(), "cluster", "unused", &route1)
|
err = cloud.CreateRoute(context.TODO(), "cluster", "unused", &route1)
|
||||||
@ -326,7 +326,7 @@ func TestProcessRoutes(t *testing.T) {
|
|||||||
expectedRoute: []cloudprovider.Route{
|
expectedRoute: []cloudprovider.Route{
|
||||||
{
|
{
|
||||||
Name: "name",
|
Name: "name",
|
||||||
TargetNode: mapRouteNameToNodeName("name"),
|
TargetNode: mapRouteNameToNodeName(false, "name"),
|
||||||
DestinationCIDR: "1.2.3.4/16",
|
DestinationCIDR: "1.2.3.4/16",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@ -355,12 +355,12 @@ func TestProcessRoutes(t *testing.T) {
|
|||||||
expectedRoute: []cloudprovider.Route{
|
expectedRoute: []cloudprovider.Route{
|
||||||
{
|
{
|
||||||
Name: "name",
|
Name: "name",
|
||||||
TargetNode: mapRouteNameToNodeName("name"),
|
TargetNode: mapRouteNameToNodeName(false, "name"),
|
||||||
DestinationCIDR: "1.2.3.4/16",
|
DestinationCIDR: "1.2.3.4/16",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
Name: "name2",
|
Name: "name2",
|
||||||
TargetNode: mapRouteNameToNodeName("name2"),
|
TargetNode: mapRouteNameToNodeName(false, "name2"),
|
||||||
DestinationCIDR: "5.6.7.8/16",
|
DestinationCIDR: "5.6.7.8/16",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@ -368,7 +368,7 @@ func TestProcessRoutes(t *testing.T) {
|
|||||||
},
|
},
|
||||||
}
|
}
|
||||||
for _, test := range tests {
|
for _, test := range tests {
|
||||||
routes, err := processRoutes(test.rt, test.exists, test.err)
|
routes, err := processRoutes(false, test.rt, test.exists, test.err)
|
||||||
if test.expectErr {
|
if test.expectErr {
|
||||||
if err == nil {
|
if err == nil {
|
||||||
t.Errorf("%s: unexpected non-error", test.name)
|
t.Errorf("%s: unexpected non-error", test.name)
|
||||||
@ -423,11 +423,11 @@ func TestRouteNameFuncs(t *testing.T) {
|
|||||||
v6CIDR := "fd3e:5f02:6ec0:30ba::/64"
|
v6CIDR := "fd3e:5f02:6ec0:30ba::/64"
|
||||||
nodeName := "thisNode"
|
nodeName := "thisNode"
|
||||||
|
|
||||||
routeName := mapNodeNameToRouteName(types.NodeName(nodeName), v4CIDR)
|
routeName := mapNodeNameToRouteName(false, types.NodeName(nodeName), v4CIDR)
|
||||||
outNodeName := mapRouteNameToNodeName(routeName)
|
outNodeName := mapRouteNameToNodeName(false, routeName)
|
||||||
assert.Equal(t, string(outNodeName), nodeName)
|
assert.Equal(t, string(outNodeName), nodeName)
|
||||||
|
|
||||||
routeName = mapNodeNameToRouteName(types.NodeName(nodeName), v6CIDR)
|
routeName = mapNodeNameToRouteName(false, types.NodeName(nodeName), v6CIDR)
|
||||||
outNodeName = mapRouteNameToNodeName(routeName)
|
outNodeName = mapRouteNameToNodeName(false, routeName)
|
||||||
assert.Equal(t, string(outNodeName), nodeName)
|
assert.Equal(t, string(outNodeName), nodeName)
|
||||||
}
|
}
|
||||||
|
@ -40,7 +40,6 @@ import (
|
|||||||
cloudprovider "k8s.io/cloud-provider"
|
cloudprovider "k8s.io/cloud-provider"
|
||||||
"k8s.io/klog"
|
"k8s.io/klog"
|
||||||
|
|
||||||
utilfeature "k8s.io/apiserver/pkg/util/feature"
|
|
||||||
"k8s.io/component-base/featuregate"
|
"k8s.io/component-base/featuregate"
|
||||||
utilnet "k8s.io/utils/net"
|
utilnet "k8s.io/utils/net"
|
||||||
)
|
)
|
||||||
@ -263,8 +262,8 @@ func isInternalLoadBalancer(lb *network.LoadBalancer) bool {
|
|||||||
// clusters moving from IPv4 to duakstack will require no changes
|
// clusters moving from IPv4 to duakstack will require no changes
|
||||||
// clusters moving from IPv6 (while not seen in the wild, we can not rule out their existence)
|
// clusters moving from IPv6 (while not seen in the wild, we can not rule out their existence)
|
||||||
// to dualstack will require deleting backend pools (the reconciler will take care of creating correct backendpools)
|
// to dualstack will require deleting backend pools (the reconciler will take care of creating correct backendpools)
|
||||||
func getBackendPoolName(clusterName string, service *v1.Service) string {
|
func getBackendPoolName(ipv6DualStackEnabled bool, clusterName string, service *v1.Service) string {
|
||||||
if !utilfeature.DefaultFeatureGate.Enabled(IPv6DualStack) {
|
if !ipv6DualStackEnabled {
|
||||||
return clusterName
|
return clusterName
|
||||||
}
|
}
|
||||||
IPv6 := utilnet.IsIPv6String(service.Spec.ClusterIP)
|
IPv6 := utilnet.IsIPv6String(service.Spec.ClusterIP)
|
||||||
@ -721,7 +720,7 @@ func (as *availabilitySet) EnsureHostInPool(service *v1.Service, nodeName types.
|
|||||||
}
|
}
|
||||||
|
|
||||||
var primaryIPConfig *network.InterfaceIPConfiguration
|
var primaryIPConfig *network.InterfaceIPConfiguration
|
||||||
if !utilfeature.DefaultFeatureGate.Enabled(IPv6DualStack) {
|
if !as.Cloud.ipv6DualStackEnabled {
|
||||||
primaryIPConfig, err = getPrimaryIPConfig(nic)
|
primaryIPConfig, err = getPrimaryIPConfig(nic)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
|
@ -1701,14 +1701,10 @@ func validateConfig(t *testing.T, config string) {
|
|||||||
|
|
||||||
func getCloudFromConfig(t *testing.T, config string) *Cloud {
|
func getCloudFromConfig(t *testing.T, config string) *Cloud {
|
||||||
configReader := strings.NewReader(config)
|
configReader := strings.NewReader(config)
|
||||||
cloud, err := NewCloud(configReader)
|
azureCloud, err := NewCloudWithoutFeatureGates(configReader)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Error(err)
|
t.Error(err)
|
||||||
}
|
}
|
||||||
azureCloud, ok := cloud.(*Cloud)
|
|
||||||
if !ok {
|
|
||||||
t.Error("NewCloud returned incorrect type")
|
|
||||||
}
|
|
||||||
return azureCloud
|
return azureCloud
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -37,7 +37,6 @@ import (
|
|||||||
cloudprovider "k8s.io/cloud-provider"
|
cloudprovider "k8s.io/cloud-provider"
|
||||||
"k8s.io/klog"
|
"k8s.io/klog"
|
||||||
|
|
||||||
utilfeature "k8s.io/apiserver/pkg/util/feature"
|
|
||||||
utilnet "k8s.io/utils/net"
|
utilnet "k8s.io/utils/net"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -775,7 +774,7 @@ func (ss *scaleSet) EnsureHostInPool(service *v1.Service, nodeName types.NodeNam
|
|||||||
|
|
||||||
var primaryIPConfiguration *compute.VirtualMachineScaleSetIPConfiguration
|
var primaryIPConfiguration *compute.VirtualMachineScaleSetIPConfiguration
|
||||||
// Find primary network interface configuration.
|
// Find primary network interface configuration.
|
||||||
if !utilfeature.DefaultFeatureGate.Enabled(IPv6DualStack) {
|
if !ss.Cloud.ipv6DualStackEnabled {
|
||||||
// Find primary IP configuration.
|
// Find primary IP configuration.
|
||||||
primaryIPConfiguration, err = getPrimaryIPConfigFromVMSSNetworkConfig(primaryNetworkInterfaceConfiguration)
|
primaryIPConfiguration, err = getPrimaryIPConfigFromVMSSNetworkConfig(primaryNetworkInterfaceConfiguration)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
Loading…
Reference in New Issue
Block a user