From 739949e0abc1cc4e4849a7bb156faa5e7d28d9c8 Mon Sep 17 00:00:00 2001 From: Edward Haas Date: Tue, 2 Mar 2021 10:11:50 +0200 Subject: [PATCH] state, filter: Fix the interpretation of ifaces names In scenarios where an interface has only numeric characters, the application panics with a failure to extract a string type from a Go interface (which is actually a float64). In order to fix the problem, the parsing of the interface name is performed using a dedicated interface-state structure. Note: The usage of the interface name in this context is solely limited for the filter matching. This change does not solve the problem of incorrectly representing valid numeric values like `0xfe` and `1.0` (they are now seen as 254 and 1). Signed-off-by: Edward Haas --- pkg/state/filter.go | 15 ++++++++----- pkg/state/filter_test.go | 47 ++++++++++++++++++++++++++++++++++++++++ pkg/state/type.go | 8 +++++++ 3 files changed, 65 insertions(+), 5 deletions(-) diff --git a/pkg/state/filter.go b/pkg/state/filter.go index d1b2d8e172..381a01ffcb 100644 --- a/pkg/state/filter.go +++ b/pkg/state/filter.go @@ -73,11 +73,11 @@ func filterOutDynamicAttributes(iface map[string]interface{}) { delete(options, "hello-timer") } -func filterOutInterfaces(ifaces []interface{}, interfacesFilterGlob glob.Glob) []interface{} { +func filterOutInterfaces(ifaces []interface{}, ifacesNames []Interface, interfacesFilterGlob glob.Glob) []interface{} { filteredInterfaces := []interface{}{} - for _, iface := range ifaces { - name := iface.(map[string]interface{})["name"] - if !interfacesFilterGlob.Match(name.(string)) { + for i, iface := range ifaces { + name := ifacesNames[i].Name + if !interfacesFilterGlob.Match(name) { filterOutDynamicAttributes(iface.(map[string]interface{})) filteredInterfaces = append(filteredInterfaces, iface) } @@ -92,7 +92,12 @@ func filterOut(currentState shared.State, interfacesFilterGlob glob.Glob) (share return currentState, err } - state.Interfaces = filterOutInterfaces(state.Interfaces, interfacesFilterGlob) + var ifacesState InterfacesState + if err := yaml.Unmarshal(currentState.Raw, &ifacesState); err != nil { + return currentState, err + } + + state.Interfaces = filterOutInterfaces(state.Interfaces, ifacesState.Interfaces, interfacesFilterGlob) if state.Routes != nil { state.Routes.Running = filterOutRoutes(state.Routes.Running, interfacesFilterGlob) state.Routes.Config = filterOutRoutes(state.Routes.Config, interfacesFilterGlob) diff --git a/pkg/state/filter_test.go b/pkg/state/filter_test.go index c87149ffef..0e20505787 100644 --- a/pkg/state/filter_test.go +++ b/pkg/state/filter_test.go @@ -331,4 +331,51 @@ interfaces: }) }) + Context("when the interfaces have (only) numeric characters", func() { + BeforeEach(func() { + state = nmstate.NewState(` +interfaces: +- name: eth0 +- name: 0 +- name: 1101010 +`) + filteredState = nmstate.NewState(` +interfaces: +- name: eth0 +- name: 1101010 +`) + interfacesFilterGlob = glob.MustCompile("0*") + }) + + It("should filter out interfaces correctly", func() { + returnedState, err := filterOut(state, interfacesFilterGlob) + Expect(err).NotTo(HaveOccurred()) + Expect(returnedState).To(MatchYAML(filteredState)) + }) + }) + + Context("when the interfaces have special numeric characters", func() { + BeforeEach(func() { + state = nmstate.NewState(` +interfaces: +- name: eth0 +- name: 0.0 +- name: 1.0 +- name: 0xfe +`) + filteredState = nmstate.NewState(` +interfaces: +- name: eth0 +- name: 0 +- name: 254 +`) + interfacesFilterGlob = glob.MustCompile("1*") + }) + + It("should filter out interfaces correctly but they are not represented correctly", func() { + returnedState, err := filterOut(state, interfacesFilterGlob) + Expect(err).NotTo(HaveOccurred()) + Expect(returnedState).To(MatchYAML(filteredState)) + }) + }) }) diff --git a/pkg/state/type.go b/pkg/state/type.go index 98b69b6a08..a1882b38e2 100644 --- a/pkg/state/type.go +++ b/pkg/state/type.go @@ -9,3 +9,11 @@ type Routes struct { Config []interface{} `json:"config"` Running []interface{} `json:"running"` } + +type InterfacesState struct { + Interfaces []Interface `json:"interfaces"` +} + +type Interface struct { + Name string `json:"name"` +}