adjust admin tooling to support creating open/closed permission mode frontends (#539)

This commit is contained in:
Michael Quigley 2024-06-18 13:38:00 -04:00
parent c2878dcd85
commit 49368dc542
No known key found for this signature in database
GPG Key ID: 9B60314A9DD20A62
15 changed files with 156 additions and 23 deletions

View File

@ -4,6 +4,7 @@ import (
"github.com/openziti/zrok/environment" "github.com/openziti/zrok/environment"
"github.com/openziti/zrok/rest_client_zrok/admin" "github.com/openziti/zrok/rest_client_zrok/admin"
"github.com/openziti/zrok/rest_model_zrok" "github.com/openziti/zrok/rest_model_zrok"
"github.com/openziti/zrok/sdk/golang/sdk"
"github.com/openziti/zrok/tui" "github.com/openziti/zrok/tui"
"github.com/sirupsen/logrus" "github.com/sirupsen/logrus"
"github.com/spf13/cobra" "github.com/spf13/cobra"
@ -15,7 +16,8 @@ func init() {
} }
type adminCreateFrontendCommand struct { type adminCreateFrontendCommand struct {
cmd *cobra.Command cmd *cobra.Command
closed bool
} }
func newAdminCreateFrontendCommand() *adminCreateFrontendCommand { func newAdminCreateFrontendCommand() *adminCreateFrontendCommand {
@ -25,6 +27,7 @@ func newAdminCreateFrontendCommand() *adminCreateFrontendCommand {
Args: cobra.ExactArgs(3), Args: cobra.ExactArgs(3),
} }
command := &adminCreateFrontendCommand{cmd: cmd} command := &adminCreateFrontendCommand{cmd: cmd}
cmd.Flags().BoolVar(&command.closed, "closed", false, "Enabled closed permission mode")
cmd.Run = command.run cmd.Run = command.run
return command return command
} }
@ -44,11 +47,16 @@ func (cmd *adminCreateFrontendCommand) run(_ *cobra.Command, args []string) {
panic(err) panic(err)
} }
permissionMode := sdk.OpenPermissionMode
if cmd.closed {
permissionMode = sdk.ClosedPermissionMode
}
req := admin.NewCreateFrontendParams() req := admin.NewCreateFrontendParams()
req.Body = &rest_model_zrok.CreateFrontendRequest{ req.Body = &rest_model_zrok.CreateFrontendRequest{
ZID: zId, ZID: zId,
PublicName: publicName, PublicName: publicName,
URLTemplate: urlTemplate, URLTemplate: urlTemplate,
PermissionMode: string(permissionMode),
} }
resp, err := zrok.Admin.CreateFrontend(req, mustGetAdminAuth()) resp, err := zrok.Admin.CreateFrontend(req, mustGetAdminAuth())

View File

@ -2,7 +2,6 @@ package controller
import ( import (
"errors" "errors"
"github.com/go-openapi/runtime/middleware" "github.com/go-openapi/runtime/middleware"
"github.com/lib/pq" "github.com/lib/pq"
"github.com/mattn/go-sqlite3" "github.com/mattn/go-sqlite3"
@ -57,11 +56,12 @@ func (h *createFrontendHandler) Handle(params admin.CreateFrontendParams, princi
} }
fe := &store.Frontend{ fe := &store.Frontend{
Token: feToken, Token: feToken,
ZId: params.Body.ZID, ZId: params.Body.ZID,
PublicName: &params.Body.PublicName, PublicName: &params.Body.PublicName,
UrlTemplate: &params.Body.URLTemplate, UrlTemplate: &params.Body.URLTemplate,
Reserved: true, Reserved: true,
PermissionMode: store.PermissionMode(params.Body.PermissionMode),
} }
if _, err := str.CreateGlobalFrontend(fe, tx); err != nil { if _, err := str.CreateGlobalFrontend(fe, tx); err != nil {
perr := &pq.Error{} perr := &pq.Error{}

View File

@ -14,28 +14,28 @@ type Frontend struct {
PublicName *string PublicName *string
UrlTemplate *string UrlTemplate *string
Reserved bool Reserved bool
Deleted bool PermissionMode PermissionMode
} }
func (str *Store) CreateFrontend(envId int, f *Frontend, tx *sqlx.Tx) (int, error) { func (str *Store) CreateFrontend(envId int, f *Frontend, tx *sqlx.Tx) (int, error) {
stmt, err := tx.Prepare("insert into frontends (environment_id, private_share_id, token, z_id, public_name, url_template, reserved) values ($1, $2, $3, $4, $5, $6, $7) returning id") stmt, err := tx.Prepare("insert into frontends (environment_id, private_share_id, token, z_id, public_name, url_template, reserved, permission_mode) values ($1, $2, $3, $4, $5, $6, $7, $8) returning id")
if err != nil { if err != nil {
return 0, errors.Wrap(err, "error preparing frontends insert statement") return 0, errors.Wrap(err, "error preparing frontends insert statement")
} }
var id int var id int
if err := stmt.QueryRow(envId, f.PrivateShareId, f.Token, f.ZId, f.PublicName, f.UrlTemplate, f.Reserved).Scan(&id); err != nil { if err := stmt.QueryRow(envId, f.PrivateShareId, f.Token, f.ZId, f.PublicName, f.UrlTemplate, f.Reserved, f.PermissionMode).Scan(&id); err != nil {
return 0, errors.Wrap(err, "error executing frontends insert statement") return 0, errors.Wrap(err, "error executing frontends insert statement")
} }
return id, nil return id, nil
} }
func (str *Store) CreateGlobalFrontend(f *Frontend, tx *sqlx.Tx) (int, error) { func (str *Store) CreateGlobalFrontend(f *Frontend, tx *sqlx.Tx) (int, error) {
stmt, err := tx.Prepare("insert into frontends (token, z_id, public_name, url_template, reserved) values ($1, $2, $3, $4, $5) returning id") stmt, err := tx.Prepare("insert into frontends (token, z_id, public_name, url_template, reserved, permission_mode) values ($1, $2, $3, $4, $5, $6) returning id")
if err != nil { if err != nil {
return 0, errors.Wrap(err, "error preparing global frontends insert statement") return 0, errors.Wrap(err, "error preparing global frontends insert statement")
} }
var id int var id int
if err := stmt.QueryRow(f.Token, f.ZId, f.PublicName, f.UrlTemplate, f.Reserved).Scan(&id); err != nil { if err := stmt.QueryRow(f.Token, f.ZId, f.PublicName, f.UrlTemplate, f.Reserved, f.PermissionMode).Scan(&id); err != nil {
return 0, errors.Wrap(err, "error executing global frontends insert statement") return 0, errors.Wrap(err, "error executing global frontends insert statement")
} }
return id, nil return id, nil
@ -122,12 +122,12 @@ func (str *Store) FindFrontendsForPrivateShare(shrId int, tx *sqlx.Tx) ([]*Front
} }
func (str *Store) UpdateFrontend(fe *Frontend, tx *sqlx.Tx) error { func (str *Store) UpdateFrontend(fe *Frontend, tx *sqlx.Tx) error {
sql := "update frontends set environment_id = $1, private_share_id = $2, token = $3, z_id = $4, public_name = $5, url_template = $6, reserved = $7, updated_at = current_timestamp where id = $8" sql := "update frontends set environment_id = $1, private_share_id = $2, token = $3, z_id = $4, public_name = $5, url_template = $6, reserved = $7, permission_mode = $8, updated_at = current_timestamp where id = $9"
stmt, err := tx.Prepare(sql) stmt, err := tx.Prepare(sql)
if err != nil { if err != nil {
return errors.Wrap(err, "error preparing frontends update statement") return errors.Wrap(err, "error preparing frontends update statement")
} }
_, err = stmt.Exec(fe.EnvironmentId, fe.PrivateShareId, fe.Token, fe.ZId, fe.PublicName, fe.UrlTemplate, fe.Reserved, fe.Id) _, err = stmt.Exec(fe.EnvironmentId, fe.PrivateShareId, fe.Token, fe.ZId, fe.PublicName, fe.UrlTemplate, fe.Reserved, fe.PermissionMode, fe.Id)
if err != nil { if err != nil {
return errors.Wrap(err, "error executing frontends update statement") return errors.Wrap(err, "error executing frontends update statement")
} }

View File

@ -18,7 +18,6 @@ type Share struct {
Reserved bool Reserved bool
UniqueName bool UniqueName bool
PermissionMode PermissionMode PermissionMode PermissionMode
Deleted bool
} }
func (str *Store) CreateShare(envId int, shr *Share, tx *sqlx.Tx) (int, error) { func (str *Store) CreateShare(envId int, shr *Share, tx *sqlx.Tx) (int, error) {

View File

@ -1,5 +1,7 @@
-- +migrate Up -- +migrate Up
alter table frontends add column permission_mode permission_mode_type not null default('open');
create table frontend_grants ( create table frontend_grants (
id serial primary key, id serial primary key,

View File

@ -1,5 +1,7 @@
-- +migrate Up -- +migrate Up
alter table frontends add column permission_mode string not null default('open');
create table frontend_grants ( create table frontend_grants (
id integer primary key, id integer primary key,

View File

@ -7,9 +7,12 @@ package rest_model_zrok
import ( import (
"context" "context"
"encoding/json"
"github.com/go-openapi/errors"
"github.com/go-openapi/strfmt" "github.com/go-openapi/strfmt"
"github.com/go-openapi/swag" "github.com/go-openapi/swag"
"github.com/go-openapi/validate"
) )
// CreateFrontendRequest create frontend request // CreateFrontendRequest create frontend request
@ -17,6 +20,10 @@ import (
// swagger:model createFrontendRequest // swagger:model createFrontendRequest
type CreateFrontendRequest struct { type CreateFrontendRequest struct {
// permission mode
// Enum: [open closed]
PermissionMode string `json:"permissionMode,omitempty"`
// public name // public name
PublicName string `json:"public_name,omitempty"` PublicName string `json:"public_name,omitempty"`
@ -29,6 +36,57 @@ type CreateFrontendRequest struct {
// Validate validates this create frontend request // Validate validates this create frontend request
func (m *CreateFrontendRequest) Validate(formats strfmt.Registry) error { func (m *CreateFrontendRequest) Validate(formats strfmt.Registry) error {
var res []error
if err := m.validatePermissionMode(formats); err != nil {
res = append(res, err)
}
if len(res) > 0 {
return errors.CompositeValidationError(res...)
}
return nil
}
var createFrontendRequestTypePermissionModePropEnum []interface{}
func init() {
var res []string
if err := json.Unmarshal([]byte(`["open","closed"]`), &res); err != nil {
panic(err)
}
for _, v := range res {
createFrontendRequestTypePermissionModePropEnum = append(createFrontendRequestTypePermissionModePropEnum, v)
}
}
const (
// CreateFrontendRequestPermissionModeOpen captures enum value "open"
CreateFrontendRequestPermissionModeOpen string = "open"
// CreateFrontendRequestPermissionModeClosed captures enum value "closed"
CreateFrontendRequestPermissionModeClosed string = "closed"
)
// prop value enum
func (m *CreateFrontendRequest) validatePermissionModeEnum(path, location string, value string) error {
if err := validate.EnumCase(path, location, value, createFrontendRequestTypePermissionModePropEnum, true); err != nil {
return err
}
return nil
}
func (m *CreateFrontendRequest) validatePermissionMode(formats strfmt.Registry) error {
if swag.IsZero(m.PermissionMode) { // not required
return nil
}
// value enum
if err := m.validatePermissionModeEnum("permissionMode", "body", m.PermissionMode); err != nil {
return err
}
return nil return nil
} }

View File

@ -1200,6 +1200,13 @@ func init() {
"createFrontendRequest": { "createFrontendRequest": {
"type": "object", "type": "object",
"properties": { "properties": {
"permissionMode": {
"type": "string",
"enum": [
"open",
"closed"
]
},
"public_name": { "public_name": {
"type": "string" "type": "string"
}, },
@ -2956,6 +2963,13 @@ func init() {
"createFrontendRequest": { "createFrontendRequest": {
"type": "object", "type": "object",
"properties": { "properties": {
"permissionMode": {
"type": "string",
"enum": [
"open",
"closed"
]
},
"public_name": { "public_name": {
"type": "string" "type": "string"
}, },

View File

@ -1 +1 @@
7.4.0 7.6.0

View File

@ -16,6 +16,7 @@ export class CreateFrontendRequest {
'zId'?: string; 'zId'?: string;
'urlTemplate'?: string; 'urlTemplate'?: string;
'publicName'?: string; 'publicName'?: string;
'permissionMode'?: CreateFrontendRequest.PermissionModeEnum;
static discriminator: string | undefined = undefined; static discriminator: string | undefined = undefined;
@ -34,6 +35,11 @@ export class CreateFrontendRequest {
"name": "publicName", "name": "publicName",
"baseName": "public_name", "baseName": "public_name",
"type": "string" "type": "string"
},
{
"name": "permissionMode",
"baseName": "permissionMode",
"type": "CreateFrontendRequest.PermissionModeEnum"
} ]; } ];
static getAttributeTypeMap() { static getAttributeTypeMap() {
@ -41,3 +47,9 @@ export class CreateFrontendRequest {
} }
} }
export namespace CreateFrontendRequest {
export enum PermissionModeEnum {
Open = <any> 'open',
Closed = <any> 'closed'
}
}

View File

@ -108,6 +108,7 @@ let primitives = [
]; ];
let enumsMap: {[index: string]: any} = { let enumsMap: {[index: string]: any} = {
"CreateFrontendRequest.PermissionModeEnum": CreateFrontendRequest.PermissionModeEnum,
"ShareRequest.ShareModeEnum": ShareRequest.ShareModeEnum, "ShareRequest.ShareModeEnum": ShareRequest.ShareModeEnum,
"ShareRequest.BackendModeEnum": ShareRequest.BackendModeEnum, "ShareRequest.BackendModeEnum": ShareRequest.BackendModeEnum,
"ShareRequest.OauthProviderEnum": ShareRequest.OauthProviderEnum, "ShareRequest.OauthProviderEnum": ShareRequest.OauthProviderEnum,

View File

@ -120,7 +120,8 @@ export namespace ShareRequest {
UdpTunnel = <any> 'udpTunnel', UdpTunnel = <any> 'udpTunnel',
Caddy = <any> 'caddy', Caddy = <any> 'caddy',
Drive = <any> 'drive', Drive = <any> 'drive',
Socks = <any> 'socks' Socks = <any> 'socks',
Vpn = <any> 'vpn'
} }
export enum OauthProviderEnum { export enum OauthProviderEnum {
Github = <any> 'github', Github = <any> 'github',

View File

@ -30,20 +30,23 @@ class CreateFrontendRequest(object):
swagger_types = { swagger_types = {
'z_id': 'str', 'z_id': 'str',
'url_template': 'str', 'url_template': 'str',
'public_name': 'str' 'public_name': 'str',
'permission_mode': 'str'
} }
attribute_map = { attribute_map = {
'z_id': 'zId', 'z_id': 'zId',
'url_template': 'url_template', 'url_template': 'url_template',
'public_name': 'public_name' 'public_name': 'public_name',
'permission_mode': 'permissionMode'
} }
def __init__(self, z_id=None, url_template=None, public_name=None): # noqa: E501 def __init__(self, z_id=None, url_template=None, public_name=None, permission_mode=None): # noqa: E501
"""CreateFrontendRequest - a model defined in Swagger""" # noqa: E501 """CreateFrontendRequest - a model defined in Swagger""" # noqa: E501
self._z_id = None self._z_id = None
self._url_template = None self._url_template = None
self._public_name = None self._public_name = None
self._permission_mode = None
self.discriminator = None self.discriminator = None
if z_id is not None: if z_id is not None:
self.z_id = z_id self.z_id = z_id
@ -51,6 +54,8 @@ class CreateFrontendRequest(object):
self.url_template = url_template self.url_template = url_template
if public_name is not None: if public_name is not None:
self.public_name = public_name self.public_name = public_name
if permission_mode is not None:
self.permission_mode = permission_mode
@property @property
def z_id(self): def z_id(self):
@ -115,6 +120,33 @@ class CreateFrontendRequest(object):
self._public_name = public_name self._public_name = public_name
@property
def permission_mode(self):
"""Gets the permission_mode of this CreateFrontendRequest. # noqa: E501
:return: The permission_mode of this CreateFrontendRequest. # noqa: E501
:rtype: str
"""
return self._permission_mode
@permission_mode.setter
def permission_mode(self, permission_mode):
"""Sets the permission_mode of this CreateFrontendRequest.
:param permission_mode: The permission_mode of this CreateFrontendRequest. # noqa: E501
:type: str
"""
allowed_values = ["open", "closed"] # noqa: E501
if permission_mode not in allowed_values:
raise ValueError(
"Invalid value for `permission_mode` ({0}), must be one of {1}" # noqa: E501
.format(permission_mode, allowed_values)
)
self._permission_mode = permission_mode
def to_dict(self): def to_dict(self):
"""Returns the model properties as a dict""" """Returns the model properties as a dict"""
result = {} result = {}

View File

@ -766,6 +766,9 @@ definitions:
type: string type: string
public_name: public_name:
type: string type: string
permissionMode:
type: string
enum: ["open", "closed"]
createFrontendResponse: createFrontendResponse:
type: object type: object

View File

@ -53,6 +53,7 @@
* @property {string} zId * @property {string} zId
* @property {string} url_template * @property {string} url_template
* @property {string} public_name * @property {string} public_name
* @property {string} permissionMode
*/ */
/** /**