diff --git a/lib/defaults/defaults.go b/lib/defaults/defaults.go index 758d7c9251..d8bafb0b6a 100644 --- a/lib/defaults/defaults.go +++ b/lib/defaults/defaults.go @@ -1345,6 +1345,9 @@ var ( // KubeControllerManagerPort specifies the default controller manager healthz port KubeControllerManagerPort = 10257 + + // FlannelBackend specifies the default flannel backend + FlannelBackend = "vxlan" ) // HookSecurityContext returns default securityContext for hook pods diff --git a/lib/ops/opsservice/configure.go b/lib/ops/opsservice/configure.go index a6af77a7c5..5082cf35e0 100644 --- a/lib/ops/opsservice/configure.go +++ b/lib/ops/opsservice/configure.go @@ -1444,9 +1444,9 @@ func (s *site) addClusterConfig(config clusterconfig.Interface, overrideArgs map if globalConfig.HighAvailability != nil && *globalConfig.HighAvailability { args = append(args, "--high-availability") } - if globalConfig.FlannelBackend != "" { + if globalConfig.FlannelBackend != nil { args = append(args, - fmt.Sprintf("--flannel-backend=%v", globalConfig.FlannelBackend)) + fmt.Sprintf("--flannel-backend=%v", *globalConfig.FlannelBackend)) } return args } diff --git a/lib/ops/resources/gravity/collection.go b/lib/ops/resources/gravity/collection.go index a411bf957e..1d54031a8f 100644 --- a/lib/ops/resources/gravity/collection.go +++ b/lib/ops/resources/gravity/collection.go @@ -664,9 +664,7 @@ func (r configCollection) WriteText(w io.Writer) error { fmt.Fprintf(t, "%v\n", string(config.Config)) } config := r.GetGlobalConfig() - if len(config.FlannelBackend) != 0 { - fmt.Fprintf(t, "Flannel Backend:\t%v\n", config.FlannelBackend) - } + fmt.Fprintf(t, "Flannel Backend:\t%v\n", utils.FormatStringPtrWithDefault(config.FlannelBackend, defaults.FlannelBackend)) if len(config.PodCIDR) != 0 { fmt.Fprintf(t, "Pod IP Range:\t%v\n", config.PodCIDR) } @@ -685,7 +683,7 @@ func (r configCollection) WriteText(w io.Writer) error { if len(config.FeatureGates) != 0 { fmt.Fprintf(t, "Feature Gates:\t%v\n", formatFeatureGates(config.FeatureGates)) } - fmt.Fprintf(t, "High Availability:\t%v\n", formatBoolPtr(config.HighAvailability)) + fmt.Fprintf(t, "High Availability:\t%v\n", utils.FormatBoolPtr(config.HighAvailability)) displayCloudConfig := config.CloudProvider != "" || config.CloudConfig != "" if displayCloudConfig { common.PrintCustomTableHeader(t, []string{"Cloud"}, "-") @@ -742,13 +740,6 @@ func formatFeatureGates(features map[string]bool) string { return strings.Join(result, ",") } -func formatBoolPtr(ptr *bool) string { - if ptr == nil { - return "" - } - return fmt.Sprint(*ptr) -} - type operationsCollection struct { operations []storage.Operation } diff --git a/lib/storage/clusterconfig/clusterconfig.go b/lib/storage/clusterconfig/clusterconfig.go index 9751df475f..ae10b052b0 100644 --- a/lib/storage/clusterconfig/clusterconfig.go +++ b/lib/storage/clusterconfig/clusterconfig.go @@ -140,8 +140,11 @@ func (r Resource) Merge(other Resource) Resource { } } // Changing cloud provider is not supported - if other.Spec.Global.FlannelBackend != "" { - r.Spec.Global.FlannelBackend = other.Spec.Global.FlannelBackend + if other.Spec.Global.FlannelBackend != nil { + if r.Spec.Global.FlannelBackend == nil { + r.Spec.Global.FlannelBackend = new(string) + } + *r.Spec.Global.FlannelBackend = *other.Spec.Global.FlannelBackend } if other.Spec.Global.PodCIDR != "" { r.Spec.Global.PodCIDR = other.Spec.Global.PodCIDR @@ -279,7 +282,7 @@ func (r Global) IsEmpty() bool { r.ServiceNodePortRange == "" && r.ProxyPortRange == "" && r.HighAvailability == nil && - r.FlannelBackend == "" && + r.FlannelBackend == nil && len(r.FeatureGates) == 0 } @@ -313,8 +316,8 @@ type Global struct { FeatureGates map[string]bool `json:"featureGates,omitempty"` // HighAvailability enables high availability mode for Kubernetes. HighAvailability *bool `json:"highAvailability,omitempty"` - // FlannelBackend specifies the backend to pair with flannel. - FlannelBackend string `json:"flannelBackend,omitempty"` + // FlannelBackend optionally specifies the backend to pair with flannel. + FlannelBackend *string `json:"flannelBackend,omitempty"` } // specSchemaTemplate is JSON schema for the cluster configuration resource diff --git a/lib/storage/clusterconfig/clusterconfig_test.go b/lib/storage/clusterconfig/clusterconfig_test.go index 0af802a2bb..d3aa6dd86a 100644 --- a/lib/storage/clusterconfig/clusterconfig_test.go +++ b/lib/storage/clusterconfig/clusterconfig_test.go @@ -24,6 +24,7 @@ import ( "github.com/gravitational/gravity/lib/constants" "github.com/gravitational/gravity/lib/defaults" "github.com/gravitational/gravity/lib/storage" + "github.com/gravitational/gravity/lib/utils" teleservices "github.com/gravitational/teleport/lib/services" "github.com/gravitational/trace" @@ -187,7 +188,7 @@ spec: }, PodSubnetSize: "26", HighAvailability: newBoolPtr(true), - FlannelBackend: "vxlan", + FlannelBackend: utils.StringPtr("vxlan"), }, }, }, @@ -246,7 +247,7 @@ func (*S) TestMergesClusterConfiguration(c *C) { "feature2": false, }, HighAvailability: newBoolPtr(true), - FlannelBackend: "vxlan", + FlannelBackend: utils.StringPtr("vxlan"), }, }, }, @@ -266,7 +267,7 @@ func (*S) TestMergesClusterConfiguration(c *C) { "feature2": false, }, HighAvailability: newBoolPtr(true), - FlannelBackend: "vxlan", + FlannelBackend: utils.StringPtr("vxlan"), }, }, }, @@ -294,7 +295,7 @@ address: 10.0.0.1 "feature1": true, "feature2": false, }, - FlannelBackend: "vxlan", + FlannelBackend: utils.StringPtr("vxlan"), }, }, }, @@ -341,7 +342,7 @@ address: 10.0.0.1 "feature1": true, "feature3": true, }, - FlannelBackend: "vxlan", + FlannelBackend: utils.StringPtr("vxlan"), }, }, }, diff --git a/lib/update/clusterconfig/plan.go b/lib/update/clusterconfig/plan.go index bcc1c9235f..1bd580b766 100644 --- a/lib/update/clusterconfig/plan.go +++ b/lib/update/clusterconfig/plan.go @@ -197,7 +197,7 @@ func shouldUpdateNodes(clusterConfig clusterconfig.Interface, numWorkerNodes int config := clusterConfig.GetGlobalConfig() hasComponentUpdate := len(config.FeatureGates) != 0 hasCIDRUpdate := len(config.PodCIDR) != 0 || len(config.ServiceCIDR) != 0 || config.PodSubnetSize != "" - hasFlannelUpdate := config.FlannelBackend != "" + hasFlannelUpdate := config.FlannelBackend != nil return !clusterConfig.GetKubeletConfig().IsEmpty() || hasComponentUpdate || hasCIDRUpdate || hasFlannelUpdate } diff --git a/lib/utils/units.go b/lib/utils/units.go index 25ae672260..653f38eac5 100644 --- a/lib/utils/units.go +++ b/lib/utils/units.go @@ -146,13 +146,38 @@ func BoolPtr(v bool) *bool { return &v } +// FormatBoolPtr formats the bool pointer value for output +func FormatBoolPtr(v *bool) string { + if v == nil { + return "" + } + return fmt.Sprint(*v) +} + // DurationPtr returns a pointer to the provided duration value func DurationPtr(v time.Duration) *teleservices.Duration { d := teleservices.NewDuration(v) return &d } +// StringValue returns the string value in v or an empty string if it's nil +func StringValue(v *string) string { + if v != nil { + return *v + } + return "" +} + // StringPtr returns a pointer to the provided string func StringPtr(s string) *string { return &s } + +// FormatStringPtrWithDefault formats the string pointer value for output. +// If the pointer value is nil, the specified default is used +func FormatStringPtrWithDefault(v *string, def string) string { + if v == nil { + return def + } + return *v +} diff --git a/lib/validate/clusterconfig.go b/lib/validate/clusterconfig.go index 941ca2afa5..ec4c840824 100644 --- a/lib/validate/clusterconfig.go +++ b/lib/validate/clusterconfig.go @@ -89,8 +89,13 @@ func ClusterConfiguration(existing, update clusterconfig.Interface) error { return trace.Wrap(err) } - if !isSupportedBackend(newGlobalConfig.FlannelBackend) { - return trace.BadParameter("unsupported flannel backend was specified: %v", newGlobalConfig.FlannelBackend) + if newGlobalConfig.FlannelBackend != nil { + if *newGlobalConfig.FlannelBackend == "" { + return trace.BadParameter("flannel backend cannot be reset") + } + if !isSupportedBackend(*newGlobalConfig.FlannelBackend) { + return trace.BadParameter("unsupported flannel backend was specified: %v", *newGlobalConfig.FlannelBackend) + } } return nil diff --git a/tool/gravity/cli/config_test.go b/tool/gravity/cli/config_test.go index a9b1e95156..0268a65796 100644 --- a/tool/gravity/cli/config_test.go +++ b/tool/gravity/cli/config_test.go @@ -23,6 +23,7 @@ import ( "github.com/gravitational/gravity/lib/ops/resources" "github.com/gravitational/gravity/lib/storage" "github.com/gravitational/gravity/lib/storage/clusterconfig" + "github.com/gravitational/gravity/lib/utils" "gopkg.in/check.v1" ) @@ -77,7 +78,7 @@ spec: ServiceCIDR: "100.200.0.0/16", PodCIDR: "100.96.0.0/16", PodSubnetSize: "26", - FlannelBackend: "vxlan", + FlannelBackend: utils.StringPtr("vxlan"), CloudConfig: `[global] node-tags=example-cluster multizone="true"