From 5359754ba1cdee74550476cff37823466e4bbe77 Mon Sep 17 00:00:00 2001 From: Michael Quigley Date: Mon, 28 Nov 2022 13:33:59 -0500 Subject: [PATCH] continued refinement of frontends; access/unacess (#113, #109) --- controller/access.go | 24 +++++++-- controller/store/frontend.go | 7 +-- .../002_v0_3_0_frontend_selection.sql | 3 +- .../sqlite3/002_v0_3_0_frontend_selection.sql | 3 +- rest_client_zrok/service/access_responses.go | 19 ++++++- rest_model_zrok/access_response.go | 50 +++++++++++++++++++ rest_server_zrok/embedded_spec.go | 26 +++++++++- .../operations/service/access_responses.go | 26 +++++++++- specs/zrok.yml | 8 +++ ui/src/api/service.js | 2 +- ui/src/api/types.js | 7 +++ 11 files changed, 160 insertions(+), 15 deletions(-) create mode 100644 rest_model_zrok/access_response.go diff --git a/controller/access.go b/controller/access.go index 5e3e15cc..ae5f06aa 100644 --- a/controller/access.go +++ b/controller/access.go @@ -67,19 +67,37 @@ func (h *accessHandler) Handle(params service.AccessParams, principal *rest_mode return service.NewAccessNotFound() } - edge, err := edgeClient() + frontendName, err := createToken() if err != nil { logrus.Error(err) return service.NewAccessInternalServerError() } - extraTags := &rest_model_edge.Tags{SubTags: map[string]interface{}{"zrokEnvironmentZId": envZId}} + if _, err := str.CreateFrontend(envId, &store.Frontend{Name: frontendName, ZId: envZId}, tx); err != nil { + logrus.Errorf("error creating frontend record: %v", err) + return service.NewAccessInternalServerError() + } + + edge, err := edgeClient() + if err != nil { + logrus.Error(err) + return service.NewAccessInternalServerError() + } + extraTags := &rest_model_edge.Tags{SubTags: map[string]interface{}{ + "zrokEnvironmentZId": envZId, + "zrokFrontendName": frontendName, + }} if err := createServicePolicyDialForEnvironment(envZId, ssvc.Name, ssvc.ZId, edge, extraTags); err != nil { logrus.Errorf("unable to create dial policy: %v", err) return service.NewAccessInternalServerError() } - return service.NewAccessCreated() + if err := tx.Commit(); err != nil { + logrus.Errorf("error committing frontend record: %v", err) + return service.NewAccessInternalServerError() + } + + return service.NewAccessCreated().WithPayload(&rest_model_zrok.AccessResponse{FrontendName: frontendName}) } func createServicePolicyDialForEnvironment(envZId, svcName, svcZId string, edge *rest_management_api_client.ZitiEdgeManagement, tags ...*rest_model.Tags) error { diff --git a/controller/store/frontend.go b/controller/store/frontend.go index 1e9093fd..db198425 100644 --- a/controller/store/frontend.go +++ b/controller/store/frontend.go @@ -8,17 +8,18 @@ import ( type Frontend struct { Model EnvironmentId int + Name string ZId string - Name *string + PublicName *string } func (str *Store) CreateFrontend(envId int, f *Frontend, tx *sqlx.Tx) (int, error) { - stmt, err := tx.Prepare("insert into frontends (environment_id, z_id, name) values ($1, $2, $3) returning id") + stmt, err := tx.Prepare("insert into frontends (environment_id, name, z_id, public_name) values ($1, $2, $3, $4) returning id") if err != nil { return 0, errors.Wrap(err, "error preparing frontends insert statement") } var id int - if err := stmt.QueryRow(envId, f.ZId, f.Name).Scan(&id); err != nil { + if err := stmt.QueryRow(envId, f.Name, f.ZId, f.PublicName).Scan(&id); err != nil { return 0, errors.Wrap(err, "error executing frontends insert statement") } return id, nil diff --git a/controller/store/sql/postgresql/002_v0_3_0_frontend_selection.sql b/controller/store/sql/postgresql/002_v0_3_0_frontend_selection.sql index 15baa1ae..c319c17b 100644 --- a/controller/store/sql/postgresql/002_v0_3_0_frontend_selection.sql +++ b/controller/store/sql/postgresql/002_v0_3_0_frontend_selection.sql @@ -3,8 +3,9 @@ create table frontends ( id serial primary key, environment_id integer not null references environments(id), + name varchar(32) not null unique, z_id varchar(32) not null unique, - name varchar(64) unique, + public_name varchar(64) unique, created_at timestamptz not null default(current_timestamp), updated_at timestamptz not null default(current_timestamp) ); diff --git a/controller/store/sql/sqlite3/002_v0_3_0_frontend_selection.sql b/controller/store/sql/sqlite3/002_v0_3_0_frontend_selection.sql index 84c0802f..4f3bc302 100644 --- a/controller/store/sql/sqlite3/002_v0_3_0_frontend_selection.sql +++ b/controller/store/sql/sqlite3/002_v0_3_0_frontend_selection.sql @@ -20,8 +20,9 @@ drop table environments_old; create table frontends ( id integer primary key, environment_id integer not null references environments(id), + name varchar(32) not null unique, z_id varchar(32) not null unique, - name varchar(64) unique, + public_name varchar(64) unique, created_at datetime not null default(strftime('%Y-%m-%d %H:%M:%f', 'now')), updated_at datetime not null default(strftime('%Y-%m-%d %H:%M:%f', 'now')) ); diff --git a/rest_client_zrok/service/access_responses.go b/rest_client_zrok/service/access_responses.go index ccdf71d2..6d942552 100644 --- a/rest_client_zrok/service/access_responses.go +++ b/rest_client_zrok/service/access_responses.go @@ -7,9 +7,12 @@ package service import ( "fmt" + "io" "github.com/go-openapi/runtime" "github.com/go-openapi/strfmt" + + "github.com/openziti-test-kitchen/zrok/rest_model_zrok" ) // AccessReader is a Reader for the Access structure. @@ -60,6 +63,7 @@ AccessCreated describes a response with status code 201, with default header val access created */ type AccessCreated struct { + Payload *rest_model_zrok.AccessResponse } // IsSuccess returns true when this access created response has a 2xx status code @@ -88,15 +92,26 @@ func (o *AccessCreated) IsCode(code int) bool { } func (o *AccessCreated) Error() string { - return fmt.Sprintf("[POST /access][%d] accessCreated ", 201) + return fmt.Sprintf("[POST /access][%d] accessCreated %+v", 201, o.Payload) } func (o *AccessCreated) String() string { - return fmt.Sprintf("[POST /access][%d] accessCreated ", 201) + return fmt.Sprintf("[POST /access][%d] accessCreated %+v", 201, o.Payload) +} + +func (o *AccessCreated) GetPayload() *rest_model_zrok.AccessResponse { + return o.Payload } func (o *AccessCreated) readResponse(response runtime.ClientResponse, consumer runtime.Consumer, formats strfmt.Registry) error { + o.Payload = new(rest_model_zrok.AccessResponse) + + // response payload + if err := consumer.Consume(response.Body(), o.Payload); err != nil && err != io.EOF { + return err + } + return nil } diff --git a/rest_model_zrok/access_response.go b/rest_model_zrok/access_response.go new file mode 100644 index 00000000..2cd056b5 --- /dev/null +++ b/rest_model_zrok/access_response.go @@ -0,0 +1,50 @@ +// Code generated by go-swagger; DO NOT EDIT. + +package rest_model_zrok + +// This file was generated by the swagger tool. +// Editing this file might prove futile when you re-run the swagger generate command + +import ( + "context" + + "github.com/go-openapi/strfmt" + "github.com/go-openapi/swag" +) + +// AccessResponse access response +// +// swagger:model accessResponse +type AccessResponse struct { + + // frontend name + FrontendName string `json:"frontendName,omitempty"` +} + +// Validate validates this access response +func (m *AccessResponse) Validate(formats strfmt.Registry) error { + return nil +} + +// ContextValidate validates this access response based on context it is used +func (m *AccessResponse) ContextValidate(ctx context.Context, formats strfmt.Registry) error { + return nil +} + +// MarshalBinary interface implementation +func (m *AccessResponse) MarshalBinary() ([]byte, error) { + if m == nil { + return nil, nil + } + return swag.WriteJSON(m) +} + +// UnmarshalBinary interface implementation +func (m *AccessResponse) UnmarshalBinary(b []byte) error { + var res AccessResponse + if err := swag.ReadJSON(b, &res); err != nil { + return err + } + *m = res + return nil +} diff --git a/rest_server_zrok/embedded_spec.go b/rest_server_zrok/embedded_spec.go index 2bc1bf77..c74b6c18 100644 --- a/rest_server_zrok/embedded_spec.go +++ b/rest_server_zrok/embedded_spec.go @@ -57,7 +57,10 @@ func init() { ], "responses": { "201": { - "description": "access created" + "description": "access created", + "schema": { + "$ref": "#/definitions/accessResponse" + } }, "401": { "description": "unauthorized" @@ -449,6 +452,14 @@ func init() { } } }, + "accessResponse": { + "type": "object", + "properties": { + "frontendName": { + "type": "string" + } + } + }, "accountRequest": { "type": "object", "properties": { @@ -777,7 +788,10 @@ func init() { ], "responses": { "201": { - "description": "access created" + "description": "access created", + "schema": { + "$ref": "#/definitions/accessResponse" + } }, "401": { "description": "unauthorized" @@ -1169,6 +1183,14 @@ func init() { } } }, + "accessResponse": { + "type": "object", + "properties": { + "frontendName": { + "type": "string" + } + } + }, "accountRequest": { "type": "object", "properties": { diff --git a/rest_server_zrok/operations/service/access_responses.go b/rest_server_zrok/operations/service/access_responses.go index 914ae630..5073cece 100644 --- a/rest_server_zrok/operations/service/access_responses.go +++ b/rest_server_zrok/operations/service/access_responses.go @@ -9,6 +9,8 @@ import ( "net/http" "github.com/go-openapi/runtime" + + "github.com/openziti-test-kitchen/zrok/rest_model_zrok" ) // AccessCreatedCode is the HTTP code returned for type AccessCreated @@ -20,6 +22,11 @@ AccessCreated access created swagger:response accessCreated */ type AccessCreated struct { + + /* + In: Body + */ + Payload *rest_model_zrok.AccessResponse `json:"body,omitempty"` } // NewAccessCreated creates AccessCreated with default headers values @@ -28,12 +35,27 @@ func NewAccessCreated() *AccessCreated { return &AccessCreated{} } +// WithPayload adds the payload to the access created response +func (o *AccessCreated) WithPayload(payload *rest_model_zrok.AccessResponse) *AccessCreated { + o.Payload = payload + return o +} + +// SetPayload sets the payload to the access created response +func (o *AccessCreated) SetPayload(payload *rest_model_zrok.AccessResponse) { + o.Payload = payload +} + // WriteResponse to the client func (o *AccessCreated) WriteResponse(rw http.ResponseWriter, producer runtime.Producer) { - rw.Header().Del(runtime.HeaderContentType) //Remove Content-Type on empty responses - rw.WriteHeader(201) + if o.Payload != nil { + payload := o.Payload + if err := producer.Produce(rw, payload); err != nil { + panic(err) // let the recovery middleware deal with this + } + } } // AccessUnauthorizedCode is the HTTP code returned for type AccessUnauthorized diff --git a/specs/zrok.yml b/specs/zrok.yml index 9f6515ad..3ab3c134 100644 --- a/specs/zrok.yml +++ b/specs/zrok.yml @@ -194,6 +194,8 @@ paths: responses: 201: description: access created + schema: + $ref: "#/definitions/accessResponse" 401: description: unauthorized 404: @@ -280,6 +282,12 @@ definitions: svcName: type: string + accessResponse: + type: object + properties: + frontendName: + type: string + accountRequest: type: object properties: diff --git a/ui/src/api/service.js b/ui/src/api/service.js index 1e43fb66..7d540fc7 100644 --- a/ui/src/api/service.js +++ b/ui/src/api/service.js @@ -5,7 +5,7 @@ import * as gateway from './gateway' /** * @param {object} options Optional options * @param {module:types.accessRequest} [options.body] - * @return {Promise} access created + * @return {Promise} access created */ export function access(options) { if (!options) options = {} diff --git a/ui/src/api/types.js b/ui/src/api/types.js index 981042d2..6aaf5f60 100644 --- a/ui/src/api/types.js +++ b/ui/src/api/types.js @@ -9,6 +9,13 @@ * @property {string} svcName */ +/** + * @typedef accessResponse + * @memberof module:types + * + * @property {string} frontendName + */ + /** * @typedef accountRequest * @memberof module:types