in pkg/providers/vsphere/validator.go [455:564]
func (v *Validator) validateUserPrivs(ctx context.Context, spec *Spec, vuc *config.VSphereUserConfig) (bool, error) {
resourcePaths, err := v.collectResourcePathConfig(ctx, spec)
if err != nil {
return false, err
}
requiredPrivAssociations := []PrivAssociation{
// validate global root priv settings are correct
{
objectType: govmomi.VSphereTypeFolder,
privsContent: config.VSphereGlobalPrivsFile,
path: vsphereRootPath,
},
{
objectType: govmomi.VSphereTypeNetwork,
privsContent: config.VSphereUserPrivsFile,
path: spec.VSphereDatacenter.Spec.Network,
},
}
seen := map[string]interface{}{}
for _, mc := range resourcePaths {
datastore := mc.ResourcePaths()["datastore"]
if _, ok := seen[datastore]; !ok {
requiredPrivAssociations = append(requiredPrivAssociations, PrivAssociation{
objectType: govmomi.VSphereTypeDatastore,
privsContent: config.VSphereUserPrivsFile,
path: datastore,
},
)
seen[datastore] = 1
}
resourcePool := mc.ResourcePaths()["resourcePool"]
if _, ok := seen[resourcePool]; !ok {
requiredPrivAssociations = append(requiredPrivAssociations, PrivAssociation{
objectType: govmomi.VSphereTypeResourcePool,
privsContent: config.VSphereUserPrivsFile,
path: resourcePool,
})
seen[resourcePool] = 1
}
folder := mc.ResourcePaths()["folder"]
if _, ok := seen[folder]; !ok {
requiredPrivAssociations = append(requiredPrivAssociations, PrivAssociation{
objectType: govmomi.VSphereTypeFolder,
privsContent: config.VSphereAdminPrivsFile,
path: folder,
})
seen[folder] = 1
}
switch v := mc.(type) {
case *anywherev1.FailureDomain:
computecluster := v.ResourcePaths()["computeCluster"]
if _, ok := seen[computecluster]; !ok {
requiredPrivAssociations = append(requiredPrivAssociations, PrivAssociation{
objectType: govmomi.VSphereTypeComputeCluster,
privsContent: config.VSphereAdminPrivsFile,
path: computecluster,
})
seen[computecluster] = 1
}
case *anywherev1.VSphereMachineConfig:
template := v.ResourcePaths()["template"]
if _, ok := seen[template]; !ok {
// ToDo: add more sophisticated validation around a scenario where someone has uploaded templates
// on their own and does not want to allow EKSA user write access to templates
// Verify privs on the template
requiredPrivAssociations = append(requiredPrivAssociations, PrivAssociation{
objectType: govmomi.VSphereTypeVirtualMachine,
privsContent: config.VSphereAdminPrivsFile,
path: template,
})
seen[template] = 1
}
if _, ok := seen[filepath.Dir(template)]; !ok {
requiredPrivAssociations = append(requiredPrivAssociations, PrivAssociation{
objectType: govmomi.VSphereTypeFolder,
privsContent: config.VSphereAdminPrivsFile,
path: filepath.Dir(template),
})
seen[filepath.Dir(template)] = 1
}
default:
return false, errors.New("unexpected type in missing validateUserPrivs")
}
}
host := spec.VSphereDatacenter.Spec.Server
datacenter := spec.VSphereDatacenter.Spec.Datacenter
vsc, err := v.vSphereClientBuilder.Build(
ctx,
host,
vuc.EksaVsphereUsername,
vuc.EksaVspherePassword,
spec.VSphereDatacenter.Spec.Insecure,
datacenter,
)
if err != nil {
return false, err
}
return v.validatePrivs(ctx, requiredPrivAssociations, vsc)
}