1
0
mirror of https://github.com/openshift/installer.git synced 2026-02-05 15:47:14 +01:00

pkg/ipnet: Provide an IPNet structure with CIDR serialization

Use CIDR notation [1] for serliazing IPNet structures so the values
are human editable (vs. the stdlib's base64 netmasks).  It's
unfortunate that we can't update the stdlib to do this, but their
encodings are frozen [2].

[1]: https://en.wikipedia.org/wiki/Classless_Inter-Domain_Routing#CIDR_notation
[2]: https://github.com/golang/go/issues/12803#issuecomment-150673932
This commit is contained in:
W. Trevor King
2018-09-06 16:51:59 -07:00
parent 7a1e69a6e9
commit c756ba504f
7 changed files with 123 additions and 18 deletions

View File

@@ -31,12 +31,8 @@ data:
creationTimestamp: null
name: test
networking:
podCIDR:
IP: 10.2.0.0
Mask: //8AAA==
serviceCIDR:
IP: 10.3.0.0
Mask: //8AAA==
podCIDR: 10.2.0.0/16
serviceCIDR: 10.3.0.0/16
type: canal
platform:
aws:

View File

@@ -19,6 +19,7 @@ import (
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"github.com/openshift/installer/installer/pkg/config"
"github.com/openshift/installer/pkg/ipnet"
"github.com/openshift/installer/pkg/types"
)
@@ -185,8 +186,8 @@ func (c *ConfigGenerator) installConfig() (*types.InstallConfig, error) {
PullSecret: c.PullSecret,
Networking: types.Networking{
Type: types.NetworkType(string(c.Networking.Type)),
ServiceCIDR: *serviceCIDR,
PodCIDR: *podCIDR,
ServiceCIDR: ipnet.IPNet{IPNet: *serviceCIDR},
PodCIDR: ipnet.IPNet{IPNet: *podCIDR},
},
Platform: platform,
Machines: []types.MachinePool{{

View File

@@ -163,12 +163,8 @@ metadata:
creationTimestamp: null
name: test-cluster-name
networking:
podCIDR:
IP: ""
Mask: null
serviceCIDR:
IP: ""
Mask: null
podCIDR: null
serviceCIDR: null
type: ""
platform:
%s

View File

@@ -53,7 +53,7 @@ func genDNSNamesForAPIServerCertKey(cfg *types.InstallConfig) ([]string, error)
}
func genIPAddressesForAPIServerCertKey(cfg *types.InstallConfig) ([]net.IP, error) {
apiServerAddress, err := cidrhost(cfg.Networking.ServiceCIDR, 1)
apiServerAddress, err := cidrhost(cfg.Networking.ServiceCIDR.IPNet, 1)
if err != nil {
return nil, err
}
@@ -72,7 +72,7 @@ func genDNSNamesForOpenshiftAPIServerCertKey(cfg *types.InstallConfig) ([]string
}
func genIPAddressesForOpenshiftAPIServerCertKey(cfg *types.InstallConfig) ([]net.IP, error) {
apiServerAddress, err := cidrhost(cfg.Networking.ServiceCIDR, 1)
apiServerAddress, err := cidrhost(cfg.Networking.ServiceCIDR.IPNet, 1)
if err != nil {
return nil, err
}

49
pkg/ipnet/ipnet.go Normal file
View File

@@ -0,0 +1,49 @@
// Package ipnet wraps net.IPNet to get CIDR serialization.
package ipnet
import (
"encoding/json"
"net"
"reflect"
)
var nullString = "null"
var nullBytes = []byte(nullString)
var emptyIPNet = net.IPNet{}
// IPNet wraps net.IPNet to get CIDR serialization.
type IPNet struct {
net.IPNet
}
// MarshalJSON interface for an IPNet
func (ipnet IPNet) MarshalJSON() (data []byte, err error) {
if reflect.DeepEqual(ipnet.IPNet, emptyIPNet) {
return nullBytes, nil
}
return json.Marshal(ipnet.String())
}
// UnmarshalJSON interface for an IPNet
func (ipnet *IPNet) UnmarshalJSON(b []byte) (err error) {
if string(b) == nullString {
ipnet.IP = net.IP{}
ipnet.Mask = net.IPMask{}
return nil
}
var cidr string
err = json.Unmarshal(b, &cidr)
if err != nil {
return err
}
ip, net, err := net.ParseCIDR(cidr)
if err != nil {
return err
}
ipnet.IP = ip
ipnet.Mask = net.Mask
return nil
}

62
pkg/ipnet/ipnet_test.go Normal file
View File

@@ -0,0 +1,62 @@
package ipnet
import (
"encoding/json"
"net"
"testing"
)
func assertJSON(t *testing.T, data interface{}, expected string) {
actualBytes, err := json.Marshal(data)
if err != nil {
t.Fatal(err)
}
actual := string(actualBytes)
if actual != expected {
t.Fatalf("%s != %s", actual, expected)
}
}
func TestMarshal(t *testing.T) {
stdlibIPNet := &net.IPNet{
IP: net.IP{192, 168, 0, 10},
Mask: net.IPv4Mask(255, 255, 255, 0),
}
assertJSON(t, stdlibIPNet, "{\"IP\":\"192.168.0.10\",\"Mask\":\"////AA==\"}")
wrappedIPNet := &IPNet{IPNet: *stdlibIPNet}
assertJSON(t, wrappedIPNet, "\"192.168.0.10/24\"")
assertJSON(t, &IPNet{}, "null")
assertJSON(t, nil, "null")
}
func TestUnmarshal(t *testing.T) {
for _, ipNetIn := range []*IPNet{
nil,
{IPNet: net.IPNet{
IP: net.IP{192, 168, 0, 10},
Mask: net.IPv4Mask(255, 255, 255, 0),
}},
} {
data, err := json.Marshal(ipNetIn)
if err != nil {
t.Fatal(err)
}
t.Run(string(data), func(t *testing.T) {
var ipNetOut *IPNet
err := json.Unmarshal(data, &ipNetOut)
if err != nil {
t.Fatal(err)
}
if ipNetIn == nil {
if ipNetOut != nil {
t.Fatalf("%v != %v", ipNetOut, ipNetIn)
}
} else if ipNetOut.String() != ipNetIn.String() {
t.Fatalf("%v != %v", ipNetOut, ipNetIn)
}
})
}
}

View File

@@ -3,6 +3,7 @@ package types
import (
"net"
"github.com/openshift/installer/pkg/ipnet"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
)
@@ -58,8 +59,8 @@ type Platform struct {
// Networking defines the pod network provider in the cluster.
type Networking struct {
Type NetworkType `json:"type"`
ServiceCIDR net.IPNet `json:"serviceCIDR"`
PodCIDR net.IPNet `json:"podCIDR"`
ServiceCIDR ipnet.IPNet `json:"serviceCIDR"`
PodCIDR ipnet.IPNet `json:"podCIDR"`
}
// NetworkType defines the pod network provider in the cluster.