Skip to content

Commit

Permalink
Create region-zone-sysType hierarchy
Browse files Browse the repository at this point in the history
  • Loading branch information
AshwinHIBM authored and KeerthanaAP committed Dec 19, 2024
1 parent ae4205b commit b107504
Show file tree
Hide file tree
Showing 7 changed files with 341 additions and 40 deletions.
10 changes: 10 additions & 0 deletions pkg/asset/cluster/tfvars.go
Original file line number Diff line number Diff line change
Expand Up @@ -875,6 +875,16 @@ func (t *TerraformVariables) Generate(parents asset.Parents) error {

err = powervsconfig.ValidatePERAvailability(client, installConfig.Config)
transitGatewayEnabled := err == nil
cpStanza := installConfig.Config.ControlPlane
if cpStanza == nil || cpStanza.Platform.PowerVS == nil || cpStanza.Platform.PowerVS.SysType == "" {
sysTypes, err := powervs.AvailableSysTypes(installConfig.Config.PowerVS.Region, installConfig.Config.PowerVS.Zone)
if err != nil {
return err
}
for i := range masters {
masterConfigs[i].SystemType = sysTypes[0]
}
}

serviceInstanceCRN, err := client.ServiceInstanceIDToCRN(ctx, installConfig.Config.PowerVS.ServiceInstanceID)
if err != nil {
Expand Down
5 changes: 5 additions & 0 deletions pkg/asset/installconfig/platformprovisioncheck.go
Original file line number Diff line number Diff line change
Expand Up @@ -175,6 +175,11 @@ func (a *PlatformProvisionCheck) Generate(dependencies asset.Parents) error {
return err
}

err = powervsconfig.ValidateSystemTypeForZone(client, ic.Config)
if err != nil {
return err
}

err = powervsconfig.ValidateServiceInstance(client, ic.Config)
if err != nil {
return err
Expand Down
6 changes: 5 additions & 1 deletion pkg/asset/installconfig/powervs/regions.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,11 @@ func IsKnownRegion(region string) bool {
}

func knownZones(region string) []string {
return powervs.Regions[region].Zones
zones := make([]string, 0, len(powervs.Regions[region].Zones))
for z := range powervs.Regions[region].Zones {
zones = append(zones, z)
}
return zones
}

// IsKnownZone return true is a specified zone is Known to the installer.
Expand Down
25 changes: 24 additions & 1 deletion pkg/asset/installconfig/powervs/validation.go
Original file line number Diff line number Diff line change
Expand Up @@ -263,7 +263,30 @@ func ValidateResourceGroup(client API, ic *types.InstallConfig) error {
return nil
}

// ValidateServiceInstance validates the service instance in our install config.
// ValidateSystemTypeForZone checks if the specified sysType is available in the target zone.
func ValidateSystemTypeForZone(client API, ic *types.InstallConfig) error {
if ic.ControlPlane == nil || ic.ControlPlane.Platform.PowerVS == nil || ic.ControlPlane.Platform.PowerVS.SysType == "" {
return nil
}
availableOnes, err := powervstypes.AvailableSysTypes(ic.PowerVS.Region, ic.PowerVS.Zone)
if err != nil {
return fmt.Errorf("failed to obtain available SysTypes for: %s", ic.PowerVS.Zone)
}
requested := ic.ControlPlane.Platform.PowerVS.SysType
found := false
for i := range availableOnes {
if requested == availableOnes[i] {
found = true
break
}
}
if found {
return nil
}
return fmt.Errorf("%s is not available in: %s", requested, ic.PowerVS.Zone)
}

// ValidateServiceInstance validates the optional service instance GUID in our install config.
func ValidateServiceInstance(client API, ic *types.InstallConfig) error {
ctx, cancel := context.WithTimeout(context.TODO(), 5*time.Minute)
defer cancel()
Expand Down
140 changes: 139 additions & 1 deletion pkg/asset/installconfig/powervs/validation_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ var (
validPrivateSubnetUSSouth2ID,
}
validUserID = "[email protected]"
validZone = "dal10"
validZone = "dal12"

existingDNSRecordsResponse = []powervs.DNSRecordResponse{
{
Expand Down Expand Up @@ -134,6 +134,10 @@ var (
"disaster-recover-site": true,
"power-vpn-connections": false,
}
defaultSysType = "s922"
newSysType = "s1022"
invalidZone = "dal11"
validServiceInstanceGUID = ""
)

func validInstallConfig() *types.InstallConfig {
Expand Down Expand Up @@ -734,6 +738,140 @@ func TestValidatePERAvailability(t *testing.T) {
}
}

func TestValidateSystemTypeForZone(t *testing.T) {
cases := []struct {
name string
edits editFunctions
errorMsg string
}{
{
name: "Unknown Zone specified",
edits: editFunctions{
func(ic *types.InstallConfig) {
ic.Platform.PowerVS.Zone = invalidZone
ic.ControlPlane.Platform.PowerVS = validMachinePool()
ic.ControlPlane.Platform.PowerVS.SysType = defaultSysType
},
},
errorMsg: fmt.Sprintf("failed to obtain available SysTypes for: %s", invalidZone),
},
{
name: "No Platform block",
edits: editFunctions{
func(ic *types.InstallConfig) {
ic.ControlPlane.Platform.PowerVS = nil
},
},
errorMsg: "",
},
{
name: "Structure present, but no SysType specified",
edits: editFunctions{
func(ic *types.InstallConfig) {
ic.ControlPlane.Platform.PowerVS = validMachinePool()
},
},
errorMsg: "",
},
{
name: "Unavailable SysType specified for dal12 zone",
edits: editFunctions{
func(ic *types.InstallConfig) {
ic.Platform.PowerVS.Region = validRegion
ic.Platform.PowerVS.Zone = validZone
ic.ControlPlane.Platform.PowerVS = validMachinePool()
ic.ControlPlane.Platform.PowerVS.SysType = newSysType
},
},
errorMsg: fmt.Sprintf("%s is not available in: %s", newSysType, validZone),
},
{
name: "Good Zone/SysType combo specified",
edits: editFunctions{
func(ic *types.InstallConfig) {
ic.Platform.PowerVS.Region = validRegion
ic.Platform.PowerVS.Zone = validZone
ic.ControlPlane.Platform.PowerVS = validMachinePool()
ic.ControlPlane.Platform.PowerVS.SysType = defaultSysType
},
},
errorMsg: "",
},
}
setMockEnvVars()

mockCtrl := gomock.NewController(t)
defer mockCtrl.Finish()

powervsClient := mock.NewMockAPI(mockCtrl)

// Run tests
for _, tc := range cases {
t.Run(tc.name, func(t *testing.T) {
editedInstallConfig := validInstallConfig()
for _, edit := range tc.edits {
edit(editedInstallConfig)
}

aggregatedErrors := powervs.ValidateSystemTypeForZone(powervsClient, editedInstallConfig)
if tc.errorMsg != "" {
assert.Regexp(t, tc.errorMsg, aggregatedErrors)
} else {
assert.NoError(t, aggregatedErrors)
}
})
}
}

func TestValidateServiceInstance(t *testing.T) {
cases := []struct {
name string
edits editFunctions
errorMsg string
}{
{
name: "valid install config",
edits: editFunctions{},
errorMsg: "",
},
{
name: "invalid install config",
edits: editFunctions{
func(ic *types.InstallConfig) {
ic.Platform.PowerVS.ServiceInstanceGUID = "invalid-uuid"
},
},
errorMsg: "platform:powervs:serviceInstanceGUID has an invalid guid",
},
}
setMockEnvVars()

mockCtrl := gomock.NewController(t)
defer mockCtrl.Finish()

powervsClient := mock.NewMockAPI(mockCtrl)

// FIX: Unexpected call to *mock.MockAPI.ListServiceInstances([context.TODO.WithDeadline(2023-12-02 08:38:15.542340268 -0600 CST m=+300.012357408 [4m59.999979046s])]) at validation.go:289 because: there are no expected calls of the method "ListServiceInstances" for that receiver
powervsClient.EXPECT().ListServiceInstances(gomock.Any()).AnyTimes()

// Run tests
for _, tc := range cases {
t.Run(tc.name, func(t *testing.T) {
editedInstallConfig := validInstallConfig()
for _, edit := range tc.edits {
edit(editedInstallConfig)
}

aggregatedErrors := powervs.ValidateServiceInstance(powervsClient, editedInstallConfig)
if tc.errorMsg != "" {
assert.Regexp(t, tc.errorMsg, aggregatedErrors)
} else {
assert.NoError(t, aggregatedErrors)
}
})
}
}

func setMockEnvVars() {
os.Setenv("POWERVS_AUTH_FILEPATH", "./tmp/powervs/config.json")
os.Setenv("IBMID", "foo")
Expand Down
9 changes: 9 additions & 0 deletions pkg/asset/machines/worker.go
Original file line number Diff line number Diff line change
Expand Up @@ -186,6 +186,15 @@ func defaultPowerVSMachinePoolPlatform() powervstypes.MachinePool {
ProcType: machinev1.PowerVSProcessorTypeShared,
SysType: "s922",
}

sysTypes, err = powervstypes.AvailableSysTypes(ic.PowerVS.Region, ic.PowerVS.Zone)
if err == nil {
defaultMp.SysType = sysTypes[0]
} else {
logrus.Warnf("For given zone %v, AvailableSysTypes returns %v", ic.PowerVS.Zone, err)
}

return defaultMp
}

func defaultNutanixMachinePoolPlatform() nutanixtypes.MachinePool {
Expand Down
Loading

0 comments on commit b107504

Please sign in to comment.