Skip to content

Commit c662265

Browse files
committed
topology-updater: Add owner reference to NRT object
Signed-off-by: Oleg Zhurakivskyy <[email protected]>
1 parent 52d4337 commit c662265

File tree

5 files changed

+98
-7
lines changed

5 files changed

+98
-7
lines changed

deployment/base/rbac-topologyupdater/topologyupdater-clusterrole.yaml

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,12 @@ rules:
1010
verbs:
1111
- get
1212
- list
13+
- apiGroups:
14+
- ""
15+
resources:
16+
- namespaces
17+
verbs:
18+
- get
1319
- apiGroups:
1420
- ""
1521
resources:

deployment/helm/node-feature-discovery/templates/clusterrole.yaml

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,12 @@ rules:
5858
verbs:
5959
- get
6060
- list
61+
- apiGroups:
62+
- ""
63+
resources:
64+
- namespaces
65+
verbs:
66+
- get
6167
- apiGroups:
6268
- ""
6369
resources:

pkg/nfd-topology-updater/nfd-topology-updater.go

Lines changed: 27 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ import (
2626

2727
"k8s.io/apimachinery/pkg/api/errors"
2828
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
29+
"k8s.io/apimachinery/pkg/types"
2930
k8sclient "k8s.io/client-go/kubernetes"
3031
"k8s.io/klog/v2"
3132
kubeletconfigv1beta1 "k8s.io/kubelet/config/v1beta1"
@@ -80,6 +81,9 @@ type nfdTopologyUpdater struct {
8081
eventSource <-chan kubeletnotifier.Info
8182
configFilePath string
8283
config *NFDConfig
84+
kubernetesNamespace string
85+
ownerRefs []metav1.OwnerReference
86+
k8sClient k8sclient.Interface
8387
kubeletConfigFunc func() (*kubeletconfigv1beta1.KubeletConfiguration, error)
8488
}
8589

@@ -105,6 +109,8 @@ func NewTopologyUpdater(args Args, resourcemonitorArgs resourcemonitor.Args) (Nf
105109
nodeName: utils.NodeName(),
106110
eventSource: eventSource,
107111
config: &NFDConfig{},
112+
kubernetesNamespace: utils.GetKubernetesNamespace(),
113+
ownerRefs: []metav1.OwnerReference{},
108114
kubeletConfigFunc: kubeletConfigFunc,
109115
}
110116
if args.ConfigFile != "" {
@@ -146,6 +152,7 @@ func (w *nfdTopologyUpdater) Run() error {
146152
if err != nil {
147153
return err
148154
}
155+
w.k8sClient = k8sClient
149156

150157
if err := w.configure(); err != nil {
151158
return fmt.Errorf("faild to configure Node Feature Discovery Topology Updater: %w", err)
@@ -222,11 +229,29 @@ func (w *nfdTopologyUpdater) Stop() {
222229
}
223230

224231
func (w *nfdTopologyUpdater) updateNodeResourceTopology(zoneInfo v1alpha2.ZoneList, scanResponse resourcemonitor.ScanResponse, readKubeletConfig bool) error {
232+
233+
if len(w.ownerRefs) == 0 {
234+
ns, err := w.k8sClient.CoreV1().Namespaces().Get(context.TODO(), w.kubernetesNamespace, metav1.GetOptions{})
235+
if err != nil {
236+
klog.ErrorS(err, "Cannot get NodeResourceTopology owner reference")
237+
} else {
238+
w.ownerRefs = []metav1.OwnerReference{
239+
{
240+
APIVersion: ns.APIVersion,
241+
Kind: ns.Kind,
242+
Name: ns.Name,
243+
UID: types.UID(ns.UID),
244+
},
245+
}
246+
}
247+
}
248+
225249
nrt, err := w.topoClient.TopologyV1alpha2().NodeResourceTopologies().Get(context.TODO(), w.nodeName, metav1.GetOptions{})
226250
if errors.IsNotFound(err) {
227251
nrtNew := v1alpha2.NodeResourceTopology{
228252
ObjectMeta: metav1.ObjectMeta{
229-
Name: w.nodeName,
253+
Name: w.nodeName,
254+
OwnerReferences: w.ownerRefs,
230255
},
231256
Zones: zoneInfo,
232257
Attributes: v1alpha2.AttributeList{},
@@ -248,6 +273,7 @@ func (w *nfdTopologyUpdater) updateNodeResourceTopology(zoneInfo v1alpha2.ZoneLi
248273

249274
nrtMutated := nrt.DeepCopy()
250275
nrtMutated.Zones = zoneInfo
276+
nrtMutated.OwnerReferences = w.ownerRefs
251277

252278
attributes := scanResponse.Attributes
253279

test/e2e/topology_updater_test.go

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -261,6 +261,44 @@ var _ = NFDDescribe(Label("nfd-topology-updater"), func() {
261261
return true
262262
}, time.Minute, 5*time.Second).Should(BeTrue(), "didn't get updated node topology info")
263263
})
264+
265+
It("should check that that topology object is garbage colleted", func(ctx context.Context) {
266+
267+
By("Check if the topology object has owner reference")
268+
ns, err := f.ClientSet.CoreV1().Namespaces().Get(ctx, f.Namespace.Name, metav1.GetOptions{})
269+
Expect(err).NotTo(HaveOccurred())
270+
271+
t, err := topologyClient.TopologyV1alpha2().NodeResourceTopologies().Get(ctx, topologyUpdaterNode.Name, metav1.GetOptions{})
272+
Expect(err).NotTo(HaveOccurred())
273+
274+
owned := false
275+
for _, r := range t.OwnerReferences {
276+
if r.UID == ns.UID {
277+
owned = true
278+
break
279+
}
280+
}
281+
Expect(owned).Should(BeTrue())
282+
283+
By("Deleting the nfd-topology namespace")
284+
err = f.ClientSet.CoreV1().Namespaces().Delete(ctx, f.Namespace.Name, metav1.DeleteOptions{})
285+
Expect(err).NotTo(HaveOccurred())
286+
287+
By("checking that topology was garbage collected")
288+
Eventually(func() bool {
289+
t, err := topologyClient.TopologyV1alpha2().NodeResourceTopologies().Get(ctx, topologyUpdaterNode.Name, metav1.GetOptions{})
290+
if err != nil {
291+
if apierrors.IsNotFound(err) {
292+
framework.Logf("missing node topology resource for %q", topologyUpdaterNode.Name)
293+
return false
294+
}
295+
framework.Logf("failed to get the node topology resource: %v", err)
296+
return true
297+
}
298+
framework.Logf("topology resource: %v", t)
299+
return true
300+
}).WithPolling(15 * time.Second).WithTimeout(60 * time.Second).Should(BeFalse())
301+
})
264302
})
265303

266304
When("sleep interval disabled", func() {

test/e2e/utils/rbac.go

Lines changed: 21 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ import (
2222

2323
corev1 "k8s.io/api/core/v1"
2424
rbacv1 "k8s.io/api/rbac/v1"
25+
apierrors "k8s.io/apimachinery/pkg/api/errors"
2526
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
2627
clientset "k8s.io/client-go/kubernetes"
2728
)
@@ -105,10 +106,6 @@ func DeconfigureRBAC(ctx context.Context, cs clientset.Interface, ns string) err
105106
if err != nil {
106107
return err
107108
}
108-
err = cs.RbacV1().RoleBindings(ns).Delete(ctx, "nfd-worker-e2e", metav1.DeleteOptions{})
109-
if err != nil {
110-
return err
111-
}
112109
err = cs.RbacV1().ClusterRoleBindings().Delete(ctx, "nfd-gc-e2e", metav1.DeleteOptions{})
113110
if err != nil {
114111
return err
@@ -121,11 +118,24 @@ func DeconfigureRBAC(ctx context.Context, cs clientset.Interface, ns string) err
121118
if err != nil {
122119
return err
123120
}
124-
err = cs.RbacV1().Roles(ns).Delete(ctx, "nfd-worker-e2e", metav1.DeleteOptions{})
121+
err = cs.RbacV1().ClusterRoles().Delete(ctx, "nfd-gc-e2e", metav1.DeleteOptions{})
125122
if err != nil {
126123
return err
127124
}
128-
err = cs.RbacV1().ClusterRoles().Delete(ctx, "nfd-gc-e2e", metav1.DeleteOptions{})
125+
126+
// Skip the deletion of namespaced objects in case the namespace is gone
127+
_, err = cs.CoreV1().Namespaces().Get(ctx, ns, metav1.GetOptions{})
128+
if err != nil {
129+
if apierrors.IsNotFound(err) {
130+
return nil
131+
}
132+
return err
133+
}
134+
err = cs.RbacV1().RoleBindings(ns).Delete(ctx, "nfd-worker-e2e", metav1.DeleteOptions{})
135+
if err != nil {
136+
return err
137+
}
138+
err = cs.RbacV1().Roles(ns).Delete(ctx, "nfd-worker-e2e", metav1.DeleteOptions{})
129139
if err != nil {
130140
return err
131141
}
@@ -251,6 +261,11 @@ func createClusterRoleTopologyUpdater(ctx context.Context, cs clientset.Interfac
251261
Resources: []string{"pods"},
252262
Verbs: []string{"get", "list", "watch"},
253263
},
264+
{
265+
APIGroups: []string{""},
266+
Resources: []string{"namespaces"},
267+
Verbs: []string{"get"},
268+
},
254269
{
255270
APIGroups: []string{"topology.node.k8s.io"},
256271
Resources: []string{"noderesourcetopologies"},

0 commit comments

Comments
 (0)