Skip to content

Commit d9734ca

Browse files
authored
Avoid nil pointer panics with clusterProfileCreds (#8071)
1 parent 0b3b6aa commit d9734ca

File tree

6 files changed

+81
-1
lines changed

6 files changed

+81
-1
lines changed

pkg/controller/admissionchecks/multikueue/controllers.go

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -124,7 +124,7 @@ func SetupControllers(mgr ctrl.Manager, namespace string, opts ...SetupOption) e
124124
return err
125125
}
126126

127-
var cpCreds *credentials.CredentialsProvider
127+
var cpCreds clusterProfileCreds
128128
if features.Enabled(features.MultiKueueClusterProfile) && options.clusterProfileConfig != nil {
129129
p := make([]credentials.Provider, 0, len(options.clusterProfileConfig.CredentialsProviders))
130130
for _, provider := range options.clusterProfileConfig.CredentialsProviders {
@@ -135,6 +135,9 @@ func SetupControllers(mgr ctrl.Manager, namespace string, opts ...SetupOption) e
135135
}
136136
cpCreds = credentials.New(p)
137137
}
138+
if cpCreds == nil {
139+
cpCreds = &NoOpClusterProfileCreds{}
140+
}
138141

139142
cRec := newClustersReconciler(mgr.GetClient(), namespace, options.gcInterval, options.origin, fsWatcher, options.adapters, cpCreds)
140143
err = cRec.setupWithManager(mgr)

pkg/controller/admissionchecks/multikueue/multikueuecluster.go

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@ import (
4646
"k8s.io/klog/v2"
4747
"k8s.io/utils/ptr"
4848
inventoryv1alpha1 "sigs.k8s.io/cluster-inventory-api/apis/v1alpha1"
49+
"sigs.k8s.io/cluster-inventory-api/pkg/credentials"
4950
ctrl "sigs.k8s.io/controller-runtime"
5051
"sigs.k8s.io/controller-runtime/pkg/client"
5152
"sigs.k8s.io/controller-runtime/pkg/event"
@@ -358,6 +359,15 @@ type clusterProfileCreds interface {
358359
BuildConfigFromCP(clusterprofile *inventoryv1alpha1.ClusterProfile) (*rest.Config, error)
359360
}
360361

362+
type NoOpClusterProfileCreds struct{}
363+
364+
func (NoOpClusterProfileCreds) BuildConfigFromCP(clusterprofile *inventoryv1alpha1.ClusterProfile) (*rest.Config, error) {
365+
return nil, errors.New("no credentials provider configured")
366+
}
367+
368+
var _ clusterProfileCreds = (*credentials.CredentialsProvider)(nil)
369+
var _ clusterProfileCreds = (*NoOpClusterProfileCreds)(nil)
370+
361371
var _ manager.Runnable = (*clustersReconciler)(nil)
362372
var _ reconcile.Reconciler = (*clustersReconciler)(nil)
363373

pkg/util/testing/v1beta2/wrappers.go

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ import (
2828
"k8s.io/apimachinery/pkg/runtime/schema"
2929
"k8s.io/apimachinery/pkg/types"
3030
"k8s.io/utils/ptr"
31+
inventoryv1alpha1 "sigs.k8s.io/cluster-inventory-api/apis/v1alpha1"
3132
"sigs.k8s.io/controller-runtime/pkg/client"
3233

3334
kueue "sigs.k8s.io/kueue/apis/kueue/v1beta2"
@@ -1561,3 +1562,35 @@ func (prc *ProvisioningRequestConfigWrapper) Clone() *ProvisioningRequestConfigW
15611562
func (prc *ProvisioningRequestConfigWrapper) Obj() *kueue.ProvisioningRequestConfig {
15621563
return &prc.ProvisioningRequestConfig
15631564
}
1565+
1566+
type ClusterProfileWrapper struct {
1567+
inventoryv1alpha1.ClusterProfile
1568+
}
1569+
1570+
func MakeClusterProfile(name, ns string) *ClusterProfileWrapper {
1571+
return &ClusterProfileWrapper{
1572+
ClusterProfile: inventoryv1alpha1.ClusterProfile{
1573+
ObjectMeta: metav1.ObjectMeta{
1574+
Name: name,
1575+
Namespace: ns,
1576+
},
1577+
Spec: inventoryv1alpha1.ClusterProfileSpec{},
1578+
},
1579+
}
1580+
}
1581+
1582+
func (cpw *ClusterProfileWrapper) Obj() *inventoryv1alpha1.ClusterProfile {
1583+
return &cpw.ClusterProfile
1584+
}
1585+
1586+
func (cpw *ClusterProfileWrapper) DisplayName(displayName string) *ClusterProfileWrapper {
1587+
cpw.Spec.DisplayName = displayName
1588+
return cpw
1589+
}
1590+
1591+
func (cpw *ClusterProfileWrapper) ClusterManager(clusterManagerName string) *ClusterProfileWrapper {
1592+
cpw.Spec.ClusterManager = inventoryv1alpha1.ClusterManager{
1593+
Name: clusterManagerName,
1594+
}
1595+
return cpw
1596+
}

test/integration/framework/framework.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@ import (
4040
clientgoscheme "k8s.io/client-go/kubernetes/scheme"
4141
"k8s.io/client-go/rest"
4242
"k8s.io/utils/ptr"
43+
inventoryv1alpha1 "sigs.k8s.io/cluster-inventory-api/apis/v1alpha1"
4344
ctrl "sigs.k8s.io/controller-runtime"
4445
"sigs.k8s.io/controller-runtime/pkg/client"
4546
crconfig "sigs.k8s.io/controller-runtime/pkg/config"
@@ -158,6 +159,9 @@ func (f *Framework) SetupClient(cfg *rest.Config) (context.Context, client.WithW
158159
err = resourcev1.AddToScheme(f.scheme)
159160
gomega.ExpectWithOffset(1, err).NotTo(gomega.HaveOccurred())
160161

162+
err = inventoryv1alpha1.AddToScheme(f.scheme)
163+
gomega.ExpectWithOffset(1, err).NotTo(gomega.HaveOccurred())
164+
161165
k8sClient, err := client.NewWithWatch(cfg, client.Options{Scheme: f.scheme})
162166
gomega.ExpectWithOffset(1, err).NotTo(gomega.HaveOccurred())
163167
gomega.ExpectWithOffset(1, k8sClient).NotTo(gomega.BeNil())

test/integration/multikueue/setup_test.go

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -809,4 +809,33 @@ var _ = ginkgo.Describe("MultiKueue", ginkgo.Label("area:multikueue", "feature:m
809809
})
810810
})
811811
})
812+
813+
ginkgo.It("Should report no cluster providers configured", func() {
814+
features.SetFeatureGateDuringTest(ginkgo.GinkgoTB(), features.MultiKueueClusterProfile, true)
815+
816+
ginkgo.By("Create ClusterProfile", func() {
817+
clusterProfile := utiltestingapi.MakeClusterProfile("test-profile", config.DefaultNamespace).Obj()
818+
gomega.Expect(managerTestCluster.client.Create(managerTestCluster.ctx, clusterProfile)).To(gomega.Succeed())
819+
})
820+
821+
var workerCluster3 *kueue.MultiKueueCluster
822+
ginkgo.By("Create a MultiKueueCluster with ClusterProfile as ClusterSource", func() {
823+
workerCluster3 = utiltestingapi.MakeMultiKueueCluster("worker3").ClusterProfile("test-profile").Obj()
824+
gomega.Expect(managerTestCluster.client.Create(managerTestCluster.ctx, workerCluster3)).To(gomega.Succeed())
825+
})
826+
827+
workerCluster3Key := client.ObjectKeyFromObject(workerCluster3)
828+
ginkgo.By("Verify status of the MultiKueueCluster", func() {
829+
mkc := &kueue.MultiKueueCluster{}
830+
gomega.Eventually(func(g gomega.Gomega) {
831+
g.Expect(managerTestCluster.client.Get(managerTestCluster.ctx, workerCluster3Key, mkc)).To(gomega.Succeed())
832+
g.Expect(mkc.Status.Conditions).To(gomega.ContainElement(gomega.BeComparableTo(metav1.Condition{
833+
Type: kueue.MultiKueueClusterActive,
834+
Status: metav1.ConditionFalse,
835+
Reason: "BadClusterProfile",
836+
Message: "load client config failed: no credentials provider configured",
837+
}, util.IgnoreConditionTimestampsAndObservedGeneration)))
838+
}, util.Timeout, util.Interval).Should(gomega.Succeed())
839+
})
840+
})
812841
})

test/integration/multikueue/suite_test.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -110,6 +110,7 @@ func createCluster(setupFnc framework.ManagerSetup, apiFeatureGates ...string) c
110110
util.AppWrapperCrds,
111111
util.KfTrainerCrds,
112112
util.AutoscalerCrds,
113+
util.ClusterProfileCrds,
113114
},
114115
APIServerFeatureGates: apiFeatureGates,
115116
}

0 commit comments

Comments
 (0)