Skip to content

Commit

Permalink
Merge pull request #1136 from openziti/raft-transit-routers
Browse files Browse the repository at this point in the history
Convert transit routers to use raft commands. Fixes #1132
  • Loading branch information
plorenz authored Aug 11, 2022
2 parents 6302b24 + 4ce51b2 commit 7b7b43d
Show file tree
Hide file tree
Showing 6 changed files with 564 additions and 174 deletions.
6 changes: 3 additions & 3 deletions controller/internal/routes/router_router.go
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,7 @@ func (r *TransitRouterRouter) Detail(ae *env.AppEnv, rc *response.RequestContext

func (r *TransitRouterRouter) Create(ae *env.AppEnv, rc *response.RequestContext, router *rest_model.RouterCreate) {
Create(rc, rc, TransitRouterLinkFactory, func() (string, error) {
return ae.Managers.TransitRouter.Create(MapCreateRouterToModel(router))
return MapCreate(ae.Managers.TransitRouter.Create, MapCreateRouterToModel(router))
})
}

Expand All @@ -113,12 +113,12 @@ func (r *TransitRouterRouter) Delete(ae *env.AppEnv, rc *response.RequestContext

func (r *TransitRouterRouter) Update(ae *env.AppEnv, rc *response.RequestContext, routerId string, router *rest_model.RouterUpdate) {
Update(rc, func(id string) error {
return ae.Managers.TransitRouter.Update(MapUpdateTransitRouterToModel(routerId, router), false)
return ae.Managers.TransitRouter.Update(MapUpdateTransitRouterToModel(routerId, router), false, nil)
})
}

func (r *TransitRouterRouter) Patch(ae *env.AppEnv, rc *response.RequestContext, routerId string, router *rest_model.RouterPatch) {
Patch(rc, func(id string, fields fields.UpdatedFields) error {
return ae.Managers.TransitRouter.Patch(MapPatchTransitRouterToModel(routerId, router), fields.ConcatNestedNames().FilterMaps("tags"), false)
return ae.Managers.TransitRouter.Update(MapPatchTransitRouterToModel(routerId, router), false, fields.ConcatNestedNames().FilterMaps("tags"))
})
}
2 changes: 1 addition & 1 deletion controller/model/enrollment_mod_trott.go
Original file line number Diff line number Diff line change
Expand Up @@ -128,7 +128,7 @@ func (module *EnrollModuleRouterOtt) Process(context EnrollmentContext) (*Enroll
txRouter.IsVerified = true
txRouter.Fingerprint = &cltFp

if err := module.env.GetManagers().TransitRouter.Update(txRouter, true); err != nil {
if err := module.env.GetManagers().TransitRouter.Update(txRouter, true, nil); err != nil {
return nil, fmt.Errorf("could not update edge router: %s", err)
}

Expand Down
217 changes: 156 additions & 61 deletions controller/model/transit_router_manager.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,11 +22,16 @@ import (
"github.com/openziti/edge/controller/apierror"
"github.com/openziti/edge/controller/persistence"
"github.com/openziti/edge/eid"
"github.com/openziti/edge/pb/edge_cmd_pb"
"github.com/openziti/fabric/controller/command"
"github.com/openziti/fabric/controller/db"
"github.com/openziti/fabric/controller/fields"
"github.com/openziti/fabric/controller/models"
"github.com/openziti/fabric/controller/network"
"github.com/openziti/storage/boltz"
"github.com/pkg/errors"
"go.etcd.io/bbolt"
"google.golang.org/protobuf/proto"
)

func NewTransitRouterManager(env Env) *TransitRouterManager {
Expand All @@ -38,6 +43,11 @@ func NewTransitRouterManager(env Env) *TransitRouterManager {
},
}
manager.impl = manager

network.RegisterUpdateDecoder[*TransitRouter](env.GetHostController().GetNetwork().Managers, manager)
network.RegisterDeleteDecoder(env.GetHostController().GetNetwork().Managers, manager)
RegisterCommand(env, &CreateTransitRouterCmd{}, &edge_cmd_pb.CreateTransitRouterCmd{})

return manager
}

Expand All @@ -46,32 +56,35 @@ type TransitRouterManager struct {
allowedFields boltz.FieldChecker
}

func (self *TransitRouterManager) Delete(id string) error {
return self.deleteEntity(id)
}

func (self *TransitRouterManager) newModelEntity() edgeEntity {
return &TransitRouter{}
}

func (self *TransitRouterManager) Create(entity *TransitRouter) (string, error) {
func (self *TransitRouterManager) Create(txRouter *TransitRouter) error {
if txRouter.Id == "" {
txRouter.Id = eid.New()
}

enrollment := &Enrollment{
BaseEntity: models.BaseEntity{},
Method: MethodEnrollTransitRouterOtt,
BaseEntity: models.BaseEntity{},
Method: MethodEnrollTransitRouterOtt,
TransitRouterId: &txRouter.Id,
}

cmd := &CreateTransitRouterCmd{
manager: self,
router: txRouter,
enrollment: enrollment,
}

id, _, err := self.CreateWithEnrollment(entity, enrollment)
return id, err
return self.Dispatch(cmd)
}

func (self *TransitRouterManager) CreateWithEnrollment(txRouter *TransitRouter, enrollment *Enrollment) (string, string, error) {
func (self *TransitRouterManager) ApplyCreate(cmd *CreateTransitRouterCmd) error {
txRouter := cmd.router
enrollment := cmd.enrollment

if txRouter.Id == "" {
txRouter.Id = eid.New()
}
var enrollmentId string

err := self.GetDb().Update(func(tx *bbolt.Tx) error {
return self.GetDb().Update(func(tx *bbolt.Tx) error {
ctx := boltz.NewMutateContext(tx)
boltEntity, err := txRouter.toBoltEntityForCreate(tx, self.impl)
if err != nil {
Expand All @@ -82,31 +95,16 @@ func (self *TransitRouterManager) CreateWithEnrollment(txRouter *TransitRouter,
return err
}

enrollment.TransitRouterId = &txRouter.Id

err = enrollment.FillJwtInfo(self.env, txRouter.Id)

if err != nil {
if err = enrollment.FillJwtInfo(self.env, txRouter.Id); err != nil {
return err
}

enrollmentId, err = self.env.GetManagers().Enrollment.createEntityInTx(ctx, enrollment)

if err != nil {
return err
}

return nil
_, err = self.env.GetManagers().Enrollment.createEntityInTx(ctx, enrollment)
return err
})

if err != nil {
return "", "", err
}

return txRouter.Id, enrollmentId, nil
}

func (self *TransitRouterManager) Update(entity *TransitRouter, allowAllFields bool) error {
func (self *TransitRouterManager) Update(entity *TransitRouter, unrestricted bool, checker fields.UpdatedFields) error {
curEntity, err := self.Read(entity.Id)

if err != nil {
Expand All @@ -117,30 +115,27 @@ func (self *TransitRouterManager) Update(entity *TransitRouter, allowAllFields b
return apierror.NewFabricRouterCannotBeUpdate()
}

if allowAllFields {
return self.updateEntity(entity, nil)
cmd := &command.UpdateEntityCommand[*TransitRouter]{
Updater: self,
Entity: entity,
UpdatedFields: checker,
}

return self.updateEntity(entity, self.allowedFields)

}

func (self *TransitRouterManager) Patch(entity *TransitRouter, checker boltz.FieldChecker, allowAllFields bool) error {
curEntity, err := self.Read(entity.Id)

if err != nil {
return err
}

if curEntity.IsBase {
return apierror.NewFabricRouterCannotBeUpdate()
if unrestricted {
cmd.Flags = updateUnrestricted
}
return self.Dispatch(cmd)
}

if allowAllFields {
return self.patchEntity(entity, checker)
func (self *TransitRouterManager) ApplyUpdate(cmd *command.UpdateEntityCommand[*TransitRouter]) error {
var checker boltz.FieldChecker = cmd.UpdatedFields
if cmd.Flags != updateUnrestricted {
if checker == nil {
checker = self.allowedFields
} else {
checker = &AndFieldChecker{first: self.allowedFields, second: cmd.UpdatedFields}
}
}
combinedChecker := &AndFieldChecker{first: self.allowedFields, second: checker}
return self.patchEntity(entity, combinedChecker)
return self.updateEntity(cmd.Entity, checker)
}

func (self *TransitRouterManager) ReadOneByFingerprint(fingerprint string) (*TransitRouter, error) {
Expand Down Expand Up @@ -230,10 +225,10 @@ func (self *TransitRouterManager) ExtendEnrollment(router *TransitRouter, client

router.Fingerprint = &fingerprint

err = self.Patch(router, &boltz.MapFieldChecker{
err = self.Update(router, true, &fields.UpdatedFieldsMap{
persistence.FieldEdgeRouterCertPEM: struct{}{},
db.FieldRouterFingerprint: struct{}{},
}, true)
})

if err != nil {
return nil, err
Expand Down Expand Up @@ -272,10 +267,10 @@ func (self *TransitRouterManager) ExtendEnrollmentWithVerify(router *TransitRout

router.UnverifiedFingerprint = &fingerprint

err = self.Patch(router, &boltz.MapFieldChecker{
err = self.Update(router, true, &fields.UpdatedFieldsMap{
persistence.FieldEdgeRouterUnverifiedCertPEM: struct{}{},
persistence.FieldEdgeRouterUnverifiedFingerprint: struct{}{},
}, true)
})

if err != nil {
return nil, err
Expand All @@ -298,12 +293,112 @@ func (self *TransitRouterManager) ExtendEnrollmentVerify(router *TransitRouter)
router.UnverifiedFingerprint = nil
router.UnverifiedCertPem = nil

return self.Patch(router, boltz.MapFieldChecker{
return self.Update(router, true, fields.UpdatedFieldsMap{
db.FieldRouterFingerprint: struct{}{},
persistence.FieldEdgeRouterUnverifiedCertPEM: struct{}{},
persistence.FieldEdgeRouterUnverifiedFingerprint: struct{}{},
}, true)
})
}

return errors.New("no outstanding verification necessary")
}

func (self *TransitRouterManager) TransitRouterToProtobuf(entity *TransitRouter) (*edge_cmd_pb.TransitRouter, error) {
tags, err := edge_cmd_pb.EncodeTags(entity.Tags)
if err != nil {
return nil, err
}

msg := &edge_cmd_pb.TransitRouter{
Id: entity.Id,
Name: entity.Name,
Tags: tags,
IsVerified: entity.IsVerified,
Fingerprint: entity.Fingerprint,
UnverifiedFingerprint: entity.UnverifiedFingerprint,
UnverifiedCertPem: entity.UnverifiedCertPem,
Cost: uint32(entity.Cost),
NoTraversal: entity.NoTraversal,
}

return msg, nil
}

func (self *TransitRouterManager) Marshall(entity *TransitRouter) ([]byte, error) {
msg, err := self.TransitRouterToProtobuf(entity)
if err != nil {
return nil, err
}
return proto.Marshal(msg)
}

func (self *TransitRouterManager) ProtobufToTransitRouter(msg *edge_cmd_pb.TransitRouter) (*TransitRouter, error) {
return &TransitRouter{
BaseEntity: models.BaseEntity{
Id: msg.Id,
Tags: edge_cmd_pb.DecodeTags(msg.Tags),
},
Name: msg.Name,
IsVerified: msg.IsVerified,
Fingerprint: msg.Fingerprint,
UnverifiedFingerprint: msg.UnverifiedFingerprint,
UnverifiedCertPem: msg.UnverifiedCertPem,
Cost: uint16(msg.Cost),
NoTraversal: msg.NoTraversal,
}, nil
}

func (self *TransitRouterManager) Unmarshall(bytes []byte) (*TransitRouter, error) {
msg := &edge_cmd_pb.TransitRouter{}
if err := proto.Unmarshal(bytes, msg); err != nil {
return nil, err
}
return self.ProtobufToTransitRouter(msg)
}

type CreateTransitRouterCmd struct {
manager *TransitRouterManager
router *TransitRouter
enrollment *Enrollment
}

func (self *CreateTransitRouterCmd) Apply() error {
return self.manager.ApplyCreate(self)
}

func (self *CreateTransitRouterCmd) Encode() ([]byte, error) {
transitRouterMsg, err := self.manager.TransitRouterToProtobuf(self.router)
if err != nil {
return nil, err
}

enrollment, err := self.manager.GetEnv().GetManagers().Enrollment.EnrollmentToProtobuf(self.enrollment)
if err != nil {
return nil, err
}

cmd := &edge_cmd_pb.CreateTransitRouterCmd{
Router: transitRouterMsg,
Enrollment: enrollment,
}

return proto.Marshal(cmd)
}

func (self *CreateTransitRouterCmd) Decode(env Env, msg *edge_cmd_pb.CreateTransitRouterCmd) error {
router, err := self.manager.ProtobufToTransitRouter(msg.Router)
if err != nil {
return err
}

enrollment, err := self.manager.GetEnv().GetManagers().Enrollment.ProtobufToEnrollment(msg.Enrollment)
if err != nil {
return err
}

self.manager = env.GetManagers().TransitRouter
self.router = router
self.enrollment = enrollment

return nil
}
Loading

0 comments on commit 7b7b43d

Please sign in to comment.