1
0
mirror of https://github.com/openshift/installer.git synced 2026-02-06 00:48:45 +01:00

types/vsphere: simplify vsphere platform

Remove most of the configuration from the vSphere platform,
leaving only the options that a basic customer would need
to get a cluster running.
This commit is contained in:
staebler
2019-04-10 16:49:59 -04:00
parent abc11d532a
commit 3e73413069
15 changed files with 99 additions and 696 deletions

View File

@@ -16,8 +16,6 @@ data:
{{- else if .CloudCreds.OpenStack}}
clouds.yaml: {{.CloudCreds.OpenStack.Base64encodeCloudCreds}}
{{- else if .CloudCreds.VSphere}}
{{- range .CloudCreds.VSphere.VirtualCenters}}
{{.Name}}.username: {{.Base64encodeUsername}}
{{.Name}}.password: {{.Base64encodePassword}}
{{- end}}
{{.CloudCreds.VSphere.VCenter}}.username: {{.CloudCreds.VSphere.Base64encodeUsername}}
{{.CloudCreds.VSphere.VCenter}}.password: {{.CloudCreds.VSphere.Base64encodePassword}}
{{- end}}

View File

@@ -91,7 +91,10 @@ func (cpc *CloudProviderConfig) Generate(dependencies asset.Parents) error {
}
cm.Data[cloudProviderConfigDataKey] = string(marshalled)
case vspheretypes.Name:
vsphereConfig, err := vspheremanifests.CloudProviderConfig(installConfig.Config.Platform.VSphere)
vsphereConfig, err := vspheremanifests.CloudProviderConfig(
installConfig.Config.ObjectMeta.Name,
installConfig.Config.Platform.VSphere,
)
if err != nil {
return errors.Wrap(err, "could not create cloud provider config")
}

View File

@@ -97,15 +97,11 @@ func (o *Openshift) Generate(dependencies asset.Parents) error {
},
}
case vspheretypes.Name:
vcCreds := make([]VSphereVirtualCenterCredsSecretData, len(installConfig.Config.VSphere.VirtualCenters))
for i, vc := range installConfig.Config.VSphere.VirtualCenters {
vcCreds[i].Name = vc.Name
vcCreds[i].Base64encodeUsername = base64.StdEncoding.EncodeToString([]byte(vc.Username))
vcCreds[i].Base64encodePassword = base64.StdEncoding.EncodeToString([]byte(vc.Password))
}
cloudCreds = cloudCredsSecretData{
VSphere: &VSphereCredsSecretData{
VirtualCenters: vcCreds,
VCenter: installConfig.Config.VSphere.VCenter,
Base64encodeUsername: base64.StdEncoding.EncodeToString([]byte(installConfig.Config.VSphere.Username)),
Base64encodePassword: base64.StdEncoding.EncodeToString([]byte(installConfig.Config.VSphere.Password)),
},
}
}

View File

@@ -17,7 +17,6 @@ import (
"github.com/openshift/installer/pkg/asset/templates/content/bootkube"
"github.com/openshift/installer/pkg/asset/tls"
"github.com/openshift/installer/pkg/types"
vspheretypes "github.com/openshift/installer/pkg/types/vsphere"
)
const (
@@ -268,12 +267,8 @@ func redactedInstallConfig(config types.InstallConfig) ([]byte, error) {
config.PullSecret = ""
if config.Platform.VSphere != nil {
p := *config.Platform.VSphere
p.VirtualCenters = make([]vspheretypes.VirtualCenter, len(config.Platform.VSphere.VirtualCenters))
for i, vc := range config.Platform.VSphere.VirtualCenters {
vc.Username = ""
vc.Password = ""
p.VirtualCenters[i] = vc
}
p.Username = ""
p.Password = ""
config.Platform.VSphere = &p
}
return yaml.Marshal(config)

View File

@@ -44,29 +44,11 @@ func TestRedactedInstallConfig(t *testing.T) {
},
Platform: types.Platform{
VSphere: &vspheretypes.Platform{
VirtualCenters: []vspheretypes.VirtualCenter{
{
Name: "test-server-1",
Username: "test-user-1",
Password: "test-pass-1",
Datacenters: []string{"test-datacenter-1"},
},
{
Name: "test-server-2",
Username: "test-user-2",
Password: "test-pass-2",
Datacenters: []string{"test-datacenter-2"},
},
},
Workspace: vspheretypes.Workspace{
Server: "test-server-1",
Datacenter: "test-datacenter-1",
DefaultDatastore: "test-datastore",
ResourcePoolPath: "test-resource-pool",
Folder: "test-folder",
},
SCSIControllerType: "test-controller-type",
PublicNetwork: "test-network",
VCenter: "test-server-1",
Username: "test-user-1",
Password: "test-pass-1",
Datacenter: "test-datacenter",
DefaultDatastore: "test-datastore",
},
},
PullSecret: "test-pull-secret",
@@ -95,25 +77,11 @@ networking:
- 1.2.3.4/5
platform:
vsphere:
publicNetwork: test-network
scsiControllerType: test-controller-type
virtualCenters:
- datacenters:
- test-datacenter-1
name: test-server-1
password: ""
username: ""
- datacenters:
- test-datacenter-2
name: test-server-2
password: ""
username: ""
workspace:
datacenter: test-datacenter-1
defaultDatastore: test-datastore
folder: test-folder
resourcePoolPath: test-resource-pool
server: test-server-1
datacenter: test-datacenter
defaultDatastore: test-datastore
password: ""
username: ""
vCenter: test-server-1
pullSecret: ""
sshKey: test-ssh-key
`

View File

@@ -13,12 +13,7 @@ type OpenStackCredsSecretData struct {
// VSphereCredsSecretData holds encoded credentials and is used to generated cloud-creds secret
type VSphereCredsSecretData struct {
VirtualCenters []VSphereVirtualCenterCredsSecretData
}
// VSphereVirtualCenterCredsSecretData holds the encoded credentials for a vSphere vCenter.
type VSphereVirtualCenterCredsSecretData struct {
Name string
VCenter string
Base64encodeUsername string
Base64encodePassword string
}

View File

@@ -13,71 +13,53 @@ import (
type config struct {
Global global
Workspace workspace
Disk disk
Network network
}
type global struct {
SecretName string `ini:"secret-name"`
SecretNamespace string `ini:"secret-namespace"`
InsecureFlag int `ini:"insecure-flag"`
}
type workspace struct {
Server string `ini:"server"`
Datacenter string `ini:"datacenter"`
DefaultDatastore string `ini:"default-datastore"`
ResourcePoolPath string `ini:"resourcepool-path,omitempty"`
Folder string `ini:"folder"`
}
type disk struct {
SCSIControllerType string `ini:"scsicontrollertype"`
}
type network struct {
PublicNetwork string `ini:"public-network"`
}
type virtualCenter struct {
Datacenters []string `ini:"datacenters"`
Datacenters string `ini:"datacenters"`
}
// CloudProviderConfig generates the cloud provider config for the vSphere platform.
func CloudProviderConfig(p *vspheretypes.Platform) (string, error) {
func CloudProviderConfig(clusterName string, p *vspheretypes.Platform) (string, error) {
file := ini.Empty()
config := &config{
Global: global{
SecretName: "vsphere-creds",
SecretNamespace: "kube-system",
InsecureFlag: 1,
},
Workspace: workspace{
Server: p.Workspace.Server,
Datacenter: p.Workspace.Datacenter,
DefaultDatastore: p.Workspace.DefaultDatastore,
ResourcePoolPath: p.Workspace.ResourcePoolPath,
Folder: p.Workspace.Folder,
},
Disk: disk{
SCSIControllerType: p.SCSIControllerType,
},
Network: network{
PublicNetwork: p.PublicNetwork,
Server: p.VCenter,
Datacenter: p.Datacenter,
DefaultDatastore: p.DefaultDatastore,
Folder: clusterName,
},
}
if err := file.ReflectFrom(config); err != nil {
return "", errors.Wrap(err, "failed to reflect from config")
}
for _, vc := range p.VirtualCenters {
s, err := file.NewSection(fmt.Sprintf("VirtualCenter %q", vc.Name))
if err != nil {
return "", errors.Wrapf(err, "failed to create section for virtual center %q", vc.Name)
}
if err := s.ReflectFrom(
&virtualCenter{
Datacenters: vc.Datacenters,
}); err != nil {
return "", errors.Wrapf(err, "failed to reflect from virtual center %q", vc.Name)
}
s, err := file.NewSection(fmt.Sprintf("VirtualCenter %q", p.VCenter))
if err != nil {
return "", errors.Wrapf(err, "failed to create section for virtual center")
}
if err := s.ReflectFrom(
&virtualCenter{
Datacenters: p.Datacenter,
}); err != nil {
return "", errors.Wrapf(err, "failed to reflect from virtual center")
}
buf := &bytes.Buffer{}
if _, err := file.WriteTo(buf); err != nil {

View File

@@ -9,196 +9,30 @@ import (
)
func TestCloudProviderConfig(t *testing.T) {
cases := []struct {
name string
platform *vspheretypes.Platform
expectedConfig string
}{
{
name: "single virtualcenter",
platform: &vspheretypes.Platform{
VirtualCenters: []vspheretypes.VirtualCenter{
{
Name: "test-name",
Username: "test-username",
Password: "test-password",
Datacenters: []string{"test-datacenter"},
},
},
Workspace: vspheretypes.Workspace{
Server: "test-name",
Datacenter: "test-datacenter",
DefaultDatastore: "test-datastore",
ResourcePoolPath: "test-resource-pool",
Folder: "test-folder",
},
SCSIControllerType: "test-scsi",
PublicNetwork: "test-network",
},
expectedConfig: `[Global]
clusterName := "test-cluster"
platform := &vspheretypes.Platform{
VCenter: "test-name",
Username: "test-username",
Password: "test-password",
Datacenter: "test-datacenter",
DefaultDatastore: "test-datastore",
}
expectedConfig := `[Global]
secret-name = vsphere-creds
secret-namespace = kube-system
insecure-flag = 1
[Workspace]
server = test-name
datacenter = test-datacenter
default-datastore = test-datastore
resourcepool-path = test-resource-pool
folder = test-folder
[Disk]
scsicontrollertype = test-scsi
[Network]
public-network = test-network
folder = test-cluster
[VirtualCenter "test-name"]
datacenters = test-datacenter
`,
},
{
name: "multiple datacenters",
platform: &vspheretypes.Platform{
VirtualCenters: []vspheretypes.VirtualCenter{
{
Name: "test-name",
Username: "test-username",
Password: "test-password",
Datacenters: []string{"test-dc1", "test-dc2"},
},
},
Workspace: vspheretypes.Workspace{
Server: "test-name",
Datacenter: "test-dc1",
DefaultDatastore: "test-datastore",
ResourcePoolPath: "test-resource-pool",
Folder: "test-folder",
},
SCSIControllerType: "test-scsi",
PublicNetwork: "test-network",
},
expectedConfig: `[Global]
secret-name = vsphere-creds
secret-namespace = kube-system
[Workspace]
server = test-name
datacenter = test-dc1
default-datastore = test-datastore
resourcepool-path = test-resource-pool
folder = test-folder
[Disk]
scsicontrollertype = test-scsi
[Network]
public-network = test-network
[VirtualCenter "test-name"]
datacenters = test-dc1,test-dc2
`,
},
{
name: "multiple virtualcenters",
platform: &vspheretypes.Platform{
VirtualCenters: []vspheretypes.VirtualCenter{
{
Name: "test-name1",
Username: "test-username1",
Password: "test-password1",
Datacenters: []string{"test-datacenter1"},
},
{
Name: "test-name2",
Username: "test-username2",
Password: "test-password2",
Datacenters: []string{"test-datacenter2"},
},
},
Workspace: vspheretypes.Workspace{
Server: "test-name",
Datacenter: "test-datacenter",
DefaultDatastore: "test-datastore",
ResourcePoolPath: "test-resource-pool",
Folder: "test-folder",
},
SCSIControllerType: "test-scsi",
PublicNetwork: "test-network",
},
expectedConfig: `[Global]
secret-name = vsphere-creds
secret-namespace = kube-system
[Workspace]
server = test-name
datacenter = test-datacenter
default-datastore = test-datastore
resourcepool-path = test-resource-pool
folder = test-folder
[Disk]
scsicontrollertype = test-scsi
[Network]
public-network = test-network
[VirtualCenter "test-name1"]
datacenters = test-datacenter1
[VirtualCenter "test-name2"]
datacenters = test-datacenter2
`,
},
{
name: "empty resource pool path",
platform: &vspheretypes.Platform{
VirtualCenters: []vspheretypes.VirtualCenter{
{
Name: "test-name",
Username: "test-username",
Password: "test-password",
Datacenters: []string{"test-datacenter"},
},
},
Workspace: vspheretypes.Workspace{
Server: "test-name",
Datacenter: "test-datacenter",
DefaultDatastore: "test-datastore",
Folder: "test-folder",
},
SCSIControllerType: "test-scsi",
PublicNetwork: "test-network",
},
expectedConfig: `[Global]
secret-name = vsphere-creds
secret-namespace = kube-system
[Workspace]
server = test-name
datacenter = test-datacenter
default-datastore = test-datastore
folder = test-folder
[Disk]
scsicontrollertype = test-scsi
[Network]
public-network = test-network
[VirtualCenter "test-name"]
datacenters = test-datacenter
`,
},
}
for _, tc := range cases {
t.Run(tc.name, func(t *testing.T) {
config, err := CloudProviderConfig(tc.platform)
assert.NoError(t, err, "failed to create cloud provider config")
assert.Equal(t, tc.expectedConfig, config, "unexpected cloud provider config")
})
}
`
actualConfig, err := CloudProviderConfig(clusterName, platform)
assert.NoError(t, err, "failed to create cloud provider config")
assert.Equal(t, expectedConfig, actualConfig, "unexpected cloud provider config")
}

View File

@@ -73,22 +73,11 @@ func validLibvirtPlatform() *libvirt.Platform {
func validVSpherePlatform() *vsphere.Platform {
return &vsphere.Platform{
VirtualCenters: []vsphere.VirtualCenter{
{
Name: "test-server",
Username: "test-username",
Password: "test-password",
Datacenters: []string{"test-datacenter"},
},
},
Workspace: vsphere.Workspace{
Server: "test-server",
Datacenter: "test-datacenter",
DefaultDatastore: "test-datastore",
Folder: "test-folder",
},
SCSIControllerType: "test-controller-type",
PublicNetwork: "test-network",
VCenter: "test-server",
Username: "test-username",
Password: "test-password",
Datacenter: "test-datacenter",
DefaultDatastore: "test-datastore",
}
}
@@ -470,10 +459,10 @@ func TestValidateInstallConfig(t *testing.T) {
c.Platform = types.Platform{
VSphere: validVSpherePlatform(),
}
c.Platform.VSphere.Workspace.Server = ""
c.Platform.VSphere.VCenter = ""
return c
}(),
expectedError: `^platform\.vsphere.workspace.server: Required value: must specify the workspace server$`,
expectedError: `^platform\.vsphere.vCenter: Required value: must specify the name of the vCenter$`,
},
}
for _, tc := range cases {

View File

@@ -7,25 +7,4 @@ import (
// SetPlatformDefaults sets the defaults for the platform.
func SetPlatformDefaults(p *vsphere.Platform, installConfig *types.InstallConfig) {
if p.Workspace.Server == "" {
if len(p.VirtualCenters) == 1 {
p.Workspace.Server = p.VirtualCenters[0].Name
}
}
if p.Workspace.Datacenter == "" {
for _, vc := range p.VirtualCenters {
if p.Workspace.Server == vc.Name {
if len(vc.Datacenters) == 1 {
p.Workspace.Datacenter = vc.Datacenters[0]
}
break
}
}
}
if p.Workspace.Folder == "" {
p.Workspace.Folder = installConfig.ObjectMeta.Name
}
if p.SCSIControllerType == "" {
p.SCSIControllerType = "pvscsi"
}
}

View File

@@ -13,12 +13,7 @@ import (
const testClusterName = "test-cluster"
func defaultPlatform() *vsphere.Platform {
return &vsphere.Platform{
Workspace: vsphere.Workspace{
Folder: testClusterName,
},
SCSIControllerType: "pvscsi",
}
return &vsphere.Platform{}
}
func TestSetPlatformDefaults(t *testing.T) {
@@ -32,152 +27,6 @@ func TestSetPlatformDefaults(t *testing.T) {
platform: &vsphere.Platform{},
expected: defaultPlatform(),
},
{
name: "single vCenter",
platform: &vsphere.Platform{
VirtualCenters: []vsphere.VirtualCenter{{Name: "test-server"}},
},
expected: func() *vsphere.Platform {
p := defaultPlatform()
p.VirtualCenters = []vsphere.VirtualCenter{{Name: "test-server"}}
p.Workspace.Server = "test-server"
return p
}(),
},
{
name: "multiple vCenters",
platform: &vsphere.Platform{
VirtualCenters: []vsphere.VirtualCenter{
{Name: "test-server1"},
{Name: "test-server2"},
},
},
expected: func() *vsphere.Platform {
p := defaultPlatform()
p.VirtualCenters = []vsphere.VirtualCenter{
{Name: "test-server1"},
{Name: "test-server2"},
}
return p
}(),
},
{
name: "vCenter set",
platform: &vsphere.Platform{
VirtualCenters: []vsphere.VirtualCenter{{Name: "test-server"}},
Workspace: vsphere.Workspace{
Server: "other-server",
},
},
expected: func() *vsphere.Platform {
p := defaultPlatform()
p.VirtualCenters = []vsphere.VirtualCenter{{Name: "test-server"}}
p.Workspace.Server = "other-server"
return p
}(),
},
{
name: "single datacenter",
platform: &vsphere.Platform{
VirtualCenters: []vsphere.VirtualCenter{
{
Name: "test-server",
Datacenters: []string{"test-datacenter"},
},
},
Workspace: vsphere.Workspace{
Server: "test-server",
},
},
expected: func() *vsphere.Platform {
p := defaultPlatform()
p.VirtualCenters = []vsphere.VirtualCenter{
{
Name: "test-server",
Datacenters: []string{"test-datacenter"},
},
}
p.Workspace.Server = "test-server"
p.Workspace.Datacenter = "test-datacenter"
return p
}(),
},
{
name: "multiple datacenter",
platform: &vsphere.Platform{
VirtualCenters: []vsphere.VirtualCenter{
{
Name: "test-server",
Datacenters: []string{"test-datacenter1", "test-datacenter2"},
},
},
Workspace: vsphere.Workspace{
Server: "test-server",
},
},
expected: func() *vsphere.Platform {
p := defaultPlatform()
p.VirtualCenters = []vsphere.VirtualCenter{
{
Name: "test-server",
Datacenters: []string{"test-datacenter1", "test-datacenter2"},
},
}
p.Workspace.Server = "test-server"
return p
}(),
},
{
name: "datacenter set",
platform: &vsphere.Platform{
VirtualCenters: []vsphere.VirtualCenter{
{
Name: "test-server",
Datacenters: []string{"test-datacenter"},
},
},
Workspace: vsphere.Workspace{
Server: "test-server",
Datacenter: "other-datacenter",
},
},
expected: func() *vsphere.Platform {
p := defaultPlatform()
p.VirtualCenters = []vsphere.VirtualCenter{
{
Name: "test-server",
Datacenters: []string{"test-datacenter"},
},
}
p.Workspace.Server = "test-server"
p.Workspace.Datacenter = "other-datacenter"
return p
}(),
},
{
name: "folder set",
platform: &vsphere.Platform{
Workspace: vsphere.Workspace{
Folder: "test-folder",
},
},
expected: func() *vsphere.Platform {
p := defaultPlatform()
p.Workspace.Folder = "test-folder"
return p
}(),
},
{
name: "SCSI controller type set",
platform: &vsphere.Platform{
SCSIControllerType: "test-controller-type",
},
expected: func() *vsphere.Platform {
p := defaultPlatform()
p.SCSIControllerType = "test-controller-type"
return p
}(),
},
}
for _, tc := range cases {
t.Run(tc.name, func(t *testing.T) {

View File

@@ -2,49 +2,14 @@ package vsphere
// Platform stores any global configuration used for vsphere platforms.
type Platform struct {
// VirtualCenters are the configurations for the vCenters.
VirtualCenters []VirtualCenter `json:"virtualCenters"`
// Workspace is the configuration for the workspace.
Workspace Workspace `json:"workspace"`
// SCSIControllerType is the SCSI controller type in use.
// +optional
// Default is pvscsi.
SCSIControllerType string `json:"scsiControllerType"`
// PublicNetwork is the name of the VM network to use.
PublicNetwork string `json:"publicNetwork"`
}
// VirtualCenter is the configuration of a vCenter.
type VirtualCenter struct {
// Name of the vCenter. This is the domain name or the IP address of the vCenter.
Name string `json:"name"`
// VCenter is the domain name or IP address of the vCenter.
VCenter string `json:"vCenter"`
// Username is the name of the user to use to connect to the vCenter.
Username string `json:"username"`
// Password is the password for the user to use to connect to the vCenter.
Password string `json:"password"`
// Datacenters are the names of the datacenters to use in the vCenter.
Datacenters []string `json:"datacenters"`
}
// Workspace is the configuration of the vSphere workspace.
type Workspace struct {
// Server is the server to use for provisioning.
// +optional
// Default is the name of the vCenter, if there is only a single vCenter.
Server string `json:"server"`
// Datacenter is the datacenter to use for provisioning.
// +optional
// Default is the datacenter in Server, if that vCenter has only a single
// datacenter.
// Datacenter is the name of the datacenter to use in the vCenter.
Datacenter string `json:"datacenter"`
// DefaultDatastore is the default datastore to use for provisioning volumes.
DefaultDatastore string `json:"defaultDatastore"`
// ResourcePoolPath is the resource pool to use in the datacenter.
// +optional
// Default is the name of the cluster.
ResourcePoolPath string `json:"resourcePoolPath"`
// Folder is the vCenter VM folder path in the datacenter.
// +optional
// Default is the name of the cluster.
Folder string `json:"folder"`
}

View File

@@ -9,74 +9,20 @@ import (
// ValidatePlatform checks that the specified platform is valid.
func ValidatePlatform(p *vsphere.Platform, fldPath *field.Path) field.ErrorList {
allErrs := field.ErrorList{}
if len(p.VirtualCenters) == 0 {
allErrs = append(allErrs, field.Required(fldPath.Child("virtualCenters"), "must include at least one vCenter"))
if len(p.VCenter) == 0 {
allErrs = append(allErrs, field.Required(fldPath.Child("vCenter"), "must specify the name of the vCenter"))
}
foundServer := false
vcNames := map[string]bool{}
for i, vc := range p.VirtualCenters {
allErrs = append(allErrs, validateVirtualCenter(&vc, fldPath.Child("virtualCenters").Index(i))...)
if vcNames[vc.Name] {
allErrs = append(allErrs, field.Duplicate(fldPath.Child("virtualCenters").Index(i), vc.Name))
}
vcNames[vc.Name] = true
if vc.Name == p.Workspace.Server {
foundDatacenter := false
for _, dc := range vc.Datacenters {
if dc == p.Workspace.Datacenter {
foundDatacenter = true
break
}
}
if p.Workspace.Datacenter != "" && !foundDatacenter {
allErrs = append(allErrs, field.Invalid(fldPath.Child("workspace").Child("datacenter"), p.Workspace.Datacenter, "workspace datacenter must be a datacenter in the workspace server"))
}
foundServer = true
}
if len(p.Username) == 0 {
allErrs = append(allErrs, field.Required(fldPath.Child("username"), "must specify the username"))
}
if len(p.Workspace.Server) == 0 {
allErrs = append(allErrs, field.Required(fldPath.Child("workspace").Child("server"), "must specify the workspace server"))
} else if !foundServer {
allErrs = append(allErrs, field.Invalid(fldPath.Child("workspace").Child("server"), p.Workspace.Server, "workspace server must be a specified vCenter"))
if len(p.Password) == 0 {
allErrs = append(allErrs, field.Required(fldPath.Child("password"), "must specify the password"))
}
if len(p.Workspace.Datacenter) == 0 {
allErrs = append(allErrs, field.Required(fldPath.Child("workspace").Child("datacenter"), "must specify the workspace datacenter"))
if len(p.Datacenter) == 0 {
allErrs = append(allErrs, field.Required(fldPath.Child("datacenter"), "must specify the datacenter"))
}
if len(p.Workspace.DefaultDatastore) == 0 {
allErrs = append(allErrs, field.Required(fldPath.Child("workspace").Child("defaultDatastore"), "must specify the default datastore"))
}
if len(p.Workspace.Folder) == 0 {
allErrs = append(allErrs, field.Required(fldPath.Child("workspace").Child("folder"), "must specify the VM folder"))
}
if len(p.SCSIControllerType) == 0 {
allErrs = append(allErrs, field.Required(fldPath.Child("scsiControllerType"), "must specify the SCSI controller type"))
}
if len(p.PublicNetwork) == 0 {
allErrs = append(allErrs, field.Required(fldPath.Child("publicNetwork"), "must specify the public VM network"))
}
return allErrs
}
func validateVirtualCenter(vc *vsphere.VirtualCenter, fldPath *field.Path) field.ErrorList {
allErrs := field.ErrorList{}
if len(vc.Name) == 0 {
allErrs = append(allErrs, field.Required(fldPath.Child("name"), "vCenter must have a name"))
}
if len(vc.Username) == 0 {
allErrs = append(allErrs, field.Required(fldPath.Child("username"), "username required for each vCenter"))
}
if len(vc.Password) == 0 {
allErrs = append(allErrs, field.Required(fldPath.Child("password"), "password required for each vCenter"))
}
if len(vc.Datacenters) == 0 {
allErrs = append(allErrs, field.Required(fldPath.Child("datacenters"), "must include at least one datacenter"))
}
dcs := map[string]bool{}
for i, dc := range vc.Datacenters {
if dcs[dc] {
allErrs = append(allErrs, field.Duplicate(fldPath.Child("datacenters").Index(i), dc))
}
dcs[dc] = true
if len(p.DefaultDatastore) == 0 {
allErrs = append(allErrs, field.Required(fldPath.Child("defaultDatastore"), "must specify the default datastore"))
}
return allErrs
}

View File

@@ -11,23 +11,11 @@ import (
func validPlatform() *vsphere.Platform {
return &vsphere.Platform{
VirtualCenters: []vsphere.VirtualCenter{
{
Name: "test-server-name",
Username: "test-username",
Password: "test-password",
Datacenters: []string{"test-datacenter"},
},
},
Workspace: vsphere.Workspace{
Server: "test-server-name",
Datacenter: "test-datacenter",
DefaultDatastore: "test-datastore",
ResourcePoolPath: "test-resource-pool",
Folder: "test-folder",
},
SCSIControllerType: "test-controller-type",
PublicNetwork: "test-network",
VCenter: "test-vcenter",
Username: "test-username",
Password: "test-password",
Datacenter: "test-datacenter",
DefaultDatastore: "test-datastore",
}
}
@@ -41,139 +29,50 @@ func TestValidatePlatform(t *testing.T) {
name: "minimal",
platform: validPlatform(),
},
{
name: "empty vCenters",
platform: func() *vsphere.Platform {
p := validPlatform()
p.VirtualCenters = nil
return p
}(),
expectedError: `^\[test-path\.virtualCenters: Required value: must include at least one vCenter, test-path\.workspace\.server: Invalid value: "test-server-name": workspace server must be a specified vCenter]$`,
},
{
name: "missing vCenter name",
platform: func() *vsphere.Platform {
p := validPlatform()
p.VirtualCenters[0].Name = ""
p.VCenter = ""
return p
}(),
expectedError: `^\[test-path\.virtualCenters\[0]\.name: Required value: vCenter must have a name, test-path\.workspace\.server: Invalid value: "test-server-name": workspace server must be a specified vCenter]$`,
expectedError: `^test-path\.vCenter: Required value: must specify the name of the vCenter$`,
},
{
name: "missing vCenter username",
name: "missing username",
platform: func() *vsphere.Platform {
p := validPlatform()
p.VirtualCenters[0].Username = ""
p.Username = ""
return p
}(),
expectedError: `^test-path\.virtualCenters\[0]\.username: Required value: username required for each vCenter$`,
expectedError: `^test-path\.username: Required value: must specify the username$`,
},
{
name: "missing vCenter password",
name: "missing password",
platform: func() *vsphere.Platform {
p := validPlatform()
p.VirtualCenters[0].Password = ""
p.Password = ""
return p
}(),
expectedError: `^test-path\.virtualCenters\[0]\.password: Required value: password required for each vCenter$`,
expectedError: `^test-path\.password: Required value: must specify the password$`,
},
{
name: "empty vCenter datacenters",
name: "missing datacenter",
platform: func() *vsphere.Platform {
p := validPlatform()
p.VirtualCenters[0].Datacenters = nil
p.Datacenter = ""
return p
}(),
expectedError: `^\[test-path\.virtualCenters\[0]\.datacenters: Required value: must include at least one datacenter, test-path\.workspace\.datacenter: Invalid value: "test-datacenter": workspace datacenter must be a datacenter in the workspace server]$`,
},
{
name: "multiple vCenter datacenters",
platform: func() *vsphere.Platform {
p := validPlatform()
p.VirtualCenters[0].Datacenters = []string{"test-datacenter", "other-datacenter"}
return p
}(),
},
{
name: "duplicate vCenter datacenters",
platform: func() *vsphere.Platform {
p := validPlatform()
p.VirtualCenters[0].Datacenters = []string{"test-datacenter", "test-datacenter"}
return p
}(),
expectedError: `^test-path\.virtualCenters\[0]\.datacenters\[1]: Duplicate value: "test-datacenter"$`,
},
{
name: "missing workspace server",
platform: func() *vsphere.Platform {
p := validPlatform()
p.Workspace.Server = ""
return p
}(),
expectedError: `^test-path\.workspace\.server: Required value: must specify the workspace server$`,
},
{
name: "no vCenter for workspace server",
platform: func() *vsphere.Platform {
p := validPlatform()
p.Workspace.Server = "other-server-name"
return p
}(),
expectedError: `^test-path\.workspace\.server: Invalid value: "other-server-name": workspace server must be a specified vCenter$`,
},
{
name: "missing workspace datacenter",
platform: func() *vsphere.Platform {
p := validPlatform()
p.Workspace.Datacenter = ""
return p
}(),
expectedError: `^test-path\.workspace\.datacenter: Required value: must specify the workspace datacenter$`,
},
{
name: "missing workspace datacenter",
platform: func() *vsphere.Platform {
p := validPlatform()
p.Workspace.Datacenter = ""
return p
}(),
expectedError: `^test-path\.workspace\.datacenter: Required value: must specify the workspace datacenter$`,
expectedError: `^test-path\.datacenter: Required value: must specify the datacenter$`,
},
{
name: "missing default datastore",
platform: func() *vsphere.Platform {
p := validPlatform()
p.Workspace.DefaultDatastore = ""
p.DefaultDatastore = ""
return p
}(),
expectedError: `^test-path\.workspace\.defaultDatastore: Required value: must specify the default datastore$`,
},
{
name: "missing folder",
platform: func() *vsphere.Platform {
p := validPlatform()
p.Workspace.Folder = ""
return p
}(),
expectedError: `^test-path\.workspace\.folder: Required value: must specify the VM folder$`,
},
{
name: "missing SCSI controller type",
platform: func() *vsphere.Platform {
p := validPlatform()
p.SCSIControllerType = ""
return p
}(),
expectedError: `^test-path\.scsiControllerType: Required value: must specify the SCSI controller type$`,
},
{
name: "missing public network",
platform: func() *vsphere.Platform {
p := validPlatform()
p.PublicNetwork = ""
return p
}(),
expectedError: `^test-path\.publicNetwork: Required value: must specify the public VM network$`,
expectedError: `^test-path\.defaultDatastore: Required value: must specify the default datastore$`,
},
}
for _, tc := range cases {

View File

@@ -9,7 +9,12 @@ metadata:
networking:
machineCIDR: "139.178.89.192/26"
platform:
vsphere: {}
vsphere:
vCenter: vcsa.vmware.devcluster.openshift.com
username: YOUR_VSPHERE_USER
password: YOUR_VSPHERE_PASSWORD
datacenter: dc1
defaultDatastore: nvme-ds1
pullSecret: YOUR_PULL_SECRET
sshKey: YOUR_SSH_KEY
```