github.com/vmware/govmomi@v0.51.0/lookup/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 "context" 9 "net/url" 10 "strings" 11 "sync" 12 13 "github.com/vmware/govmomi/lookup" 14 "github.com/vmware/govmomi/lookup/methods" 15 "github.com/vmware/govmomi/lookup/types" 16 "github.com/vmware/govmomi/simulator" 17 "github.com/vmware/govmomi/vim25/soap" 18 vim "github.com/vmware/govmomi/vim25/types" 19 ) 20 21 var content = types.LookupServiceContent{ 22 LookupService: vim.ManagedObjectReference{Type: "LookupLookupService", Value: "lookupService"}, 23 ServiceRegistration: &vim.ManagedObjectReference{Type: "LookupServiceRegistration", Value: "ServiceRegistration"}, 24 DeploymentInformationService: vim.ManagedObjectReference{Type: "LookupDeploymentInformationService", Value: "deploymentInformationService"}, 25 L10n: vim.ManagedObjectReference{Type: "LookupL10n", Value: "l10n"}, 26 } 27 28 func init() { 29 simulator.RegisterEndpoint(func(s *simulator.Service, r *simulator.Registry) { 30 if r.IsVPX() { 31 s.RegisterSDK(New()) 32 } 33 }) 34 } 35 36 func New() *simulator.Registry { 37 r := simulator.NewRegistry() 38 r.Namespace = lookup.Namespace 39 r.Path = lookup.Path 40 41 r.Put(&ServiceInstance{ 42 ManagedObjectReference: lookup.ServiceInstance, 43 Content: content, 44 }) 45 46 r.Put(&ServiceRegistration{ 47 ManagedObjectReference: *content.ServiceRegistration, 48 }) 49 50 return r 51 } 52 53 type ServiceInstance struct { 54 vim.ManagedObjectReference 55 56 Content types.LookupServiceContent 57 } 58 59 func (s *ServiceInstance) RetrieveServiceContent(ctx *simulator.Context, _ *types.RetrieveServiceContent) soap.HasFault { 60 // Initialize prior to List() being called (see ExampleServiceRegistration) 61 ctx.Map.Get(*content.ServiceRegistration).(*ServiceRegistration).info(ctx) 62 63 return &methods.RetrieveServiceContentBody{ 64 Res: &types.RetrieveServiceContentResponse{ 65 Returnval: s.Content, 66 }, 67 } 68 } 69 70 type ServiceRegistration struct { 71 vim.ManagedObjectReference 72 73 Info []types.LookupServiceRegistrationInfo 74 75 register sync.Once 76 } 77 78 func (s *ServiceRegistration) GetSiteId(_ *types.GetSiteId) soap.HasFault { 79 return &methods.GetSiteIdBody{ 80 Res: &types.GetSiteIdResponse{ 81 Returnval: siteID, 82 }, 83 } 84 } 85 86 func matchServiceType(filter, info *types.LookupServiceRegistrationServiceType) bool { 87 if filter.Product != "" { 88 if filter.Product != info.Product { 89 return false 90 } 91 } 92 93 if filter.Type != "" { 94 if filter.Type != info.Type { 95 return false 96 } 97 } 98 99 return true 100 } 101 102 func matchEndpointType(filter, info *types.LookupServiceRegistrationEndpointType) bool { 103 if filter.Protocol != "" { 104 if filter.Protocol != info.Protocol { 105 return false 106 } 107 } 108 109 if filter.Type != "" { 110 if filter.Type != info.Type { 111 return false 112 } 113 } 114 115 return true 116 } 117 118 // defer register to this point to ensure we can include vcsim's cert in ServiceEndpoints.SslTrust 119 // TODO: we should be able to register within New(), but this is the only place that currently depends on vcsim's cert 120 func (s *ServiceRegistration) info(ctx *simulator.Context) []types.LookupServiceRegistrationInfo { 121 s.register.Do(func() { 122 s.Info = registrationInfo(ctx) 123 }) 124 return s.Info 125 } 126 127 func (s *ServiceRegistration) List(ctx *simulator.Context, req *types.List) soap.HasFault { 128 body := new(methods.ListBody) 129 filter := req.FilterCriteria 130 131 if filter == nil { 132 // This is what a real PSC returns if FilterCriteria is nil. 133 body.Fault_ = simulator.Fault("LookupFaultServiceFault", &vim.SystemError{ 134 Reason: "Invalid fault", 135 }) 136 return body 137 } 138 body.Res = new(types.ListResponse) 139 140 for _, info := range s.info(ctx) { 141 if filter.SiteId != "" { 142 if filter.SiteId != info.SiteId { 143 continue 144 } 145 } 146 if filter.NodeId != "" { 147 if filter.NodeId != info.NodeId { 148 continue 149 } 150 } 151 if filter.ServiceType != nil { 152 if !matchServiceType(filter.ServiceType, &info.ServiceType) { 153 continue 154 } 155 } 156 if filter.EndpointType != nil { 157 services := info.ServiceEndpoints 158 info.ServiceEndpoints = nil 159 for _, service := range services { 160 if !matchEndpointType(filter.EndpointType, &service.EndpointType) { 161 continue 162 } 163 info.ServiceEndpoints = append(info.ServiceEndpoints, service) 164 } 165 if len(info.ServiceEndpoints) == 0 { 166 continue 167 } 168 } 169 body.Res.Returnval = append(body.Res.Returnval, info) 170 } 171 172 return body 173 } 174 175 // BreakLookupServiceURLs makes the path of all lookup service urls invalid 176 func BreakLookupServiceURLs(ctx context.Context) { 177 setting := simulator.Map(ctx).OptionManager().Setting 178 179 for _, s := range setting { 180 o := s.GetOptionValue() 181 if strings.HasSuffix(o.Key, ".uri") { 182 val := o.Value.(string) 183 u, _ := url.Parse(val) 184 u.Path = "/enoent" + u.Path 185 o.Value = u.String() 186 } 187 } 188 } 189 190 // UnresolveLookupServiceURLs makes the path of all lookup service urls invalid 191 func UnresolveLookupServiceURLs(ctx context.Context) { 192 setting := simulator.Map(ctx).OptionManager().Setting 193 194 for _, s := range setting { 195 o := s.GetOptionValue() 196 if strings.HasSuffix(o.Key, ".uri") { 197 val := o.Value.(string) 198 u, _ := url.Parse(val) 199 port := u.Port() 200 u.Host = "fake-name-will-not-dns-resolve:" + port 201 o.Value = u.String() 202 } 203 } 204 }