github.com/openshift/installer@v1.4.17/pkg/asset/installconfig/vsphere/permissions.go (about) 1 package vsphere 2 3 import ( 4 "context" 5 6 "github.com/pkg/errors" 7 "github.com/vmware/govmomi/object" 8 "github.com/vmware/govmomi/session" 9 "github.com/vmware/govmomi/vim25" 10 "github.com/vmware/govmomi/vim25/mo" 11 vim25types "github.com/vmware/govmomi/vim25/types" 12 "k8s.io/apimachinery/pkg/util/sets" 13 14 vspheretypes "github.com/openshift/installer/pkg/types/vsphere" 15 ) 16 17 //go:generate mockgen -source=./permissions.go -destination=./mock/authmanager_generated.go -package=mock 18 19 // AuthManager defines an interface to an implementation of the AuthorizationManager to facilitate mocking 20 type AuthManager interface { 21 FetchUserPrivilegeOnEntities(ctx context.Context, entities []vim25types.ManagedObjectReference, userName string) ([]vim25types.UserPrivilegeResult, error) 22 Properties(ctx context.Context, r vim25types.ManagedObjectReference, ps []string, dst interface{}) error 23 Reference() vim25types.ManagedObjectReference 24 } 25 26 // SessionManager defines an interface to an implementation of the SessionManager to facilitate mocking. 27 type SessionManager interface { 28 UserSession(ctx context.Context) (*vim25types.UserSession, error) 29 } 30 31 // permissionGroup is the group of permissions needed by cluster creation, operation, or teardown. 32 type permissionGroup string 33 34 // PermissionGroupDefinition defines a group of permissions and a related human friendly description 35 type PermissionGroupDefinition struct { 36 /* Permissions array of privileges which correlate with the privileges listed in docs */ 37 Permissions []string 38 /* Description friendly description of privilege group */ 39 Description string 40 } 41 42 // PrivilegeRelevanceFunc returns true if the associated privilege group privileges should be verified 43 type PrivilegeRelevanceFunc func(*vspheretypes.Platform) bool 44 45 var ( 46 permissionVcenter permissionGroup = "vcenter" 47 permissionCluster permissionGroup = "cluster" 48 permissionPortgroup permissionGroup = "portgroup" 49 permissionDatacenter permissionGroup = "datacenter" 50 permissionDatastore permissionGroup = "datastore" 51 permissionResourcePool permissionGroup = "resourcepool" 52 permissionFolder permissionGroup = "folder" 53 ) 54 55 var permissions = map[permissionGroup]PermissionGroupDefinition{ 56 // Base set of permissions required for cluster creation 57 permissionVcenter: { 58 Permissions: []string{ 59 "Cns.Searchable", 60 "InventoryService.Tagging.AttachTag", 61 "InventoryService.Tagging.CreateCategory", 62 "InventoryService.Tagging.CreateTag", 63 "InventoryService.Tagging.DeleteCategory", 64 "InventoryService.Tagging.DeleteTag", 65 "InventoryService.Tagging.EditCategory", 66 "InventoryService.Tagging.EditTag", 67 "Sessions.ValidateSession", 68 "StorageProfile.Update", 69 "StorageProfile.View", 70 }, 71 Description: "vSphere vCenter", 72 }, 73 permissionCluster: { 74 Permissions: []string{ 75 "Resource.AssignVMToPool", 76 "VApp.AssignResourcePool", 77 "VApp.Import", 78 "VirtualMachine.Config.AddNewDisk", 79 }, 80 Description: "vSphere vCenter Cluster", 81 }, 82 permissionPortgroup: { 83 Permissions: []string{ 84 "Network.Assign", 85 }, 86 Description: "vSphere Port Group", 87 }, 88 permissionFolder: { 89 Permissions: []string{ 90 "Resource.AssignVMToPool", 91 "VApp.Import", 92 "VirtualMachine.Config.AddExistingDisk", 93 "VirtualMachine.Config.AddNewDisk", 94 "VirtualMachine.Config.AddRemoveDevice", 95 "VirtualMachine.Config.AdvancedConfig", 96 "VirtualMachine.Config.Annotation", 97 "VirtualMachine.Config.CPUCount", 98 "VirtualMachine.Config.DiskExtend", 99 "VirtualMachine.Config.DiskLease", 100 "VirtualMachine.Config.EditDevice", 101 "VirtualMachine.Config.Memory", 102 "VirtualMachine.Config.RemoveDisk", 103 "VirtualMachine.Config.Rename", 104 "VirtualMachine.Config.ResetGuestInfo", 105 "VirtualMachine.Config.Resource", 106 "VirtualMachine.Config.Settings", 107 "VirtualMachine.Config.UpgradeVirtualHardware", 108 "VirtualMachine.Interact.GuestControl", 109 "VirtualMachine.Interact.PowerOff", 110 "VirtualMachine.Interact.PowerOn", 111 "VirtualMachine.Interact.Reset", 112 "VirtualMachine.Inventory.Create", 113 "VirtualMachine.Inventory.CreateFromExisting", 114 "VirtualMachine.Inventory.Delete", 115 "VirtualMachine.Provisioning.Clone", 116 "VirtualMachine.Provisioning.MarkAsTemplate", 117 "VirtualMachine.Provisioning.DeployTemplate", 118 "InventoryService.Tagging.ObjectAttachable", 119 }, 120 Description: "Pre-existing Virtual Machine Folder", 121 }, 122 permissionDatacenter: { 123 Permissions: []string{ 124 "Resource.AssignVMToPool", 125 "VApp.Import", 126 "VirtualMachine.Config.AddExistingDisk", 127 "VirtualMachine.Config.AddNewDisk", 128 "VirtualMachine.Config.AddRemoveDevice", 129 "VirtualMachine.Config.AdvancedConfig", 130 "VirtualMachine.Config.Annotation", 131 "VirtualMachine.Config.CPUCount", 132 "VirtualMachine.Config.DiskExtend", 133 "VirtualMachine.Config.DiskLease", 134 "VirtualMachine.Config.EditDevice", 135 "VirtualMachine.Config.Memory", 136 "VirtualMachine.Config.RemoveDisk", 137 "VirtualMachine.Config.Rename", 138 "VirtualMachine.Config.ResetGuestInfo", 139 "VirtualMachine.Config.Resource", 140 "VirtualMachine.Config.Settings", 141 "VirtualMachine.Config.UpgradeVirtualHardware", 142 "VirtualMachine.Interact.GuestControl", 143 "VirtualMachine.Interact.PowerOff", 144 "VirtualMachine.Interact.PowerOn", 145 "VirtualMachine.Interact.Reset", 146 "VirtualMachine.Inventory.Create", 147 "VirtualMachine.Inventory.CreateFromExisting", 148 "VirtualMachine.Inventory.Delete", 149 "VirtualMachine.Provisioning.Clone", 150 "VirtualMachine.Provisioning.DeployTemplate", 151 "VirtualMachine.Provisioning.MarkAsTemplate", 152 "Folder.Create", 153 "Folder.Delete", 154 "InventoryService.Tagging.ObjectAttachable", 155 }, 156 Description: "vSphere vCenter Datacenter", 157 }, 158 permissionDatastore: { 159 Permissions: []string{ 160 "Datastore.AllocateSpace", 161 "Datastore.Browse", 162 "Datastore.FileManagement", 163 "InventoryService.Tagging.ObjectAttachable", 164 }, 165 Description: "vSphere vCenter Datastore", 166 }, 167 permissionResourcePool: { 168 Permissions: []string{ 169 "Resource.AssignVMToPool", 170 "VApp.AssignResourcePool", 171 "VApp.Import", 172 "VirtualMachine.Config.AddNewDisk", 173 }, 174 Description: "vSphere vCenter Resource Pool", 175 }, 176 } 177 178 // pruneToAvailablePermissions different versions of vCenter support different privileges. the intent of this method 179 // is to prune privileges from the check that don't exist. 180 func pruneToAvailablePermissions(ctx context.Context, manager AuthManager) error { 181 var authManagerMo mo.AuthorizationManager 182 err := manager.Properties(ctx, manager.Reference(), []string{"privilegeList"}, &authManagerMo) 183 if err != nil { 184 return err 185 } 186 187 availablePermissions := sets.NewString() 188 for _, availablePermission := range authManagerMo.PrivilegeList { 189 availablePermissions.Insert(availablePermission.PrivId) 190 } 191 for permissionGroupKey, permissionGroup := range permissions { 192 prunedPermissions := sets.NewString(permissionGroup.Permissions...) 193 194 prunedPermissions = prunedPermissions.Intersection(availablePermissions) 195 permissions[permissionGroupKey] = PermissionGroupDefinition{ 196 Permissions: prunedPermissions.List(), 197 Description: permissionGroup.Description, 198 } 199 } 200 return nil 201 } 202 203 func newAuthManager(client *vim25.Client) AuthManager { 204 authManager := object.NewAuthorizationManager(client) 205 return authManager 206 } 207 208 func comparePrivileges(ctx context.Context, validationCtx *validationContext, moRef vim25types.ManagedObjectReference, permissionGroup PermissionGroupDefinition) error { 209 authManager := validationCtx.AuthManager 210 sessionMgr := session.NewManager(validationCtx.Client) 211 user, err := sessionMgr.UserSession(ctx) 212 if err != nil { 213 return errors.Wrap(err, "unable to get user session") 214 } 215 derived, err := authManager.FetchUserPrivilegeOnEntities(ctx, []vim25types.ManagedObjectReference{moRef}, user.UserName) 216 if err != nil { 217 return errors.Wrap(err, "unable to retrieve privileges") 218 } 219 var missingPrivileges = "" 220 for _, neededPrivilege := range permissionGroup.Permissions { 221 var hasPrivilege = false 222 for _, userPrivilege := range derived { 223 for _, assignedPrivilege := range userPrivilege.Privileges { 224 if assignedPrivilege == neededPrivilege { 225 hasPrivilege = true 226 } 227 } 228 } 229 if !hasPrivilege { 230 if missingPrivileges != "" { 231 missingPrivileges += ", " 232 } 233 missingPrivileges += neededPrivilege 234 } 235 } 236 if missingPrivileges != "" { 237 return errors.Errorf("privileges missing for %s: %s", permissionGroup.Description, missingPrivileges) 238 } 239 return nil 240 }