diff options
Diffstat (limited to 'libpod/network')
-rw-r--r-- | libpod/network/cni/run.go | 2 | ||||
-rw-r--r-- | libpod/network/cni/run_test.go | 14 | ||||
-rw-r--r-- | libpod/network/types/network.go | 49 | ||||
-rw-r--r-- | libpod/network/types/network_test.go | 82 |
4 files changed, 137 insertions, 10 deletions
diff --git a/libpod/network/cni/run.go b/libpod/network/cni/run.go index 99b2adce5..7795dfeeb 100644 --- a/libpod/network/cni/run.go +++ b/libpod/network/cni/run.go @@ -160,7 +160,7 @@ func CNIResultToStatus(res cnitypes.Result) (types.StatusBlock, error) { return result, err } interfaces[cniInt.Name] = types.NetInterface{ - MacAddress: mac, + MacAddress: types.HardwareAddr(mac), Networks: []types.NetAddress{{ Subnet: types.IPNet{IPNet: ip.Address}, Gateway: ip.Gateway, diff --git a/libpod/network/cni/run_test.go b/libpod/network/cni/run_test.go index 965203c2a..3169cd0eb 100644 --- a/libpod/network/cni/run_test.go +++ b/libpod/network/cni/run_test.go @@ -398,7 +398,7 @@ var _ = Describe("run CNI", func() { i, err := net.InterfaceByName(intName1) Expect(err).To(BeNil()) Expect(i.Name).To(Equal(intName1)) - Expect(i.HardwareAddr).To(Equal(macInt1)) + Expect(i.HardwareAddr).To(Equal((net.HardwareAddr)(macInt1))) addrs, err := i.Addrs() Expect(err).To(BeNil()) subnet := &net.IPNet{ @@ -448,7 +448,7 @@ var _ = Describe("run CNI", func() { i, err := net.InterfaceByName(intName1) Expect(err).To(BeNil()) Expect(i.Name).To(Equal(intName1)) - Expect(i.HardwareAddr).To(Equal(macInt1)) + Expect(i.HardwareAddr).To(Equal(net.HardwareAddr(macInt1))) addrs, err := i.Addrs() Expect(err).To(BeNil()) subnet := &net.IPNet{ @@ -460,7 +460,7 @@ var _ = Describe("run CNI", func() { i, err = net.InterfaceByName(intName2) Expect(err).To(BeNil()) Expect(i.Name).To(Equal(intName2)) - Expect(i.HardwareAddr).To(Equal(macInt2)) + Expect(i.HardwareAddr).To(Equal(net.HardwareAddr(macInt2))) addrs, err = i.Addrs() Expect(err).To(BeNil()) subnet = &net.IPNet{ @@ -600,7 +600,7 @@ var _ = Describe("run CNI", func() { i, err := net.InterfaceByName(intName1) Expect(err).To(BeNil()) Expect(i.Name).To(Equal(intName1)) - Expect(i.HardwareAddr).To(Equal(macInt1)) + Expect(i.HardwareAddr).To(Equal(net.HardwareAddr(macInt1))) addrs, err := i.Addrs() Expect(err).To(BeNil()) subnet := &net.IPNet{ @@ -612,7 +612,7 @@ var _ = Describe("run CNI", func() { i, err = net.InterfaceByName(intName2) Expect(err).To(BeNil()) Expect(i.Name).To(Equal(intName2)) - Expect(i.HardwareAddr).To(Equal(macInt2)) + Expect(i.HardwareAddr).To(Equal(net.HardwareAddr(macInt2))) addrs, err = i.Addrs() Expect(err).To(BeNil()) subnet = &net.IPNet{ @@ -690,7 +690,7 @@ var _ = Describe("run CNI", func() { netName: { InterfaceName: interfaceName, StaticIPs: []net.IP{ip1, ip2}, - StaticMAC: mac, + StaticMAC: types.HardwareAddr(mac), }, }, }, @@ -708,7 +708,7 @@ var _ = Describe("run CNI", func() { Expect(res[netName].Interfaces[interfaceName].Networks[1].Subnet.IP.String()).To(Equal(ip2.String())) Expect(res[netName].Interfaces[interfaceName].Networks[1].Subnet.Mask).To(Equal(subnet2.Mask)) Expect(res[netName].Interfaces[interfaceName].Networks[1].Gateway).To(Equal(net.ParseIP("fd41:0a75:2ca0:48a9::1"))) - Expect(res[netName].Interfaces[interfaceName].MacAddress).To(Equal(mac)) + Expect(res[netName].Interfaces[interfaceName].MacAddress).To(Equal(types.HardwareAddr(mac))) // default network has no dns Expect(res[netName].DNSServerIPs).To(BeEmpty()) Expect(res[netName].DNSSearchDomains).To(BeEmpty()) diff --git a/libpod/network/types/network.go b/libpod/network/types/network.go index 657c1ca6a..5cf523e20 100644 --- a/libpod/network/types/network.go +++ b/libpod/network/types/network.go @@ -1,6 +1,7 @@ package types import ( + "encoding/json" "net" "time" ) @@ -94,6 +95,50 @@ func (n *IPNet) UnmarshalText(text []byte) error { return nil } +// HardwareAddr is the same as net.HardwareAddr except +// that it adds the json marshal/unmarshal methods. +// This allows us to read the mac from a json string +// and a byte array. +type HardwareAddr net.HardwareAddr + +func (h *HardwareAddr) String() string { + return (*net.HardwareAddr)(h).String() +} + +func (h *HardwareAddr) MarshalText() ([]byte, error) { + return []byte((*net.HardwareAddr)(h).String()), nil +} + +func (h *HardwareAddr) UnmarshalJSON(text []byte) error { + if len(text) == 0 { + *h = nil + return nil + } + + // if the json string start with a quote we got a string + // unmarshal the string and parse the mac from this string + if string(text[0]) == `"` { + var macString string + err := json.Unmarshal(text, &macString) + if err == nil { + mac, err := net.ParseMAC(macString) + if err == nil { + *h = HardwareAddr(mac) + return nil + } + } + } + // not a string or got an error fallback to the normal parsing + mac := make(net.HardwareAddr, 0, 6) + // use the standard json unmarshal for backwards compat + err := json.Unmarshal(text, &mac) + if err != nil { + return err + } + *h = HardwareAddr(mac) + return nil +} + type Subnet struct { // Subnet for this Network in CIDR form. // swagger:strfmt string @@ -134,7 +179,7 @@ type NetInterface struct { // Networks list of assigned subnets with their gateway. Networks []NetAddress `json:"networks,omitempty"` // MacAddress for this Interface. - MacAddress net.HardwareAddr `json:"mac_address"` + MacAddress HardwareAddr `json:"mac_address"` } // NetAddress contains the subnet and gateway. @@ -157,7 +202,7 @@ type PerNetworkOptions struct { // Optional. Aliases []string `json:"aliases,omitempty"` // StaticMac for this container. Optional. - StaticMAC net.HardwareAddr `json:"static_mac,omitempty"` + StaticMAC HardwareAddr `json:"static_mac,omitempty"` // InterfaceName for this container. Required. InterfaceName string `json:"interface_name"` } diff --git a/libpod/network/types/network_test.go b/libpod/network/types/network_test.go new file mode 100644 index 000000000..91ee93692 --- /dev/null +++ b/libpod/network/types/network_test.go @@ -0,0 +1,82 @@ +package types_test + +import ( + "encoding/json" + "reflect" + "testing" + + "github.com/containers/podman/v3/libpod/network/types" +) + +func TestUnmarshalMacAddress(t *testing.T) { + tests := []struct { + name string + json string + want types.HardwareAddr + wantErr bool + }{ + { + name: "mac as string with colon", + json: `"52:54:00:1c:2e:46"`, + want: types.HardwareAddr{0x52, 0x54, 0x00, 0x1c, 0x2e, 0x46}, + }, + { + name: "mac as string with dash", + json: `"52-54-00-1c-2e-46"`, + want: types.HardwareAddr{0x52, 0x54, 0x00, 0x1c, 0x2e, 0x46}, + }, + { + name: "mac as byte array", + json: `[82, 84, 0, 28, 46, 70]`, + want: types.HardwareAddr{0x52, 0x54, 0x00, 0x1c, 0x2e, 0x46}, + }, + { + name: "null value", + json: `null`, + want: nil, + }, + { + name: "mac as base64", + json: `"qrvM3e7/"`, + want: types.HardwareAddr{0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff}, + }, + { + name: "invalid string", + json: `"52:54:00:1c:2e`, + wantErr: true, + }, + { + name: "invalid array", + json: `[82, 84, 0, 28, 46`, + wantErr: true, + }, + + { + name: "invalid value", + json: `ab`, + wantErr: true, + }, + { + name: "invalid object", + json: `{}`, + wantErr: true, + }, + } + for _, tt := range tests { + test := tt + t.Run(test.name, func(t *testing.T) { + mac := types.HardwareAddr{} + err := json.Unmarshal([]byte(test.json), &mac) + if (err != nil) != test.wantErr { + t.Errorf("types.HardwareAddress Unmarshal() error = %v, wantErr %v", err, test.wantErr) + return + } + if test.wantErr { + return + } + if !reflect.DeepEqual(mac, test.want) { + t.Errorf("types.HardwareAddress Unmarshal() got = %v, want %v", mac, test.want) + } + }) + } +} |