Skip to content

Commit

Permalink
Define an OpenAPI document for vic-machine
Browse files Browse the repository at this point in the history
Use an OpenAPI (Swagger) document to define a preliminary API for
vic-machine based on the vic-machine API design document (vmware#6116).

This document is expected to evolve as implementation proceeds.
  • Loading branch information
zjs committed Aug 28, 2017
1 parent ba7c619 commit beea9b2
Show file tree
Hide file tree
Showing 6 changed files with 1,284 additions and 3 deletions.
5 changes: 5 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,11 @@ lib/config/dynamic/admiral/client
lib/config/dynamic/admiral/models
lib/config/dynamic/admiral/operations

lib/apiservers/service/models
lib/apiservers/service/restapi/*.go
lib/apiservers/service/restapi/operations
!lib/apiservers/service/restapi/configure_port_layer.go

tests/.project
# go test binaries
*.test
Expand Down
33 changes: 30 additions & 3 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,8 @@ portlayerapi := $(BIN)/port-layer-server
portlayerapi-test := $(BIN)/port-layer-server-test
portlayerapi-client := lib/apiservers/portlayer/client/port_layer_client.go
portlayerapi-server := lib/apiservers/portlayer/restapi/server.go
serviceapi := $(BIN)/vic-machine-server
serviceapi-server := lib/apiservers/service/restapi/server.go

imagec := $(BIN)/imagec
vicadmin := $(BIN)/vicadmin
Expand Down Expand Up @@ -123,6 +125,8 @@ portlayerapi: $(portlayerapi)
portlayerapi-test: $(portlayerapi-test)
portlayerapi-client: $(portlayerapi-client)
portlayerapi-server: $(portlayerapi-server)
serviceapi: $(serviceapi)
serviceapi-server: $(serviceapi-server)
admiralapi-client: $(admiralapi-client)

imagec: $(imagec)
Expand Down Expand Up @@ -156,12 +160,12 @@ misspell: $(MISSPELL)
all: components tethers isos vic-machine imagec vic-ui
tools: $(GOIMPORTS) $(GVT) $(GOLINT) $(SWAGGER) $(GAS) $(MISSPELL) goversion
check: goversion goimports gofmt misspell govet golint copyright whitespace gas
apiservers: $(portlayerapi) $(docker-engine-api)
apiservers: $(portlayerapi) $(docker-engine-api) $(serviceapi)
components: check apiservers $(vicadmin) $(rpctool)
isos: $(appliance) $(bootstrap)
tethers: $(tether-linux)

most: $(portlayerapi) $(docker-engine-api) $(vicadmin) $(tether-linux) $(appliance) $(bootstrap) $(vic-machine-linux)
most: $(portlayerapi) $(docker-engine-api) $(vicadmin) $(tether-linux) $(appliance) $(bootstrap) $(vic-machine-linux) $(serviceapi-server)

# utility targets
goversion:
Expand Down Expand Up @@ -355,6 +359,24 @@ $(portlayerapi-test): $$(call godeps,cmd/port-layer-server/*.go) $(portlayerapi-
@echo building Portlayer API server for test...
@$(TIME) $(GO) test -c -coverpkg github.com/vmware/vic/lib/...,github.com/vmware/vic/pkg/... -coverprofile port-layer-server.cov -outputdir /tmp -o $@ ./cmd/port-layer-server

# Common service dependencies between client and server
SERVICE_DEPS ?= lib/apiservers/service/swagger.json #\
# lib/apiservers/service/restapi/configure_service.go \
# lib/apiservers/service/restapi/options/*.go \
# lib/apiservers/service/restapi/handlers/*.go



$(serviceapi-server): $(SERVICE_DEPS) $(SWAGGER)
@echo regenerating swagger models and operations for vic-machine-as-a-service API server...
@$(SWAGGER) generate server --exclude-main --target lib/apiservers/service -f lib/apiservers/service/swagger.json 2>>service-swagger-gen.log
@echo done regenerating swagger models and operations for vic-machine-as-a-service API server...

$(serviceapi): $$(call godeps,cmd/vic-machine-server/*.go) $(serviceapi-server)
@echo building vic-machine-as-a-service API server...
@$(TIME) $(GO) build $(RACE) -ldflags "$(LDFLAGS)" -o $@ ./cmd/vic-machine-server


$(iso-base): isos/base.sh isos/base/*.repo isos/base/isolinux/** isos/base/xorriso-options.cfg
@echo building iso-base docker image
@$(TIME) $< -c $(BIN)/.yum-cache.tgz -p $@
Expand All @@ -365,7 +387,7 @@ $(appliance-staging): isos/appliance-staging.sh $(iso-base)
@$(TIME) $< -c $(BIN)/.yum-cache.tgz -p $(iso-base) -o $@

# main appliance target - depends on all top level component targets
$(appliance): isos/appliance.sh isos/appliance/* isos/vicadmin/** $(vicadmin) $(vic-init) $(portlayerapi) $(docker-engine-api) $(appliance-staging)
$(appliance): isos/appliance.sh isos/appliance/* isos/vicadmin/** $(vicadmin) $(vic-init) $(portlayerapi) $(serviceapi-server) $(docker-engine-api) $(appliance-staging)
@echo building VCH appliance ISO
@$(TIME) $< -p $(appliance-staging) -b $(BIN)

Expand Down Expand Up @@ -485,6 +507,11 @@ clean:
@rm -rf ./lib/config/dynamic/admiral/models
@rm -rf ./lib/config/dynamic/admiral/operations

@rm -f ./lib/apiservers/service/restapi/doc.go
@rm -f ./lib/apiservers/service/restapi/embedded_spec.go
@rm -f ./lib/apiservers/service/restapi/server.go
@rm -rf ./lib/apiservers/service/restapi/operations/

@rm -f *.log
@rm -f *.pem

Expand Down
56 changes: 56 additions & 0 deletions cmd/vic-machine-server/main.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
package main

import (
"log"
"os"

loads "github.com/go-openapi/loads"
flags "github.com/jessevdk/go-flags"

"github.com/vmware/vic/lib/apiservers/service/restapi"
"github.com/vmware/vic/lib/apiservers/service/restapi/operations"
)

// This file was generated by the swagger tool.
// Make sure not to overwrite this file after you generated it because all your edits would be lost!

func main() {

swaggerSpec, err := loads.Analyzed(restapi.SwaggerJSON, "")
if err != nil {
log.Fatalln(err)
}

api := operations.NewVicMachineAPI(swaggerSpec)
server := restapi.NewServer(api)
defer server.Shutdown()

parser := flags.NewParser(server, flags.Default)
parser.ShortDescription = "vic-machine API"
parser.LongDescription = "An API for interacting with vic-machine as a RESTful web service."

server.ConfigureFlags()
for _, optsGroup := range api.CommandLineOptionsGroups {
_, err := parser.AddGroup(optsGroup.ShortDescription, optsGroup.LongDescription, optsGroup.Options)
if err != nil {
log.Fatalln(err)
}
}

if _, err := parser.Parse(); err != nil {
code := 1
if fe, ok := err.(*flags.Error); ok {
if fe.Type == flags.ErrHelp {
code = 0
}
}
os.Exit(code)
}

server.ConfigureAPI()

if err := server.Serve(); err != nil {
log.Fatalln(err)
}

}
161 changes: 161 additions & 0 deletions lib/apiservers/service/restapi/configure_vic_machine.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,161 @@
package restapi

import (
"crypto/tls"
"net/http"

"github.com/go-openapi/errors"
"github.com/go-openapi/runtime"
"github.com/go-openapi/runtime/middleware"
"github.com/tylerb/graceful"

"github.com/vmware/vic/lib/apiservers/service/restapi/operations"
)

// This file is safe to edit. Once it exists it will not be overwritten

//go:generate swagger generate server --target ../lib/apiservers/service --name --spec ../lib/apiservers/service/swagger.json --exclude-main

func configureFlags(api *operations.VicMachineAPI) {
// api.CommandLineOptionsGroups = []swag.CommandLineOptionsGroup{ ... }
}

func configureAPI(api *operations.VicMachineAPI) http.Handler {
// configure the api here
api.ServeError = errors.ServeError

// Set your custom logger if needed. Default one is log.Printf
// Expected interface func(string, ...interface{})
//
// Example:
// s.api.Logger = log.Printf

api.JSONConsumer = runtime.JSONConsumer()

api.JSONProducer = runtime.JSONProducer()

api.TxtProducer = runtime.TextProducer()

// Applies when the Authorization header is set with the Basic scheme
api.BasicAuth = func(user string, pass string) (interface{}, error) {
return nil, errors.NotImplemented("basic auth (basic) has not yet been implemented")
}

// GET /container
api.GetHandler = operations.GetHandlerFunc(func(params operations.GetParams) middleware.Responder {
return middleware.NotImplemented("operation .Get has not yet been implemented")
})

// GET /container/version
api.GetVersionHandler = operations.GetVersionHandlerFunc(func(params operations.GetVersionParams) middleware.Responder {
return middleware.NotImplemented("operation .GetVersion has not yet been implemented")
})

// POST /container/{target}
api.PostTargetHandler = operations.PostTargetHandlerFunc(func(params operations.PostTargetParams, principal interface{}) middleware.Responder {
return middleware.NotImplemented("operation .PostTarget has not yet been implemented")
})

// GET /container/{target}/vch
api.GetTargetVchHandler = operations.GetTargetVchHandlerFunc(func(params operations.GetTargetVchParams, principal interface{}) middleware.Responder {
return middleware.NotImplemented("operation .GetTargetVch has not yet been implemented")
})

// POST /container/{target}/vch
api.PostTargetVchHandler = operations.PostTargetVchHandlerFunc(func(params operations.PostTargetVchParams, principal interface{}) middleware.Responder {
return middleware.NotImplemented("operation .PostTargetVch has not yet been implemented")
})

// GET /container/{target}/vch/{vch-id}
api.GetTargetVchVchIDHandler = operations.GetTargetVchVchIDHandlerFunc(func(params operations.GetTargetVchVchIDParams, principal interface{}) middleware.Responder {
return middleware.NotImplemented("operation .GetTargetVchVchID has not yet been implemented")
})

// PUT /container/{target}/vch/{vch-id}
api.PutTargetVchVchIDHandler = operations.PutTargetVchVchIDHandlerFunc(func(params operations.PutTargetVchVchIDParams, principal interface{}) middleware.Responder {
return middleware.NotImplemented("operation .PutTargetVchVchID has not yet been implemented")
})

// PATCH /container/{target}/vch/{vch-id}
api.PatchTargetVchVchIDHandler = operations.PatchTargetVchVchIDHandlerFunc(func(params operations.PatchTargetVchVchIDParams, principal interface{}) middleware.Responder {
return middleware.NotImplemented("operation .PatchTargetVchVchID has not yet been implemented")
})

// POST /container/{target}/vch/{vch-id}
api.PostTargetVchVchIDHandler = operations.PostTargetVchVchIDHandlerFunc(func(params operations.PostTargetVchVchIDParams, principal interface{}) middleware.Responder {
return middleware.NotImplemented("operation .PostTargetVchVchID has not yet been implemented")
})

// DELETE /container/{target}/vch/{vch-id}
api.DeleteTargetVchVchIDHandler = operations.DeleteTargetVchVchIDHandlerFunc(func(params operations.DeleteTargetVchVchIDParams, principal interface{}) middleware.Responder {
return middleware.NotImplemented("operation .DeleteTargetVchVchID has not yet been implemented")
})

// POST /container/{target}/datacenter/{datacenter}
api.PostTargetDatacenterDatacenterHandler = operations.PostTargetDatacenterDatacenterHandlerFunc(func(params operations.PostTargetDatacenterDatacenterParams, principal interface{}) middleware.Responder {
return middleware.NotImplemented("operation .PostTargetDatacenterDatacenter has not yet been implemented")
})

// GET /container/{target}/datacenter/{datacenter}/vch
api.GetTargetVchVchIDHandler = operations.GetTargetVchVchIDHandlerFunc(func(params operations.GetTargetVchVchIDParams, principal interface{}) middleware.Responder {
return middleware.NotImplemented("operation .GetTargetVchVchID has not yet been implemented")
})

// POST /container/target/datacenter/{datacenter}/vch
api.PostTargetDatacenterDatacenterVchHandler = operations.PostTargetDatacenterDatacenterVchHandlerFunc(func(params operations.PostTargetDatacenterDatacenterVchParams, principal interface{}) middleware.Responder {
return middleware.NotImplemented("operation .PostTargetDatacenterDatacenterVch has not yet been implemented")
})

// GET /container/{target}/datacenter/{datacenter}/vch/{vch-id}
api.GetTargetDatacenterDatacenterVchVchIDHandler = operations.GetTargetDatacenterDatacenterVchVchIDHandlerFunc(func(params operations.GetTargetDatacenterDatacenterVchVchIDParams, principal interface{}) middleware.Responder {
return middleware.NotImplemented("operation .GetTargetDatacenterDatacenterVchVchID has not yet been implemented")
})

// PUT /container/{target}/datacenter/{datacenter}/vch/{vch-id}
api.PutTargetDatacenterDatacenterVchVchIDHandler = operations.PutTargetDatacenterDatacenterVchVchIDHandlerFunc(func(params operations.PutTargetDatacenterDatacenterVchVchIDParams, principal interface{}) middleware.Responder {
return middleware.NotImplemented("operation .PutTargetDatacenterDatacenterVchVchID has not yet been implemented")
})

// PATCH /container/{target}/datacenter/{datacenter}/vch/{vch-id}
api.PatchTargetDatacenterDatacenterVchVchIDHandler = operations.PatchTargetDatacenterDatacenterVchVchIDHandlerFunc(func(params operations.PatchTargetDatacenterDatacenterVchVchIDParams, principal interface{}) middleware.Responder {
return middleware.NotImplemented("operation .PatchTargetDatacenterDatacenterVchVchID has not yet been implemented")
})

// POST /container/{target}/datacenter/{datacenter}/vch/{vch-id}
api.PostTargetDatacenterDatacenterVchVchIDHandler = operations.PostTargetDatacenterDatacenterVchVchIDHandlerFunc(func(params operations.PostTargetDatacenterDatacenterVchVchIDParams, principal interface{}) middleware.Responder {
return middleware.NotImplemented("operation .PostTargetDatacenterDatacenterVchVchID has not yet been implemented")
})

// DELETE /container/{target}/datacenter/{datacenter}/vch/{vch-id}
api.DeleteTargetDatacenterDatacenterVchVchIDHandler = operations.DeleteTargetDatacenterDatacenterVchVchIDHandlerFunc(func(params operations.DeleteTargetDatacenterDatacenterVchVchIDParams, principal interface{}) middleware.Responder {
return middleware.NotImplemented("operation .DeleteTargetDatacenterDatacenterVchVchID has not yet been implemented")
})

api.ServerShutdown = func() {}

return setupGlobalMiddleware(api.Serve(setupMiddlewares))
}

// The TLS configuration before HTTPS server starts.
func configureTLS(tlsConfig *tls.Config) {
// Make all necessary changes to the TLS configuration here.
}

// As soon as server is initialized but not run yet, this function will be called.
// If you need to modify a config, store server instance to stop it individually later, this is the place.
// This function can be called multiple times, depending on the number of serving schemes.
// scheme value will be set accordingly: "http", "https" or "unix"
func configureServer(s *graceful.Server, scheme string) {
}

// The middleware configuration is for the handler executors. These do not apply to the swagger.json document.
// The middleware executes after routing but before authentication, binding and validation
func setupMiddlewares(handler http.Handler) http.Handler {
return handler
}

// The middleware configuration happens before anything, this middleware also applies to serving the swagger.json document.
// So this is a good place to plug in a panic handling middleware, logging and metrics
func setupGlobalMiddleware(handler http.Handler) http.Handler {
return handler
}
Loading

0 comments on commit beea9b2

Please sign in to comment.