roughed in environment details (#107)

This commit is contained in:
Michael Quigley 2022-12-22 14:56:19 -05:00
parent a0fd3a9c63
commit 3856d6eb61
No known key found for this signature in database
GPG Key ID: 9B60314A9DD20A62
17 changed files with 182 additions and 174 deletions

View File

@ -20,9 +20,9 @@ func (h *environmentDetailHandler) Handle(params metadata.GetEnvironmentDetailPa
return metadata.NewGetEnvironmentDetailInternalServerError()
}
defer func() { _ = tx.Rollback() }()
senv, err := str.FindEnvironmentForAccount(params.Body.EnvZID, int(principal.ID), tx)
senv, err := str.FindEnvironmentForAccount(params.EnvZID, int(principal.ID), tx)
if err != nil {
logrus.Errorf("environment '%v' not found for account '%v': %v", params.Body.EnvZID, principal.Email, err)
logrus.Errorf("environment '%v' not found for account '%v': %v", params.EnvZID, principal.Email, err)
return metadata.NewGetEnvironmentDetailNotFound()
}
es := &rest_model_zrok.EnvironmentServices{

View File

@ -64,7 +64,7 @@ func (self *Store) FindEnvironmentsForAccount(accountId int, tx *sqlx.Tx) ([]*En
func (self *Store) FindEnvironmentForAccount(envZId string, accountId int, tx *sqlx.Tx) (*Environment, error) {
env := &Environment{}
if err := tx.QueryRowx("select environments.* from environments where z_id = $1 and account_id = $1", envZId, accountId).StructScan(env); err != nil {
if err := tx.QueryRowx("select environments.* from environments where z_id = $1 and account_id = $2", envZId, accountId).StructScan(env); err != nil {
return nil, errors.Wrap(err, "error finding environment by z_id and account_id")
}
return env, nil

View File

@ -61,8 +61,8 @@ GetEnvironmentDetailParams contains all the parameters to send to the API endpoi
*/
type GetEnvironmentDetailParams struct {
// Body.
Body GetEnvironmentDetailBody
// EnvZID.
EnvZID string
timeout time.Duration
Context context.Context
@ -117,15 +117,15 @@ func (o *GetEnvironmentDetailParams) SetHTTPClient(client *http.Client) {
o.HTTPClient = client
}
// WithBody adds the body to the get environment detail params
func (o *GetEnvironmentDetailParams) WithBody(body GetEnvironmentDetailBody) *GetEnvironmentDetailParams {
o.SetBody(body)
// WithEnvZID adds the envZID to the get environment detail params
func (o *GetEnvironmentDetailParams) WithEnvZID(envZID string) *GetEnvironmentDetailParams {
o.SetEnvZID(envZID)
return o
}
// SetBody adds the body to the get environment detail params
func (o *GetEnvironmentDetailParams) SetBody(body GetEnvironmentDetailBody) {
o.Body = body
// SetEnvZID adds the envZId to the get environment detail params
func (o *GetEnvironmentDetailParams) SetEnvZID(envZID string) {
o.EnvZID = envZID
}
// WriteToRequest writes these params to a swagger request
@ -135,7 +135,9 @@ func (o *GetEnvironmentDetailParams) WriteToRequest(r runtime.ClientRequest, reg
return err
}
var res []error
if err := r.SetBodyParam(o.Body); err != nil {
// path param envZId
if err := r.SetPathParam("envZId", o.EnvZID); err != nil {
return err
}

View File

@ -6,13 +6,11 @@ package metadata
// Editing this file might prove futile when you re-run the swagger generate command
import (
"context"
"fmt"
"io"
"github.com/go-openapi/runtime"
"github.com/go-openapi/strfmt"
"github.com/go-openapi/swag"
"github.com/openziti-test-kitchen/zrok/rest_model_zrok"
)
@ -94,11 +92,11 @@ func (o *GetEnvironmentDetailOK) IsCode(code int) bool {
}
func (o *GetEnvironmentDetailOK) Error() string {
return fmt.Sprintf("[GET /detail/environment][%d] getEnvironmentDetailOK %+v", 200, o.Payload)
return fmt.Sprintf("[GET /detail/environment/{envZId}][%d] getEnvironmentDetailOK %+v", 200, o.Payload)
}
func (o *GetEnvironmentDetailOK) String() string {
return fmt.Sprintf("[GET /detail/environment][%d] getEnvironmentDetailOK %+v", 200, o.Payload)
return fmt.Sprintf("[GET /detail/environment/{envZId}][%d] getEnvironmentDetailOK %+v", 200, o.Payload)
}
func (o *GetEnvironmentDetailOK) GetPayload() *rest_model_zrok.EnvironmentServices {
@ -156,11 +154,11 @@ func (o *GetEnvironmentDetailUnauthorized) IsCode(code int) bool {
}
func (o *GetEnvironmentDetailUnauthorized) Error() string {
return fmt.Sprintf("[GET /detail/environment][%d] getEnvironmentDetailUnauthorized ", 401)
return fmt.Sprintf("[GET /detail/environment/{envZId}][%d] getEnvironmentDetailUnauthorized ", 401)
}
func (o *GetEnvironmentDetailUnauthorized) String() string {
return fmt.Sprintf("[GET /detail/environment][%d] getEnvironmentDetailUnauthorized ", 401)
return fmt.Sprintf("[GET /detail/environment/{envZId}][%d] getEnvironmentDetailUnauthorized ", 401)
}
func (o *GetEnvironmentDetailUnauthorized) readResponse(response runtime.ClientResponse, consumer runtime.Consumer, formats strfmt.Registry) error {
@ -207,11 +205,11 @@ func (o *GetEnvironmentDetailNotFound) IsCode(code int) bool {
}
func (o *GetEnvironmentDetailNotFound) Error() string {
return fmt.Sprintf("[GET /detail/environment][%d] getEnvironmentDetailNotFound ", 404)
return fmt.Sprintf("[GET /detail/environment/{envZId}][%d] getEnvironmentDetailNotFound ", 404)
}
func (o *GetEnvironmentDetailNotFound) String() string {
return fmt.Sprintf("[GET /detail/environment][%d] getEnvironmentDetailNotFound ", 404)
return fmt.Sprintf("[GET /detail/environment/{envZId}][%d] getEnvironmentDetailNotFound ", 404)
}
func (o *GetEnvironmentDetailNotFound) readResponse(response runtime.ClientResponse, consumer runtime.Consumer, formats strfmt.Registry) error {
@ -258,52 +256,14 @@ func (o *GetEnvironmentDetailInternalServerError) IsCode(code int) bool {
}
func (o *GetEnvironmentDetailInternalServerError) Error() string {
return fmt.Sprintf("[GET /detail/environment][%d] getEnvironmentDetailInternalServerError ", 500)
return fmt.Sprintf("[GET /detail/environment/{envZId}][%d] getEnvironmentDetailInternalServerError ", 500)
}
func (o *GetEnvironmentDetailInternalServerError) String() string {
return fmt.Sprintf("[GET /detail/environment][%d] getEnvironmentDetailInternalServerError ", 500)
return fmt.Sprintf("[GET /detail/environment/{envZId}][%d] getEnvironmentDetailInternalServerError ", 500)
}
func (o *GetEnvironmentDetailInternalServerError) readResponse(response runtime.ClientResponse, consumer runtime.Consumer, formats strfmt.Registry) error {
return nil
}
/*
GetEnvironmentDetailBody get environment detail body
swagger:model GetEnvironmentDetailBody
*/
type GetEnvironmentDetailBody struct {
// env z Id
EnvZID string `json:"envZId,omitempty"`
}
// Validate validates this get environment detail body
func (o *GetEnvironmentDetailBody) Validate(formats strfmt.Registry) error {
return nil
}
// ContextValidate validates this get environment detail body based on context it is used
func (o *GetEnvironmentDetailBody) ContextValidate(ctx context.Context, formats strfmt.Registry) error {
return nil
}
// MarshalBinary interface implementation
func (o *GetEnvironmentDetailBody) MarshalBinary() ([]byte, error) {
if o == nil {
return nil, nil
}
return swag.WriteJSON(o)
}
// UnmarshalBinary interface implementation
func (o *GetEnvironmentDetailBody) UnmarshalBinary(b []byte) error {
var res GetEnvironmentDetailBody
if err := swag.ReadJSON(b, &res); err != nil {
return err
}
*o = res
return nil
}

View File

@ -50,7 +50,7 @@ func (a *Client) GetEnvironmentDetail(params *GetEnvironmentDetailParams, authIn
op := &runtime.ClientOperation{
ID: "getEnvironmentDetail",
Method: "GET",
PathPattern: "/detail/environment",
PathPattern: "/detail/environment/{envZId}",
ProducesMediaTypes: []string{"application/zrok.v1+json"},
ConsumesMediaTypes: []string{"application/zrok.v1+json"},
Schemes: []string{"http"},

View File

@ -74,7 +74,7 @@ func init() {
}
}
},
"/detail/environment": {
"/detail/environment/{envZId}": {
"get": {
"security": [
{
@ -87,15 +87,10 @@ func init() {
"operationId": "getEnvironmentDetail",
"parameters": [
{
"name": "body",
"in": "body",
"schema": {
"properties": {
"envZId": {
"type": "string"
}
}
}
"type": "string",
"name": "envZId",
"in": "path",
"required": true
}
],
"responses": {
@ -1209,7 +1204,7 @@ func init() {
}
}
},
"/detail/environment": {
"/detail/environment/{envZId}": {
"get": {
"security": [
{
@ -1222,15 +1217,10 @@ func init() {
"operationId": "getEnvironmentDetail",
"parameters": [
{
"name": "body",
"in": "body",
"schema": {
"properties": {
"envZId": {
"type": "string"
}
}
}
"type": "string",
"name": "envZId",
"in": "path",
"required": true
}
],
"responses": {

View File

@ -6,12 +6,9 @@ package metadata
// Editing this file might prove futile when you re-run the generate command
import (
"context"
"net/http"
"github.com/go-openapi/runtime/middleware"
"github.com/go-openapi/strfmt"
"github.com/go-openapi/swag"
"github.com/openziti-test-kitchen/zrok/rest_model_zrok"
)
@ -35,7 +32,7 @@ func NewGetEnvironmentDetail(ctx *middleware.Context, handler GetEnvironmentDeta
}
/*
GetEnvironmentDetail swagger:route GET /detail/environment metadata getEnvironmentDetail
GetEnvironmentDetail swagger:route GET /detail/environment/{envZId} metadata getEnvironmentDetail
GetEnvironmentDetail get environment detail API
*/
@ -72,40 +69,3 @@ func (o *GetEnvironmentDetail) ServeHTTP(rw http.ResponseWriter, r *http.Request
o.Context.Respond(rw, r, route.Produces, route, res)
}
// GetEnvironmentDetailBody get environment detail body
//
// swagger:model GetEnvironmentDetailBody
type GetEnvironmentDetailBody struct {
// env z Id
EnvZID string `json:"envZId,omitempty"`
}
// Validate validates this get environment detail body
func (o *GetEnvironmentDetailBody) Validate(formats strfmt.Registry) error {
return nil
}
// ContextValidate validates this get environment detail body based on context it is used
func (o *GetEnvironmentDetailBody) ContextValidate(ctx context.Context, formats strfmt.Registry) error {
return nil
}
// MarshalBinary interface implementation
func (o *GetEnvironmentDetailBody) MarshalBinary() ([]byte, error) {
if o == nil {
return nil, nil
}
return swag.WriteJSON(o)
}
// UnmarshalBinary interface implementation
func (o *GetEnvironmentDetailBody) UnmarshalBinary(b []byte) error {
var res GetEnvironmentDetailBody
if err := swag.ReadJSON(b, &res); err != nil {
return err
}
*o = res
return nil
}

View File

@ -9,9 +9,8 @@ import (
"net/http"
"github.com/go-openapi/errors"
"github.com/go-openapi/runtime"
"github.com/go-openapi/runtime/middleware"
"github.com/go-openapi/validate"
"github.com/go-openapi/strfmt"
)
// NewGetEnvironmentDetailParams creates a new GetEnvironmentDetailParams object
@ -32,9 +31,10 @@ type GetEnvironmentDetailParams struct {
HTTPRequest *http.Request `json:"-"`
/*
In: body
Required: true
In: path
*/
Body GetEnvironmentDetailBody
EnvZID string
}
// BindRequest both binds and validates a request, it assumes that complex things implement a Validatable(strfmt.Registry) error interface
@ -46,29 +46,26 @@ func (o *GetEnvironmentDetailParams) BindRequest(r *http.Request, route *middlew
o.HTTPRequest = r
if runtime.HasBody(r) {
defer r.Body.Close()
var body GetEnvironmentDetailBody
if err := route.Consumer.Consume(r.Body, &body); err != nil {
res = append(res, errors.NewParseError("body", "body", "", err))
} else {
// validate body object
if err := body.Validate(route.Formats); err != nil {
res = append(res, err)
}
ctx := validate.WithOperationRequest(r.Context())
if err := body.ContextValidate(ctx, route.Formats); err != nil {
res = append(res, err)
}
if len(res) == 0 {
o.Body = body
}
}
rEnvZID, rhkEnvZID, _ := route.Params.GetOK("envZId")
if err := o.bindEnvZID(rEnvZID, rhkEnvZID, route.Formats); err != nil {
res = append(res, err)
}
if len(res) > 0 {
return errors.CompositeValidationError(res...)
}
return nil
}
// bindEnvZID binds and validates parameter EnvZID from path.
func (o *GetEnvironmentDetailParams) bindEnvZID(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
o.EnvZID = raw
return nil
}

View File

@ -9,11 +9,16 @@ import (
"errors"
"net/url"
golangswaggerpaths "path"
"strings"
)
// GetEnvironmentDetailURL generates an URL for the get environment detail operation
type GetEnvironmentDetailURL struct {
EnvZID string
_basePath string
// avoid unkeyed usage
_ struct{}
}
// WithBasePath sets the base path for this url builder, only required when it's different from the
@ -35,7 +40,14 @@ func (o *GetEnvironmentDetailURL) SetBasePath(bp string) {
func (o *GetEnvironmentDetailURL) Build() (*url.URL, error) {
var _result url.URL
var _path = "/detail/environment"
var _path = "/detail/environment/{envZId}"
envZID := o.EnvZID
if envZID != "" {
_path = strings.Replace(_path, "{envZId}", envZID, -1)
} else {
return nil, errors.New("envZId is required on GetEnvironmentDetailURL")
}
_basePath := o._basePath
if _basePath == "" {

View File

@ -466,7 +466,7 @@ func (o *ZrokAPI) initHandlerCache() {
if o.handlers["GET"] == nil {
o.handlers["GET"] = make(map[string]http.Handler)
}
o.handlers["GET"]["/detail/environment"] = metadata.NewGetEnvironmentDetail(o.context, o.MetadataGetEnvironmentDetailHandler)
o.handlers["GET"]["/detail/environment/{envZId}"] = metadata.NewGetEnvironmentDetail(o.context, o.MetadataGetEnvironmentDetailHandler)
if o.handlers["GET"] == nil {
o.handlers["GET"] = make(map[string]http.Handler)
}

View File

@ -252,7 +252,7 @@ paths:
#
# metadata
#
/detail/environment:
/detail/environment/{envZId}:
get:
tags:
- metadata
@ -260,12 +260,10 @@ paths:
- key: []
operationId: getEnvironmentDetail
parameters:
- name: body
in: body
schema:
properties:
envZId:
type: string
- name: envZId
in: path
type: string
required: true
responses:
200:
description: ok

View File

@ -3,15 +3,13 @@
import * as gateway from './gateway'
/**
* @param {object} options Optional options
* @param {object} [options.body]
* @param {string} envZId
* @return {Promise<module:types.environmentServices>} ok
*/
export function getEnvironmentDetail(options) {
if (!options) options = {}
export function getEnvironmentDetail(envZId) {
const parameters = {
body: {
body: options.body
path: {
envZId
}
}
return gateway.request(getEnvironmentDetailOperation, parameters)
@ -30,8 +28,7 @@ export function version() {
}
const getEnvironmentDetailOperation = {
path: '/detail/environment',
contentTypes: ['application/zrok.v1+json'],
path: '/detail/environment/{envZId}',
method: 'get',
security: [
{

View File

@ -4,7 +4,7 @@ import Visualizer from "./visualizer/Visualizer";
import Enable from "./modals/Enable";
import Version from "./modals/Version";
import * as metadata from "../api/metadata";
import Detail from "./Detail";
import Detail from "./detail/Detail";
const Console = (props) => {
const [showEnableModal, setShowEnableModal] = useState(false);
@ -34,7 +34,7 @@ const Console = (props) => {
setOverview(resp.data);
}
})
}, 1000)
}, 1000);
return () => {
mounted = false;
clearInterval(interval);

View File

@ -1,9 +0,0 @@
const Detail = (props) => {
return (
<div className={"detail-container"}>
<h1>{props.selection.id} ({props.selection.type})</h1>
</div>
);
};
export default Detail;

View File

@ -0,0 +1,17 @@
import EnvironmentDetail from "./EnvironmentDetail";
const Detail = (props) => {
let detailComponent = <h1>{props.selection.id} ({props.selection.type})</h1>;
switch(props.selection.type) {
case "environment":
detailComponent = <EnvironmentDetail selection={props.selection} />;
break;
}
return (
<div className={"detail-container"}>{detailComponent}</div>
);
};
export default Detail;

View File

@ -0,0 +1,80 @@
import * as metadata from "../../api/metadata";
import {useEffect, useState} from "react";
import DataTable from 'react-data-table-component';
import {Sparklines, SparklinesLine, SparklinesSpots} from "react-sparklines";
const EnvironmentDetail = (props) => {
const [detail, setDetail] = useState({});
useEffect(() => {
metadata.getEnvironmentDetail(props.selection.id)
.then(resp => {
setDetail(resp.data);
});
}, [props.selection]);
useEffect(() => {
let mounted = true;
let interval = setInterval(() => {
if(mounted) {}
metadata.getEnvironmentDetail(props.selection.id)
.then(resp => {
if(mounted) {
setDetail(resp.data);
}
});
}, 1000);
return () => {
mounted = false;
clearInterval(interval);
}
}, [props.selection]);
const columns = [
{
name: "Frontend",
selector: row => <a href={row.frontendEndpoint} target={"_"}>{row.frontendEndpoint}</a>,
sortable: true
},
{
name: "Backend",
selector: row => row.backendProxyEndpoint,
sortable: true
},
{
name: "Share Mode",
selector: row => row.shareMode,
},
{
name: "Token",
selector: row => row.token,
sortable: true,
},
{
name: "Activity",
cell: row => {
console.log(row.metrics);
return <Sparklines data={row.metrics} height={20} limit={60}><SparklinesLine color={"#3b2693"}/><SparklinesSpots/></Sparklines>;
}
}
];
if(detail.environment) {
return (
<div>
<h2>Environment: {detail.environment.description} ({detail.environment.zId})</h2>
<div className={"zrok-datatable"}>
<DataTable
className={"zrok-datatable"}
data={detail.services}
columns={columns}
defaultSortField={1}
/>
</div>
</div>
);
}
return <></>;
}
export default EnvironmentDetail;

View File

@ -37,6 +37,10 @@ code, pre {
margin-top: 15px;
}
.zrok-datatable {
margin-top: 30px;
}
.btn-close {
background: transparent url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='%23000'%3E%3Cpath d='M.293.293a1 1 0 0 1 1.414 0L8 6.586 14.293.293a1 1 0 1 1 1.414 1.414L9.414 8l6.293 6.293a1 1 0 0 1-1.414 1.414L8 9.414l-6.293 6.293a1 1 0 0 1-1.414-1.414L6.586 8 .293 1.707a1 1 0 0 1 0-1.414z'/%3E%3C/svg%3E") 50%/1em auto no-repeat;
height: 25px;