Skip to content

Commit

Permalink
Declare Data Plane Cluster configuration in gitops config
Browse files Browse the repository at this point in the history
  • Loading branch information
kovayur committed Dec 8, 2023
1 parent 4064113 commit 65db6ca
Show file tree
Hide file tree
Showing 3 changed files with 192 additions and 2 deletions.
62 changes: 60 additions & 2 deletions internal/dinosaur/pkg/gitops/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,9 @@ import (

// Config represents the gitops configuration
type Config struct {
Centrals CentralsConfig `json:"centrals"`
RHACSOperators operator.OperatorConfigs `json:"rhacsOperators"`
Centrals CentralsConfig `json:"centrals"`
RHACSOperators operator.OperatorConfigs `json:"rhacsOperators"`
DataPlaneClusters []DataPlaneClusterConfig `json:"dataPlaneClusters"`
}

// CentralsConfig represents the declarative configuration for Central instances defaults and overrides.
Expand All @@ -28,11 +29,25 @@ type CentralOverride struct {
Patch string `json:"patch"`
}

// DataPlaneClusterConfig represents the configuration to be applied for a data plane cluster.
type DataPlaneClusterConfig struct {
ClusterID string `json:"clusterID"`
Addons []AddonConfig `json:"addons"`
}

// AddonConfig represents the addon configuration to be installed on a cluster
type AddonConfig struct {
ID string `json:"id"`
Version string `json:"version"`
Parameters map[string]string `json:"parameters"`
}

// ValidateConfig validates the GitOps configuration.
func ValidateConfig(config Config) field.ErrorList {
var errs field.ErrorList
errs = append(errs, validateCentralsConfig(field.NewPath("centrals"), config.Centrals)...)
errs = append(errs, operator.Validate(field.NewPath("rhacsOperators"), config.RHACSOperators)...)
errs = append(errs, validateDataPlaneClusterConfigs(field.NewPath("dataPlaneClusters"), config.DataPlaneClusters)...)
return errs
}

Expand Down Expand Up @@ -130,3 +145,46 @@ func validateInstanceID(path *field.Path, instanceID string) field.ErrorList {
}
return errs
}

func validateDataPlaneClusterConfigs(path *field.Path, clusters []DataPlaneClusterConfig) field.ErrorList {
var errs field.ErrorList
var seenCluster = make(map[string]struct{})
for i, cluster := range clusters {
errs = append(errs, validateClusterID(path.Index(i).Child("clusterID"), cluster.ClusterID)...)
if _, ok := seenCluster[cluster.ClusterID]; ok {
errs = append(errs, field.Duplicate(path, cluster))
}
seenCluster[cluster.ClusterID] = struct{}{}
errs = append(errs, validateAddons(path.Index(i).Child("addons"), cluster.Addons)...)
}
return errs
}

func validateClusterID(path *field.Path, clusterID string) field.ErrorList {
var errs field.ErrorList
if len(clusterID) == 0 {
errs = append(errs, field.Required(path, "clusterID is required"))
}
return errs
}

func validateAddons(path *field.Path, addons []AddonConfig) field.ErrorList {
var errs field.ErrorList
var seenAddon = make(map[string]struct{})
for i, addon := range addons {
errs = append(errs, validateAddonID(path.Index(i).Child("id"), addon.ID)...)
if _, ok := seenAddon[addon.ID]; ok {
errs = append(errs, field.Duplicate(path, addon))
}
seenAddon[addon.ID] = struct{}{}
}
return errs
}

func validateAddonID(path *field.Path, addonID string) field.ErrorList {
var errs field.ErrorList
if len(addonID) == 0 {
errs = append(errs, field.Required(path, "id is required"))
}
return errs
}
37 changes: 37 additions & 0 deletions internal/dinosaur/pkg/gitops/config_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,43 @@ centrals:
resources:
requests:
memory: "a"
`,
},
{
name: "valid cluster config",
assert: func(t *testing.T, c *Config, err field.ErrorList) {
require.Empty(t, err)
},
yaml: `
dataPlaneClusters:
- clusterID: 1234567890abcdef1234567890abcdef
addons:
- id: acs-fleetshard
`,
},
{
name: "invalid cluster config when no clusterID",
assert: func(t *testing.T, c *Config, err field.ErrorList) {
require.Len(t, err, 1)
assert.Equal(t, field.Required(field.NewPath("dataPlaneClusters").Index(0).Child("clusterID"), "clusterID is required"), err[0])
},
yaml: `
dataPlaneClusters:
- addons:
- id: acs-fleetshard
`,
},
{
name: "invalid cluster config when no addon ID",
assert: func(t *testing.T, c *Config, err field.ErrorList) {
require.Len(t, err, 1)
assert.Equal(t, field.Required(field.NewPath("dataPlaneClusters").Index(0).Child("addons").Index(0).Child("id"), "id is required"), err[0])
},
yaml: `
dataPlaneClusters:
- clusterID: 1234567890abcdef1234567890abcdef
addons:
- version: 0.2.0
`,
},
}
Expand Down
95 changes: 95 additions & 0 deletions internal/dinosaur/pkg/gitops/provider_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -177,3 +177,98 @@ centrals:
assert.Equal(t, 2, validationFnCalls)

}

func TestProviderGet_DataPlaneClusters(t *testing.T) {
successfulValidation := func(config Config) error {
return nil
}
type tc struct {
name string
file string
expectedConfigs []DataPlaneClusterConfig
}

tcs := []tc{
{
name: "should return nil when no data plane clusters defined",
file: "",
expectedConfigs: nil,
},
{
name: "should return empty slice when the list of clusters is empty",
file: "dataPlaneClusters: []",
expectedConfigs: []DataPlaneClusterConfig{},
},
{
name: "should return config when no addons defined in the cluster",
file: `
dataPlaneClusters:
- clusterID: 1234567890abcdef1234567890abcdef
`,
expectedConfigs: []DataPlaneClusterConfig{
{
ClusterID: "1234567890abcdef1234567890abcdef", // pragma: allowlist secret
},
},
},
{
name: "should return config when cluster with the empty addon slice is defined",
file: `
dataPlaneClusters:
- clusterID: 1234567890abcdef1234567890abcdef
addons: []
`,
expectedConfigs: []DataPlaneClusterConfig{
{
ClusterID: "1234567890abcdef1234567890abcdef", // pragma: allowlist secret
Addons: []AddonConfig{},
},
},
},
{
name: "should return config when cluster with an addon is defined",
file: `
dataPlaneClusters:
- clusterID: 1234567890abcdef1234567890abcdef
addons:
- id: acs-fleetshard
version: 0.2.0
parameters:
acscsEnvironment: test
`,
expectedConfigs: []DataPlaneClusterConfig{
{
ClusterID: "1234567890abcdef1234567890abcdef", // pragma: allowlist secret
Addons: []AddonConfig{
{
ID: "acs-fleetshard",
Version: "0.2.0",
Parameters: map[string]string{
"acscsEnvironment": "test",
},
},
},
},
},
},
}
for _, tc := range tcs {
t.Run(tc.name, func(t *testing.T) {
tmpDir := t.TempDir()
tmpFile := filepath.Join(tmpDir, "config.yaml")
err := os.WriteFile(tmpFile, []byte(tc.file), 0644)
if err != nil {
t.Fatal(err)
}
p := &provider{
reader: NewFileReader(tmpFile),
lastWorkingConfig: atomic.Pointer[Config]{},
validationFn: successfulValidation,
}
config, err := p.Get()
require.NoError(t, err)
assert.Equal(t, tc.expectedConfigs, config.DataPlaneClusters)
})
}

}

0 comments on commit 65db6ca

Please sign in to comment.