allow share endpoint to return multiple frontends; more frontend selection (#110)

This commit is contained in:
Michael Quigley 2022-12-06 12:00:25 -05:00
parent 081a558ba2
commit a0c50c68e5
No known key found for this signature in database
GPG Key ID: 9B60314A9DD20A62
10 changed files with 134 additions and 28 deletions

View File

@ -42,6 +42,7 @@ type loopCmd struct {
maxDwellMs int
minPacingMs int
maxPacingMs int
frontendSelection []string
}
func newLoopCmd() *loopCmd {
@ -62,6 +63,7 @@ func newLoopCmd() *loopCmd {
cmd.Flags().IntVar(&r.maxDwellMs, "max-dwell-ms", 1000, "Maximum dwell time in milliseconds")
cmd.Flags().IntVar(&r.minPacingMs, "min-pacing-ms", 0, "Minimum pacing in milliseconds")
cmd.Flags().IntVar(&r.maxPacingMs, "max-pacing-ms", 0, "Maximum pacing in milliseconds")
cmd.Flags().StringArrayVar(&r.frontendSelection, "frontends", []string{"public"}, "Selected frontends to use for the share")
return r
}
@ -186,6 +188,7 @@ func (l *looper) startup() {
tunnelReq.Body = &rest_model_zrok.ShareRequest{
EnvZID: l.env.ZId,
ShareMode: "public",
FrontendSelection: l.cmd.frontendSelection,
BackendMode: "proxy",
BackendProxyEndpoint: fmt.Sprintf("looper#%d", l.id),
AuthScheme: string(model.None),
@ -196,7 +199,7 @@ func (l *looper) startup() {
panic(err)
}
l.service = tunnelResp.Payload.SvcToken
l.proxyEndpoint = tunnelResp.Payload.FrontendProxyEndpoint
l.proxyEndpoint = tunnelResp.Payload.FrontendProxyEndpoints[0]
}
func (l *looper) dwell() {

View File

@ -102,7 +102,7 @@ func (cmd *reserveCommand) run(_ *cobra.Command, args []string) {
}
logrus.Infof("your reserved service token is '%v'", resp.Payload.SvcToken)
if resp.Payload.FrontendProxyEndpoint != "" {
logrus.Infof("your reserved service frontend is '%v'", resp.Payload.FrontendProxyEndpoint)
for _, fpe := range resp.Payload.FrontendProxyEndpoints {
logrus.Infof("reserved frontend endpoint: %v", fpe)
}
}

View File

@ -166,7 +166,7 @@ func (self *sharePublicCommand) run(_ *cobra.Command, args []string) {
p := widgets.NewParagraph()
p.Border = true
p.Title = " access your zrok service "
p.Text = fmt.Sprintf("%v%v", strings.Repeat(" ", (((w-12)-len(resp.Payload.FrontendProxyEndpoint))/2)-1), resp.Payload.FrontendProxyEndpoint)
p.Text = fmt.Sprintf("%v%v", strings.Repeat(" ", (((w-12)-len(resp.Payload.FrontendProxyEndpoints[0]))/2)-1), resp.Payload.FrontendProxyEndpoints[0])
p.TextStyle = ui.Style{Fg: ui.ColorWhite}
p.PaddingTop = 1
p.SetRect(5, 5, w-10, 10)
@ -220,7 +220,7 @@ func (self *sharePublicCommand) run(_ *cobra.Command, args []string) {
}
}
} else {
logrus.Infof("access your zrok service: %v", resp.Payload.FrontendProxyEndpoint)
logrus.Infof("access your zrok service: %v", resp.Payload.FrontendProxyEndpoints[0])
for {
time.Sleep(30 * time.Second)
}

View File

@ -60,13 +60,18 @@ func (h *shareHandler) Handle(params service.ShareParams, principal *rest_model_
var frontendEndpoints []string
switch params.Body.ShareMode {
case "public":
if len(params.Body.FrontendSelection) < 1 {
logrus.Info("no frontend selection provided")
return service.NewShareNotFound()
}
var frontendZIds []string
var frontendTemplates []string
for _, frontendSelection := range params.Body.FrontendSelection {
sfe, err := str.FindFrontendPubliclyNamed(frontendSelection, tx)
if err != nil {
logrus.Error(err)
return service.NewUpdateShareNotFound()
return service.NewShareNotFound()
}
if sfe != nil && sfe.UrlTemplate != nil {
frontendZIds = append(frontendZIds, sfe.ZId)
@ -116,7 +121,7 @@ func (h *shareHandler) Handle(params service.ShareParams, principal *rest_model_
logrus.Infof("recorded service '%v' with id '%v' for '%v'", svcToken, sid, principal.Email)
return service.NewShareCreated().WithPayload(&rest_model_zrok.ShareResponse{
FrontendProxyEndpoint: frontendEndpoints[0],
FrontendProxyEndpoints: frontendEndpoints,
SvcToken: svcToken,
})
}

View File

@ -35,6 +35,12 @@ func (o *ShareReader) ReadResponse(response runtime.ClientResponse, consumer run
return nil, err
}
return nil, result
case 404:
result := NewShareNotFound()
if err := result.readResponse(response, consumer, o.formats); err != nil {
return nil, err
}
return nil, result
case 500:
result := NewShareInternalServerError()
if err := result.readResponse(response, consumer, o.formats); err != nil {
@ -160,6 +166,57 @@ func (o *ShareUnauthorized) readResponse(response runtime.ClientResponse, consum
return nil
}
// NewShareNotFound creates a ShareNotFound with default headers values
func NewShareNotFound() *ShareNotFound {
return &ShareNotFound{}
}
/*
ShareNotFound describes a response with status code 404, with default header values.
not found
*/
type ShareNotFound struct {
}
// IsSuccess returns true when this share not found response has a 2xx status code
func (o *ShareNotFound) IsSuccess() bool {
return false
}
// IsRedirect returns true when this share not found response has a 3xx status code
func (o *ShareNotFound) IsRedirect() bool {
return false
}
// IsClientError returns true when this share not found response has a 4xx status code
func (o *ShareNotFound) IsClientError() bool {
return true
}
// IsServerError returns true when this share not found response has a 5xx status code
func (o *ShareNotFound) IsServerError() bool {
return false
}
// IsCode returns true when this share not found response a status code equal to that given
func (o *ShareNotFound) IsCode(code int) bool {
return code == 404
}
func (o *ShareNotFound) Error() string {
return fmt.Sprintf("[POST /share][%d] shareNotFound ", 404)
}
func (o *ShareNotFound) String() string {
return fmt.Sprintf("[POST /share][%d] shareNotFound ", 404)
}
func (o *ShareNotFound) readResponse(response runtime.ClientResponse, consumer runtime.Consumer, formats strfmt.Registry) error {
return nil
}
// NewShareInternalServerError creates a ShareInternalServerError with default headers values
func NewShareInternalServerError() *ShareInternalServerError {
return &ShareInternalServerError{}

View File

@ -17,8 +17,8 @@ import (
// swagger:model shareResponse
type ShareResponse struct {
// frontend proxy endpoint
FrontendProxyEndpoint string `json:"frontendProxyEndpoint,omitempty"`
// frontend proxy endpoints
FrontendProxyEndpoints []string `json:"frontendProxyEndpoints"`
// svc token
SvcToken string `json:"svcToken,omitempty"`

View File

@ -463,6 +463,9 @@ func init() {
"401": {
"description": "unauthorized"
},
"404": {
"description": "not found"
},
"500": {
"description": "internal server error",
"schema": {
@ -967,8 +970,11 @@ func init() {
"shareResponse": {
"type": "object",
"properties": {
"frontendProxyEndpoint": {
"frontendProxyEndpoints": {
"type": "array",
"items": {
"type": "string"
}
},
"svcToken": {
"type": "string"
@ -1502,6 +1508,9 @@ func init() {
"401": {
"description": "unauthorized"
},
"404": {
"description": "not found"
},
"500": {
"description": "internal server error",
"schema": {
@ -2006,8 +2015,11 @@ func init() {
"shareResponse": {
"type": "object",
"properties": {
"frontendProxyEndpoint": {
"frontendProxyEndpoints": {
"type": "array",
"items": {
"type": "string"
}
},
"svcToken": {
"type": "string"

View File

@ -83,6 +83,31 @@ func (o *ShareUnauthorized) WriteResponse(rw http.ResponseWriter, producer runti
rw.WriteHeader(401)
}
// ShareNotFoundCode is the HTTP code returned for type ShareNotFound
const ShareNotFoundCode int = 404
/*
ShareNotFound not found
swagger:response shareNotFound
*/
type ShareNotFound struct {
}
// NewShareNotFound creates ShareNotFound with default headers values
func NewShareNotFound() *ShareNotFound {
return &ShareNotFound{}
}
// WriteResponse to the client
func (o *ShareNotFound) WriteResponse(rw http.ResponseWriter, producer runtime.Producer) {
rw.Header().Del(runtime.HeaderContentType) //Remove Content-Type on empty responses
rw.WriteHeader(404)
}
// ShareInternalServerErrorCode is the HTTP code returned for type ShareInternalServerError
const ShareInternalServerErrorCode int = 500

View File

@ -321,6 +321,8 @@ paths:
$ref: "#/definitions/shareResponse"
401:
description: unauthorized
404:
description: not found
500:
description: internal server error
schema:
@ -635,7 +637,9 @@ definitions:
shareResponse:
type: object
properties:
frontendProxyEndpoint:
frontendProxyEndpoints:
type: array
items:
type: string
svcToken:
type: string

View File

@ -186,7 +186,7 @@
* @typedef shareResponse
* @memberof module:types
*
* @property {string} frontendProxyEndpoint
* @property {string[]} frontendProxyEndpoints
* @property {string} svcToken
*/