mirror of
https://github.com/kubernetes-sigs/node-feature-discovery.git
synced 2025-03-16 21:38:23 +00:00
pkg/utils: move JsonPatch from pkg/apihelper
This commit is contained in:
parent
5d30be1013
commit
53003cbf69
8 changed files with 91 additions and 86 deletions
|
@ -22,6 +22,7 @@ import (
|
||||||
topologyclientset "github.com/k8stopologyawareschedwg/noderesourcetopology-api/pkg/generated/clientset/versioned"
|
topologyclientset "github.com/k8stopologyawareschedwg/noderesourcetopology-api/pkg/generated/clientset/versioned"
|
||||||
corev1 "k8s.io/api/core/v1"
|
corev1 "k8s.io/api/core/v1"
|
||||||
k8sclient "k8s.io/client-go/kubernetes"
|
k8sclient "k8s.io/client-go/kubernetes"
|
||||||
|
"sigs.k8s.io/node-feature-discovery/pkg/utils"
|
||||||
)
|
)
|
||||||
|
|
||||||
// APIHelpers represents a set of API helpers for Kubernetes
|
// APIHelpers represents a set of API helpers for Kubernetes
|
||||||
|
@ -39,10 +40,10 @@ type APIHelpers interface {
|
||||||
UpdateNode(*k8sclient.Clientset, *corev1.Node) error
|
UpdateNode(*k8sclient.Clientset, *corev1.Node) error
|
||||||
|
|
||||||
// PatchNode updates the node object via the API server using a client.
|
// PatchNode updates the node object via the API server using a client.
|
||||||
PatchNode(*k8sclient.Clientset, string, []JsonPatch) error
|
PatchNode(*k8sclient.Clientset, string, []utils.JsonPatch) error
|
||||||
|
|
||||||
// PatchNodeStatus updates the node status via the API server using a client.
|
// PatchNodeStatus updates the node status via the API server using a client.
|
||||||
PatchNodeStatus(*k8sclient.Clientset, string, []JsonPatch) error
|
PatchNodeStatus(*k8sclient.Clientset, string, []utils.JsonPatch) error
|
||||||
|
|
||||||
// GetTopologyClient returns a topologyclientset
|
// GetTopologyClient returns a topologyclientset
|
||||||
GetTopologyClient() (*topologyclientset.Clientset, error)
|
GetTopologyClient() (*topologyclientset.Clientset, error)
|
||||||
|
|
|
@ -26,6 +26,7 @@ import (
|
||||||
"k8s.io/apimachinery/pkg/types"
|
"k8s.io/apimachinery/pkg/types"
|
||||||
k8sclient "k8s.io/client-go/kubernetes"
|
k8sclient "k8s.io/client-go/kubernetes"
|
||||||
restclient "k8s.io/client-go/rest"
|
restclient "k8s.io/client-go/rest"
|
||||||
|
"sigs.k8s.io/node-feature-discovery/pkg/utils"
|
||||||
)
|
)
|
||||||
|
|
||||||
// K8sHelpers implements APIHelpers
|
// K8sHelpers implements APIHelpers
|
||||||
|
@ -77,7 +78,7 @@ func (h K8sHelpers) UpdateNode(c *k8sclient.Clientset, n *corev1.Node) error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (h K8sHelpers) PatchNode(c *k8sclient.Clientset, nodeName string, patches []JsonPatch) error {
|
func (h K8sHelpers) PatchNode(c *k8sclient.Clientset, nodeName string, patches []utils.JsonPatch) error {
|
||||||
if len(patches) > 0 {
|
if len(patches) > 0 {
|
||||||
data, err := json.Marshal(patches)
|
data, err := json.Marshal(patches)
|
||||||
if err == nil {
|
if err == nil {
|
||||||
|
@ -88,7 +89,7 @@ func (h K8sHelpers) PatchNode(c *k8sclient.Clientset, nodeName string, patches [
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (h K8sHelpers) PatchNodeStatus(c *k8sclient.Clientset, nodeName string, patches []JsonPatch) error {
|
func (h K8sHelpers) PatchNodeStatus(c *k8sclient.Clientset, nodeName string, patches []utils.JsonPatch) error {
|
||||||
if len(patches) > 0 {
|
if len(patches) > 0 {
|
||||||
data, err := json.Marshal(patches)
|
data, err := json.Marshal(patches)
|
||||||
if err == nil {
|
if err == nil {
|
||||||
|
|
|
@ -6,6 +6,8 @@ import (
|
||||||
mock "github.com/stretchr/testify/mock"
|
mock "github.com/stretchr/testify/mock"
|
||||||
kubernetes "k8s.io/client-go/kubernetes"
|
kubernetes "k8s.io/client-go/kubernetes"
|
||||||
|
|
||||||
|
utils "sigs.k8s.io/node-feature-discovery/pkg/utils"
|
||||||
|
|
||||||
v1 "k8s.io/api/core/v1"
|
v1 "k8s.io/api/core/v1"
|
||||||
|
|
||||||
versioned "github.com/k8stopologyawareschedwg/noderesourcetopology-api/pkg/generated/clientset/versioned"
|
versioned "github.com/k8stopologyawareschedwg/noderesourcetopology-api/pkg/generated/clientset/versioned"
|
||||||
|
@ -147,11 +149,11 @@ func (_m *MockAPIHelpers) GetTopologyClient() (*versioned.Clientset, error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// PatchNode provides a mock function with given fields: _a0, _a1, _a2
|
// PatchNode provides a mock function with given fields: _a0, _a1, _a2
|
||||||
func (_m *MockAPIHelpers) PatchNode(_a0 *kubernetes.Clientset, _a1 string, _a2 []JsonPatch) error {
|
func (_m *MockAPIHelpers) PatchNode(_a0 *kubernetes.Clientset, _a1 string, _a2 []utils.JsonPatch) error {
|
||||||
ret := _m.Called(_a0, _a1, _a2)
|
ret := _m.Called(_a0, _a1, _a2)
|
||||||
|
|
||||||
var r0 error
|
var r0 error
|
||||||
if rf, ok := ret.Get(0).(func(*kubernetes.Clientset, string, []JsonPatch) error); ok {
|
if rf, ok := ret.Get(0).(func(*kubernetes.Clientset, string, []utils.JsonPatch) error); ok {
|
||||||
r0 = rf(_a0, _a1, _a2)
|
r0 = rf(_a0, _a1, _a2)
|
||||||
} else {
|
} else {
|
||||||
r0 = ret.Error(0)
|
r0 = ret.Error(0)
|
||||||
|
@ -161,11 +163,11 @@ func (_m *MockAPIHelpers) PatchNode(_a0 *kubernetes.Clientset, _a1 string, _a2 [
|
||||||
}
|
}
|
||||||
|
|
||||||
// PatchNodeStatus provides a mock function with given fields: _a0, _a1, _a2
|
// PatchNodeStatus provides a mock function with given fields: _a0, _a1, _a2
|
||||||
func (_m *MockAPIHelpers) PatchNodeStatus(_a0 *kubernetes.Clientset, _a1 string, _a2 []JsonPatch) error {
|
func (_m *MockAPIHelpers) PatchNodeStatus(_a0 *kubernetes.Clientset, _a1 string, _a2 []utils.JsonPatch) error {
|
||||||
ret := _m.Called(_a0, _a1, _a2)
|
ret := _m.Called(_a0, _a1, _a2)
|
||||||
|
|
||||||
var r0 error
|
var r0 error
|
||||||
if rf, ok := ret.Get(0).(func(*kubernetes.Clientset, string, []JsonPatch) error); ok {
|
if rf, ok := ret.Get(0).(func(*kubernetes.Clientset, string, []utils.JsonPatch) error); ok {
|
||||||
r0 = rf(_a0, _a1, _a2)
|
r0 = rf(_a0, _a1, _a2)
|
||||||
} else {
|
} else {
|
||||||
r0 = ret.Error(0)
|
r0 = ret.Error(0)
|
||||||
|
|
|
@ -151,9 +151,9 @@ func TestUpdateNodeObject(t *testing.T) {
|
||||||
sort.Strings(fakeExtResourceNames)
|
sort.Strings(fakeExtResourceNames)
|
||||||
|
|
||||||
// Create a list of expected node status patches
|
// Create a list of expected node status patches
|
||||||
statusPatches := []apihelper.JsonPatch{}
|
statusPatches := []utils.JsonPatch{}
|
||||||
for k, v := range fakeExtResources {
|
for k, v := range fakeExtResources {
|
||||||
statusPatches = append(statusPatches, apihelper.NewJsonPatch("add", "/status/capacity", k, v))
|
statusPatches = append(statusPatches, utils.NewJsonPatch("add", "/status/capacity", k, v))
|
||||||
}
|
}
|
||||||
|
|
||||||
mockAPIHelper := new(apihelper.MockAPIHelpers)
|
mockAPIHelper := new(apihelper.MockAPIHelpers)
|
||||||
|
@ -166,17 +166,17 @@ func TestUpdateNodeObject(t *testing.T) {
|
||||||
|
|
||||||
Convey("When I successfully update the node with feature labels", func() {
|
Convey("When I successfully update the node with feature labels", func() {
|
||||||
// Create a list of expected node metadata patches
|
// Create a list of expected node metadata patches
|
||||||
metadataPatches := []apihelper.JsonPatch{
|
metadataPatches := []utils.JsonPatch{
|
||||||
apihelper.NewJsonPatch("replace", "/metadata/annotations", nfdv1alpha1.AnnotationNs+"/feature-labels", strings.Join(fakeFeatureLabelNames, ",")),
|
utils.NewJsonPatch("replace", "/metadata/annotations", nfdv1alpha1.AnnotationNs+"/feature-labels", strings.Join(fakeFeatureLabelNames, ",")),
|
||||||
apihelper.NewJsonPatch("add", "/metadata/annotations", nfdv1alpha1.FeatureAnnotationsTrackingAnnotation, strings.Join(fakeFeatureAnnotationsNames, ",")),
|
utils.NewJsonPatch("add", "/metadata/annotations", nfdv1alpha1.FeatureAnnotationsTrackingAnnotation, strings.Join(fakeFeatureAnnotationsNames, ",")),
|
||||||
apihelper.NewJsonPatch("add", "/metadata/annotations", nfdv1alpha1.AnnotationNs+"/extended-resources", strings.Join(fakeExtResourceNames, ",")),
|
utils.NewJsonPatch("add", "/metadata/annotations", nfdv1alpha1.AnnotationNs+"/extended-resources", strings.Join(fakeExtResourceNames, ",")),
|
||||||
apihelper.NewJsonPatch("remove", "/metadata/labels", nfdv1alpha1.FeatureLabelNs+"/old-feature", ""),
|
utils.NewJsonPatch("remove", "/metadata/labels", nfdv1alpha1.FeatureLabelNs+"/old-feature", ""),
|
||||||
}
|
}
|
||||||
for k, v := range fakeFeatureLabels {
|
for k, v := range fakeFeatureLabels {
|
||||||
metadataPatches = append(metadataPatches, apihelper.NewJsonPatch("add", "/metadata/labels", k, v))
|
metadataPatches = append(metadataPatches, utils.NewJsonPatch("add", "/metadata/labels", k, v))
|
||||||
}
|
}
|
||||||
for k, v := range fakeAnnotations {
|
for k, v := range fakeAnnotations {
|
||||||
metadataPatches = append(metadataPatches, apihelper.NewJsonPatch("add", "/metadata/annotations", k, v))
|
metadataPatches = append(metadataPatches, utils.NewJsonPatch("add", "/metadata/annotations", k, v))
|
||||||
}
|
}
|
||||||
|
|
||||||
mockAPIHelper.On("GetClient").Return(mockClient, nil)
|
mockAPIHelper.On("GetClient").Return(mockClient, nil)
|
||||||
|
@ -244,7 +244,7 @@ func TestUpdateMasterNode(t *testing.T) {
|
||||||
mockClient := &k8sclient.Clientset{}
|
mockClient := &k8sclient.Clientset{}
|
||||||
mockNode := newMockNode()
|
mockNode := newMockNode()
|
||||||
Convey("When update operation succeeds", func() {
|
Convey("When update operation succeeds", func() {
|
||||||
expectedPatches := []apihelper.JsonPatch{}
|
expectedPatches := []utils.JsonPatch{}
|
||||||
mockHelper.On("GetClient").Return(mockClient, nil)
|
mockHelper.On("GetClient").Return(mockClient, nil)
|
||||||
mockHelper.On("GetNode", mockClient, mockNodeName).Return(mockNode, nil)
|
mockHelper.On("GetNode", mockClient, mockNodeName).Return(mockNode, nil)
|
||||||
mockHelper.On("PatchNode", mockClient, mockNodeName, mock.MatchedBy(jsonPatchMatcher(expectedPatches))).Return(nil)
|
mockHelper.On("PatchNode", mockClient, mockNodeName, mock.MatchedBy(jsonPatchMatcher(expectedPatches))).Return(nil)
|
||||||
|
@ -297,9 +297,9 @@ func TestAddingExtResources(t *testing.T) {
|
||||||
Convey("When there are matching labels", func() {
|
Convey("When there are matching labels", func() {
|
||||||
mockNode := newMockNode()
|
mockNode := newMockNode()
|
||||||
mockResourceLabels := ExtendedResources{"feature-1": "1", "feature-2": "2"}
|
mockResourceLabels := ExtendedResources{"feature-1": "1", "feature-2": "2"}
|
||||||
expectedPatches := []apihelper.JsonPatch{
|
expectedPatches := []utils.JsonPatch{
|
||||||
apihelper.NewJsonPatch("add", "/status/capacity", "feature-1", "1"),
|
utils.NewJsonPatch("add", "/status/capacity", "feature-1", "1"),
|
||||||
apihelper.NewJsonPatch("add", "/status/capacity", "feature-2", "2"),
|
utils.NewJsonPatch("add", "/status/capacity", "feature-2", "2"),
|
||||||
}
|
}
|
||||||
patches := mockMaster.createExtendedResourcePatches(mockNode, mockResourceLabels)
|
patches := mockMaster.createExtendedResourcePatches(mockNode, mockResourceLabels)
|
||||||
So(sortJsonPatches(patches), ShouldResemble, sortJsonPatches(expectedPatches))
|
So(sortJsonPatches(patches), ShouldResemble, sortJsonPatches(expectedPatches))
|
||||||
|
@ -317,9 +317,9 @@ func TestAddingExtResources(t *testing.T) {
|
||||||
mockNode := newMockNode()
|
mockNode := newMockNode()
|
||||||
mockNode.Status.Capacity[corev1.ResourceName("feature-1")] = *resource.NewQuantity(2, resource.BinarySI)
|
mockNode.Status.Capacity[corev1.ResourceName("feature-1")] = *resource.NewQuantity(2, resource.BinarySI)
|
||||||
mockResourceLabels := ExtendedResources{"feature-1": "1"}
|
mockResourceLabels := ExtendedResources{"feature-1": "1"}
|
||||||
expectedPatches := []apihelper.JsonPatch{
|
expectedPatches := []utils.JsonPatch{
|
||||||
apihelper.NewJsonPatch("replace", "/status/capacity", "feature-1", "1"),
|
utils.NewJsonPatch("replace", "/status/capacity", "feature-1", "1"),
|
||||||
apihelper.NewJsonPatch("replace", "/status/allocatable", "feature-1", "1"),
|
utils.NewJsonPatch("replace", "/status/allocatable", "feature-1", "1"),
|
||||||
}
|
}
|
||||||
patches := mockMaster.createExtendedResourcePatches(mockNode, mockResourceLabels)
|
patches := mockMaster.createExtendedResourcePatches(mockNode, mockResourceLabels)
|
||||||
So(sortJsonPatches(patches), ShouldResemble, sortJsonPatches(expectedPatches))
|
So(sortJsonPatches(patches), ShouldResemble, sortJsonPatches(expectedPatches))
|
||||||
|
@ -379,15 +379,15 @@ func TestSetLabels(t *testing.T) {
|
||||||
}
|
}
|
||||||
sort.Strings(mockLabelNames)
|
sort.Strings(mockLabelNames)
|
||||||
|
|
||||||
expectedStatusPatches := []apihelper.JsonPatch{}
|
expectedStatusPatches := []utils.JsonPatch{}
|
||||||
|
|
||||||
Convey("When node update succeeds", func() {
|
Convey("When node update succeeds", func() {
|
||||||
mockMaster.config.ExtraLabelNs = map[string]struct{}{"example.io": {}}
|
mockMaster.config.ExtraLabelNs = map[string]struct{}{"example.io": {}}
|
||||||
expectedPatches := []apihelper.JsonPatch{
|
expectedPatches := []utils.JsonPatch{
|
||||||
apihelper.NewJsonPatch("add", "/metadata/annotations", nfdv1alpha1.FeatureLabelsAnnotation, strings.Join(mockLabelNames, ",")),
|
utils.NewJsonPatch("add", "/metadata/annotations", nfdv1alpha1.FeatureLabelsAnnotation, strings.Join(mockLabelNames, ",")),
|
||||||
}
|
}
|
||||||
for k, v := range mockLabels {
|
for k, v := range mockLabels {
|
||||||
expectedPatches = append(expectedPatches, apihelper.NewJsonPatch("add", "/metadata/labels", k, v))
|
expectedPatches = append(expectedPatches, utils.NewJsonPatch("add", "/metadata/labels", k, v))
|
||||||
}
|
}
|
||||||
|
|
||||||
mockHelper.On("GetClient").Return(mockClient, nil)
|
mockHelper.On("GetClient").Return(mockClient, nil)
|
||||||
|
@ -402,9 +402,9 @@ func TestSetLabels(t *testing.T) {
|
||||||
|
|
||||||
Convey("When -label-whitelist is specified", func() {
|
Convey("When -label-whitelist is specified", func() {
|
||||||
mockMaster.config.ExtraLabelNs = map[string]struct{}{"example.io": {}}
|
mockMaster.config.ExtraLabelNs = map[string]struct{}{"example.io": {}}
|
||||||
expectedPatches := []apihelper.JsonPatch{
|
expectedPatches := []utils.JsonPatch{
|
||||||
apihelper.NewJsonPatch("add", "/metadata/annotations", nfdv1alpha1.FeatureLabelsAnnotation, "example.io/feature-2"),
|
utils.NewJsonPatch("add", "/metadata/annotations", nfdv1alpha1.FeatureLabelsAnnotation, "example.io/feature-2"),
|
||||||
apihelper.NewJsonPatch("add", "/metadata/labels", "example.io/feature-2", mockLabels["example.io/feature-2"]),
|
utils.NewJsonPatch("add", "/metadata/labels", "example.io/feature-2", mockLabels["example.io/feature-2"]),
|
||||||
}
|
}
|
||||||
|
|
||||||
mockMaster.config.LabelWhiteList.Regexp = *regexp.MustCompile("^f.*2$")
|
mockMaster.config.LabelWhiteList.Regexp = *regexp.MustCompile("^f.*2$")
|
||||||
|
@ -434,14 +434,14 @@ func TestSetLabels(t *testing.T) {
|
||||||
vendorProfileLabel: "val-7",
|
vendorProfileLabel: "val-7",
|
||||||
"--invalid-name--": "valid-val",
|
"--invalid-name--": "valid-val",
|
||||||
"valid-name": "--invalid-val--"}
|
"valid-name": "--invalid-val--"}
|
||||||
expectedPatches := []apihelper.JsonPatch{
|
expectedPatches := []utils.JsonPatch{
|
||||||
apihelper.NewJsonPatch("add", "/metadata/annotations",
|
utils.NewJsonPatch("add", "/metadata/annotations",
|
||||||
instance+"."+nfdv1alpha1.FeatureLabelsAnnotation,
|
instance+"."+nfdv1alpha1.FeatureLabelsAnnotation,
|
||||||
"feature-1,valid.ns/feature-2,"+vendorFeatureLabel+","+vendorProfileLabel),
|
"feature-1,valid.ns/feature-2,"+vendorFeatureLabel+","+vendorProfileLabel),
|
||||||
apihelper.NewJsonPatch("add", "/metadata/labels", "feature.node.kubernetes.io/feature-1", mockLabels["feature.node.kubernetes.io/feature-1"]),
|
utils.NewJsonPatch("add", "/metadata/labels", "feature.node.kubernetes.io/feature-1", mockLabels["feature.node.kubernetes.io/feature-1"]),
|
||||||
apihelper.NewJsonPatch("add", "/metadata/labels", "valid.ns/feature-2", mockLabels["valid.ns/feature-2"]),
|
utils.NewJsonPatch("add", "/metadata/labels", "valid.ns/feature-2", mockLabels["valid.ns/feature-2"]),
|
||||||
apihelper.NewJsonPatch("add", "/metadata/labels", vendorFeatureLabel, mockLabels[vendorFeatureLabel]),
|
utils.NewJsonPatch("add", "/metadata/labels", vendorFeatureLabel, mockLabels[vendorFeatureLabel]),
|
||||||
apihelper.NewJsonPatch("add", "/metadata/labels", vendorProfileLabel, mockLabels[vendorProfileLabel]),
|
utils.NewJsonPatch("add", "/metadata/labels", vendorProfileLabel, mockLabels[vendorProfileLabel]),
|
||||||
}
|
}
|
||||||
|
|
||||||
mockMaster.deniedNs.normal = map[string]struct{}{"random.denied.ns": {}}
|
mockMaster.deniedNs.normal = map[string]struct{}{"random.denied.ns": {}}
|
||||||
|
@ -461,14 +461,14 @@ func TestSetLabels(t *testing.T) {
|
||||||
|
|
||||||
Convey("When -resource-labels is specified", func() {
|
Convey("When -resource-labels is specified", func() {
|
||||||
mockMaster.config.ExtraLabelNs = map[string]struct{}{"example.io": {}}
|
mockMaster.config.ExtraLabelNs = map[string]struct{}{"example.io": {}}
|
||||||
expectedPatches := []apihelper.JsonPatch{
|
expectedPatches := []utils.JsonPatch{
|
||||||
apihelper.NewJsonPatch("add", "/metadata/annotations", nfdv1alpha1.FeatureLabelsAnnotation, "example.io/feature-2"),
|
utils.NewJsonPatch("add", "/metadata/annotations", nfdv1alpha1.FeatureLabelsAnnotation, "example.io/feature-2"),
|
||||||
apihelper.NewJsonPatch("add", "/metadata/labels", "example.io/feature-2", mockLabels["example.io/feature-2"]),
|
utils.NewJsonPatch("add", "/metadata/labels", "example.io/feature-2", mockLabels["example.io/feature-2"]),
|
||||||
apihelper.NewJsonPatch("add", "/metadata/annotations", nfdv1alpha1.ExtendedResourceAnnotation, "feature-1,feature-3"),
|
utils.NewJsonPatch("add", "/metadata/annotations", nfdv1alpha1.ExtendedResourceAnnotation, "feature-1,feature-3"),
|
||||||
}
|
}
|
||||||
expectedStatusPatches := []apihelper.JsonPatch{
|
expectedStatusPatches := []utils.JsonPatch{
|
||||||
apihelper.NewJsonPatch("add", "/status/capacity", "feature.node.kubernetes.io/feature-1", mockLabels["feature.node.kubernetes.io/feature-1"]),
|
utils.NewJsonPatch("add", "/status/capacity", "feature.node.kubernetes.io/feature-1", mockLabels["feature.node.kubernetes.io/feature-1"]),
|
||||||
apihelper.NewJsonPatch("add", "/status/capacity", "feature.node.kubernetes.io/feature-3", mockLabels["feature.node.kubernetes.io/feature-3"]),
|
utils.NewJsonPatch("add", "/status/capacity", "feature.node.kubernetes.io/feature-3", mockLabels["feature.node.kubernetes.io/feature-3"]),
|
||||||
}
|
}
|
||||||
|
|
||||||
mockMaster.config.ResourceLabels = map[string]struct{}{"feature.node.kubernetes.io/feature-3": {}, "feature-1": {}}
|
mockMaster.config.ResourceLabels = map[string]struct{}{"feature.node.kubernetes.io/feature-3": {}, "feature-1": {}}
|
||||||
|
@ -605,9 +605,9 @@ func TestCreatePatches(t *testing.T) {
|
||||||
|
|
||||||
Convey("When when there are itmes to remoe but none to add or update", func() {
|
Convey("When when there are itmes to remoe but none to add or update", func() {
|
||||||
p := createPatches([]string{"key-2", "key-3", "foo"}, existingItems, map[string]string{}, jsonPath)
|
p := createPatches([]string{"key-2", "key-3", "foo"}, existingItems, map[string]string{}, jsonPath)
|
||||||
expected := []apihelper.JsonPatch{
|
expected := []utils.JsonPatch{
|
||||||
apihelper.NewJsonPatch("remove", jsonPath, "key-2", ""),
|
utils.NewJsonPatch("remove", jsonPath, "key-2", ""),
|
||||||
apihelper.NewJsonPatch("remove", jsonPath, "key-3", ""),
|
utils.NewJsonPatch("remove", jsonPath, "key-3", ""),
|
||||||
}
|
}
|
||||||
So(sortJsonPatches(p), ShouldResemble, sortJsonPatches(expected))
|
So(sortJsonPatches(p), ShouldResemble, sortJsonPatches(expected))
|
||||||
})
|
})
|
||||||
|
@ -615,9 +615,9 @@ func TestCreatePatches(t *testing.T) {
|
||||||
Convey("When when there are no itmes to remove but new items to add", func() {
|
Convey("When when there are no itmes to remove but new items to add", func() {
|
||||||
newItems := map[string]string{"new-key": "new-val", "key-1": "new-1"}
|
newItems := map[string]string{"new-key": "new-val", "key-1": "new-1"}
|
||||||
p := createPatches([]string{"key-1"}, existingItems, newItems, jsonPath)
|
p := createPatches([]string{"key-1"}, existingItems, newItems, jsonPath)
|
||||||
expected := []apihelper.JsonPatch{
|
expected := []utils.JsonPatch{
|
||||||
apihelper.NewJsonPatch("add", jsonPath, "new-key", newItems["new-key"]),
|
utils.NewJsonPatch("add", jsonPath, "new-key", newItems["new-key"]),
|
||||||
apihelper.NewJsonPatch("replace", jsonPath, "key-1", newItems["key-1"]),
|
utils.NewJsonPatch("replace", jsonPath, "key-1", newItems["key-1"]),
|
||||||
}
|
}
|
||||||
So(sortJsonPatches(p), ShouldResemble, sortJsonPatches(expected))
|
So(sortJsonPatches(p), ShouldResemble, sortJsonPatches(expected))
|
||||||
})
|
})
|
||||||
|
@ -625,12 +625,12 @@ func TestCreatePatches(t *testing.T) {
|
||||||
Convey("When when there are items to remove add and update", func() {
|
Convey("When when there are items to remove add and update", func() {
|
||||||
newItems := map[string]string{"new-key": "new-val", "key-2": "new-2", "key-4": "val-4"}
|
newItems := map[string]string{"new-key": "new-val", "key-2": "new-2", "key-4": "val-4"}
|
||||||
p := createPatches([]string{"key-1", "key-2", "key-3", "foo"}, existingItems, newItems, jsonPath)
|
p := createPatches([]string{"key-1", "key-2", "key-3", "foo"}, existingItems, newItems, jsonPath)
|
||||||
expected := []apihelper.JsonPatch{
|
expected := []utils.JsonPatch{
|
||||||
apihelper.NewJsonPatch("add", jsonPath, "new-key", newItems["new-key"]),
|
utils.NewJsonPatch("add", jsonPath, "new-key", newItems["new-key"]),
|
||||||
apihelper.NewJsonPatch("add", jsonPath, "key-4", newItems["key-4"]),
|
utils.NewJsonPatch("add", jsonPath, "key-4", newItems["key-4"]),
|
||||||
apihelper.NewJsonPatch("replace", jsonPath, "key-2", newItems["key-2"]),
|
utils.NewJsonPatch("replace", jsonPath, "key-2", newItems["key-2"]),
|
||||||
apihelper.NewJsonPatch("remove", jsonPath, "key-1", ""),
|
utils.NewJsonPatch("remove", jsonPath, "key-1", ""),
|
||||||
apihelper.NewJsonPatch("remove", jsonPath, "key-3", ""),
|
utils.NewJsonPatch("remove", jsonPath, "key-3", ""),
|
||||||
}
|
}
|
||||||
So(sortJsonPatches(p), ShouldResemble, sortJsonPatches(expected))
|
So(sortJsonPatches(p), ShouldResemble, sortJsonPatches(expected))
|
||||||
})
|
})
|
||||||
|
@ -651,14 +651,14 @@ func TestRemoveLabelsWithPrefix(t *testing.T) {
|
||||||
|
|
||||||
Convey("a unique label should be removed", func() {
|
Convey("a unique label should be removed", func() {
|
||||||
p := removeLabelsWithPrefix(n, "single")
|
p := removeLabelsWithPrefix(n, "single")
|
||||||
So(p, ShouldResemble, []apihelper.JsonPatch{apihelper.NewJsonPatch("remove", "/metadata/labels", "single-label", "")})
|
So(p, ShouldResemble, []utils.JsonPatch{utils.NewJsonPatch("remove", "/metadata/labels", "single-label", "")})
|
||||||
})
|
})
|
||||||
|
|
||||||
Convey("a non-unique search string should remove all matching keys", func() {
|
Convey("a non-unique search string should remove all matching keys", func() {
|
||||||
p := removeLabelsWithPrefix(n, "multiple")
|
p := removeLabelsWithPrefix(n, "multiple")
|
||||||
So(sortJsonPatches(p), ShouldResemble, sortJsonPatches([]apihelper.JsonPatch{
|
So(sortJsonPatches(p), ShouldResemble, sortJsonPatches([]utils.JsonPatch{
|
||||||
apihelper.NewJsonPatch("remove", "/metadata/labels", "multiple_A", ""),
|
utils.NewJsonPatch("remove", "/metadata/labels", "multiple_A", ""),
|
||||||
apihelper.NewJsonPatch("remove", "/metadata/labels", "multiple_B", ""),
|
utils.NewJsonPatch("remove", "/metadata/labels", "multiple_B", ""),
|
||||||
}))
|
}))
|
||||||
})
|
})
|
||||||
|
|
||||||
|
@ -851,8 +851,8 @@ func BenchmarkNfdAPIUpdateAllNodes(b *testing.B) {
|
||||||
|
|
||||||
mockClient := &k8sclient.Clientset{}
|
mockClient := &k8sclient.Clientset{}
|
||||||
|
|
||||||
statusPatches := []apihelper.JsonPatch{}
|
statusPatches := []utils.JsonPatch{}
|
||||||
metadataPatches := []apihelper.JsonPatch{
|
metadataPatches := []utils.JsonPatch{
|
||||||
{Op: "add", Path: "/metadata/annotations/nfd.node.kubernetes.io~1feature-labels", Value: ""}, {Op: "add", Path: "/metadata/annotations/nfd.node.kubernetes.io~1extended-resources", Value: ""},
|
{Op: "add", Path: "/metadata/annotations/nfd.node.kubernetes.io~1feature-labels", Value: ""}, {Op: "add", Path: "/metadata/annotations/nfd.node.kubernetes.io~1extended-resources", Value: ""},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -909,8 +909,8 @@ func withTimeout(actual interface{}, expected ...interface{}) string {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func jsonPatchMatcher(expected []apihelper.JsonPatch) func([]apihelper.JsonPatch) bool {
|
func jsonPatchMatcher(expected []utils.JsonPatch) func([]utils.JsonPatch) bool {
|
||||||
return func(actual []apihelper.JsonPatch) bool {
|
return func(actual []utils.JsonPatch) bool {
|
||||||
// We don't care about modifying the original slices
|
// We don't care about modifying the original slices
|
||||||
ok, msg := assertions.So(sortJsonPatches(actual), ShouldResemble, sortJsonPatches(expected))
|
ok, msg := assertions.So(sortJsonPatches(actual), ShouldResemble, sortJsonPatches(expected))
|
||||||
if !ok {
|
if !ok {
|
||||||
|
@ -926,18 +926,18 @@ func jsonPatchMatcher(expected []apihelper.JsonPatch) func([]apihelper.JsonPatch
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func sortJsonPatches(p []apihelper.JsonPatch) []apihelper.JsonPatch {
|
func sortJsonPatches(p []utils.JsonPatch) []utils.JsonPatch {
|
||||||
sort.Slice(p, func(i, j int) bool { return p[i].Path < p[j].Path })
|
sort.Slice(p, func(i, j int) bool { return p[i].Path < p[j].Path })
|
||||||
return p
|
return p
|
||||||
}
|
}
|
||||||
|
|
||||||
// Remove any labels having the given prefix
|
// Remove any labels having the given prefix
|
||||||
func removeLabelsWithPrefix(n *corev1.Node, search string) []apihelper.JsonPatch {
|
func removeLabelsWithPrefix(n *corev1.Node, search string) []utils.JsonPatch {
|
||||||
var p []apihelper.JsonPatch
|
var p []utils.JsonPatch
|
||||||
|
|
||||||
for k := range n.Labels {
|
for k := range n.Labels {
|
||||||
if strings.HasPrefix(k, search) {
|
if strings.HasPrefix(k, search) {
|
||||||
p = append(p, apihelper.NewJsonPatch("remove", "/metadata/labels", k, ""))
|
p = append(p, utils.NewJsonPatch("remove", "/metadata/labels", k, ""))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1146,14 +1146,14 @@ func (m *nfdMaster) getKubeconfig() (*restclient.Config, error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// createPatches is a generic helper that returns json patch operations to perform
|
// createPatches is a generic helper that returns json patch operations to perform
|
||||||
func createPatches(removeKeys []string, oldItems map[string]string, newItems map[string]string, jsonPath string) []apihelper.JsonPatch {
|
func createPatches(removeKeys []string, oldItems map[string]string, newItems map[string]string, jsonPath string) []utils.JsonPatch {
|
||||||
patches := []apihelper.JsonPatch{}
|
patches := []utils.JsonPatch{}
|
||||||
|
|
||||||
// Determine items to remove
|
// Determine items to remove
|
||||||
for _, key := range removeKeys {
|
for _, key := range removeKeys {
|
||||||
if _, ok := oldItems[key]; ok {
|
if _, ok := oldItems[key]; ok {
|
||||||
if _, ok := newItems[key]; !ok {
|
if _, ok := newItems[key]; !ok {
|
||||||
patches = append(patches, apihelper.NewJsonPatch("remove", jsonPath, key, ""))
|
patches = append(patches, utils.NewJsonPatch("remove", jsonPath, key, ""))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1162,10 +1162,10 @@ func createPatches(removeKeys []string, oldItems map[string]string, newItems map
|
||||||
for key, newVal := range newItems {
|
for key, newVal := range newItems {
|
||||||
if oldVal, ok := oldItems[key]; ok {
|
if oldVal, ok := oldItems[key]; ok {
|
||||||
if newVal != oldVal {
|
if newVal != oldVal {
|
||||||
patches = append(patches, apihelper.NewJsonPatch("replace", jsonPath, key, newVal))
|
patches = append(patches, utils.NewJsonPatch("replace", jsonPath, key, newVal))
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
patches = append(patches, apihelper.NewJsonPatch("add", jsonPath, key, newVal))
|
patches = append(patches, utils.NewJsonPatch("add", jsonPath, key, newVal))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1174,8 +1174,8 @@ func createPatches(removeKeys []string, oldItems map[string]string, newItems map
|
||||||
|
|
||||||
// createExtendedResourcePatches returns a slice of operations to perform on
|
// createExtendedResourcePatches returns a slice of operations to perform on
|
||||||
// the node status
|
// the node status
|
||||||
func (m *nfdMaster) createExtendedResourcePatches(n *corev1.Node, extendedResources ExtendedResources) []apihelper.JsonPatch {
|
func (m *nfdMaster) createExtendedResourcePatches(n *corev1.Node, extendedResources ExtendedResources) []utils.JsonPatch {
|
||||||
patches := []apihelper.JsonPatch{}
|
patches := []utils.JsonPatch{}
|
||||||
|
|
||||||
// Form a list of namespaced resource names managed by us
|
// Form a list of namespaced resource names managed by us
|
||||||
oldResources := stringToNsNames(n.Annotations[m.instanceAnnotation(nfdv1alpha1.ExtendedResourceAnnotation)], nfdv1alpha1.FeatureLabelNs)
|
oldResources := stringToNsNames(n.Annotations[m.instanceAnnotation(nfdv1alpha1.ExtendedResourceAnnotation)], nfdv1alpha1.FeatureLabelNs)
|
||||||
|
@ -1185,8 +1185,8 @@ func (m *nfdMaster) createExtendedResourcePatches(n *corev1.Node, extendedResour
|
||||||
if _, ok := n.Status.Capacity[corev1.ResourceName(resource)]; ok {
|
if _, ok := n.Status.Capacity[corev1.ResourceName(resource)]; ok {
|
||||||
// check if the ext resource is still needed
|
// check if the ext resource is still needed
|
||||||
if _, extResNeeded := extendedResources[resource]; !extResNeeded {
|
if _, extResNeeded := extendedResources[resource]; !extResNeeded {
|
||||||
patches = append(patches, apihelper.NewJsonPatch("remove", "/status/capacity", resource, ""))
|
patches = append(patches, utils.NewJsonPatch("remove", "/status/capacity", resource, ""))
|
||||||
patches = append(patches, apihelper.NewJsonPatch("remove", "/status/allocatable", resource, ""))
|
patches = append(patches, utils.NewJsonPatch("remove", "/status/allocatable", resource, ""))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1197,11 +1197,11 @@ func (m *nfdMaster) createExtendedResourcePatches(n *corev1.Node, extendedResour
|
||||||
if quantity, ok := n.Status.Capacity[corev1.ResourceName(resource)]; ok {
|
if quantity, ok := n.Status.Capacity[corev1.ResourceName(resource)]; ok {
|
||||||
val, _ := quantity.AsInt64()
|
val, _ := quantity.AsInt64()
|
||||||
if strconv.FormatInt(val, 10) != value {
|
if strconv.FormatInt(val, 10) != value {
|
||||||
patches = append(patches, apihelper.NewJsonPatch("replace", "/status/capacity", resource, value))
|
patches = append(patches, utils.NewJsonPatch("replace", "/status/capacity", resource, value))
|
||||||
patches = append(patches, apihelper.NewJsonPatch("replace", "/status/allocatable", resource, value))
|
patches = append(patches, utils.NewJsonPatch("replace", "/status/allocatable", resource, value))
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
patches = append(patches, apihelper.NewJsonPatch("add", "/status/capacity", resource, value))
|
patches = append(patches, utils.NewJsonPatch("add", "/status/capacity", resource, value))
|
||||||
// "allocatable" gets added implicitly after adding to capacity
|
// "allocatable" gets added implicitly after adding to capacity
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -26,6 +26,7 @@ import (
|
||||||
k8sclient "k8s.io/client-go/kubernetes"
|
k8sclient "k8s.io/client-go/kubernetes"
|
||||||
"sigs.k8s.io/node-feature-discovery/pkg/apihelper"
|
"sigs.k8s.io/node-feature-discovery/pkg/apihelper"
|
||||||
"sigs.k8s.io/node-feature-discovery/pkg/generated/clientset/versioned/fake"
|
"sigs.k8s.io/node-feature-discovery/pkg/generated/clientset/versioned/fake"
|
||||||
|
"sigs.k8s.io/node-feature-discovery/pkg/utils"
|
||||||
)
|
)
|
||||||
|
|
||||||
func newMockNodeUpdaterPool(nfdMaster *nfdMaster) *nodeUpdaterPool {
|
func newMockNodeUpdaterPool(nfdMaster *nfdMaster) *nodeUpdaterPool {
|
||||||
|
@ -80,8 +81,8 @@ func TestRunNodeUpdater(t *testing.T) {
|
||||||
mockClient := &k8sclient.Clientset{}
|
mockClient := &k8sclient.Clientset{}
|
||||||
mockNode := newMockNode()
|
mockNode := newMockNode()
|
||||||
mockNodeUpdaterPool := newMockNodeUpdaterPool(mockMaster)
|
mockNodeUpdaterPool := newMockNodeUpdaterPool(mockMaster)
|
||||||
statusPatches := []apihelper.JsonPatch{}
|
statusPatches := []utils.JsonPatch{}
|
||||||
metadataPatches := []apihelper.JsonPatch{}
|
metadataPatches := []utils.JsonPatch{}
|
||||||
|
|
||||||
mockAPIHelper.On("GetClient").Return(mockClient, nil)
|
mockAPIHelper.On("GetClient").Return(mockClient, nil)
|
||||||
mockAPIHelper.On("GetNode", mockClient, mockNodeName).Return(mockNode, nil)
|
mockAPIHelper.On("GetNode", mockClient, mockNodeName).Return(mockNode, nil)
|
||||||
|
|
|
@ -14,7 +14,7 @@ See the License for the specific language governing permissions and
|
||||||
limitations under the License.
|
limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package apihelper
|
package utils
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"path"
|
"path"
|
|
@ -42,9 +42,9 @@ import (
|
||||||
e2epod "k8s.io/kubernetes/test/e2e/framework/pod"
|
e2epod "k8s.io/kubernetes/test/e2e/framework/pod"
|
||||||
admissionapi "k8s.io/pod-security-admission/api"
|
admissionapi "k8s.io/pod-security-admission/api"
|
||||||
|
|
||||||
"sigs.k8s.io/node-feature-discovery/pkg/apihelper"
|
|
||||||
nfdv1alpha1 "sigs.k8s.io/node-feature-discovery/pkg/apis/nfd/v1alpha1"
|
nfdv1alpha1 "sigs.k8s.io/node-feature-discovery/pkg/apis/nfd/v1alpha1"
|
||||||
nfdclient "sigs.k8s.io/node-feature-discovery/pkg/generated/clientset/versioned"
|
nfdclient "sigs.k8s.io/node-feature-discovery/pkg/generated/clientset/versioned"
|
||||||
|
"sigs.k8s.io/node-feature-discovery/pkg/utils"
|
||||||
"sigs.k8s.io/node-feature-discovery/source/custom"
|
"sigs.k8s.io/node-feature-discovery/source/custom"
|
||||||
testutils "sigs.k8s.io/node-feature-discovery/test/e2e/utils"
|
testutils "sigs.k8s.io/node-feature-discovery/test/e2e/utils"
|
||||||
testds "sigs.k8s.io/node-feature-discovery/test/e2e/utils/daemonset"
|
testds "sigs.k8s.io/node-feature-discovery/test/e2e/utils/daemonset"
|
||||||
|
@ -974,8 +974,8 @@ resyncPeriod: "1s"
|
||||||
eventuallyNonControlPlaneNodes(ctx, f.ClientSet).Should(MatchLabels(expectedLabels, nodes))
|
eventuallyNonControlPlaneNodes(ctx, f.ClientSet).Should(MatchLabels(expectedLabels, nodes))
|
||||||
|
|
||||||
patches, err := json.Marshal(
|
patches, err := json.Marshal(
|
||||||
[]apihelper.JsonPatch{
|
[]utils.JsonPatch{
|
||||||
apihelper.NewJsonPatch(
|
utils.NewJsonPatch(
|
||||||
"replace",
|
"replace",
|
||||||
"/metadata/labels",
|
"/metadata/labels",
|
||||||
nfdv1alpha1.FeatureLabelNs+"/e2e-nodefeature-test-1",
|
nfdv1alpha1.FeatureLabelNs+"/e2e-nodefeature-test-1",
|
||||||
|
|
Loading…
Add table
Reference in a new issue