more cleanups and polish for sharing and reserving (#122, #41)

This commit is contained in:
Michael Quigley 2022-11-30 14:38:49 -05:00
parent 3f5c5003de
commit 301249fe4a
No known key found for this signature in database
GPG Key ID: 9B60314A9DD20A62
18 changed files with 227 additions and 20 deletions

View File

@ -56,7 +56,10 @@ func (cmd *releaseCommand) run(_ *cobra.Command, args []string) {
Reserved: true,
}
if _, err := zrok.Service.Unshare(req, auth); err != nil {
logrus.Errorf("error releasing service '%v': %v", svcToken, err)
if !panicInstead {
showError("error releasing service", err)
}
panic(err)
}
logrus.Infof("reserved service '%v' released", svcToken)

View File

@ -41,7 +41,7 @@ func (cmd *reserveCommand) run(_ *cobra.Command, args []string) {
showError("invalid sharing mode; expecting 'public' or 'private'", nil)
}
targetEndpoint, err := url.Parse(args[0])
targetEndpoint, err := url.Parse(args[1])
if err != nil {
if !panicInstead {
showError("invalid target endpoint URL", err)

129
cmd/zrok/share_reserved.go Normal file
View File

@ -0,0 +1,129 @@
package main
import (
ui "github.com/gizak/termui/v3"
httptransport "github.com/go-openapi/runtime/client"
"github.com/openziti-test-kitchen/zrok/endpoints/backend"
"github.com/openziti-test-kitchen/zrok/rest_client_zrok/service"
"github.com/openziti-test-kitchen/zrok/rest_model_zrok"
"github.com/openziti-test-kitchen/zrok/zrokdir"
"github.com/sirupsen/logrus"
"github.com/spf13/cobra"
"net/url"
"time"
)
func init() {
shareCmd.AddCommand(newShareReservedCommand().cmd)
}
type shareReservedCommand struct {
overrideEndpoint string
cmd *cobra.Command
}
func newShareReservedCommand() *shareReservedCommand {
cmd := &cobra.Command{
Use: "reserved <serviceToken>",
}
command := &shareReservedCommand{cmd: cmd}
cmd.Flags().StringVar(&command.overrideEndpoint, "override-endpoint", "", "Override the stored target endpoint with a replacement")
cmd.Run = command.run
return command
}
func (cmd *shareReservedCommand) run(_ *cobra.Command, args []string) {
svcToken := args[0]
targetEndpoint := ""
if cmd.overrideEndpoint != "" {
e, err := url.Parse(cmd.overrideEndpoint)
if err != nil {
if !panicInstead {
showError("invalid override endpoint URL", err)
}
panic(err)
}
if e.Scheme == "" {
e.Scheme = "https"
}
targetEndpoint = e.String()
}
env, err := zrokdir.LoadEnvironment()
if err != nil {
ui.Close()
if !panicInstead {
showError("unable to load environment; did you 'zrok enable'?", err)
}
panic(err)
}
zrok, err := zrokdir.ZrokClient(env.ApiEndpoint)
if err != nil {
ui.Close()
if !panicInstead {
showError("unable to create zrok client", err)
}
panic(err)
}
auth := httptransport.APIKeyAuth("X-TOKEN", "header", env.Token)
req := service.NewGetServiceParams()
req.Body = &rest_model_zrok.ServiceRequest{
EnvZID: env.ZId,
SvcToken: svcToken,
}
resp, err := zrok.Service.GetService(req, auth)
if err != nil {
if !panicInstead {
showError("unable to retrieve reserved service", err)
}
panic(err)
}
if targetEndpoint == "" {
targetEndpoint = resp.Payload.BackendProxyEndpoint
}
zif, err := zrokdir.ZitiIdentityFile("backend")
if err != nil {
ui.Close()
if !panicInstead {
showError("unable to load ziti identity configuration", err)
}
panic(err)
}
cfg := &backend.Config{
IdentityPath: zif,
EndpointAddress: targetEndpoint,
Service: svcToken,
}
logrus.Infof("sharing target endpoint: '%v'", cfg.EndpointAddress)
httpProxy, err := backend.NewHTTP(cfg)
if err != nil {
ui.Close()
if !panicInstead {
showError("unable to create http backend", err)
}
panic(err)
}
go func() {
if err := httpProxy.Run(); err != nil {
if !panicInstead {
showError("unable to run http proxy", err)
}
panic(err)
}
}()
switch resp.Payload.ShareMode {
case "public":
logrus.Infof("access your zrok service: %v", resp.Payload.FrontendEndpoint)
case "private":
logrus.Infof("use this command to access your zrok service: 'zrok access private %v'", svcToken)
}
for {
time.Sleep(30 * time.Second)
}
}

View File

@ -8,6 +8,7 @@ import (
"github.com/openziti-test-kitchen/zrok/rest_server_zrok/operations"
"github.com/openziti-test-kitchen/zrok/rest_server_zrok/operations/account"
"github.com/openziti-test-kitchen/zrok/rest_server_zrok/operations/metadata"
"github.com/openziti-test-kitchen/zrok/rest_server_zrok/operations/service"
"github.com/pkg/errors"
)
@ -35,6 +36,7 @@ func Run(inCfg *Config) error {
api.MetadataOverviewHandler = metadata.OverviewHandlerFunc(overviewHandler)
api.MetadataVersionHandler = metadata.VersionHandlerFunc(versionHandler)
api.ServiceAccessHandler = newAccessHandler()
api.ServiceGetServiceHandler = service.GetServiceHandlerFunc(getServiceHandler)
api.ServiceShareHandler = newShareHandler()
api.ServiceUnaccessHandler = newUnaccessHandler()
api.ServiceUnshareHandler = newUnshareHandler()

61
controller/get_service.go Normal file
View File

@ -0,0 +1,61 @@
package controller
import (
"github.com/go-openapi/runtime/middleware"
"github.com/openziti-test-kitchen/zrok/rest_model_zrok"
"github.com/openziti-test-kitchen/zrok/rest_server_zrok/operations/service"
"github.com/sirupsen/logrus"
)
func getServiceHandler(params service.GetServiceParams, principal *rest_model_zrok.Principal) middleware.Responder {
envZId := params.Body.EnvZID
svcToken := params.Body.SvcToken
tx, err := str.Begin()
if err != nil {
logrus.Errorf("error starting transaction: %v", err)
return service.NewGetServiceInternalServerError()
}
defer func() { _ = tx.Rollback() }()
ssvc, err := str.FindServiceWithToken(svcToken, tx)
if err != nil {
logrus.Errorf("error finding service with token '%v': %v", svcToken, err)
return service.NewGetServiceNotFound()
}
senvs, err := str.FindEnvironmentsForAccount(int(principal.ID), tx)
if err != nil {
logrus.Errorf("error listing environments for account '%v': %v", principal.Email, err)
return service.NewGetServiceInternalServerError()
}
envFound := false
for _, senv := range senvs {
if senv.Id == ssvc.EnvironmentId && senv.ZId == envZId {
envFound = true
break
}
}
if !envFound {
logrus.Errorf("service '%v' not in environment '%v'", svcToken, envZId)
return service.NewGetServiceNotFound()
}
svc := &rest_model_zrok.Service03{
Token: ssvc.Token,
ZID: ssvc.ZId,
ShareMode: ssvc.ShareMode,
BackendMode: ssvc.BackendMode,
Reserved: ssvc.Reserved,
}
if ssvc.FrontendSelection != nil {
svc.FrontendSelection = *ssvc.FrontendSelection
}
if ssvc.FrontendEndpoint != nil {
svc.FrontendEndpoint = *ssvc.FrontendEndpoint
}
if ssvc.BackendProxyEndpoint != nil {
svc.BackendProxyEndpoint = *ssvc.BackendProxyEndpoint
}
return service.NewGetServiceOK().WithPayload(svc)
}

View File

@ -34,9 +34,9 @@ func (str *Store) GetFrontend(id int, tx *sqlx.Tx) (*Frontend, error) {
return i, nil
}
func (str *Store) FindFrontendNamed(name string, tx *sqlx.Tx) (*Frontend, error) {
func (str *Store) FindFrontendWithToken(token string, tx *sqlx.Tx) (*Frontend, error) {
i := &Frontend{}
if err := tx.QueryRowx("select frontends.* from frontends where name = $1", name).StructScan(i); err != nil {
if err := tx.QueryRowx("select frontends.* from frontends where token = $1", token).StructScan(i); err != nil {
return nil, errors.Wrap(err, "error selecting frontend by name")
}
return i, nil

View File

@ -51,7 +51,7 @@ func TestPublicFrontend(t *testing.T) {
err = str.DeleteFrontend(fe.Id, tx)
assert.Nil(t, err)
fe0, err = str.FindFrontendNamed(feName, tx)
fe0, err = str.FindFrontendWithToken(feName, tx)
assert.NotNil(t, err)
assert.Nil(t, fe0)

View File

@ -4,7 +4,7 @@ create table frontends (
id serial primary key,
environment_id integer not null references environments(id),
token varchar(32) not null unique,
z_id varchar(32) not null unique,
z_id varchar(32) not null,
public_name varchar(64) unique,
reserved boolean not null default(false),
created_at timestamptz not null default(current_timestamp),

View File

@ -21,7 +21,7 @@ create table frontends (
id integer primary key,
environment_id integer not null references environments(id),
token varchar(32) not null unique,
z_id varchar(32) not null unique,
z_id varchar(32) not null,
public_name varchar(64) unique,
reserved boolean not null default(false),
created_at datetime not null default(strftime('%Y-%m-%d %H:%M:%f', 'now')),

View File

@ -53,7 +53,7 @@ func (h *unaccessHandler) Handle(params service.UnaccessParams, principal *rest_
return service.NewUnaccessUnauthorized()
}
sfe, err := str.FindFrontendNamed(feToken, tx)
sfe, err := str.FindFrontendWithToken(feToken, tx)
if err != nil {
logrus.Error(err)
return service.NewUnaccessInternalServerError()

View File

@ -37,7 +37,7 @@ func (h *unshareHandler) Handle(params service.UnshareParams, principal *rest_mo
svcZId, err := h.findServiceZId(svcToken, edge)
if err != nil {
logrus.Error(err)
return service.NewUnshareInternalServerError()
return service.NewUnshareNotFound()
}
var senv *store.Environment
if envs, err := str.FindEnvironmentsForAccount(int(principal.ID), tx); err == nil {
@ -54,7 +54,7 @@ func (h *unshareHandler) Handle(params service.UnshareParams, principal *rest_mo
}
} else {
logrus.Errorf("error finding environments for account '%v': %v", principal.Email, err)
return service.NewUnshareInternalServerError()
return service.NewUnshareNotFound()
}
var ssvc *store.Service

View File

@ -63,7 +63,7 @@ GetServiceOK describes a response with status code 200, with default header valu
ok
*/
type GetServiceOK struct {
Payload *rest_model_zrok.Service
Payload *rest_model_zrok.Service03
}
// IsSuccess returns true when this get service o k response has a 2xx status code
@ -99,13 +99,13 @@ func (o *GetServiceOK) String() string {
return fmt.Sprintf("[GET /service][%d] getServiceOK %+v", 200, o.Payload)
}
func (o *GetServiceOK) GetPayload() *rest_model_zrok.Service {
func (o *GetServiceOK) GetPayload() *rest_model_zrok.Service03 {
return o.Payload
}
func (o *GetServiceOK) readResponse(response runtime.ClientResponse, consumer runtime.Consumer, formats strfmt.Registry) error {
o.Payload = new(rest_model_zrok.Service)
o.Payload = new(rest_model_zrok.Service03)
// response payload
if err := consumer.Consume(response.Body(), o.Payload); err != nil && err != io.EOF {

View File

@ -17,6 +17,9 @@ import (
// swagger:model serviceRequest
type ServiceRequest struct {
// env z Id
EnvZID string `json:"envZId,omitempty"`
// svc token
SvcToken string `json:"svcToken,omitempty"`
}

View File

@ -284,7 +284,7 @@ func init() {
"200": {
"description": "ok",
"schema": {
"$ref": "#/definitions/service"
"$ref": "#/definitions/service03"
}
},
"401": {
@ -693,6 +693,9 @@ func init() {
"serviceRequest": {
"type": "object",
"properties": {
"envZId": {
"type": "string"
},
"svcToken": {
"type": "string"
}
@ -1082,7 +1085,7 @@ func init() {
"200": {
"description": "ok",
"schema": {
"$ref": "#/definitions/service"
"$ref": "#/definitions/service03"
}
},
"401": {
@ -1491,6 +1494,9 @@ func init() {
"serviceRequest": {
"type": "object",
"properties": {
"envZId": {
"type": "string"
},
"svcToken": {
"type": "string"
}

View File

@ -26,7 +26,7 @@ type GetServiceOK struct {
/*
In: Body
*/
Payload *rest_model_zrok.Service `json:"body,omitempty"`
Payload *rest_model_zrok.Service03 `json:"body,omitempty"`
}
// NewGetServiceOK creates GetServiceOK with default headers values
@ -36,13 +36,13 @@ func NewGetServiceOK() *GetServiceOK {
}
// WithPayload adds the payload to the get service o k response
func (o *GetServiceOK) WithPayload(payload *rest_model_zrok.Service) *GetServiceOK {
func (o *GetServiceOK) WithPayload(payload *rest_model_zrok.Service03) *GetServiceOK {
o.Payload = payload
return o
}
// SetPayload sets the payload to the get service o k response
func (o *GetServiceOK) SetPayload(payload *rest_model_zrok.Service) {
func (o *GetServiceOK) SetPayload(payload *rest_model_zrok.Service03) {
o.Payload = payload
}

View File

@ -211,7 +211,7 @@ paths:
200:
description: ok
schema:
$ref: "#/definitions/service"
$ref: "#/definitions/service03"
401:
description: unauthorized
404:
@ -465,6 +465,8 @@ definitions:
serviceRequest:
type: object
properties:
envZId:
type: string
svcToken:
type: string

View File

@ -20,7 +20,7 @@ export function access(options) {
/**
* @param {object} options Optional options
* @param {module:types.serviceRequest} [options.body]
* @return {Promise<module:types.service>} ok
* @return {Promise<module:types.service03>} ok
*/
export function getService(options) {
if (!options) options = {}

View File

@ -138,6 +138,7 @@
* @typedef serviceRequest
* @memberof module:types
*
* @property {string} envZId
* @property {string} svcToken
*/