github.com/vmware/govmomi@v0.51.0/pbm/simulator/simulator.go (about) 1 // © Broadcom. All Rights Reserved. 2 // The term “Broadcom” refers to Broadcom Inc. and/or its subsidiaries. 3 // SPDX-License-Identifier: Apache-2.0 4 5 package simulator 6 7 import ( 8 "slices" 9 "time" 10 11 "github.com/google/uuid" 12 13 "github.com/vmware/govmomi/pbm" 14 "github.com/vmware/govmomi/pbm/methods" 15 "github.com/vmware/govmomi/pbm/types" 16 "github.com/vmware/govmomi/simulator" 17 "github.com/vmware/govmomi/vim25" 18 "github.com/vmware/govmomi/vim25/soap" 19 vim "github.com/vmware/govmomi/vim25/types" 20 ) 21 22 var content = types.PbmServiceInstanceContent{ 23 AboutInfo: types.PbmAboutInfo{ 24 Name: "PBM", 25 Version: "2.0", 26 InstanceUuid: "df09f335-be97-4f33-8c27-315faaaad6fc", 27 }, 28 SessionManager: vim.ManagedObjectReference{Type: "PbmSessionManager", Value: "SessionManager"}, 29 CapabilityMetadataManager: vim.ManagedObjectReference{Type: "PbmCapabilityMetadataManager", Value: "CapabilityMetadataManager"}, 30 ProfileManager: vim.ManagedObjectReference{Type: "PbmProfileProfileManager", Value: "ProfileManager"}, 31 ComplianceManager: vim.ManagedObjectReference{Type: "PbmComplianceManager", Value: "complianceManager"}, 32 PlacementSolver: vim.ManagedObjectReference{Type: "PbmPlacementSolver", Value: "placementSolver"}, 33 ReplicationManager: &vim.ManagedObjectReference{Type: "PbmReplicationManager", Value: "ReplicationManager"}, 34 } 35 36 func init() { 37 simulator.RegisterEndpoint(func(s *simulator.Service, r *simulator.Registry) { 38 if r.IsVPX() { 39 s.RegisterSDK(New()) 40 } 41 }) 42 } 43 44 func New() *simulator.Registry { 45 r := simulator.NewRegistry() 46 r.Namespace = pbm.Namespace 47 r.Path = pbm.Path 48 r.Cookie = simulator.SOAPCookie 49 50 r.Put(&ServiceInstance{ 51 ManagedObjectReference: pbm.ServiceInstance, 52 Content: content, 53 }) 54 55 profileManager := &ProfileManager{ 56 ManagedObjectReference: content.ProfileManager, 57 } 58 profileManager.init(r) 59 r.Put(profileManager) 60 61 r.Put(&PlacementSolver{ 62 ManagedObjectReference: content.PlacementSolver, 63 }) 64 65 return r 66 } 67 68 type ServiceInstance struct { 69 vim.ManagedObjectReference 70 71 Content types.PbmServiceInstanceContent 72 } 73 74 func (s *ServiceInstance) PbmRetrieveServiceContent(_ *types.PbmRetrieveServiceContent) soap.HasFault { 75 return &methods.PbmRetrieveServiceContentBody{ 76 Res: &types.PbmRetrieveServiceContentResponse{ 77 Returnval: s.Content, 78 }, 79 } 80 } 81 82 type ProfileManager struct { 83 vim.ManagedObjectReference 84 85 profiles []types.BasePbmProfile 86 profileDetails map[string]types.PbmProfileDetails 87 } 88 89 func (m *ProfileManager) init(_ *simulator.Registry) { 90 m.profiles = slices.Clone(vcenter67DefaultProfiles) 91 92 // Ensure the default encryption profile has the encryption IOFILTER as this 93 // is required when detecting whether a policy supports encryption. 94 m.profileDetails = map[string]types.PbmProfileDetails{ 95 defaultEncryptionProfile.ProfileId.UniqueId: { 96 Profile: defaultEncryptionProfile, 97 IofInfos: []types.PbmIofilterInfo{ 98 { 99 FilterType: string(types.PbmIofilterInfoFilterTypeENCRYPTION), 100 }, 101 }, 102 }, 103 } 104 } 105 106 func (m *ProfileManager) PbmQueryProfile(req *types.PbmQueryProfile) soap.HasFault { 107 body := new(methods.PbmQueryProfileBody) 108 body.Res = new(types.PbmQueryProfileResponse) 109 110 for i := range m.profiles { 111 b, ok := m.profiles[i].(types.BasePbmCapabilityProfile) 112 if !ok { 113 continue 114 } 115 p := b.GetPbmCapabilityProfile() 116 117 if p.ResourceType != req.ResourceType { 118 continue 119 } 120 121 if req.ProfileCategory != "" { 122 if p.ProfileCategory != req.ProfileCategory { 123 continue 124 } 125 } 126 127 body.Res.Returnval = append(body.Res.Returnval, types.PbmProfileId{ 128 UniqueId: p.ProfileId.UniqueId, 129 }) 130 } 131 132 return body 133 } 134 135 func (m *ProfileManager) PbmQueryAssociatedProfile(req *types.PbmQueryAssociatedProfile) soap.HasFault { 136 body := new(methods.PbmQueryAssociatedProfileBody) 137 body.Res = new(types.PbmQueryAssociatedProfileResponse) 138 139 return body 140 } 141 142 func (m *ProfileManager) PbmQueryAssociatedProfiles(req *types.PbmQueryAssociatedProfiles) soap.HasFault { 143 body := new(methods.PbmQueryAssociatedProfilesBody) 144 body.Res = new(types.PbmQueryAssociatedProfilesResponse) 145 146 return body 147 } 148 149 func (m *ProfileManager) PbmRetrieveContent(req *types.PbmRetrieveContent) soap.HasFault { 150 body := new(methods.PbmRetrieveContentBody) 151 if len(req.ProfileIds) == 0 { 152 body.Fault_ = simulator.Fault("", new(vim.InvalidRequest)) 153 return body 154 } 155 156 var res []types.BasePbmProfile 157 158 match := func(id string) bool { 159 for _, p := range m.profiles { 160 if id == p.GetPbmProfile().ProfileId.UniqueId { 161 res = append(res, p) 162 return true 163 } 164 } 165 return false 166 } 167 168 for _, p := range req.ProfileIds { 169 if match(p.UniqueId) { 170 continue 171 } 172 173 body.Fault_ = simulator.Fault("", &vim.InvalidArgument{InvalidProperty: "profileId"}) 174 return body 175 } 176 177 body.Res = &types.PbmRetrieveContentResponse{Returnval: res} 178 179 return body 180 } 181 182 func (m *ProfileManager) PbmCreate(ctx *simulator.Context, req *types.PbmCreate) soap.HasFault { 183 body := new(methods.PbmCreateBody) 184 body.Res = new(types.PbmCreateResponse) 185 186 profile := &types.PbmCapabilityProfile{ 187 PbmProfile: types.PbmProfile{ 188 ProfileId: types.PbmProfileId{ 189 UniqueId: uuid.New().String(), 190 }, 191 Name: req.CreateSpec.Name, 192 Description: req.CreateSpec.Description, 193 CreationTime: time.Now(), 194 CreatedBy: ctx.Session.UserName, 195 LastUpdatedTime: time.Now(), 196 LastUpdatedBy: ctx.Session.UserName, 197 }, 198 ProfileCategory: req.CreateSpec.Category, 199 ResourceType: req.CreateSpec.ResourceType, 200 Constraints: req.CreateSpec.Constraints, 201 GenerationId: 0, 202 IsDefault: false, 203 SystemCreatedProfileType: "", 204 LineOfService: "", 205 } 206 207 m.profiles = append(m.profiles, profile) 208 body.Res.Returnval.UniqueId = profile.PbmProfile.ProfileId.UniqueId 209 210 return body 211 } 212 213 func (m *ProfileManager) PbmDelete(req *types.PbmDelete) soap.HasFault { 214 body := new(methods.PbmDeleteBody) 215 216 for _, id := range req.ProfileId { 217 for i, p := range m.profiles { 218 pid := p.GetPbmProfile().ProfileId 219 220 if id == pid { 221 m.profiles = append(m.profiles[:i], m.profiles[i+1:]...) 222 break 223 } 224 } 225 } 226 227 body.Res = new(types.PbmDeleteResponse) 228 229 return body 230 } 231 232 func (m *ProfileManager) PbmQueryIOFiltersFromProfileId(req *types.PbmQueryIOFiltersFromProfileId) soap.HasFault { 233 body := methods.PbmQueryIOFiltersFromProfileIdBody{ 234 Res: &types.PbmQueryIOFiltersFromProfileIdResponse{}, 235 } 236 237 for i := range req.ProfileIds { 238 profileID := req.ProfileIds[i] 239 if profileDetails, ok := m.profileDetails[profileID.UniqueId]; ok { 240 body.Res.Returnval = append( 241 body.Res.Returnval, 242 types.PbmProfileToIofilterMap{ 243 Key: profileID, 244 Iofilters: profileDetails.IofInfos, 245 }) 246 } else { 247 body.Fault_ = simulator.Fault("Invalid profile ID", &vim.RuntimeFault{}) 248 break 249 } 250 } 251 252 if body.Fault_ != nil { 253 body.Res = nil 254 } 255 256 return &body 257 } 258 259 type PlacementSolver struct { 260 vim.ManagedObjectReference 261 } 262 263 func (m *PlacementSolver) PbmCheckRequirements(ctx *simulator.Context, req *types.PbmCheckRequirements) soap.HasFault { 264 body := new(methods.PbmCheckRequirementsBody) 265 body.Res = new(types.PbmCheckRequirementsResponse) 266 267 for _, ds := range ctx.For(vim25.Path).Map.All("Datastore") { 268 // TODO: filter 269 ref := ds.Reference() 270 body.Res.Returnval = append(body.Res.Returnval, types.PbmPlacementCompatibilityResult{ 271 Hub: types.PbmPlacementHub{ 272 HubType: ref.Type, 273 HubId: ref.Value, 274 }, 275 MatchingResources: nil, 276 HowMany: 0, 277 Utilization: nil, 278 Warning: nil, 279 Error: nil, 280 }) 281 } 282 283 return body 284 } 285 286 func (m *PlacementSolver) PbmCheckCompatibility(ctx *simulator.Context, _ *types.PbmCheckCompatibility) soap.HasFault { 287 body := new(methods.PbmCheckCompatibilityBody) 288 body.Res = new(types.PbmCheckCompatibilityResponse) 289 290 for _, ds := range ctx.For(vim25.Path).Map.All("Datastore") { 291 // TODO: filter 292 ref := ds.Reference() 293 body.Res.Returnval = append(body.Res.Returnval, types.PbmPlacementCompatibilityResult{ 294 Hub: types.PbmPlacementHub{ 295 HubType: ref.Type, 296 HubId: ref.Value, 297 }, 298 MatchingResources: nil, 299 HowMany: 0, 300 Utilization: nil, 301 Warning: nil, 302 Error: nil, 303 }) 304 } 305 306 return body 307 }