diff --git a/controller/controller.go b/controller/controller.go index 70af7b81..15288e3b 100644 --- a/controller/controller.go +++ b/controller/controller.go @@ -54,6 +54,7 @@ func Run(inCfg *config.Config) error { api.MetadataGetShareMetricsHandler = newGetShareMetricsHandler(cfg.Metrics.Influx) } api.MetadataGetEnvironmentDetailHandler = newEnvironmentDetailHandler() + api.MetadataGetFrontendDetailHandler = newGetFrontendDetailHandler() api.MetadataGetShareDetailHandler = newShareDetailHandler() api.MetadataOverviewHandler = newOverviewHandler() api.MetadataVersionHandler = metadata.VersionHandlerFunc(versionHandler) diff --git a/controller/frontendDetail.go b/controller/frontendDetail.go new file mode 100644 index 00000000..aca79322 --- /dev/null +++ b/controller/frontendDetail.go @@ -0,0 +1,60 @@ +package controller + +import ( + "github.com/go-openapi/runtime/middleware" + "github.com/openziti/zrok/rest_model_zrok" + "github.com/openziti/zrok/rest_server_zrok/operations/metadata" + "github.com/sirupsen/logrus" +) + +type getFrontendDetailHandler struct{} + +func newGetFrontendDetailHandler() *getFrontendDetailHandler { + return &getFrontendDetailHandler{} +} + +func (h *getFrontendDetailHandler) Handle(params metadata.GetFrontendDetailParams, principal *rest_model_zrok.Principal) middleware.Responder { + trx, err := str.Begin() + if err != nil { + logrus.Errorf("error starting transaction: %v", err) + return metadata.NewGetFrontendDetailInternalServerError() + } + defer func() { _ = trx.Rollback() }() + fe, err := str.GetFrontend(int(params.FeID), trx) + if err != nil { + logrus.Errorf("error finding share '%d': %v", params.FeID, err) + return metadata.NewGetFrontendDetailNotFound() + } + envs, err := str.FindEnvironmentsForAccount(int(principal.ID), trx) + if err != nil { + logrus.Errorf("error finding environments for account '%v': %v", principal.Email, err) + return metadata.NewGetFrontendDetailInternalServerError() + } + found := false + if fe.EnvironmentId == nil { + logrus.Errorf("non owned environment '%d' for '%v'", fe.Id, principal.Email) + return metadata.NewGetFrontendDetailNotFound() + } + for _, env := range envs { + if *fe.EnvironmentId == env.Id { + found = true + break + } + } + if !found { + logrus.Errorf("environment not matched for frontend '%d' for account '%v'", fe.Id, principal.Email) + return metadata.NewGetFrontendDetailNotFound() + } + shr, err := str.GetShare(fe.Id, trx) + if err != nil { + logrus.Errorf("error getting share for frontend '%d': %v", fe.Id, err) + return metadata.NewGetFrontendDetailInternalServerError() + } + return metadata.NewGetFrontendDetailOK().WithPayload(&rest_model_zrok.Frontend{ + ID: int64(fe.Id), + ShrToken: shr.Token, + ZID: fe.ZId, + CreatedAt: fe.CreatedAt.UnixMilli(), + UpdatedAt: fe.UpdatedAt.UnixMilli(), + }) +} diff --git a/rest_client_zrok/metadata/get_frontend_detail_parameters.go b/rest_client_zrok/metadata/get_frontend_detail_parameters.go new file mode 100644 index 00000000..4ce868af --- /dev/null +++ b/rest_client_zrok/metadata/get_frontend_detail_parameters.go @@ -0,0 +1,149 @@ +// Code generated by go-swagger; DO NOT EDIT. + +package metadata + +// This file was generated by the swagger tool. +// Editing this file might prove futile when you re-run the swagger generate command + +import ( + "context" + "net/http" + "time" + + "github.com/go-openapi/errors" + "github.com/go-openapi/runtime" + cr "github.com/go-openapi/runtime/client" + "github.com/go-openapi/strfmt" + "github.com/go-openapi/swag" +) + +// NewGetFrontendDetailParams creates a new GetFrontendDetailParams object, +// with the default timeout for this client. +// +// Default values are not hydrated, since defaults are normally applied by the API server side. +// +// To enforce default values in parameter, use SetDefaults or WithDefaults. +func NewGetFrontendDetailParams() *GetFrontendDetailParams { + return &GetFrontendDetailParams{ + timeout: cr.DefaultTimeout, + } +} + +// NewGetFrontendDetailParamsWithTimeout creates a new GetFrontendDetailParams object +// with the ability to set a timeout on a request. +func NewGetFrontendDetailParamsWithTimeout(timeout time.Duration) *GetFrontendDetailParams { + return &GetFrontendDetailParams{ + timeout: timeout, + } +} + +// NewGetFrontendDetailParamsWithContext creates a new GetFrontendDetailParams object +// with the ability to set a context for a request. +func NewGetFrontendDetailParamsWithContext(ctx context.Context) *GetFrontendDetailParams { + return &GetFrontendDetailParams{ + Context: ctx, + } +} + +// NewGetFrontendDetailParamsWithHTTPClient creates a new GetFrontendDetailParams object +// with the ability to set a custom HTTPClient for a request. +func NewGetFrontendDetailParamsWithHTTPClient(client *http.Client) *GetFrontendDetailParams { + return &GetFrontendDetailParams{ + HTTPClient: client, + } +} + +/* +GetFrontendDetailParams contains all the parameters to send to the API endpoint + + for the get frontend detail operation. + + Typically these are written to a http.Request. +*/ +type GetFrontendDetailParams struct { + + // FeID. + FeID int64 + + timeout time.Duration + Context context.Context + HTTPClient *http.Client +} + +// WithDefaults hydrates default values in the get frontend detail params (not the query body). +// +// All values with no default are reset to their zero value. +func (o *GetFrontendDetailParams) WithDefaults() *GetFrontendDetailParams { + o.SetDefaults() + return o +} + +// SetDefaults hydrates default values in the get frontend detail params (not the query body). +// +// All values with no default are reset to their zero value. +func (o *GetFrontendDetailParams) SetDefaults() { + // no default values defined for this parameter +} + +// WithTimeout adds the timeout to the get frontend detail params +func (o *GetFrontendDetailParams) WithTimeout(timeout time.Duration) *GetFrontendDetailParams { + o.SetTimeout(timeout) + return o +} + +// SetTimeout adds the timeout to the get frontend detail params +func (o *GetFrontendDetailParams) SetTimeout(timeout time.Duration) { + o.timeout = timeout +} + +// WithContext adds the context to the get frontend detail params +func (o *GetFrontendDetailParams) WithContext(ctx context.Context) *GetFrontendDetailParams { + o.SetContext(ctx) + return o +} + +// SetContext adds the context to the get frontend detail params +func (o *GetFrontendDetailParams) SetContext(ctx context.Context) { + o.Context = ctx +} + +// WithHTTPClient adds the HTTPClient to the get frontend detail params +func (o *GetFrontendDetailParams) WithHTTPClient(client *http.Client) *GetFrontendDetailParams { + o.SetHTTPClient(client) + return o +} + +// SetHTTPClient adds the HTTPClient to the get frontend detail params +func (o *GetFrontendDetailParams) SetHTTPClient(client *http.Client) { + o.HTTPClient = client +} + +// WithFeID adds the feID to the get frontend detail params +func (o *GetFrontendDetailParams) WithFeID(feID int64) *GetFrontendDetailParams { + o.SetFeID(feID) + return o +} + +// SetFeID adds the feId to the get frontend detail params +func (o *GetFrontendDetailParams) SetFeID(feID int64) { + o.FeID = feID +} + +// WriteToRequest writes these params to a swagger request +func (o *GetFrontendDetailParams) WriteToRequest(r runtime.ClientRequest, reg strfmt.Registry) error { + + if err := r.SetTimeout(o.timeout); err != nil { + return err + } + var res []error + + // path param feId + if err := r.SetPathParam("feId", swag.FormatInt64(o.FeID)); err != nil { + return err + } + + if len(res) > 0 { + return errors.CompositeValidationError(res...) + } + return nil +} diff --git a/rest_client_zrok/metadata/get_frontend_detail_responses.go b/rest_client_zrok/metadata/get_frontend_detail_responses.go new file mode 100644 index 00000000..90058d0b --- /dev/null +++ b/rest_client_zrok/metadata/get_frontend_detail_responses.go @@ -0,0 +1,269 @@ +// Code generated by go-swagger; DO NOT EDIT. + +package metadata + +// This file was generated by the swagger tool. +// Editing this file might prove futile when you re-run the swagger generate command + +import ( + "fmt" + "io" + + "github.com/go-openapi/runtime" + "github.com/go-openapi/strfmt" + + "github.com/openziti/zrok/rest_model_zrok" +) + +// GetFrontendDetailReader is a Reader for the GetFrontendDetail structure. +type GetFrontendDetailReader struct { + formats strfmt.Registry +} + +// ReadResponse reads a server response into the received o. +func (o *GetFrontendDetailReader) ReadResponse(response runtime.ClientResponse, consumer runtime.Consumer) (interface{}, error) { + switch response.Code() { + case 200: + result := NewGetFrontendDetailOK() + if err := result.readResponse(response, consumer, o.formats); err != nil { + return nil, err + } + return result, nil + case 401: + result := NewGetFrontendDetailUnauthorized() + if err := result.readResponse(response, consumer, o.formats); err != nil { + return nil, err + } + return nil, result + case 404: + result := NewGetFrontendDetailNotFound() + if err := result.readResponse(response, consumer, o.formats); err != nil { + return nil, err + } + return nil, result + case 500: + result := NewGetFrontendDetailInternalServerError() + if err := result.readResponse(response, consumer, o.formats); err != nil { + return nil, err + } + return nil, result + default: + return nil, runtime.NewAPIError("response status code does not match any response statuses defined for this endpoint in the swagger spec", response, response.Code()) + } +} + +// NewGetFrontendDetailOK creates a GetFrontendDetailOK with default headers values +func NewGetFrontendDetailOK() *GetFrontendDetailOK { + return &GetFrontendDetailOK{} +} + +/* +GetFrontendDetailOK describes a response with status code 200, with default header values. + +ok +*/ +type GetFrontendDetailOK struct { + Payload *rest_model_zrok.Frontend +} + +// IsSuccess returns true when this get frontend detail o k response has a 2xx status code +func (o *GetFrontendDetailOK) IsSuccess() bool { + return true +} + +// IsRedirect returns true when this get frontend detail o k response has a 3xx status code +func (o *GetFrontendDetailOK) IsRedirect() bool { + return false +} + +// IsClientError returns true when this get frontend detail o k response has a 4xx status code +func (o *GetFrontendDetailOK) IsClientError() bool { + return false +} + +// IsServerError returns true when this get frontend detail o k response has a 5xx status code +func (o *GetFrontendDetailOK) IsServerError() bool { + return false +} + +// IsCode returns true when this get frontend detail o k response a status code equal to that given +func (o *GetFrontendDetailOK) IsCode(code int) bool { + return code == 200 +} + +func (o *GetFrontendDetailOK) Error() string { + return fmt.Sprintf("[GET /detail/frontend/{feId}][%d] getFrontendDetailOK %+v", 200, o.Payload) +} + +func (o *GetFrontendDetailOK) String() string { + return fmt.Sprintf("[GET /detail/frontend/{feId}][%d] getFrontendDetailOK %+v", 200, o.Payload) +} + +func (o *GetFrontendDetailOK) GetPayload() *rest_model_zrok.Frontend { + return o.Payload +} + +func (o *GetFrontendDetailOK) readResponse(response runtime.ClientResponse, consumer runtime.Consumer, formats strfmt.Registry) error { + + o.Payload = new(rest_model_zrok.Frontend) + + // response payload + if err := consumer.Consume(response.Body(), o.Payload); err != nil && err != io.EOF { + return err + } + + return nil +} + +// NewGetFrontendDetailUnauthorized creates a GetFrontendDetailUnauthorized with default headers values +func NewGetFrontendDetailUnauthorized() *GetFrontendDetailUnauthorized { + return &GetFrontendDetailUnauthorized{} +} + +/* +GetFrontendDetailUnauthorized describes a response with status code 401, with default header values. + +unauthorized +*/ +type GetFrontendDetailUnauthorized struct { +} + +// IsSuccess returns true when this get frontend detail unauthorized response has a 2xx status code +func (o *GetFrontendDetailUnauthorized) IsSuccess() bool { + return false +} + +// IsRedirect returns true when this get frontend detail unauthorized response has a 3xx status code +func (o *GetFrontendDetailUnauthorized) IsRedirect() bool { + return false +} + +// IsClientError returns true when this get frontend detail unauthorized response has a 4xx status code +func (o *GetFrontendDetailUnauthorized) IsClientError() bool { + return true +} + +// IsServerError returns true when this get frontend detail unauthorized response has a 5xx status code +func (o *GetFrontendDetailUnauthorized) IsServerError() bool { + return false +} + +// IsCode returns true when this get frontend detail unauthorized response a status code equal to that given +func (o *GetFrontendDetailUnauthorized) IsCode(code int) bool { + return code == 401 +} + +func (o *GetFrontendDetailUnauthorized) Error() string { + return fmt.Sprintf("[GET /detail/frontend/{feId}][%d] getFrontendDetailUnauthorized ", 401) +} + +func (o *GetFrontendDetailUnauthorized) String() string { + return fmt.Sprintf("[GET /detail/frontend/{feId}][%d] getFrontendDetailUnauthorized ", 401) +} + +func (o *GetFrontendDetailUnauthorized) readResponse(response runtime.ClientResponse, consumer runtime.Consumer, formats strfmt.Registry) error { + + return nil +} + +// NewGetFrontendDetailNotFound creates a GetFrontendDetailNotFound with default headers values +func NewGetFrontendDetailNotFound() *GetFrontendDetailNotFound { + return &GetFrontendDetailNotFound{} +} + +/* +GetFrontendDetailNotFound describes a response with status code 404, with default header values. + +not found +*/ +type GetFrontendDetailNotFound struct { +} + +// IsSuccess returns true when this get frontend detail not found response has a 2xx status code +func (o *GetFrontendDetailNotFound) IsSuccess() bool { + return false +} + +// IsRedirect returns true when this get frontend detail not found response has a 3xx status code +func (o *GetFrontendDetailNotFound) IsRedirect() bool { + return false +} + +// IsClientError returns true when this get frontend detail not found response has a 4xx status code +func (o *GetFrontendDetailNotFound) IsClientError() bool { + return true +} + +// IsServerError returns true when this get frontend detail not found response has a 5xx status code +func (o *GetFrontendDetailNotFound) IsServerError() bool { + return false +} + +// IsCode returns true when this get frontend detail not found response a status code equal to that given +func (o *GetFrontendDetailNotFound) IsCode(code int) bool { + return code == 404 +} + +func (o *GetFrontendDetailNotFound) Error() string { + return fmt.Sprintf("[GET /detail/frontend/{feId}][%d] getFrontendDetailNotFound ", 404) +} + +func (o *GetFrontendDetailNotFound) String() string { + return fmt.Sprintf("[GET /detail/frontend/{feId}][%d] getFrontendDetailNotFound ", 404) +} + +func (o *GetFrontendDetailNotFound) readResponse(response runtime.ClientResponse, consumer runtime.Consumer, formats strfmt.Registry) error { + + return nil +} + +// NewGetFrontendDetailInternalServerError creates a GetFrontendDetailInternalServerError with default headers values +func NewGetFrontendDetailInternalServerError() *GetFrontendDetailInternalServerError { + return &GetFrontendDetailInternalServerError{} +} + +/* +GetFrontendDetailInternalServerError describes a response with status code 500, with default header values. + +internal server error +*/ +type GetFrontendDetailInternalServerError struct { +} + +// IsSuccess returns true when this get frontend detail internal server error response has a 2xx status code +func (o *GetFrontendDetailInternalServerError) IsSuccess() bool { + return false +} + +// IsRedirect returns true when this get frontend detail internal server error response has a 3xx status code +func (o *GetFrontendDetailInternalServerError) IsRedirect() bool { + return false +} + +// IsClientError returns true when this get frontend detail internal server error response has a 4xx status code +func (o *GetFrontendDetailInternalServerError) IsClientError() bool { + return false +} + +// IsServerError returns true when this get frontend detail internal server error response has a 5xx status code +func (o *GetFrontendDetailInternalServerError) IsServerError() bool { + return true +} + +// IsCode returns true when this get frontend detail internal server error response a status code equal to that given +func (o *GetFrontendDetailInternalServerError) IsCode(code int) bool { + return code == 500 +} + +func (o *GetFrontendDetailInternalServerError) Error() string { + return fmt.Sprintf("[GET /detail/frontend/{feId}][%d] getFrontendDetailInternalServerError ", 500) +} + +func (o *GetFrontendDetailInternalServerError) String() string { + return fmt.Sprintf("[GET /detail/frontend/{feId}][%d] getFrontendDetailInternalServerError ", 500) +} + +func (o *GetFrontendDetailInternalServerError) readResponse(response runtime.ClientResponse, consumer runtime.Consumer, formats strfmt.Registry) error { + + return nil +} diff --git a/rest_client_zrok/metadata/metadata_client.go b/rest_client_zrok/metadata/metadata_client.go index 764216b3..194736ee 100644 --- a/rest_client_zrok/metadata/metadata_client.go +++ b/rest_client_zrok/metadata/metadata_client.go @@ -40,6 +40,8 @@ type ClientService interface { GetEnvironmentMetrics(params *GetEnvironmentMetricsParams, authInfo runtime.ClientAuthInfoWriter, opts ...ClientOption) (*GetEnvironmentMetricsOK, error) + GetFrontendDetail(params *GetFrontendDetailParams, authInfo runtime.ClientAuthInfoWriter, opts ...ClientOption) (*GetFrontendDetailOK, error) + GetShareDetail(params *GetShareDetailParams, authInfo runtime.ClientAuthInfoWriter, opts ...ClientOption) (*GetShareDetailOK, error) GetShareMetrics(params *GetShareMetricsParams, authInfo runtime.ClientAuthInfoWriter, opts ...ClientOption) (*GetShareMetricsOK, error) @@ -245,6 +247,45 @@ func (a *Client) GetEnvironmentMetrics(params *GetEnvironmentMetricsParams, auth panic(msg) } +/* +GetFrontendDetail get frontend detail API +*/ +func (a *Client) GetFrontendDetail(params *GetFrontendDetailParams, authInfo runtime.ClientAuthInfoWriter, opts ...ClientOption) (*GetFrontendDetailOK, error) { + // TODO: Validate the params before sending + if params == nil { + params = NewGetFrontendDetailParams() + } + op := &runtime.ClientOperation{ + ID: "getFrontendDetail", + Method: "GET", + PathPattern: "/detail/frontend/{feId}", + ProducesMediaTypes: []string{"application/zrok.v1+json"}, + ConsumesMediaTypes: []string{"application/zrok.v1+json"}, + Schemes: []string{"http"}, + Params: params, + Reader: &GetFrontendDetailReader{formats: a.formats}, + AuthInfo: authInfo, + Context: params.Context, + Client: params.HTTPClient, + } + for _, opt := range opts { + opt(op) + } + + result, err := a.transport.Submit(op) + if err != nil { + return nil, err + } + success, ok := result.(*GetFrontendDetailOK) + if ok { + return success, nil + } + // unexpected success response + // safeguard: normally, absent a default response, unknown success responses return an error above: so this is a codegen issue + msg := fmt.Sprintf("unexpected success response for getFrontendDetail: API contract not enforced by server. Client expected to get an error, but got: %T", result) + panic(msg) +} + /* GetShareDetail get share detail API */ diff --git a/rest_server_zrok/embedded_spec.go b/rest_server_zrok/embedded_spec.go index 40dd52ea..bb04abd4 100644 --- a/rest_server_zrok/embedded_spec.go +++ b/rest_server_zrok/embedded_spec.go @@ -152,6 +152,44 @@ func init() { } } }, + "/detail/frontend/{feId}": { + "get": { + "security": [ + { + "key": [] + } + ], + "tags": [ + "metadata" + ], + "operationId": "getFrontendDetail", + "parameters": [ + { + "type": "integer", + "name": "feId", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "ok", + "schema": { + "$ref": "#/definitions/frontend" + } + }, + "401": { + "description": "unauthorized" + }, + "404": { + "description": "not found" + }, + "500": { + "description": "internal server error" + } + } + } + }, "/detail/share/{shrToken}": { "get": { "security": [ @@ -1666,6 +1704,44 @@ func init() { } } }, + "/detail/frontend/{feId}": { + "get": { + "security": [ + { + "key": [] + } + ], + "tags": [ + "metadata" + ], + "operationId": "getFrontendDetail", + "parameters": [ + { + "type": "integer", + "name": "feId", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "ok", + "schema": { + "$ref": "#/definitions/frontend" + } + }, + "401": { + "description": "unauthorized" + }, + "404": { + "description": "not found" + }, + "500": { + "description": "internal server error" + } + } + } + }, "/detail/share/{shrToken}": { "get": { "security": [ diff --git a/rest_server_zrok/operations/metadata/get_frontend_detail.go b/rest_server_zrok/operations/metadata/get_frontend_detail.go new file mode 100644 index 00000000..c532c8f1 --- /dev/null +++ b/rest_server_zrok/operations/metadata/get_frontend_detail.go @@ -0,0 +1,71 @@ +// Code generated by go-swagger; DO NOT EDIT. + +package metadata + +// This file was generated by the swagger tool. +// Editing this file might prove futile when you re-run the generate command + +import ( + "net/http" + + "github.com/go-openapi/runtime/middleware" + + "github.com/openziti/zrok/rest_model_zrok" +) + +// GetFrontendDetailHandlerFunc turns a function with the right signature into a get frontend detail handler +type GetFrontendDetailHandlerFunc func(GetFrontendDetailParams, *rest_model_zrok.Principal) middleware.Responder + +// Handle executing the request and returning a response +func (fn GetFrontendDetailHandlerFunc) Handle(params GetFrontendDetailParams, principal *rest_model_zrok.Principal) middleware.Responder { + return fn(params, principal) +} + +// GetFrontendDetailHandler interface for that can handle valid get frontend detail params +type GetFrontendDetailHandler interface { + Handle(GetFrontendDetailParams, *rest_model_zrok.Principal) middleware.Responder +} + +// NewGetFrontendDetail creates a new http.Handler for the get frontend detail operation +func NewGetFrontendDetail(ctx *middleware.Context, handler GetFrontendDetailHandler) *GetFrontendDetail { + return &GetFrontendDetail{Context: ctx, Handler: handler} +} + +/* + GetFrontendDetail swagger:route GET /detail/frontend/{feId} metadata getFrontendDetail + +GetFrontendDetail get frontend detail API +*/ +type GetFrontendDetail struct { + Context *middleware.Context + Handler GetFrontendDetailHandler +} + +func (o *GetFrontendDetail) ServeHTTP(rw http.ResponseWriter, r *http.Request) { + route, rCtx, _ := o.Context.RouteInfo(r) + if rCtx != nil { + *r = *rCtx + } + var Params = NewGetFrontendDetailParams() + uprinc, aCtx, err := o.Context.Authorize(r, route) + if err != nil { + o.Context.Respond(rw, r, route.Produces, route, err) + return + } + if aCtx != nil { + *r = *aCtx + } + var principal *rest_model_zrok.Principal + if uprinc != nil { + principal = uprinc.(*rest_model_zrok.Principal) // this is really a rest_model_zrok.Principal, I promise + } + + if err := o.Context.BindValidRequest(r, route, &Params); err != nil { // bind params + o.Context.Respond(rw, r, route.Produces, route, err) + return + } + + res := o.Handler.Handle(Params, principal) // actually handle the request + o.Context.Respond(rw, r, route.Produces, route, res) + +} diff --git a/rest_server_zrok/operations/metadata/get_frontend_detail_parameters.go b/rest_server_zrok/operations/metadata/get_frontend_detail_parameters.go new file mode 100644 index 00000000..14263c9c --- /dev/null +++ b/rest_server_zrok/operations/metadata/get_frontend_detail_parameters.go @@ -0,0 +1,77 @@ +// Code generated by go-swagger; DO NOT EDIT. + +package metadata + +// This file was generated by the swagger tool. +// Editing this file might prove futile when you re-run the swagger generate command + +import ( + "net/http" + + "github.com/go-openapi/errors" + "github.com/go-openapi/runtime/middleware" + "github.com/go-openapi/strfmt" + "github.com/go-openapi/swag" +) + +// NewGetFrontendDetailParams creates a new GetFrontendDetailParams object +// +// There are no default values defined in the spec. +func NewGetFrontendDetailParams() GetFrontendDetailParams { + + return GetFrontendDetailParams{} +} + +// GetFrontendDetailParams contains all the bound params for the get frontend detail operation +// typically these are obtained from a http.Request +// +// swagger:parameters getFrontendDetail +type GetFrontendDetailParams struct { + + // HTTP Request Object + HTTPRequest *http.Request `json:"-"` + + /* + Required: true + In: path + */ + FeID int64 +} + +// BindRequest both binds and validates a request, it assumes that complex things implement a Validatable(strfmt.Registry) error interface +// for simple values it will use straight method calls. +// +// To ensure default values, the struct must have been initialized with NewGetFrontendDetailParams() beforehand. +func (o *GetFrontendDetailParams) BindRequest(r *http.Request, route *middleware.MatchedRoute) error { + var res []error + + o.HTTPRequest = r + + rFeID, rhkFeID, _ := route.Params.GetOK("feId") + if err := o.bindFeID(rFeID, rhkFeID, route.Formats); err != nil { + res = append(res, err) + } + if len(res) > 0 { + return errors.CompositeValidationError(res...) + } + return nil +} + +// bindFeID binds and validates parameter FeID from path. +func (o *GetFrontendDetailParams) bindFeID(rawData []string, hasKey bool, formats strfmt.Registry) error { + var raw string + if len(rawData) > 0 { + raw = rawData[len(rawData)-1] + } + + // Required: true + // Parameter is provided by construction from the route + + value, err := swag.ConvertInt64(raw) + if err != nil { + return errors.InvalidType("feId", "path", "int64", raw) + } + o.FeID = value + + return nil +} diff --git a/rest_server_zrok/operations/metadata/get_frontend_detail_responses.go b/rest_server_zrok/operations/metadata/get_frontend_detail_responses.go new file mode 100644 index 00000000..538cc9bf --- /dev/null +++ b/rest_server_zrok/operations/metadata/get_frontend_detail_responses.go @@ -0,0 +1,134 @@ +// Code generated by go-swagger; DO NOT EDIT. + +package metadata + +// This file was generated by the swagger tool. +// Editing this file might prove futile when you re-run the swagger generate command + +import ( + "net/http" + + "github.com/go-openapi/runtime" + + "github.com/openziti/zrok/rest_model_zrok" +) + +// GetFrontendDetailOKCode is the HTTP code returned for type GetFrontendDetailOK +const GetFrontendDetailOKCode int = 200 + +/* +GetFrontendDetailOK ok + +swagger:response getFrontendDetailOK +*/ +type GetFrontendDetailOK struct { + + /* + In: Body + */ + Payload *rest_model_zrok.Frontend `json:"body,omitempty"` +} + +// NewGetFrontendDetailOK creates GetFrontendDetailOK with default headers values +func NewGetFrontendDetailOK() *GetFrontendDetailOK { + + return &GetFrontendDetailOK{} +} + +// WithPayload adds the payload to the get frontend detail o k response +func (o *GetFrontendDetailOK) WithPayload(payload *rest_model_zrok.Frontend) *GetFrontendDetailOK { + o.Payload = payload + return o +} + +// SetPayload sets the payload to the get frontend detail o k response +func (o *GetFrontendDetailOK) SetPayload(payload *rest_model_zrok.Frontend) { + o.Payload = payload +} + +// WriteResponse to the client +func (o *GetFrontendDetailOK) WriteResponse(rw http.ResponseWriter, producer runtime.Producer) { + + rw.WriteHeader(200) + if o.Payload != nil { + payload := o.Payload + if err := producer.Produce(rw, payload); err != nil { + panic(err) // let the recovery middleware deal with this + } + } +} + +// GetFrontendDetailUnauthorizedCode is the HTTP code returned for type GetFrontendDetailUnauthorized +const GetFrontendDetailUnauthorizedCode int = 401 + +/* +GetFrontendDetailUnauthorized unauthorized + +swagger:response getFrontendDetailUnauthorized +*/ +type GetFrontendDetailUnauthorized struct { +} + +// NewGetFrontendDetailUnauthorized creates GetFrontendDetailUnauthorized with default headers values +func NewGetFrontendDetailUnauthorized() *GetFrontendDetailUnauthorized { + + return &GetFrontendDetailUnauthorized{} +} + +// WriteResponse to the client +func (o *GetFrontendDetailUnauthorized) WriteResponse(rw http.ResponseWriter, producer runtime.Producer) { + + rw.Header().Del(runtime.HeaderContentType) //Remove Content-Type on empty responses + + rw.WriteHeader(401) +} + +// GetFrontendDetailNotFoundCode is the HTTP code returned for type GetFrontendDetailNotFound +const GetFrontendDetailNotFoundCode int = 404 + +/* +GetFrontendDetailNotFound not found + +swagger:response getFrontendDetailNotFound +*/ +type GetFrontendDetailNotFound struct { +} + +// NewGetFrontendDetailNotFound creates GetFrontendDetailNotFound with default headers values +func NewGetFrontendDetailNotFound() *GetFrontendDetailNotFound { + + return &GetFrontendDetailNotFound{} +} + +// WriteResponse to the client +func (o *GetFrontendDetailNotFound) WriteResponse(rw http.ResponseWriter, producer runtime.Producer) { + + rw.Header().Del(runtime.HeaderContentType) //Remove Content-Type on empty responses + + rw.WriteHeader(404) +} + +// GetFrontendDetailInternalServerErrorCode is the HTTP code returned for type GetFrontendDetailInternalServerError +const GetFrontendDetailInternalServerErrorCode int = 500 + +/* +GetFrontendDetailInternalServerError internal server error + +swagger:response getFrontendDetailInternalServerError +*/ +type GetFrontendDetailInternalServerError struct { +} + +// NewGetFrontendDetailInternalServerError creates GetFrontendDetailInternalServerError with default headers values +func NewGetFrontendDetailInternalServerError() *GetFrontendDetailInternalServerError { + + return &GetFrontendDetailInternalServerError{} +} + +// WriteResponse to the client +func (o *GetFrontendDetailInternalServerError) WriteResponse(rw http.ResponseWriter, producer runtime.Producer) { + + rw.Header().Del(runtime.HeaderContentType) //Remove Content-Type on empty responses + + rw.WriteHeader(500) +} diff --git a/rest_server_zrok/operations/metadata/get_frontend_detail_urlbuilder.go b/rest_server_zrok/operations/metadata/get_frontend_detail_urlbuilder.go new file mode 100644 index 00000000..ec2a9784 --- /dev/null +++ b/rest_server_zrok/operations/metadata/get_frontend_detail_urlbuilder.go @@ -0,0 +1,101 @@ +// Code generated by go-swagger; DO NOT EDIT. + +package metadata + +// This file was generated by the swagger tool. +// Editing this file might prove futile when you re-run the generate command + +import ( + "errors" + "net/url" + golangswaggerpaths "path" + "strings" + + "github.com/go-openapi/swag" +) + +// GetFrontendDetailURL generates an URL for the get frontend detail operation +type GetFrontendDetailURL struct { + FeID int64 + + _basePath string + // avoid unkeyed usage + _ struct{} +} + +// WithBasePath sets the base path for this url builder, only required when it's different from the +// base path specified in the swagger spec. +// When the value of the base path is an empty string +func (o *GetFrontendDetailURL) WithBasePath(bp string) *GetFrontendDetailURL { + o.SetBasePath(bp) + return o +} + +// SetBasePath sets the base path for this url builder, only required when it's different from the +// base path specified in the swagger spec. +// When the value of the base path is an empty string +func (o *GetFrontendDetailURL) SetBasePath(bp string) { + o._basePath = bp +} + +// Build a url path and query string +func (o *GetFrontendDetailURL) Build() (*url.URL, error) { + var _result url.URL + + var _path = "/detail/frontend/{feId}" + + feID := swag.FormatInt64(o.FeID) + if feID != "" { + _path = strings.Replace(_path, "{feId}", feID, -1) + } else { + return nil, errors.New("feId is required on GetFrontendDetailURL") + } + + _basePath := o._basePath + if _basePath == "" { + _basePath = "/api/v1" + } + _result.Path = golangswaggerpaths.Join(_basePath, _path) + + return &_result, nil +} + +// Must is a helper function to panic when the url builder returns an error +func (o *GetFrontendDetailURL) Must(u *url.URL, err error) *url.URL { + if err != nil { + panic(err) + } + if u == nil { + panic("url can't be nil") + } + return u +} + +// String returns the string representation of the path with query string +func (o *GetFrontendDetailURL) String() string { + return o.Must(o.Build()).String() +} + +// BuildFull builds a full url with scheme, host, path and query string +func (o *GetFrontendDetailURL) BuildFull(scheme, host string) (*url.URL, error) { + if scheme == "" { + return nil, errors.New("scheme is required for a full url on GetFrontendDetailURL") + } + if host == "" { + return nil, errors.New("host is required for a full url on GetFrontendDetailURL") + } + + base, err := o.Build() + if err != nil { + return nil, err + } + + base.Scheme = scheme + base.Host = host + return base, nil +} + +// StringFull returns the string representation of a complete url +func (o *GetFrontendDetailURL) StringFull(scheme, host string) string { + return o.Must(o.BuildFull(scheme, host)).String() +} diff --git a/rest_server_zrok/operations/zrok_api.go b/rest_server_zrok/operations/zrok_api.go index ed5c7721..158e03c3 100644 --- a/rest_server_zrok/operations/zrok_api.go +++ b/rest_server_zrok/operations/zrok_api.go @@ -82,6 +82,9 @@ func NewZrokAPI(spec *loads.Document) *ZrokAPI { MetadataGetEnvironmentMetricsHandler: metadata.GetEnvironmentMetricsHandlerFunc(func(params metadata.GetEnvironmentMetricsParams, principal *rest_model_zrok.Principal) middleware.Responder { return middleware.NotImplemented("operation metadata.GetEnvironmentMetrics has not yet been implemented") }), + MetadataGetFrontendDetailHandler: metadata.GetFrontendDetailHandlerFunc(func(params metadata.GetFrontendDetailParams, principal *rest_model_zrok.Principal) middleware.Responder { + return middleware.NotImplemented("operation metadata.GetFrontendDetail has not yet been implemented") + }), MetadataGetShareDetailHandler: metadata.GetShareDetailHandlerFunc(func(params metadata.GetShareDetailParams, principal *rest_model_zrok.Principal) middleware.Responder { return middleware.NotImplemented("operation metadata.GetShareDetail has not yet been implemented") }), @@ -205,6 +208,8 @@ type ZrokAPI struct { MetadataGetEnvironmentDetailHandler metadata.GetEnvironmentDetailHandler // MetadataGetEnvironmentMetricsHandler sets the operation handler for the get environment metrics operation MetadataGetEnvironmentMetricsHandler metadata.GetEnvironmentMetricsHandler + // MetadataGetFrontendDetailHandler sets the operation handler for the get frontend detail operation + MetadataGetFrontendDetailHandler metadata.GetFrontendDetailHandler // MetadataGetShareDetailHandler sets the operation handler for the get share detail operation MetadataGetShareDetailHandler metadata.GetShareDetailHandler // MetadataGetShareMetricsHandler sets the operation handler for the get share metrics operation @@ -353,6 +358,9 @@ func (o *ZrokAPI) Validate() error { if o.MetadataGetEnvironmentMetricsHandler == nil { unregistered = append(unregistered, "metadata.GetEnvironmentMetricsHandler") } + if o.MetadataGetFrontendDetailHandler == nil { + unregistered = append(unregistered, "metadata.GetFrontendDetailHandler") + } if o.MetadataGetShareDetailHandler == nil { unregistered = append(unregistered, "metadata.GetShareDetailHandler") } @@ -550,6 +558,10 @@ func (o *ZrokAPI) initHandlerCache() { if o.handlers["GET"] == nil { o.handlers["GET"] = make(map[string]http.Handler) } + o.handlers["GET"]["/detail/frontend/{feId}"] = metadata.NewGetFrontendDetail(o.context, o.MetadataGetFrontendDetailHandler) + if o.handlers["GET"] == nil { + o.handlers["GET"] = make(map[string]http.Handler) + } o.handlers["GET"]["/detail/share/{shrToken}"] = metadata.NewGetShareDetail(o.context, o.MetadataGetShareDetailHandler) if o.handlers["GET"] == nil { o.handlers["GET"] = make(map[string]http.Handler) diff --git a/specs/zrok.yml b/specs/zrok.yml index bf0ce90f..78aeb8d4 100644 --- a/specs/zrok.yml +++ b/specs/zrok.yml @@ -368,6 +368,30 @@ paths: 500: description: internal server error + /detail/frontend/{feId}: + get: + tags: + - metadata + security: + - key: [] + operationId: getFrontendDetail + parameters: + - name: feId + in: path + type: integer + required: true + responses: + 200: + description: ok + schema: + $ref: "#/definitions/frontend" + 401: + description: unauthorized + 404: + description: not found + 500: + description: internal server error + /detail/share/{shrToken}: get: tags: diff --git a/ui/src/api/metadata.js b/ui/src/api/metadata.js index 2ff94807..463128c3 100644 --- a/ui/src/api/metadata.js +++ b/ui/src/api/metadata.js @@ -27,6 +27,19 @@ export function getEnvironmentDetail(envZId) { return gateway.request(getEnvironmentDetailOperation, parameters) } +/** + * @param {number} feId + * @return {Promise} ok + */ +export function getFrontendDetail(feId) { + const parameters = { + path: { + feId + } + } + return gateway.request(getFrontendDetailOperation, parameters) +} + /** * @param {string} shrToken * @return {Promise} ok @@ -130,6 +143,16 @@ const getEnvironmentDetailOperation = { ] } +const getFrontendDetailOperation = { + path: '/detail/frontend/{feId}', + method: 'get', + security: [ + { + id: 'key' + } + ] +} + const getShareDetailOperation = { path: '/detail/share/{shrToken}', method: 'get', diff --git a/ui/src/console/detail/Detail.js b/ui/src/console/detail/Detail.js index 3c5b1aea..6a92761a 100644 --- a/ui/src/console/detail/Detail.js +++ b/ui/src/console/detail/Detail.js @@ -1,11 +1,17 @@ import AccountDetail from "./account/AccountDetail"; import ShareDetail from "./share/ShareDetail"; import EnvironmentDetail from "./environment/EnvironmentDetail"; +import AccessDetail from "./access/AccessDetail"; const Detail = (props) => { let detailComponent =

{props.selection.id} ({props.selection.type})

; + console.log("selection type", props.selection.type); switch(props.selection.type) { + case "frontend": + detailComponent = ; + break; + case "environment": detailComponent = ; break; diff --git a/ui/src/console/detail/access/AccessDetail.js b/ui/src/console/detail/access/AccessDetail.js new file mode 100644 index 00000000..07299597 --- /dev/null +++ b/ui/src/console/detail/access/AccessDetail.js @@ -0,0 +1,30 @@ +import {mdiAccessPointNetwork} from "@mdi/js"; +import Icon from "@mdi/react"; +import {useEffect, useState} from "react"; +import {getFrontendDetail} from "../../../api/metadata"; +import {Tab, Tabs} from "react-bootstrap"; +import DetailTab from "./DetailTab"; + +const AccessDetail = (props) => { + const [detail, setDetail] = useState({}); + + useEffect(() => { + getFrontendDetail(props.selection.id) + .then(resp => { + setDetail(resp.data); + }); + }, [props.selection]); + + return ( +
+

{" "}{detail.shrToken} ({detail.id})

+ + + + + +
+ ); +} + +export default AccessDetail; \ No newline at end of file diff --git a/ui/src/console/detail/access/DetailTab.js b/ui/src/console/detail/access/DetailTab.js new file mode 100644 index 00000000..65362c99 --- /dev/null +++ b/ui/src/console/detail/access/DetailTab.js @@ -0,0 +1,14 @@ +import SecretToggle from "../../SecretToggle"; +import PropertyTable from "../../PropertyTable"; + +const DetailTab = (props) => { + const customProperties = { + zId: row => + } + + return ( + + ); +}; + +export default DetailTab; \ No newline at end of file