diff --git a/cmd/zrok/loop.go b/cmd/zrok/loop.go index fbecdccf..8e3bc91b 100644 --- a/cmd/zrok/loop.go +++ b/cmd/zrok/loop.go @@ -31,17 +31,18 @@ func init() { } type loopCmd struct { - cmd *cobra.Command - loopers int - iterations int - statusEvery int - timeoutSeconds int - minPayload int - maxPayload int - minDwellMs int - maxDwellMs int - minPacingMs int - maxPacingMs int + cmd *cobra.Command + loopers int + iterations int + statusEvery int + timeoutSeconds int + minPayload int + maxPayload int + minDwellMs int + 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() { diff --git a/cmd/zrok/reserve.go b/cmd/zrok/reserve.go index 4bd88844..e515631c 100644 --- a/cmd/zrok/reserve.go +++ b/cmd/zrok/reserve.go @@ -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) } } diff --git a/cmd/zrok/share_public.go b/cmd/zrok/share_public.go index 7482c717..e7852e9f 100644 --- a/cmd/zrok/share_public.go +++ b/cmd/zrok/share_public.go @@ -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) } diff --git a/controller/share.go b/controller/share.go index 441c8a61..36e4c235 100644 --- a/controller/share.go +++ b/controller/share.go @@ -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], - SvcToken: svcToken, + FrontendProxyEndpoints: frontendEndpoints, + SvcToken: svcToken, }) } diff --git a/rest_client_zrok/service/share_responses.go b/rest_client_zrok/service/share_responses.go index 8aee1416..21023b35 100644 --- a/rest_client_zrok/service/share_responses.go +++ b/rest_client_zrok/service/share_responses.go @@ -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{} diff --git a/rest_model_zrok/share_response.go b/rest_model_zrok/share_response.go index cf6753e9..eb69f62e 100644 --- a/rest_model_zrok/share_response.go +++ b/rest_model_zrok/share_response.go @@ -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"` diff --git a/rest_server_zrok/embedded_spec.go b/rest_server_zrok/embedded_spec.go index c3cb4748..b0f3c1a9 100644 --- a/rest_server_zrok/embedded_spec.go +++ b/rest_server_zrok/embedded_spec.go @@ -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": { - "type": "string" + "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": { - "type": "string" + "frontendProxyEndpoints": { + "type": "array", + "items": { + "type": "string" + } }, "svcToken": { "type": "string" diff --git a/rest_server_zrok/operations/service/share_responses.go b/rest_server_zrok/operations/service/share_responses.go index cbb46a14..559f4f33 100644 --- a/rest_server_zrok/operations/service/share_responses.go +++ b/rest_server_zrok/operations/service/share_responses.go @@ -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 diff --git a/specs/zrok.yml b/specs/zrok.yml index c4ec920f..58fb6ba8 100644 --- a/specs/zrok.yml +++ b/specs/zrok.yml @@ -321,6 +321,8 @@ paths: $ref: "#/definitions/shareResponse" 401: description: unauthorized + 404: + description: not found 500: description: internal server error schema: @@ -635,8 +637,10 @@ definitions: shareResponse: type: object properties: - frontendProxyEndpoint: - type: string + frontendProxyEndpoints: + type: array + items: + type: string svcToken: type: string diff --git a/ui/src/api/types.js b/ui/src/api/types.js index 7a735966..d8263f6c 100644 --- a/ui/src/api/types.js +++ b/ui/src/api/types.js @@ -186,7 +186,7 @@ * @typedef shareResponse * @memberof module:types * - * @property {string} frontendProxyEndpoint + * @property {string[]} frontendProxyEndpoints * @property {string} svcToken */