diff --git a/pkg/cmd/render/render.go b/pkg/cmd/render/render.go index 1e1121ca3..8b509ad71 100644 --- a/pkg/cmd/render/render.go +++ b/pkg/cmd/render/render.go @@ -107,6 +107,15 @@ type TemplateData struct { } func discoverRestrictedCIDRs(clusterConfigFileData []byte, renderConfig *TemplateData) error { + if err := discoverRestrictedCIDRsFromNetwork(clusterConfigFileData, renderConfig); err != nil { + if err = discoverRestrictedCIDRsFromClusterAPI(clusterConfigFileData, renderConfig); err != nil { + return err + } + } + return nil +} + +func discoverRestrictedCIDRsFromClusterAPI(clusterConfigFileData []byte, renderConfig *TemplateData) error { configJson, err := yaml.YAMLToJSON(clusterConfigFileData) if err != nil { return err @@ -138,6 +147,46 @@ func discoverRestrictedCIDRs(clusterConfigFileData []byte, renderConfig *Templat return nil } +func discoverRestrictedCIDRsFromNetwork(clusterConfigFileData []byte, renderConfig *TemplateData) error { + configJson, err := yaml.YAMLToJSON(clusterConfigFileData) + if err != nil { + return err + } + clusterConfigObj, err := runtime.Decode(unstructured.UnstructuredJSONScheme, configJson) + if err != nil { + return err + } + clusterConfig, ok := clusterConfigObj.(*unstructured.Unstructured) + if !ok { + return fmt.Errorf("unexpected object in %t", clusterConfigObj) + } + clusterCIDR, found, err := unstructured.NestedSlice( + clusterConfig.Object, "spec", "clusterNetwork") + if found && err == nil { + for key := range clusterCIDR { + slice, ok := clusterCIDR[key].(map[string]interface{}) + if !ok { + return fmt.Errorf("unexpected object in %t", clusterCIDR[key]) + } + if CIDR, found, err := unstructured.NestedString(slice, "cidr"); found && err == nil { + renderConfig.ClusterCIDR = append(renderConfig.ClusterCIDR, CIDR) + } + } + } + if err != nil { + return err + } + serviceCIDR, found, err := unstructured.NestedStringSlice( + clusterConfig.Object, "spec", "serviceNetwork") + if found && err == nil { + renderConfig.ServiceClusterIPRange = serviceCIDR + } + if err != nil { + return err + } + return nil +} + // Run contains the logic of the render command. func (r *renderOpts) Run() error { renderConfig := TemplateData{} diff --git a/pkg/cmd/render/render_test.go b/pkg/cmd/render/render_test.go index ca5a74400..6f012b0ec 100644 --- a/pkg/cmd/render/render_test.go +++ b/pkg/cmd/render/render_test.go @@ -5,6 +5,7 @@ import ( "io/ioutil" "os" "path/filepath" + "reflect" "strings" "testing" @@ -12,6 +13,45 @@ import ( "github.com/spf13/cobra" ) +var ( + expectedClusterCIDR = []string{"10.128.0.0/14"} + expectedServiceCIDR = []string{"172.30.0.0/16"} + clusterAPIConfig = ` +apiVersion: machine.openshift.io/v1beta1 +kind: Cluster +metadata: + creationTimestamp: null + name: cluster + namespace: openshift-machine-api +spec: + clusterNetwork: + pods: + cidrBlocks: + - 10.128.0.0/14 + serviceDomain: "" + services: + cidrBlocks: + - 172.30.0.0/16 + providerSpec: {} +status: {} +` + networkConfig = ` +apiVersion: config.openshift.io/v1 +kind: Network +metadata: + creationTimestamp: null + name: cluster +spec: + clusterNetwork: + - cidr: 10.128.0.0/14 + hostPrefix: 23 + networkType: OpenShiftSDN + serviceNetwork: + - 172.30.0.0/16 +status: {} +` +) + func runRender(args ...string) (*cobra.Command, error) { errOut := &bytes.Buffer{} c := NewRenderCommand(errOut) @@ -113,3 +153,56 @@ func TestRenderCommand(t *testing.T) { } } } + +func TestDiscoverRestrictedCIDRsFromNetwork(t *testing.T) { + renderConfig := TemplateData{} + if err := discoverRestrictedCIDRsFromNetwork([]byte(networkConfig), &renderConfig); err != nil { + t.Errorf("failed discoverCIDRs: %v", err) + } + if !reflect.DeepEqual(renderConfig.ClusterCIDR, expectedClusterCIDR) { + t.Errorf("Got: %v, expected: %v", renderConfig.ClusterCIDR, expectedClusterCIDR) + } + if !reflect.DeepEqual(renderConfig.ServiceClusterIPRange, expectedServiceCIDR) { + t.Errorf("Got: %v, expected: %v", renderConfig.ServiceClusterIPRange, expectedServiceCIDR) + } +} + +func TestDiscoverRestrictedCIDRsFromClusterAPI(t *testing.T) { + renderConfig := TemplateData{} + if err := discoverRestrictedCIDRsFromClusterAPI([]byte(clusterAPIConfig), &renderConfig); err != nil { + t.Errorf("failed discoverCIDRs: %v", err) + } + if !reflect.DeepEqual(renderConfig.ClusterCIDR, expectedClusterCIDR) { + t.Errorf("Got: %v, expected: %v", renderConfig.ClusterCIDR, expectedClusterCIDR) + } + if !reflect.DeepEqual(renderConfig.ServiceClusterIPRange, expectedServiceCIDR) { + t.Errorf("Got: %v, expected: %v", renderConfig.ServiceClusterIPRange, expectedServiceCIDR) + } +} + +func TestDiscoverRestrictedCIDRs(t *testing.T) { + testCase := []struct { + config []byte + }{ + { + config: []byte(networkConfig), + }, + { + config: []byte(clusterAPIConfig), + }, + } + + for _, tc := range testCase { + renderConfig := TemplateData{} + if err := discoverRestrictedCIDRs(tc.config, &renderConfig); err != nil { + t.Errorf("failed to discoverCIDRs: %v", err) + } + + if !reflect.DeepEqual(renderConfig.ClusterCIDR, expectedClusterCIDR) { + t.Errorf("Got: %v, expected: %v", renderConfig.ClusterCIDR, expectedClusterCIDR) + } + if !reflect.DeepEqual(renderConfig.ServiceClusterIPRange, expectedServiceCIDR) { + t.Errorf("Got: %v, expected: %v", renderConfig.ServiceClusterIPRange, expectedServiceCIDR) + } + } +}