diff --git a/controller/model/controller_manager.go b/controller/model/controller_manager.go index 27b458d7bd..a50acbf70a 100644 --- a/controller/model/controller_manager.go +++ b/controller/model/controller_manager.go @@ -338,3 +338,30 @@ func (self *ControllerManager) PeersDisconnected(peers []*event.ClusterPeer) { } } } + +func (self *ControllerManager) ListAll() ([]*Controller, error) { + handler := &ControllerListResult{} + if err := self.ListWithHandler("", handler.collect); err != nil { + return nil, err + } + + return handler.Controllers, nil +} + +type ControllerListResult struct { + manager *ControllerManager + Controllers []*Controller + models.QueryMetaData +} + +func (result *ControllerListResult) collect(tx *bbolt.Tx, ids []string, queryMetaData *models.QueryMetaData) error { + result.QueryMetaData = *queryMetaData + for _, key := range ids { + entity, err := result.manager.readInTx(tx, key) + if err != nil { + return err + } + result.Controllers = append(result.Controllers, entity) + } + return nil +} diff --git a/controller/model/controller_model.go b/controller/model/controller_model.go index 16f42c2935..b1bd6afeaa 100644 --- a/controller/model/controller_model.go +++ b/controller/model/controller_model.go @@ -18,6 +18,7 @@ package model import ( "github.com/openziti/storage/boltz" + "github.com/openziti/ziti/controller" "github.com/openziti/ziti/controller/db" "github.com/openziti/ziti/controller/models" "go.etcd.io/bbolt" @@ -95,3 +96,15 @@ func (entity *Controller) fillFrom(env Env, tx *bbolt.Tx, boltController *db.Con return nil } + +func (entity *Controller) GetClientApi() string { + if curApis, ok := entity.ApiAddresses[controller.ClientApiBinding]; ok { + for _, curApi := range curApis { + if curApi.Version == controller.VersionV1 { + return curApi.Url + } + } + } + + return "" +} diff --git a/controller/model/edge_router_manager.go b/controller/model/edge_router_manager.go index 57e035b1ba..feb866eeed 100644 --- a/controller/model/edge_router_manager.go +++ b/controller/model/edge_router_manager.go @@ -115,6 +115,8 @@ func (self *EdgeRouterManager) ApplyCreate(cmd *CreateEdgeRouterCmd, ctx boltz.M return err } + enrollment.FillApiInfo(self.env) + if err = enrollment.FillJwtInfo(self.env, edgeRouter.Id); err != nil { return err } diff --git a/controller/model/enrollment_model.go b/controller/model/enrollment_model.go index b8a6f50cfb..8dc89bdf80 100644 --- a/controller/model/enrollment_model.go +++ b/controller/model/enrollment_model.go @@ -20,6 +20,7 @@ import ( "fmt" "github.com/golang-jwt/jwt/v5" "github.com/google/uuid" + "github.com/michaelquigley/pfxlog" "github.com/openziti/foundation/v2/errorz" "github.com/openziti/sdk-golang/ziti" "github.com/openziti/storage/boltz" @@ -41,6 +42,8 @@ type Enrollment struct { Jwt string CaId *string Username *string + CtrlAddresses []string + ClientApis []string } func (entity *Enrollment) FillJwtInfo(env Env, subject string) error { @@ -48,6 +51,54 @@ func (entity *Enrollment) FillJwtInfo(env Env, subject string) error { return entity.FillJwtInfoWithExpiresAt(env, subject, expiresAt) } +func (entity *Enrollment) FillApiInfo(env Env) { + controllers, err := env.GetManagers().Controller.ListAll() + + if err != nil { + pfxlog.Logger().WithError(err).Error("could not list controllers for router enrollment creation") + } + + thisControllerId := "" + if thisControllerCert, _, _ := env.GetServerCert(); thisControllerCert != nil { + if thisControllerCert.Leaf != nil { + thisControllerId = thisControllerCert.Leaf.Subject.CommonName + } + } + + curControllerIdx := -1 + for i, curController := range controllers { + if curController.Id == thisControllerId { + entity.CtrlAddresses = append(entity.CtrlAddresses, curController.CtrlAddress) + + if clientApi := curController.GetClientApi(); clientApi != "" { + entity.ClientApis = append(entity.ClientApis, clientApi) + } + + curControllerIdx = i + + break + } + } + + for i, curController := range controllers { + if i == curControllerIdx { + continue + } + + if curController.IsOnline { + if len(entity.CtrlAddresses) < 3 && curController.CtrlAddress != "" { + entity.CtrlAddresses = append(entity.CtrlAddresses, curController.CtrlAddress) + } + + if len(entity.ClientApis) < 3 { + if clientApi := curController.GetClientApi(); clientApi != "" { + entity.ClientApis = append(entity.ClientApis, clientApi) + } + } + } + } +} + func (entity *Enrollment) FillJwtInfoWithExpiresAt(env Env, subject string, expiresAt time.Time) error { now := time.Now().UTC() expiresAt = expiresAt.UTC() @@ -59,15 +110,10 @@ func (entity *Enrollment) FillJwtInfoWithExpiresAt(env Env, subject string, expi entity.Token = uuid.New().String() } - peerControllers := env.GetPeerControllerAddresses() - - for i, addr := range peerControllers { - peerControllers[i] = "https://" + addr - } - enrollmentClaims := &ziti.EnrollmentClaims{ EnrollmentMethod: entity.Method, - Controllers: peerControllers, + ClientApis: entity.ClientApis, + CtrlAddresses: entity.CtrlAddresses, RegisteredClaims: jwt.RegisteredClaims{ Audience: []string{""}, ExpiresAt: &jwt.NumericDate{Time: expiresAt}, diff --git a/controller/model/identity_manager.go b/controller/model/identity_manager.go index 2064df14c8..96e78372d5 100644 --- a/controller/model/identity_manager.go +++ b/controller/model/identity_manager.go @@ -125,6 +125,9 @@ func (self *IdentityManager) ApplyCreateWithEnrollments(cmd *CreateIdentityWithE for _, enrollment := range enrollmentsModels { enrollment.IdentityId = &identityModel.Id + enrollment.FillApiInfo(self.env) + enrollment.CtrlAddresses = nil + if err = enrollment.FillJwtInfo(self.env, identityModel.Id); err != nil { return err } diff --git a/router/enroll/enroll.go b/router/enroll/enroll.go index 601f62449b..562ce53e3b 100644 --- a/router/enroll/enroll.go +++ b/router/enroll/enroll.go @@ -171,7 +171,7 @@ func (re *RestEnroller) Enroll(jwtBuf []byte, silent bool, engine string, keyAlg client.SetTLSClientConfig(tc) - envelope, err := re.Send(client, ec.EnrolmentUrl(), er) + envelope, err := re.Send(client, ec.EnrolmentUrls()[0], er) if err != nil { return err