Skip to content

Commit

Permalink
Use optional fields for ClusterConfig (#256)
Browse files Browse the repository at this point in the history
* add new types.ClusterConfig{} configuration, using optional fields
* move all validation and merge logic into the types package, extend test coverae
* update callers across the codebase
  • Loading branch information
neoaggelos committed Apr 3, 2024
1 parent 2c90ea2 commit e6227da
Show file tree
Hide file tree
Showing 52 changed files with 1,890 additions and 1,481 deletions.
92 changes: 61 additions & 31 deletions src/k8s/api/v1/cluster_config.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,59 +20,89 @@ type UpdateClusterConfigResponse struct {
}

type UserFacingClusterConfig struct {
Network *NetworkConfig `json:"network,omitempty" yaml:"network,omitempty"`
DNS *DNSConfig `json:"dns,omitempty" yaml:"dns,omitempty"`
Ingress *IngressConfig `json:"ingress,omitempty" yaml:"ingress,omitempty"`
LoadBalancer *LoadBalancerConfig `json:"load-balancer,omitempty" yaml:"load-balancer,omitempty"`
LocalStorage *LocalStorageConfig `json:"local-storage,omitempty" yaml:"local-storage,omitempty"`
Gateway *GatewayConfig `json:"gateway,omitempty" yaml:"gateway,omitempty"`
MetricsServer *MetricsServerConfig `json:"metrics-server,omitempty" yaml:"metrics-server,omitempty"`
Network NetworkConfig `json:"network,omitempty" yaml:"network,omitempty"`
DNS DNSConfig `json:"dns,omitempty" yaml:"dns,omitempty"`
Ingress IngressConfig `json:"ingress,omitempty" yaml:"ingress,omitempty"`
LoadBalancer LoadBalancerConfig `json:"load-balancer,omitempty" yaml:"load-balancer,omitempty"`
LocalStorage LocalStorageConfig `json:"local-storage,omitempty" yaml:"local-storage,omitempty"`
Gateway GatewayConfig `json:"gateway,omitempty" yaml:"gateway,omitempty"`
MetricsServer MetricsServerConfig `json:"metrics-server,omitempty" yaml:"metrics-server,omitempty"`
}

type DNSConfig struct {
Enabled *bool `json:"enabled,omitempty" yaml:"enabled"`
ClusterDomain string `json:"cluster-domain,omitempty" yaml:"cluster-domain"`
ServiceIP string `json:"service-ip,omitempty" yaml:"service-ip"`
UpstreamNameservers []string `json:"upstream-nameservers,omitempty" yaml:"upstream-nameservers"`
Enabled *bool `json:"enabled,omitempty" yaml:"enabled,omitempty"`
ClusterDomain *string `json:"cluster-domain,omitempty" yaml:"cluster-domain,omitempty"`
ServiceIP *string `json:"service-ip,omitempty" yaml:"service-ip,omitempty"`
UpstreamNameservers *[]string `json:"upstream-nameservers,omitempty" yaml:"upstream-nameservers,omitempty"`
}

func (c DNSConfig) GetEnabled() bool { return getField(c.Enabled) }
func (c DNSConfig) GetClusterDomain() string { return getField(c.ClusterDomain) }
func (c DNSConfig) GetServiceIP() string { return getField(c.ServiceIP) }
func (c DNSConfig) GetUpstreamNameservers() []string { return getField(c.UpstreamNameservers) }

type IngressConfig struct {
Enabled *bool `json:"enabled,omitempty" yaml:"enabled"`
DefaultTLSSecret string `json:"default-tls-secret,omitempty" yaml:"default-tls-secret"`
EnableProxyProtocol *bool `json:"enable-proxy-protocol,omitempty" yaml:"enable-proxy-protocol"`
Enabled *bool `json:"enabled,omitempty" yaml:"enabled,omitempty"`
DefaultTLSSecret *string `json:"default-tls-secret,omitempty" yaml:"default-tls-secret,omitempty"`
EnableProxyProtocol *bool `json:"enable-proxy-protocol,omitempty" yaml:"enable-proxy-protocol,omitempty"`
}

func (c IngressConfig) GetEnabled() bool { return getField(c.Enabled) }
func (c IngressConfig) GetDefaultTLSSecret() string { return getField(c.DefaultTLSSecret) }
func (c IngressConfig) GetEnableProxyProtocol() bool { return getField(c.EnableProxyProtocol) }

type LoadBalancerConfig struct {
Enabled *bool `json:"enabled,omitempty" yaml:"enabled"`
CIDRs []string `json:"cidrs,omitempty" yaml:"cidrs"`
L2Enabled *bool `json:"l2-mode,omitempty" yaml:"l2-mode"`
L2Interfaces []string `json:"l2-interfaces,omitempty" yaml:"l2-interfaces"`
BGPEnabled *bool `json:"bgp-mode,omitempty" yaml:"bgp-mode"`
BGPLocalASN int `json:"bgp-local-asn,omitempty" yaml:"bgp-local-asn"`
BGPPeerAddress string `json:"bgp-peer-address,omitempty" yaml:"bgp-peer-address"`
BGPPeerASN int `json:"bgp-peer-asn,omitempty" yaml:"bgp-peer-asn"`
BGPPeerPort int `json:"bgp-peer-port,omitempty" yaml:"bgp-peer-port"`
}
Enabled *bool `json:"enabled,omitempty" yaml:"enabled,omitempty"`
CIDRs *[]string `json:"cidrs,omitempty" yaml:"cidrs,omitempty"`
L2Mode *bool `json:"l2-mode,omitempty" yaml:"l2-mode,omitempty"`
L2Interfaces *[]string `json:"l2-interfaces,omitempty" yaml:"l2-interfaces,omitempty"`
BGPMode *bool `json:"bgp-mode,omitempty" yaml:"bgp-mode,omitempty"`
BGPLocalASN *int `json:"bgp-local-asn,omitempty" yaml:"bgp-local-asn,omitempty"`
BGPPeerAddress *string `json:"bgp-peer-address,omitempty" yaml:"bgp-peer-address,omitempty"`
BGPPeerASN *int `json:"bgp-peer-asn,omitempty" yaml:"bgp-peer-asn,omitempty"`
BGPPeerPort *int `json:"bgp-peer-port,omitempty" yaml:"bgp-peer-port,omitempty"`
}

func (c LoadBalancerConfig) GetEnabled() bool { return getField(c.Enabled) }
func (c LoadBalancerConfig) GetCIDRs() []string { return getField(c.CIDRs) }
func (c LoadBalancerConfig) GetL2Mode() bool { return getField(c.L2Mode) }
func (c LoadBalancerConfig) GetL2Interfaces() []string { return getField(c.L2Interfaces) }
func (c LoadBalancerConfig) GetBGPMode() bool { return getField(c.BGPMode) }
func (c LoadBalancerConfig) GetBGPLocalASN() int { return getField(c.BGPLocalASN) }
func (c LoadBalancerConfig) GetBGPPeerAddress() string { return getField(c.BGPPeerAddress) }
func (c LoadBalancerConfig) GetBGPPeerASN() int { return getField(c.BGPPeerASN) }
func (c LoadBalancerConfig) GetBGPPeerPort() int { return getField(c.BGPPeerPort) }

type LocalStorageConfig struct {
Enabled *bool `json:"enabled,omitempty" yaml:"enabled"`
LocalPath string `json:"local-path,omitempty" yaml:"local-path"`
ReclaimPolicy string `json:"reclaim-policy,omitempty" yaml:"reclaim-policy"`
SetDefault *bool `json:"set-default,omitempty" yaml:"set-default"`
Enabled *bool `json:"enabled,omitempty" yaml:"enabled,omitempty"`
LocalPath *string `json:"local-path,omitempty" yaml:"local-path,omitempty"`
ReclaimPolicy *string `json:"reclaim-policy,omitempty" yaml:"reclaim-policy,omitempty"`
SetDefault *bool `json:"set-default,omitempty" yaml:"set-default,omitempty"`
}

func (c LocalStorageConfig) GetEnabled() bool { return getField(c.Enabled) }
func (c LocalStorageConfig) GetLocalPath() string { return getField(c.LocalPath) }
func (c LocalStorageConfig) GetReclaimPolicy() string { return getField(c.ReclaimPolicy) }
func (c LocalStorageConfig) GetSetDefault() bool { return getField(c.SetDefault) }

type NetworkConfig struct {
Enabled *bool `json:"enabled,omitempty" yaml:"enabled"`
Enabled *bool `json:"enabled,omitempty" yaml:"enabled,omitempty"`
}

func (c NetworkConfig) GetEnabled() bool { return getField(c.Enabled) }

type GatewayConfig struct {
Enabled *bool `json:"enabled,omitempty" yaml:"enabled"`
Enabled *bool `json:"enabled,omitempty" yaml:"enabled,omitempty"`
}

func (c GatewayConfig) GetEnabled() bool { return getField(c.Enabled) }

type MetricsServerConfig struct {
Enabled *bool `json:"enabled,omitempty" yaml:"enabled"`
Enabled *bool `json:"enabled,omitempty" yaml:"enabled,omitempty"`
}

func (c MetricsServerConfig) GetEnabled() bool { return getField(c.Enabled) }

func (c UserFacingClusterConfig) String() string {
b, err := yaml.Marshal(c)
if err != nil {
Expand Down
31 changes: 3 additions & 28 deletions src/k8s/api/v1/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -170,35 +170,10 @@ func (c ClusterStatus) String() string {
result.WriteString(" spare-nodes: none\n")
}

printedConfig := UserFacingClusterConfig{}
if c.Config.Network != nil && c.Config.Network.Enabled != nil && *c.Config.Network.Enabled {
printedConfig.Network = c.Config.Network
}
if c.Config.DNS != nil && c.Config.DNS.Enabled != nil && *c.Config.DNS.Enabled {
printedConfig.DNS = c.Config.DNS
}
if c.Config.Ingress != nil && c.Config.Ingress.Enabled != nil && *c.Config.Ingress.Enabled {
printedConfig.Ingress = c.Config.Ingress
}
if c.Config.LoadBalancer != nil && c.Config.LoadBalancer.Enabled != nil && *c.Config.LoadBalancer.Enabled {
printedConfig.LoadBalancer = c.Config.LoadBalancer
}
if c.Config.LocalStorage != nil && c.Config.LocalStorage.Enabled != nil && *c.Config.LocalStorage.Enabled {
printedConfig.LocalStorage = c.Config.LocalStorage
}
if c.Config.Gateway != nil && c.Config.Gateway.Enabled != nil && *c.Config.Gateway.Enabled {
printedConfig.Gateway = c.Config.Gateway
}
if c.Config.MetricsServer != nil && c.Config.MetricsServer.Enabled != nil && *c.Config.MetricsServer.Enabled {
printedConfig.MetricsServer = c.Config.MetricsServer
}

b, _ := yaml.Marshal(printedConfig)
// If no config is set the marshalling will return {}
if s := string(b); s != "{}\n" {
result.WriteString("\n")
var emptyConfig UserFacingClusterConfig
if c.Config != emptyConfig {
b, _ := yaml.Marshal(c.Config)
result.WriteString(string(b))
}

return result.String()
}
11 changes: 3 additions & 8 deletions src/k8s/api/v1/types_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -97,8 +97,6 @@ func TestHaClusterFormed(t *testing.T) {
}

func TestString(t *testing.T) {
g := NewGomegaWithT(t)

testCases := []struct {
name string
clusterStatus ClusterStatus
Expand All @@ -114,8 +112,8 @@ func TestString(t *testing.T) {
{Name: "node3", DatastoreRole: DatastoreRoleVoter, Address: "192.168.0.3"},
},
Config: UserFacingClusterConfig{
Network: &NetworkConfig{Enabled: vals.Pointer(true)},
DNS: &DNSConfig{Enabled: vals.Pointer(true)},
Network: NetworkConfig{Enabled: vals.Pointer(true)},
DNS: DNSConfig{Enabled: vals.Pointer(true)},
},
},
expectedOutput: `status: ready
Expand All @@ -127,14 +125,10 @@ datastore:
- 192.168.0.3
standby-nodes: none
spare-nodes: none
network:
enabled: true
dns:
enabled: true
cluster-domain: ""
service-ip: ""
upstream-nameservers: []
`,
},
{
Expand All @@ -156,6 +150,7 @@ datastore:

for _, tc := range testCases {
t.Run(tc.name, func(t *testing.T) {
g := NewWithT(t)
g.Expect(tc.clusterStatus.String()).To(Equal(tc.expectedOutput))
})
}
Expand Down
9 changes: 9 additions & 0 deletions src/k8s/api/v1/util.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
package v1

func getField[T any](val *T) T {
if val != nil {
return *val
}
var zero T
return zero
}
14 changes: 7 additions & 7 deletions src/k8s/cmd/k8s/k8s_disable.go
Original file line number Diff line number Diff line change
Expand Up @@ -38,31 +38,31 @@ func newDisableCmd(env cmdutil.ExecutionEnvironment) *cobra.Command {

switch functionality {
case "network":
config.Network = &api.NetworkConfig{
config.Network = api.NetworkConfig{
Enabled: vals.Pointer(false),
}
case "dns":
config.DNS = &api.DNSConfig{
config.DNS = api.DNSConfig{
Enabled: vals.Pointer(false),
}
case "gateway":
config.Gateway = &api.GatewayConfig{
config.Gateway = api.GatewayConfig{
Enabled: vals.Pointer(false),
}
case "ingress":
config.Ingress = &api.IngressConfig{
config.Ingress = api.IngressConfig{
Enabled: vals.Pointer(false),
}
case "local-storage":
config.LocalStorage = &api.LocalStorageConfig{
config.LocalStorage = api.LocalStorageConfig{
Enabled: vals.Pointer(false),
}
case "load-balancer":
config.LoadBalancer = &api.LoadBalancerConfig{
config.LoadBalancer = api.LoadBalancerConfig{
Enabled: vals.Pointer(false),
}
case "metrics-server":
config.MetricsServer = &api.MetricsServerConfig{
config.MetricsServer = api.MetricsServerConfig{
Enabled: vals.Pointer(false),
}
}
Expand Down
6 changes: 3 additions & 3 deletions src/k8s/cmd/k8s/k8s_disable_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ func TestDisableCmd(t *testing.T) {
funcs: []string{"gateway"},
expectedCall: apiv1.UpdateClusterConfigRequest{
Config: apiv1.UserFacingClusterConfig{
Gateway: &apiv1.GatewayConfig{Enabled: vals.Pointer(false)},
Gateway: apiv1.GatewayConfig{Enabled: vals.Pointer(false)},
},
},
expectedStdout: "disabled",
Expand All @@ -44,8 +44,8 @@ func TestDisableCmd(t *testing.T) {
funcs: []string{"load-balancer", "gateway"},
expectedCall: apiv1.UpdateClusterConfigRequest{
Config: apiv1.UserFacingClusterConfig{
Gateway: &apiv1.GatewayConfig{Enabled: vals.Pointer(false)},
LoadBalancer: &apiv1.LoadBalancerConfig{Enabled: vals.Pointer(false)},
Gateway: apiv1.GatewayConfig{Enabled: vals.Pointer(false)},
LoadBalancer: apiv1.LoadBalancerConfig{Enabled: vals.Pointer(false)},
},
},
expectedStdout: "disabled",
Expand Down
14 changes: 7 additions & 7 deletions src/k8s/cmd/k8s/k8s_enable.go
Original file line number Diff line number Diff line change
Expand Up @@ -38,31 +38,31 @@ func newEnableCmd(env cmdutil.ExecutionEnvironment) *cobra.Command {

switch functionality {
case "network":
config.Network = &api.NetworkConfig{
config.Network = api.NetworkConfig{
Enabled: vals.Pointer(true),
}
case "dns":
config.DNS = &api.DNSConfig{
config.DNS = api.DNSConfig{
Enabled: vals.Pointer(true),
}
case "gateway":
config.Gateway = &api.GatewayConfig{
config.Gateway = api.GatewayConfig{
Enabled: vals.Pointer(true),
}
case "ingress":
config.Ingress = &api.IngressConfig{
config.Ingress = api.IngressConfig{
Enabled: vals.Pointer(true),
}
case "local-storage":
config.LocalStorage = &api.LocalStorageConfig{
config.LocalStorage = api.LocalStorageConfig{
Enabled: vals.Pointer(true),
}
case "load-balancer":
config.LoadBalancer = &api.LoadBalancerConfig{
config.LoadBalancer = api.LoadBalancerConfig{
Enabled: vals.Pointer(true),
}
case "metrics-server":
config.MetricsServer = &api.MetricsServerConfig{
config.MetricsServer = api.MetricsServerConfig{
Enabled: vals.Pointer(true),
}
}
Expand Down
6 changes: 3 additions & 3 deletions src/k8s/cmd/k8s/k8s_enable_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ func TestK8sEnableCmd(t *testing.T) {
funcs: []string{"gateway"},
expectedCall: apiv1.UpdateClusterConfigRequest{
Config: apiv1.UserFacingClusterConfig{
Gateway: &apiv1.GatewayConfig{Enabled: vals.Pointer(true)},
Gateway: apiv1.GatewayConfig{Enabled: vals.Pointer(true)},
},
},
expectedStdout: "enabled",
Expand All @@ -44,8 +44,8 @@ func TestK8sEnableCmd(t *testing.T) {
funcs: []string{"load-balancer", "gateway"},
expectedCall: apiv1.UpdateClusterConfigRequest{
Config: apiv1.UserFacingClusterConfig{
Gateway: &apiv1.GatewayConfig{Enabled: vals.Pointer(true)},
LoadBalancer: &apiv1.LoadBalancerConfig{Enabled: vals.Pointer(true)},
Gateway: apiv1.GatewayConfig{Enabled: vals.Pointer(true)},
LoadBalancer: apiv1.LoadBalancerConfig{Enabled: vals.Pointer(true)},
},
},
expectedStdout: "enabled",
Expand Down
Loading

0 comments on commit e6227da

Please sign in to comment.