Skip to content

Commit

Permalink
vcsim: add endpoint registration mechanism
Browse files Browse the repository at this point in the history
Simplify endpoint registration for vapi, lookup, sts, etc.

This feature cannot be enabled by default as it would break existing
tests that currently make these calls directly.  However, both vcsim/main
and Model.Run can take advantage of it.

URL rewriting moved from the sts endpoint to the main simulator, this avoids
the previous dependency of lookup on sts.
  • Loading branch information
dougm committed Sep 7, 2019
1 parent 6b211c0 commit 43d6986
Show file tree
Hide file tree
Showing 10 changed files with 81 additions and 35 deletions.
3 changes: 0 additions & 3 deletions lookup/client_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,6 @@ import (
"github.com/vmware/govmomi"
"github.com/vmware/govmomi/simulator"
"github.com/vmware/govmomi/simulator/vpx"
sts "github.com/vmware/govmomi/sts/simulator"
)

func TestClient(t *testing.T) {
Expand All @@ -36,8 +35,6 @@ func TestClient(t *testing.T) {
ts := s.NewServer()
defer ts.Close()

_, _ = sts.New(ts.URL, vpx.Setting) // rewrite sts.uri

ctx := context.Background()

vc, err := govmomi.NewClient(ctx, ts.URL, true)
Expand Down
8 changes: 8 additions & 0 deletions lookup/simulator/simulator.go
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,14 @@ var content = types.LookupServiceContent{
L10n: vim.ManagedObjectReference{Type: "LookupL10n", Value: "l10n"},
}

func init() {
simulator.RegisterEndpoint(func(s *simulator.Service, r *simulator.Registry) {
if r.IsVPX() {
s.RegisterSDK(New())
}
})
}

func New() *simulator.Registry {
r := simulator.NewRegistry()
r.Namespace = lookup.Namespace
Expand Down
4 changes: 0 additions & 4 deletions lookup/simulator/simulator_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,6 @@ import (
"github.com/vmware/govmomi/lookup"
"github.com/vmware/govmomi/lookup/types"
"github.com/vmware/govmomi/simulator"
"github.com/vmware/govmomi/simulator/vpx"
sts "github.com/vmware/govmomi/sts/simulator"
)

func TestClient(t *testing.T) {
Expand All @@ -45,8 +43,6 @@ func TestClient(t *testing.T) {

model.Service.RegisterSDK(New())

_, _ = sts.New(s.URL, vpx.Setting) // rewrite sts.uri

vc, err := govmomi.NewClient(ctx, s.URL, true)
if err != nil {
t.Fatal(err)
Expand Down
8 changes: 8 additions & 0 deletions pbm/simulator/simulator.go
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,14 @@ var content = types.PbmServiceInstanceContent{
ReplicationManager: &vim.ManagedObjectReference{Type: "PbmReplicationManager", Value: "ReplicationManager"},
}

func init() {
simulator.RegisterEndpoint(func(s *simulator.Service, r *simulator.Registry) {
if r.IsVPX() {
s.RegisterSDK(New())
}
})
}

func New() *simulator.Registry {
r := simulator.NewRegistry()
r.Namespace = pbm.Namespace
Expand Down
4 changes: 3 additions & 1 deletion simulator/model.go
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,7 @@ type Model struct {
Pod int

// Delay configurations
DelayConfig DelayConfig
DelayConfig DelayConfig `json:"-"`

// total number of inventory objects, set by Count()
total int
Expand Down Expand Up @@ -531,6 +531,8 @@ func (m *Model) Run(f func(context.Context, *vim25.Client) error) error {
return err
}

m.Service.RegisterEndpoints = true

s := m.Service.NewServer()
defer s.Close()

Expand Down
2 changes: 1 addition & 1 deletion simulator/session_manager.go
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,7 @@ func (s *SessionManager) validLogin(ctx *Context, req *types.Login) bool {
return false
}
user := ctx.svc.Listen.User
if user == nil {
if user == nil || user == DefaultLogin {
return req.UserName != "" && req.Password != ""
}
pass, _ := user.Password()
Expand Down
35 changes: 34 additions & 1 deletion simulator/simulator.go
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,9 @@ import (
// Trace when set to true, writes SOAP traffic to stderr
var Trace = false

// DefaultLogin for authentication
var DefaultLogin = url.UserPassword("user", "pass")

// Method encapsulates a decoded SOAP client request
type Method struct {
Name string
Expand All @@ -73,6 +76,8 @@ type Service struct {
Listen *url.URL
TLS *tls.Config
ServeMux *http.ServeMux
// RegisterEndpoints will initialize any endpoints added via RegisterEndpoint
RegisterEndpoints bool
}

// Server provides a simulator Service over HTTP
Expand Down Expand Up @@ -362,6 +367,14 @@ func (s *Service) About(w http.ResponseWriter, r *http.Request) {
_ = enc.Encode(&about)
}

var endpoints []func(*Service, *Registry)

// RegisterEndpoint funcs are called after the Server is initialized if Service.RegisterEndpoints=true.
// Such a func would typically register a SOAP endpoint via Service.RegisterSDK or REST endpoint via Service.Handle
func RegisterEndpoint(endpoint func(*Service, *Registry)) {
endpoints = append(endpoints, endpoint)
}

// Handle registers the handler for the given pattern with Service.ServeMux.
func (s *Service) Handle(pattern string, handler http.Handler) {
s.ServeMux.Handle(pattern, handler)
Expand Down Expand Up @@ -619,6 +632,19 @@ func (s *Service) NewServer() *Server {

// Add vcsim config to OptionManager for use by SDK handlers (see lookup/simulator for example)
m := Map.OptionManager()
for i := range m.Setting {
setting := m.Setting[i].GetOptionValue()

if strings.HasSuffix(setting.Key, ".uri") {
// Rewrite any URIs with vcsim's host:port
endpoint, err := url.Parse(setting.Value.(string))
if err == nil {
endpoint.Scheme = u.Scheme
endpoint.Host = u.Host
setting.Value = endpoint.String()
}
}
}
m.Setting = append(m.Setting,
&types.OptionValue{
Key: "vcsim.server.url",
Expand All @@ -628,7 +654,14 @@ func (s *Service) NewServer() *Server {

u.User = s.Listen.User
if u.User == nil {
u.User = url.UserPassword("user", "pass")
u.User = DefaultLogin
}
s.Listen = u

if s.RegisterEndpoints {
for i := range endpoints {
endpoints[i](s, Map)
}
}

if s.TLS != nil {
Expand Down
14 changes: 10 additions & 4 deletions sts/simulator/simulator.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,22 +24,28 @@ import (
"path"
"time"

"github.com/vmware/govmomi/simulator"
"github.com/vmware/govmomi/sts/internal"
"github.com/vmware/govmomi/vim25/soap"
vim "github.com/vmware/govmomi/vim25/types"
)

func init() {
simulator.RegisterEndpoint(func(s *simulator.Service, r *simulator.Registry) {
if r.IsVPX() {
path, handler := New(s.Listen, r.OptionManager().Setting)
s.Handle(path, handler)
}
})
}

// New creates an STS simulator and configures the simulator endpoint in the given settings.
// The path returned is that of the settings "config.vpxd.sso.sts.uri" property.
func New(u *url.URL, settings []vim.BaseOptionValue) (string, http.Handler) {
for i := range settings {
setting := settings[i].GetOptionValue()
if setting.Key == "config.vpxd.sso.sts.uri" {
endpoint, _ := url.Parse(setting.Value.(string))
endpoint.Scheme = u.Scheme
endpoint.Host = u.Host
setting.Value = endpoint.String()
settings[i] = setting
return endpoint.Path, new(handler)
}
}
Expand Down
10 changes: 10 additions & 0 deletions vapi/simulator/simulator.go
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ import (
"github.com/vmware/govmomi"
"github.com/vmware/govmomi/nfc"
"github.com/vmware/govmomi/ovf"
"github.com/vmware/govmomi/simulator"
"github.com/vmware/govmomi/vapi/internal"
"github.com/vmware/govmomi/vapi/library"
"github.com/vmware/govmomi/vapi/rest"
Expand Down Expand Up @@ -92,6 +93,15 @@ type handler struct {
Download map[string]download
}

func init() {
simulator.RegisterEndpoint(func(s *simulator.Service, r *simulator.Registry) {
if r.IsVPX() {
path, handler := New(s.Listen, r.OptionManager().Setting)
s.Handle(path, handler)
}
})
}

// New creates a vAPI simulator.
func New(u *url.URL, settings []vim.BaseOptionValue) (string, http.Handler) {
s := &handler{
Expand Down
28 changes: 7 additions & 21 deletions vcsim/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -33,15 +33,16 @@ import (
"syscall"

"github.com/google/uuid"
lookup "github.com/vmware/govmomi/lookup/simulator"
pbm "github.com/vmware/govmomi/pbm/simulator"
"github.com/vmware/govmomi/session"
"github.com/vmware/govmomi/simulator"
"github.com/vmware/govmomi/simulator/esx"
"github.com/vmware/govmomi/simulator/vpx"
sts "github.com/vmware/govmomi/sts/simulator"
vapi "github.com/vmware/govmomi/vapi/simulator"
"github.com/vmware/govmomi/vim25/types"

// Register vcsim optional endpoints
_ "github.com/vmware/govmomi/lookup/simulator"
_ "github.com/vmware/govmomi/pbm/simulator"
_ "github.com/vmware/govmomi/sts/simulator"
_ "github.com/vmware/govmomi/vapi/simulator"
)

func main() {
Expand Down Expand Up @@ -147,6 +148,7 @@ func main() {
log.Fatal(err)
}

model.Service.RegisterEndpoints = true
model.Service.Listen = u
if *isTLS {
model.Service.TLS = new(tls.Config)
Expand Down Expand Up @@ -183,22 +185,6 @@ func main() {
}
}

if !*isESX {
// STS simulator
path, handler := sts.New(s.URL, vpx.Setting)
model.Service.Handle(path, handler)

// vAPI simulator
path, handler = vapi.New(s.URL, vpx.Setting)
model.Service.Handle(path, handler)

// Lookup Service simulator
model.Service.RegisterSDK(lookup.New())

// PBM simulator
model.Service.RegisterSDK(pbm.New())
}

fmt.Fprintf(out, "export GOVC_URL=%s GOVC_SIM_PID=%d\n", s.URL, os.Getpid())
if out != os.Stdout {
err = out.Close()
Expand Down

0 comments on commit 43d6986

Please sign in to comment.