api improvements

This commit is contained in:
Michael Quigley 2022-07-27 13:38:35 -04:00
parent d44ebb9e80
commit 4311d89526
No known key found for this signature in database
GPG Key ID: 9B60314A9DD20A62
17 changed files with 284 additions and 75 deletions

View File

@ -7,22 +7,21 @@ import (
"github.com/openziti-test-kitchen/zrok/controller/store"
"github.com/openziti-test-kitchen/zrok/rest_model_zrok"
"github.com/openziti-test-kitchen/zrok/rest_server_zrok/operations/identity"
"github.com/pkg/errors"
"github.com/sirupsen/logrus"
)
func createAccountHandler(params identity.CreateAccountParams) middleware.Responder {
logrus.Infof("received account request for username '%v'", params.Body.Username)
if params.Body == nil || params.Body.Username == "" || params.Body.Password == "" {
return middleware.Error(500, errors.Errorf("invalid username or password"))
logrus.Errorf("missing username or password")
return identity.NewCreateAccountBadRequest().WithPayload(rest_model_zrok.ErrorMessage("missing username or password"))
}
token, err := generateApiToken()
if err != nil {
logrus.Errorf("error generating api token: %v", err)
return middleware.Error(500, err.Error())
return identity.NewCreateAccountInternalServerError().WithPayload(rest_model_zrok.ErrorMessage(err.Error()))
}
a := &store.Account{
Username: params.Body.Username,
Password: hashPassword(params.Body.Password),
@ -31,22 +30,20 @@ func createAccountHandler(params identity.CreateAccountParams) middleware.Respon
tx, err := str.Begin()
if err != nil {
logrus.Errorf("error starting transaction: %v", err)
return middleware.Error(500, err.Error())
return identity.NewCreateAccountInternalServerError().WithPayload(rest_model_zrok.ErrorMessage(err.Error()))
}
id, err := str.CreateAccount(a, tx)
if err != nil {
logrus.Errorf("error creating account: %v", err)
_ = tx.Rollback()
return middleware.Error(400, err.Error())
return identity.NewCreateAccountBadRequest().WithPayload(rest_model_zrok.ErrorMessage(err.Error()))
}
if err := tx.Commit(); err != nil {
logrus.Errorf("error comitting: %v", err)
}
logrus.Infof("account created with id = '%v'", id)
return identity.NewCreateAccountCreated().WithPayload(&rest_model_zrok.AccountResponse{
Token: token,
})
return identity.NewCreateAccountCreated().WithPayload(&rest_model_zrok.AccountResponse{Token: token})
}
func hashPassword(raw string) string {

View File

@ -16,12 +16,6 @@ import (
var str *store.Store
func Run(cfg *Config) error {
if v, err := store.Open(cfg.Store); err == nil {
str = v
} else {
return errors.Wrap(err, "error opening store")
}
swaggerSpec, err := loads.Embedded(rest_server_zrok.SwaggerJSON, rest_server_zrok.FlatSwaggerJSON)
if err != nil {
return errors.Wrap(err, "error loading embedded swagger spec")
@ -34,6 +28,12 @@ func Run(cfg *Config) error {
api.TunnelTunnelHandler = tunnel.TunnelHandlerFunc(tunnelHandler)
api.TunnelUntunnelHandler = tunnel.UntunnelHandlerFunc(untunnelHandler)
if v, err := store.Open(cfg.Store); err == nil {
str = v
} else {
return errors.Wrap(err, "error opening store")
}
server := rest_server_zrok.NewServer(api)
defer func() { _ = server.Shutdown() }()
server.Host = cfg.Host

View File

@ -22,33 +22,33 @@ func enableHandler(params identity.EnableParams) middleware.Responder {
tx, err := str.Begin()
if err != nil {
logrus.Errorf("error starting transaction: %v", err)
return middleware.Error(500, err.Error())
return identity.NewCreateAccountInternalServerError().WithPayload(rest_model_zrok.ErrorMessage(err.Error()))
}
a, err := str.FindAccountWithToken(params.Body.Token, tx)
if err != nil {
logrus.Errorf("error finding account: %v", err)
return middleware.Error(500, err.Error())
return identity.NewCreateAccountBadRequest().WithPayload(rest_model_zrok.ErrorMessage(err.Error()))
}
if a == nil {
logrus.Errorf("account not found: %v", err)
return middleware.Error(404, err.Error())
return identity.NewEnableNotFound()
}
logrus.Infof("found account '%v'", a.Username)
client, err := edgeClient()
if err != nil {
logrus.Errorf("error getting edge client: %v", err)
return middleware.Error(500, err.Error())
return identity.NewEnableInternalServerError().WithPayload(rest_model_zrok.ErrorMessage(err.Error()))
}
ident, err := createIdentity(a, client)
if err != nil {
logrus.Error(err)
return middleware.Error(500, err.Error())
return identity.NewEnableInternalServerError().WithPayload(rest_model_zrok.ErrorMessage(err.Error()))
}
cfg, err := enrollIdentity(ident.Payload.Data.ID, client)
if err != nil {
logrus.Error(err)
return middleware.Error(500, err.Error())
return identity.NewEnableInternalServerError().WithPayload(rest_model_zrok.ErrorMessage(err.Error()))
}
resp := identity.NewEnableCreated().WithPayload(&rest_model_zrok.EnableResponse{
@ -73,24 +73,24 @@ func createIdentity(a *store.Account, client *rest_management_api_client.ZitiEdg
if err != nil {
return nil, err
}
iName := fmt.Sprintf("%v-%v", a.Username, iId)
iType := rest_model_edge.IdentityTypeUser
name := fmt.Sprintf("%v-%v", a.Username, iId)
identityType := rest_model_edge.IdentityTypeUser
i := &rest_model_edge.IdentityCreate{
Enrollment: &rest_model_edge.IdentityCreateEnrollment{Ott: true},
IsAdmin: &iIsAdmin,
Name: &iName,
Name: &name,
RoleAttributes: nil,
ServiceHostingCosts: nil,
Tags: nil,
Type: &iType,
Type: &identityType,
}
p := identity_edge.NewCreateIdentityParams()
p.Identity = i
ident, err := client.Identity.CreateIdentity(p, nil)
req := identity_edge.NewCreateIdentityParams()
req.Identity = i
resp, err := client.Identity.CreateIdentity(req, nil)
if err != nil {
return nil, err
}
return ident, nil
return resp, nil
}
func enrollIdentity(id string, client *rest_management_api_client.ZitiEdgeManagement) (*sdk_config.Config, error) {

View File

@ -4,6 +4,7 @@ import (
"context"
"fmt"
"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/tunnel"
"github.com/openziti/edge/rest_management_api_client"
"github.com/openziti/edge/rest_management_api_client/edge_router_policy"
@ -39,7 +40,7 @@ func untunnelHandler(params tunnel.UntunnelParams) middleware.Responder {
}
if err := deleteService(svcName, edge); err != nil {
logrus.Error(err)
return tunnel.NewUntunnelInternalServerError()
return tunnel.NewUntunnelInternalServerError().WithPayload(rest_model_zrok.ErrorMessage(err.Error()))
}
logrus.Infof("deallocated service '%v'", svcName)

View File

@ -2,10 +2,26 @@ package controller
import (
"crypto/rand"
"crypto/x509"
"encoding/hex"
"github.com/openziti/edge/rest_management_api_client"
"github.com/openziti/edge/rest_util"
"github.com/pkg/errors"
)
func edgeClient() (*rest_management_api_client.ZitiEdgeManagement, error) {
ctrlAddress := "https://linux:1280"
caCerts, err := rest_util.GetControllerWellKnownCas(ctrlAddress)
if err != nil {
return nil, err
}
caPool := x509.NewCertPool()
for _, ca := range caCerts {
caPool.AddCert(ca)
}
return rest_util.NewEdgeManagementClientWithUpdb("admin", "admin", ctrlAddress, caPool)
}
func generateApiToken() (string, error) {
bytes := make([]byte, 64)
if _, err := rand.Read(bytes); err != nil {

View File

@ -1,20 +0,0 @@
package controller
import (
"crypto/x509"
"github.com/openziti/edge/rest_management_api_client"
"github.com/openziti/edge/rest_util"
)
func edgeClient() (*rest_management_api_client.ZitiEdgeManagement, error) {
ctrlAddress := "https://linux:1280"
caCerts, err := rest_util.GetControllerWellKnownCas(ctrlAddress)
if err != nil {
return nil, err
}
caPool := x509.NewCertPool()
for _, ca := range caCerts {
caPool.AddCert(ca)
}
return rest_util.NewEdgeManagementClientWithUpdb("admin", "admin", ctrlAddress, caPool)
}

View File

@ -88,14 +88,23 @@ func NewCreateAccountBadRequest() *CreateAccountBadRequest {
account not created (already exists)
*/
type CreateAccountBadRequest struct {
Payload rest_model_zrok.ErrorMessage
}
func (o *CreateAccountBadRequest) Error() string {
return fmt.Sprintf("[POST /account][%d] createAccountBadRequest ", 400)
return fmt.Sprintf("[POST /account][%d] createAccountBadRequest %+v", 400, o.Payload)
}
func (o *CreateAccountBadRequest) GetPayload() rest_model_zrok.ErrorMessage {
return o.Payload
}
func (o *CreateAccountBadRequest) readResponse(response runtime.ClientResponse, consumer runtime.Consumer, formats strfmt.Registry) error {
// response payload
if err := consumer.Consume(response.Body(), &o.Payload); err != nil && err != io.EOF {
return err
}
return nil
}
@ -109,13 +118,22 @@ func NewCreateAccountInternalServerError() *CreateAccountInternalServerError {
internal server error
*/
type CreateAccountInternalServerError struct {
Payload rest_model_zrok.ErrorMessage
}
func (o *CreateAccountInternalServerError) Error() string {
return fmt.Sprintf("[POST /account][%d] createAccountInternalServerError ", 500)
return fmt.Sprintf("[POST /account][%d] createAccountInternalServerError %+v", 500, o.Payload)
}
func (o *CreateAccountInternalServerError) GetPayload() rest_model_zrok.ErrorMessage {
return o.Payload
}
func (o *CreateAccountInternalServerError) readResponse(response runtime.ClientResponse, consumer runtime.Consumer, formats strfmt.Registry) error {
// response payload
if err := consumer.Consume(response.Body(), &o.Payload); err != nil && err != io.EOF {
return err
}
return nil
}

View File

@ -109,13 +109,22 @@ func NewEnableInternalServerError() *EnableInternalServerError {
internal server error
*/
type EnableInternalServerError struct {
Payload rest_model_zrok.ErrorMessage
}
func (o *EnableInternalServerError) Error() string {
return fmt.Sprintf("[POST /enable][%d] enableInternalServerError ", 500)
return fmt.Sprintf("[POST /enable][%d] enableInternalServerError %+v", 500, o.Payload)
}
func (o *EnableInternalServerError) GetPayload() rest_model_zrok.ErrorMessage {
return o.Payload
}
func (o *EnableInternalServerError) readResponse(response runtime.ClientResponse, consumer runtime.Consumer, formats strfmt.Registry) error {
// response payload
if err := consumer.Consume(response.Body(), &o.Payload); err != nil && err != io.EOF {
return err
}
return nil
}

View File

@ -82,13 +82,22 @@ func NewTunnelInternalServerError() *TunnelInternalServerError {
internal server error
*/
type TunnelInternalServerError struct {
Payload rest_model_zrok.ErrorMessage
}
func (o *TunnelInternalServerError) Error() string {
return fmt.Sprintf("[POST /tunnel][%d] tunnelInternalServerError ", 500)
return fmt.Sprintf("[POST /tunnel][%d] tunnelInternalServerError %+v", 500, o.Payload)
}
func (o *TunnelInternalServerError) GetPayload() rest_model_zrok.ErrorMessage {
return o.Payload
}
func (o *TunnelInternalServerError) readResponse(response runtime.ClientResponse, consumer runtime.Consumer, formats strfmt.Registry) error {
// response payload
if err := consumer.Consume(response.Body(), &o.Payload); err != nil && err != io.EOF {
return err
}
return nil
}

View File

@ -7,9 +7,12 @@ package tunnel
import (
"fmt"
"io"
"github.com/go-openapi/runtime"
"github.com/go-openapi/strfmt"
"github.com/openziti-test-kitchen/zrok/rest_model_zrok"
)
// UntunnelReader is a Reader for the Untunnel structure.
@ -68,13 +71,22 @@ func NewUntunnelInternalServerError() *UntunnelInternalServerError {
internal server error
*/
type UntunnelInternalServerError struct {
Payload rest_model_zrok.ErrorMessage
}
func (o *UntunnelInternalServerError) Error() string {
return fmt.Sprintf("[DELETE /untunnel][%d] untunnelInternalServerError ", 500)
return fmt.Sprintf("[DELETE /untunnel][%d] untunnelInternalServerError %+v", 500, o.Payload)
}
func (o *UntunnelInternalServerError) GetPayload() rest_model_zrok.ErrorMessage {
return o.Payload
}
func (o *UntunnelInternalServerError) readResponse(response runtime.ClientResponse, consumer runtime.Consumer, formats strfmt.Registry) error {
// response payload
if err := consumer.Consume(response.Body(), &o.Payload); err != nil && err != io.EOF {
return err
}
return nil
}

View File

@ -0,0 +1,27 @@
// 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"
)
// ErrorMessage error message
//
// swagger:model errorMessage
type ErrorMessage string
// Validate validates this error message
func (m ErrorMessage) Validate(formats strfmt.Registry) error {
return nil
}
// ContextValidate validates this error message based on context it is used
func (m ErrorMessage) ContextValidate(ctx context.Context, formats strfmt.Registry) error {
return nil
}

View File

@ -57,10 +57,16 @@ func init() {
}
},
"400": {
"description": "account not created (already exists)"
"description": "account not created (already exists)",
"schema": {
"$ref": "#/definitions/errorMessage"
}
},
"500": {
"description": "internal server error"
"description": "internal server error",
"schema": {
"$ref": "#/definitions/errorMessage"
}
}
}
}
@ -91,7 +97,10 @@ func init() {
"description": "account not found"
},
"500": {
"description": "internal server error"
"description": "internal server error",
"schema": {
"$ref": "#/definitions/errorMessage"
}
}
}
}
@ -119,7 +128,10 @@ func init() {
}
},
"500": {
"description": "internal server error"
"description": "internal server error",
"schema": {
"$ref": "#/definitions/errorMessage"
}
}
}
}
@ -144,7 +156,10 @@ func init() {
"description": "tunnel removed"
},
"500": {
"description": "internal server error"
"description": "internal server error",
"schema": {
"$ref": "#/definitions/errorMessage"
}
}
}
}
@ -205,6 +220,9 @@ func init() {
}
}
},
"errorMessage": {
"type": "string"
},
"tunnelRequest": {
"type": "object",
"properties": {
@ -282,10 +300,16 @@ func init() {
}
},
"400": {
"description": "account not created (already exists)"
"description": "account not created (already exists)",
"schema": {
"$ref": "#/definitions/errorMessage"
}
},
"500": {
"description": "internal server error"
"description": "internal server error",
"schema": {
"$ref": "#/definitions/errorMessage"
}
}
}
}
@ -316,7 +340,10 @@ func init() {
"description": "account not found"
},
"500": {
"description": "internal server error"
"description": "internal server error",
"schema": {
"$ref": "#/definitions/errorMessage"
}
}
}
}
@ -344,7 +371,10 @@ func init() {
}
},
"500": {
"description": "internal server error"
"description": "internal server error",
"schema": {
"$ref": "#/definitions/errorMessage"
}
}
}
}
@ -369,7 +399,10 @@ func init() {
"description": "tunnel removed"
},
"500": {
"description": "internal server error"
"description": "internal server error",
"schema": {
"$ref": "#/definitions/errorMessage"
}
}
}
}
@ -430,6 +463,9 @@ func init() {
}
}
},
"errorMessage": {
"type": "string"
},
"tunnelRequest": {
"type": "object",
"properties": {

View File

@ -65,6 +65,11 @@ const CreateAccountBadRequestCode int = 400
swagger:response createAccountBadRequest
*/
type CreateAccountBadRequest struct {
/*
In: Body
*/
Payload rest_model_zrok.ErrorMessage `json:"body,omitempty"`
}
// NewCreateAccountBadRequest creates CreateAccountBadRequest with default headers values
@ -73,12 +78,25 @@ func NewCreateAccountBadRequest() *CreateAccountBadRequest {
return &CreateAccountBadRequest{}
}
// WithPayload adds the payload to the create account bad request response
func (o *CreateAccountBadRequest) WithPayload(payload rest_model_zrok.ErrorMessage) *CreateAccountBadRequest {
o.Payload = payload
return o
}
// SetPayload sets the payload to the create account bad request response
func (o *CreateAccountBadRequest) SetPayload(payload rest_model_zrok.ErrorMessage) {
o.Payload = payload
}
// WriteResponse to the client
func (o *CreateAccountBadRequest) WriteResponse(rw http.ResponseWriter, producer runtime.Producer) {
rw.Header().Del(runtime.HeaderContentType) //Remove Content-Type on empty responses
rw.WriteHeader(400)
payload := o.Payload
if err := producer.Produce(rw, payload); err != nil {
panic(err) // let the recovery middleware deal with this
}
}
// CreateAccountInternalServerErrorCode is the HTTP code returned for type CreateAccountInternalServerError
@ -89,6 +107,11 @@ const CreateAccountInternalServerErrorCode int = 500
swagger:response createAccountInternalServerError
*/
type CreateAccountInternalServerError struct {
/*
In: Body
*/
Payload rest_model_zrok.ErrorMessage `json:"body,omitempty"`
}
// NewCreateAccountInternalServerError creates CreateAccountInternalServerError with default headers values
@ -97,10 +120,23 @@ func NewCreateAccountInternalServerError() *CreateAccountInternalServerError {
return &CreateAccountInternalServerError{}
}
// WithPayload adds the payload to the create account internal server error response
func (o *CreateAccountInternalServerError) WithPayload(payload rest_model_zrok.ErrorMessage) *CreateAccountInternalServerError {
o.Payload = payload
return o
}
// SetPayload sets the payload to the create account internal server error response
func (o *CreateAccountInternalServerError) SetPayload(payload rest_model_zrok.ErrorMessage) {
o.Payload = payload
}
// WriteResponse to the client
func (o *CreateAccountInternalServerError) WriteResponse(rw http.ResponseWriter, producer runtime.Producer) {
rw.Header().Del(runtime.HeaderContentType) //Remove Content-Type on empty responses
rw.WriteHeader(500)
payload := o.Payload
if err := producer.Produce(rw, payload); err != nil {
panic(err) // let the recovery middleware deal with this
}
}

View File

@ -89,6 +89,11 @@ const EnableInternalServerErrorCode int = 500
swagger:response enableInternalServerError
*/
type EnableInternalServerError struct {
/*
In: Body
*/
Payload rest_model_zrok.ErrorMessage `json:"body,omitempty"`
}
// NewEnableInternalServerError creates EnableInternalServerError with default headers values
@ -97,10 +102,23 @@ func NewEnableInternalServerError() *EnableInternalServerError {
return &EnableInternalServerError{}
}
// WithPayload adds the payload to the enable internal server error response
func (o *EnableInternalServerError) WithPayload(payload rest_model_zrok.ErrorMessage) *EnableInternalServerError {
o.Payload = payload
return o
}
// SetPayload sets the payload to the enable internal server error response
func (o *EnableInternalServerError) SetPayload(payload rest_model_zrok.ErrorMessage) {
o.Payload = payload
}
// WriteResponse to the client
func (o *EnableInternalServerError) WriteResponse(rw http.ResponseWriter, producer runtime.Producer) {
rw.Header().Del(runtime.HeaderContentType) //Remove Content-Type on empty responses
rw.WriteHeader(500)
payload := o.Payload
if err := producer.Produce(rw, payload); err != nil {
panic(err) // let the recovery middleware deal with this
}
}

View File

@ -65,6 +65,11 @@ const TunnelInternalServerErrorCode int = 500
swagger:response tunnelInternalServerError
*/
type TunnelInternalServerError struct {
/*
In: Body
*/
Payload rest_model_zrok.ErrorMessage `json:"body,omitempty"`
}
// NewTunnelInternalServerError creates TunnelInternalServerError with default headers values
@ -73,10 +78,23 @@ func NewTunnelInternalServerError() *TunnelInternalServerError {
return &TunnelInternalServerError{}
}
// WithPayload adds the payload to the tunnel internal server error response
func (o *TunnelInternalServerError) WithPayload(payload rest_model_zrok.ErrorMessage) *TunnelInternalServerError {
o.Payload = payload
return o
}
// SetPayload sets the payload to the tunnel internal server error response
func (o *TunnelInternalServerError) SetPayload(payload rest_model_zrok.ErrorMessage) {
o.Payload = payload
}
// WriteResponse to the client
func (o *TunnelInternalServerError) WriteResponse(rw http.ResponseWriter, producer runtime.Producer) {
rw.Header().Del(runtime.HeaderContentType) //Remove Content-Type on empty responses
rw.WriteHeader(500)
payload := o.Payload
if err := producer.Produce(rw, payload); err != nil {
panic(err) // let the recovery middleware deal with this
}
}

View File

@ -9,6 +9,8 @@ import (
"net/http"
"github.com/go-openapi/runtime"
"github.com/openziti-test-kitchen/zrok/rest_model_zrok"
)
// UntunnelOKCode is the HTTP code returned for type UntunnelOK
@ -43,6 +45,11 @@ const UntunnelInternalServerErrorCode int = 500
swagger:response untunnelInternalServerError
*/
type UntunnelInternalServerError struct {
/*
In: Body
*/
Payload rest_model_zrok.ErrorMessage `json:"body,omitempty"`
}
// NewUntunnelInternalServerError creates UntunnelInternalServerError with default headers values
@ -51,10 +58,23 @@ func NewUntunnelInternalServerError() *UntunnelInternalServerError {
return &UntunnelInternalServerError{}
}
// WithPayload adds the payload to the untunnel internal server error response
func (o *UntunnelInternalServerError) WithPayload(payload rest_model_zrok.ErrorMessage) *UntunnelInternalServerError {
o.Payload = payload
return o
}
// SetPayload sets the payload to the untunnel internal server error response
func (o *UntunnelInternalServerError) SetPayload(payload rest_model_zrok.ErrorMessage) {
o.Payload = payload
}
// WriteResponse to the client
func (o *UntunnelInternalServerError) WriteResponse(rw http.ResponseWriter, producer runtime.Producer) {
rw.Header().Del(runtime.HeaderContentType) //Remove Content-Type on empty responses
rw.WriteHeader(500)
payload := o.Payload
if err := producer.Produce(rw, payload); err != nil {
panic(err) // let the recovery middleware deal with this
}
}

View File

@ -21,8 +21,12 @@ paths:
$ref: "#/definitions/accountResponse"
400:
description: account not created (already exists)
schema:
$ref: "#/definitions/errorMessage"
500:
description: internal server error
schema:
$ref: "#/definitions/errorMessage"
/enable:
post:
tags:
@ -42,6 +46,8 @@ paths:
description: account not found
500:
description: internal server error
schema:
$ref: "#/definitions/errorMessage"
/tunnel:
post:
tags:
@ -59,6 +65,8 @@ paths:
$ref: "#/definitions/tunnelResponse"
500:
description: internal server error
schema:
$ref: "#/definitions/errorMessage"
/untunnel:
delete:
tags:
@ -74,6 +82,8 @@ paths:
description: tunnel removed
500:
description: internal server error
schema:
$ref: "#/definitions/errorMessage"
/version:
get:
tags:
@ -115,6 +125,8 @@ definitions:
type: string
cfg:
type: string
errorMessage:
type: string
tunnelRequest:
type: object
properties: