mirror of
https://github.com/openziti/ziti.git
synced 2026-09-23 02:53:33 +00:00
116 lines
3.6 KiB
Go
116 lines
3.6 KiB
Go
package model
|
|
|
|
import (
|
|
"github.com/michaelquigley/pfxlog"
|
|
"github.com/openziti/edge/controller/persistence"
|
|
"github.com/openziti/edge/edge_common"
|
|
"github.com/openziti/edge/pb/edge_cmd_pb"
|
|
"github.com/openziti/fabric/controller/command"
|
|
"github.com/openziti/fabric/controller/network"
|
|
"github.com/openziti/fabric/pb/cmd_pb"
|
|
"github.com/pkg/errors"
|
|
"go.etcd.io/bbolt"
|
|
"strings"
|
|
)
|
|
|
|
type CreateEdgeTerminatorCmd struct {
|
|
Env Env
|
|
Entity *network.Terminator
|
|
}
|
|
|
|
func (self *CreateEdgeTerminatorCmd) Apply() error {
|
|
createCmd := &command.CreateEntityCommand[*network.Terminator]{
|
|
Creator: self.Env.GetManagers().Terminator,
|
|
Entity: self.Entity,
|
|
PostCreateHook: self.validateTerminatorIdentity,
|
|
}
|
|
return self.Env.GetManagers().Terminator.ApplyCreate(createCmd)
|
|
}
|
|
|
|
func (self *CreateEdgeTerminatorCmd) validateTerminatorIdentity(tx *bbolt.Tx, terminator *network.Terminator) error {
|
|
session, err := self.getTerminatorSession(tx, terminator, "")
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
if terminator.GetInstanceId() == "" {
|
|
return nil
|
|
}
|
|
|
|
identityTerminators, err := self.Env.GetStores().Terminator.GetTerminatorsInIdentityGroup(tx, terminator.GetId())
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
for _, otherTerminator := range identityTerminators {
|
|
otherSession, err := self.getTerminatorSession(tx, otherTerminator, "sibling ")
|
|
if err != nil {
|
|
return err
|
|
}
|
|
if otherSession != nil {
|
|
if otherSession.ApiSession.IdentityId != session.ApiSession.IdentityId {
|
|
return errors.Errorf("sibling terminator %v with shared identity %v belongs to different identity", terminator.GetId(), terminator.GetInstanceId())
|
|
}
|
|
}
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
type terminator interface {
|
|
GetId() string
|
|
GetInstanceId() string
|
|
GetBinding() string
|
|
GetAddress() string
|
|
}
|
|
|
|
func (self *CreateEdgeTerminatorCmd) getTerminatorSession(tx *bbolt.Tx, terminator terminator, context string) (*persistence.Session, error) {
|
|
if terminator.GetBinding() != edge_common.EdgeBinding {
|
|
return nil, errors.Errorf("%vterminator %v with identity %v is not edge terminator. Can't share identity", context, terminator.GetId(), terminator.GetInstanceId())
|
|
}
|
|
|
|
addressParts := strings.Split(terminator.GetAddress(), ":")
|
|
if len(addressParts) != 2 {
|
|
return nil, errors.Errorf("%vterminator %v with identity %v is not edge terminator. Can't share identity", context, terminator.GetId(), terminator.GetInstanceId())
|
|
}
|
|
|
|
if addressParts[0] != "hosted" {
|
|
return nil, errors.Errorf("%vterminator %v with identity %v is not edge terminator. Can't share identity", context, terminator.GetId(), terminator.GetInstanceId())
|
|
}
|
|
|
|
sessionToken := addressParts[1]
|
|
session, err := self.Env.GetStores().Session.LoadOneByToken(tx, sessionToken)
|
|
if err != nil {
|
|
pfxlog.Logger().Warnf("sibling terminator %v with shared identity %v has invalid session token %v", terminator.GetId(), terminator.GetInstanceId(), sessionToken)
|
|
return nil, nil
|
|
}
|
|
|
|
if session.ApiSession == nil {
|
|
apiSession, err := self.Env.GetStores().ApiSession.LoadOneById(tx, session.ApiSessionId)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
session.ApiSession = apiSession
|
|
}
|
|
|
|
return session, nil
|
|
}
|
|
|
|
func (self *CreateEdgeTerminatorCmd) Encode() ([]byte, error) {
|
|
terminatorData, err := self.Env.GetManagers().Terminator.Marshall(self.Entity)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
cmd := &edge_cmd_pb.CreateEdgeTerminatorCommand{
|
|
TerminatorData: terminatorData,
|
|
}
|
|
return cmd_pb.EncodeProtobuf(cmd)
|
|
}
|
|
|
|
func (self *CreateEdgeTerminatorCmd) Decode(env Env, msg *edge_cmd_pb.CreateEdgeTerminatorCommand) error {
|
|
var err error
|
|
self.Env = env
|
|
self.Entity, err = env.GetManagers().Terminator.Unmarshall(msg.TerminatorData)
|
|
return err
|
|
}
|