Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -36,9 +36,9 @@ data:
{{- else if .CloudCreds.OpenStack}}
clouds.yaml: {{.CloudCreds.OpenStack.Base64encodeCloudCreds}}
clouds.conf: {{.CloudCreds.OpenStack.Base64encodeCloudCredsINI}}
{{- else if .CloudCreds.VSphere}}
{{.CloudCreds.VSphere.VCenter}}.username: {{.CloudCreds.VSphere.Base64encodeUsername}}
{{.CloudCreds.VSphere.VCenter}}.password: {{.CloudCreds.VSphere.Base64encodePassword}}
{{- else if .CloudCreds.VSphere}} {{ range .CloudCreds.VSphere }}
{{.VCenter}}.username: {{.Base64encodeUsername}}
{{.VCenter}}.password: {{.Base64encodePassword}} {{ end }}
{{- else if .CloudCreds.Ovirt}}
ovirt_url: {{.CloudCreds.Ovirt.Base64encodeURL}}
ovirt_username: {{.CloudCreds.Ovirt.Base64encodeUsername}}
Expand Down
19 changes: 16 additions & 3 deletions pkg/asset/manifests/openshift.go
Original file line number Diff line number Diff line change
Expand Up @@ -181,12 +181,25 @@ func (o *Openshift) Generate(dependencies asset.Parents) error {
},
}
case vspheretypes.Name:
cloudCreds = cloudCredsSecretData{
VSphere: &VSphereCredsSecretData{
vsphereCredentials := make([]*VSphereCredsSecretData,0)
if installConfig.Config.VSphere.VCenter != "" {
vsphereCredentials = append(vsphereCredentials, &VSphereCredsSecretData{
VCenter: installConfig.Config.VSphere.VCenter,
Base64encodeUsername: base64.StdEncoding.EncodeToString([]byte(installConfig.Config.VSphere.Username)),
Base64encodePassword: base64.StdEncoding.EncodeToString([]byte(installConfig.Config.VSphere.Password)),
},
})
}
if len(installConfig.Config.VSphere.VCenters) > 0{
for _, vcenter := range installConfig.Config.VSphere.VCenters {
vsphereCredentials = append(vsphereCredentials, &VSphereCredsSecretData{
VCenter: vcenter.Server,
Base64encodeUsername: base64.StdEncoding.EncodeToString([]byte(vcenter.User)),
Base64encodePassword: base64.StdEncoding.EncodeToString([]byte(vcenter.Password)),
})
}
}
cloudCreds = cloudCredsSecretData{
VSphere: vsphereCredentials,
}
case ovirttypes.Name:
conf, err := ovirt.NewConfig()
Expand Down
2 changes: 1 addition & 1 deletion pkg/asset/manifests/template.go
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ type cloudCredsSecretData struct {
GCP *GCPCredsSecretData
IBMCloud *IBMCloudCredsSecretData
OpenStack *OpenStackCredsSecretData
VSphere *VSphereCredsSecretData
VSphere [] *VSphereCredsSecretData
Ovirt *OvirtCredsSecretData
}

Expand Down
66 changes: 62 additions & 4 deletions pkg/asset/manifests/vsphere/cloudproviderconfig.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,24 @@ func printIfNotEmpty(buf *bytes.Buffer, k, v string) {
}
}

func getDatacenters(vcenter vspheretypes.VCenter) string {
datacenters := make([]string, 0)
for _, region := range vcenter.Regions {
if region.Datacenter != "" {
datacenters = append(datacenters, region.Datacenter)
}
}
datacenterString := ""
for idx, dataCenter := range datacenters {
if idx > 0 {
datacenterString = datacenterString + "," + dataCenter
} else {
datacenterString = dataCenter
}
}
return datacenterString
}

// CloudProviderConfig generates the cloud provider config for the vSphere platform.
// folderPath is the absolute path to the VM folder that will be used for installation.
// p is the vSphere platform struct.
Expand All @@ -30,11 +48,51 @@ func CloudProviderConfig(folderPath string, p *vspheretypes.Platform) (string, e
printIfNotEmpty(buf, "datacenter", p.Datacenter)
printIfNotEmpty(buf, "default-datastore", p.DefaultDatastore)
printIfNotEmpty(buf, "folder", folderPath)
printIfNotEmpty(buf, "resourcepool-path", p.ResourcePool)
fmt.Fprintln(buf, "")

fmt.Fprintf(buf, "[VirtualCenter %q]\n", p.VCenter)
printIfNotEmpty(buf, "datacenters", p.Datacenter)
regions := make([]string, 0)
zones := make([]string, 0)

for _, vcenter := range p.VCenters {
fmt.Fprintln(buf, "")
fmt.Fprintf(buf, "[VirtualCenter %q]\n", vcenter.Server)
printIfNotEmpty(buf, "datacenters", getDatacenters(vcenter))
for _, region := range vcenter.Regions {
regions = append(regions, region.Name)
for _, zone := range region.Zones {
zones = append(zones, zone.Name)
}
}
}

if p.VCenter != "" {
fmt.Fprintln(buf, "")
fmt.Fprintf(buf, "[VirtualCenter %q]\n", p.VCenter)
printIfNotEmpty(buf, "datacenters", p.Datacenter)
}

if len(zones) > 0 {
fmt.Fprintln(buf, "")
fmt.Fprintln(buf, "[Labels]")
regionsString := ""
zonesString := ""
for idx, region := range regions {
if idx > 0 {
regionsString = regionsString + "," + region
} else {
regionsString = region
}
}
printIfNotEmpty(buf, "region", regionsString)

for idx, zone := range zones {
if idx > 0 {
zonesString = zonesString + "," + zone
} else {
zonesString = zone
}
}
printIfNotEmpty(buf, "zone", zonesString)
}

return buf.String(), nil
}
167 changes: 155 additions & 12 deletions pkg/asset/manifests/vsphere/cloudproviderconfig_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,15 +9,15 @@ import (
vspheretypes "github.com/openshift/installer/pkg/types/vsphere"
)

func TestCloudProviderConfig(t *testing.T) {
platform := &vspheretypes.Platform{
VCenter: "test-name",
Username: "test-username",
Password: "test-password",
Datacenter: "test-datacenter",
DefaultDatastore: "test-datastore",
}
expectedConfig := `[Global]
var cloudProviderLegacyPlatform = &vspheretypes.Platform{
VCenter: "test-name",
Username: "test-username",
Password: "test-password",
Datacenter: "test-datacenter",
DefaultDatastore: "test-datastore",
}

var cloudProviderLegacyExpectedConfig = `[Global]
secret-name = "vsphere-creds"
secret-namespace = "kube-system"
insecure-flag = "1"
Expand All @@ -31,8 +31,151 @@ folder = "/test-datacenter/vm/clusterID"
[VirtualCenter "test-name"]
datacenters = "test-datacenter"
`

var cloudProviderMultiClusterPlatform = &vspheretypes.Platform{
VCenters: []vspheretypes.VCenter{
{
Server: "test-vcenter-1",
User: "test-user",
Password: "test-password",
Port: 443,
Regions: []vspheretypes.Region{
{
Name: "region-a",
Datacenter: "dc-region-a",
Zones: []vspheretypes.Zone{
{
Name: "zone-a-1",
ResourcePool: "zone-a-pool-1",
Cluster: "zone-a-cluster-1",
Network: "VM Network",
Datastore: "zone-a-datastore-1",
},
{
Name: "zone-a-2",
ResourcePool: "zone-a-pool-2",
Cluster: "zone-a-cluster-2",
Network: "VM Network",
Datastore: "zone-a-datastore-2",
},
},
},
{
Name: "region-b",
Datacenter: "dc-region-b",
Zones: []vspheretypes.Zone{
{
Name: "zone-b-1",
ResourcePool: "zone-b-pool-1",
Cluster: "zone-b-cluster-1",
Network: "VM Network",
Datastore: "zone-b-datastore-1",
},
{
Name: "zone-b-2",
ResourcePool: "zone-b-pool-2",
Cluster: "zone-b-cluster-2",
Network: "VM Network",
Datastore: "zone-b-datastore-2",
},
},
},
},
},
{
Server: "test-vcenter-2",
User: "test-user",
Password: "test-password",
Port: 443,
Regions: []vspheretypes.Region{
{
Name: "region-c",
Datacenter: "dc-region-c",
Zones: []vspheretypes.Zone{
{
Name: "zone-c-1",
ResourcePool: "zone-c-pool-1",
Cluster: "zone-c-cluster-1",
Network: "VM Network",
Datastore: "zone-c-datastore-1",
},
{
Name: "zone-c-2",
ResourcePool: "zone-c-pool-2",
Cluster: "zone-c-cluster-2",
Network: "VM Network",
Datastore: "zone-c-datastore-2",
},
},
},
{
Name: "region-d",
Datacenter: "dc-region-d",
Zones: []vspheretypes.Zone{
{
Name: "zone-d-1",
ResourcePool: "zone-d-pool-1",
Cluster: "zone-d-cluster-1",
Network: "VM Network",
Datastore: "zone-d-datastore-1",
},
{
Name: "zone-d-2",
ResourcePool: "zone-d-pool-2",
Cluster: "zone-d-cluster-2",
Network: "VM Network",
Datastore: "zone-d-datastore-2",
},
},
},
},
},
},
}

var cloudProviderMultiClusteryExpectedConfig = `[Global]
secret-name = "vsphere-creds"
secret-namespace = "kube-system"
insecure-flag = "1"

[Workspace]
folder = "/test-datacenter/vm/clusterID"

[VirtualCenter "test-vcenter-1"]
datacenters = "dc-region-a,dc-region-b"

[VirtualCenter "test-vcenter-2"]
datacenters = "dc-region-c,dc-region-d"

[Labels]
region = "region-a,region-b,region-c,region-d"
zone = "zone-a-1,zone-a-2,zone-b-1,zone-b-2,zone-c-1,zone-c-2,zone-d-1,zone-d-2"
`

func TestCloudProviderConfig(t *testing.T) {
folderPath := fmt.Sprintf("/%s/vm/%s", "test-datacenter", "clusterID")
actualConfig, err := CloudProviderConfig(folderPath, platform)
assert.NoError(t, err, "failed to create cloud provider config")
assert.Equal(t, expectedConfig, actualConfig, "unexpected cloud provider config")

testCases := []struct {
testCase string
platform *vspheretypes.Platform
expectedConfig string
}{
{
testCase: "cloud provider configuration matches legacy platform specification",
platform: cloudProviderLegacyPlatform,
expectedConfig: cloudProviderLegacyExpectedConfig,
},
{
testCase: "cloud provider configuration matches multi-vcenter platform specification",
platform: cloudProviderMultiClusterPlatform,
expectedConfig: cloudProviderMultiClusteryExpectedConfig,
},
}

for _, tc := range testCases {
actualConfig, err := CloudProviderConfig(folderPath, tc.platform)
assert.NoError(t, err, "failed to create cloud provider config")
assert.Equal(t, tc.expectedConfig, actualConfig, "unexpected cloud provider config")
}

}