From 64ce3a92dff456c64a1e620461d0fcef87d754dd Mon Sep 17 00:00:00 2001 From: Paul Lorenz Date: Wed, 10 Jun 2020 15:20:29 -0400 Subject: [PATCH] move edge routers under fabric routers. Fixes GH-144 --- controller/env/broker.go | 57 ++------- controller/model/edge_router_model.go | 11 +- controller/model/enrollment_mod_erott.go | 13 -- controller/model/enrollment_mod_trott.go | 2 - controller/model/policy_advisor.go | 9 +- controller/persistence/base_entity.go | 4 - controller/persistence/base_store.go | 10 +- .../persistence/edge_router_policy_store.go | 3 +- .../edge_router_policy_store_test.go | 13 +- controller/persistence/edge_router_store.go | 27 ++--- controller/persistence/edge_service_store.go | 7 -- controller/persistence/migration_v7.go | 114 ++++++++++++++++++ controller/persistence/migrations.go | 6 +- .../service_edge_router_policy_store.go | 3 +- .../service_edge_router_policy_store_test.go | 13 +- controller/persistence/stores.go | 9 +- .../persistence/transit_router_store.go | 2 - go.mod | 2 +- go.sum | 8 +- internal/cert/fingerprint.go | 3 +- 20 files changed, 183 insertions(+), 133 deletions(-) create mode 100644 controller/persistence/migration_v7.go diff --git a/controller/env/broker.go b/controller/env/broker.go index 622d0ad76..f703d9b57 100644 --- a/controller/env/broker.go +++ b/controller/env/broker.go @@ -17,7 +17,6 @@ package env import ( - "bytes" "fmt" "github.com/golang/protobuf/proto" "github.com/kataras/go-events" @@ -29,7 +28,6 @@ import ( "github.com/openziti/fabric/controller/network" "github.com/openziti/foundation/channel2" "github.com/openziti/foundation/storage/boltz" - "strings" "sync" "time" ) @@ -584,23 +582,15 @@ func (b *Broker) GetOnlineEdgeRouter(id string) *model.EdgeRouter { func (b *Broker) RouterConnected(r *network.Router) { go func() { - if r.Fingerprint == nil { - return + if r.Fingerprint != nil { + if edgeRouter, _ := b.ae.Handlers.EdgeRouter.ReadOneByFingerprint(*r.Fingerprint); edgeRouter != nil { + b.sendHello(r, edgeRouter) + } } - - fp := formatFingerprint(*r.Fingerprint) - edgeRouter, _ := b.ae.Handlers.EdgeRouter.ReadOneByFingerprint(fp) - - // not an edge router - if edgeRouter == nil || edgeRouter.Id == "" { - return - } - - b.sendHello(r, edgeRouter, fp) }() } -func (b *Broker) sendHello(r *network.Router, edgeRouter *model.EdgeRouter, fingerprint string) { +func (b *Broker) sendHello(r *network.Router, edgeRouter *model.EdgeRouter) { serverVersion := build.GetBuildInfo().GetVersion() serverHello := &edge_ctrl_pb.ServerHello{ Version: serverVersion, @@ -665,39 +655,10 @@ func (b *Broker) sendHello(r *network.Router, edgeRouter *model.EdgeRouter, fing func (b *Broker) RouterDisconnected(r *network.Router) { go func() { - if r.Fingerprint == nil { - return - } - fp := formatFingerprint(*r.Fingerprint) - edgeRouter, _ := b.ae.Handlers.EdgeRouter.ReadOneByFingerprint(fp) - - // not an edge router - if edgeRouter == nil || edgeRouter.Id == "" { - return - } - - b.edgeRouterMap.RemoveEntry(edgeRouter.Id) - }() -} - -func formatFingerprint(fp string) string { - fp = strings.ToUpper(fp) - - return insertNth(fp, 2, ":") -} - -func insertNth(s string, n int, i string) string { - rs := []rune(i) - var buffer bytes.Buffer - var nMinus1 = n - 1 - var lenMinus1 = len(s) - 1 - for i, cr := range s { - buffer.WriteRune(cr) - if i%n == nMinus1 && i != lenMinus1 { - for _, r := range rs { - buffer.WriteRune(r) + if r.Fingerprint != nil { + if edgeRouter, _ := b.ae.Handlers.EdgeRouter.ReadOneByFingerprint(*r.Fingerprint); edgeRouter != nil { + b.edgeRouterMap.RemoveEntry(edgeRouter.Id) } } - } - return buffer.String() + }() } diff --git a/controller/model/edge_router_model.go b/controller/model/edge_router_model.go index 0deead366..a0f3757aa 100644 --- a/controller/model/edge_router_model.go +++ b/controller/model/edge_router_model.go @@ -18,6 +18,7 @@ package model import ( "github.com/openziti/edge/controller/persistence" + "github.com/openziti/fabric/controller/db" "github.com/openziti/fabric/controller/models" "github.com/openziti/foundation/storage/boltz" "github.com/pkg/errors" @@ -37,12 +38,10 @@ type EdgeRouter struct { } func (entity *EdgeRouter) toBoltEntityForCreate(_ *bbolt.Tx, handler Handler) (boltz.Entity, error) { - boltEntity := &persistence.EdgeRouter{ - BaseExtEntity: *boltz.NewExtEntity(entity.Id, entity.Tags), + Router: db.Router{BaseExtEntity: *boltz.NewExtEntity(entity.Id, entity.Tags)}, Name: entity.Name, RoleAttributes: entity.RoleAttributes, - Fingerprint: nil, IsVerified: false, } @@ -51,11 +50,13 @@ func (entity *EdgeRouter) toBoltEntityForCreate(_ *bbolt.Tx, handler Handler) (b func (entity *EdgeRouter) toBoltEntityForUpdate(_ *bbolt.Tx, _ Handler) (boltz.Entity, error) { return &persistence.EdgeRouter{ - BaseExtEntity: *boltz.NewExtEntity(entity.Id, entity.Tags), + Router: db.Router{ + BaseExtEntity: *boltz.NewExtEntity(entity.Id, entity.Tags), + Fingerprint: entity.Fingerprint, + }, Name: entity.Name, RoleAttributes: entity.RoleAttributes, IsVerified: entity.IsVerified, - Fingerprint: entity.Fingerprint, CertPem: entity.CertPem, Hostname: entity.Hostname, EdgeRouterProtocols: entity.EdgeRouterProtocols, diff --git a/controller/model/enrollment_mod_erott.go b/controller/model/enrollment_mod_erott.go index 14d193d53..102a540d7 100644 --- a/controller/model/enrollment_mod_erott.go +++ b/controller/model/enrollment_mod_erott.go @@ -21,8 +21,6 @@ import ( "github.com/openziti/edge/controller/apierror" "github.com/openziti/edge/internal/cert" "github.com/openziti/edge/rest_model" - "github.com/openziti/fabric/controller/network" - "strings" "time" ) @@ -143,7 +141,6 @@ func (module *EnrollModuleEr) Process(context EnrollmentContext) (*EnrollmentRes } cltFp := module.fingerprintGenerator.FromPem(cltPem) - edgeRouter.IsVerified = true edgeRouter.Fingerprint = &cltFp if err := module.env.GetHandlers().EdgeRouter.Update(edgeRouter, false); err != nil { @@ -154,10 +151,6 @@ func (module *EnrollModuleEr) Process(context EnrollmentContext) (*EnrollmentRes return nil, fmt.Errorf("could not delete enrollment: %s", err) } - if err := module.createRouter(cr.Subject.CommonName, cltFp); err != nil { - return nil, err - } - content := &rest_model.EnrollmentCerts{ Ca: string(module.env.GetConfig().CaPems()), Cert: string(cltPem), @@ -171,9 +164,3 @@ func (module *EnrollModuleEr) Process(context EnrollmentContext) (*EnrollmentRes Status: 200, }, nil } - -func (module *EnrollModuleEr) createRouter(commonName string, fingerprint string) error { - fgp := strings.Replace(strings.ToLower(fingerprint), ":", "", -1) - r := network.NewRouter(commonName, fgp) - return module.env.GetHostController().GetNetwork().CreateRouter(r) -} diff --git a/controller/model/enrollment_mod_trott.go b/controller/model/enrollment_mod_trott.go index b2e9d7e30..a56c4c7c6 100644 --- a/controller/model/enrollment_mod_trott.go +++ b/controller/model/enrollment_mod_trott.go @@ -21,7 +21,6 @@ import ( "github.com/openziti/edge/controller/apierror" "github.com/openziti/edge/internal/cert" "github.com/openziti/edge/rest_model" - "strings" "time" ) @@ -131,7 +130,6 @@ func (module *EnrollModuleRouterOtt) Process(context EnrollmentContext) (*Enroll cltFp := module.fingerprintGenerator.FromPem(cltPem) txRouter.IsVerified = true - cltFp = strings.ToLower(strings.Replace(cltFp, ":", "", -1)) txRouter.Fingerprint = &cltFp if err := module.env.GetHandlers().TransitRouter.Update(txRouter, true); err != nil { diff --git a/controller/model/policy_advisor.go b/controller/model/policy_advisor.go index 8e093dd2e..c7cee0f63 100644 --- a/controller/model/policy_advisor.go +++ b/controller/model/policy_advisor.go @@ -2,6 +2,7 @@ package model import ( "github.com/openziti/edge/controller/persistence" + "github.com/openziti/fabric/controller/db" "github.com/openziti/foundation/util/stringz" "go.etcd.io/bbolt" ) @@ -122,7 +123,7 @@ func (advisor *PolicyAdvisor) getIdentityEdgeRouters(identityId string) (map[str return nil } - return advisor.env.GetHandlers().EdgeRouterPolicy.iterateRelatedEntitiesInTx(tx, edgeRouterPolicyId, persistence.EntityTypeEdgeRouters, edgeRouterIterator) + return advisor.env.GetHandlers().EdgeRouterPolicy.iterateRelatedEntitiesInTx(tx, edgeRouterPolicyId, db.EntityTypeRouters, edgeRouterIterator) } if err := advisor.env.GetHandlers().Identity.iterateRelatedEntities(identityId, persistence.EntityTypeEdgeRouterPolicies, edgeRouterPolicyIterator); err != nil { return nil, err @@ -139,7 +140,7 @@ func (advisor *PolicyAdvisor) getServiceEdgeRouters(serviceId string) (map[strin edgeRouters[edgeRouterId] = struct{}{} return nil } - return advisor.env.GetHandlers().ServiceEdgeRouterPolicy.iterateRelatedEntitiesInTx(tx, policyId, persistence.EntityTypeEdgeRouters, edgeRouterIterator) + return advisor.env.GetHandlers().ServiceEdgeRouterPolicy.iterateRelatedEntitiesInTx(tx, policyId, db.EntityTypeRouters, edgeRouterIterator) } if err := advisor.env.GetHandlers().EdgeService.iterateRelatedEntities(serviceId, persistence.EntityTypeServiceEdgeRouterPolicies, serviceEdgeRouterPolicyIterator); err != nil { @@ -189,7 +190,7 @@ func (advisor *PolicyAdvisor) getEdgeRouterPolicies(identityId, edgeRouterId str if err != nil { return err } - if policyStore.IsEntityRelated(tx, policyId, persistence.EntityTypeEdgeRouters, edgeRouterId) { + if policyStore.IsEntityRelated(tx, policyId, db.EntityTypeRouters, edgeRouterId) { result = append(result, policy) } return nil @@ -295,7 +296,7 @@ func (advisor *PolicyAdvisor) getServiceEdgeRouterPolicies(serviceId, edgeRouter if err != nil { return err } - if policyStore.IsEntityRelated(tx, policyId, persistence.EntityTypeEdgeRouters, edgeRouterId) { + if policyStore.IsEntityRelated(tx, policyId, db.EntityTypeRouters, edgeRouterId) { result = append(result, policy) } return nil diff --git a/controller/persistence/base_entity.go b/controller/persistence/base_entity.go index c6643e4ff..c9b42fa68 100644 --- a/controller/persistence/base_entity.go +++ b/controller/persistence/base_entity.go @@ -20,13 +20,9 @@ import "strings" const ( EntityTypeApiSessions = "apiSessions" - EntityTypeAppwans = "appwans" EntityTypeCas = "cas" - EntityTypeClusters = "clusters" EntityTypeConfigs = "configs" EntityTypeConfigTypes = "configTypes" - EntityTypeEdgeRouters = "edgeRouters" - EntityTypeTransitRouters = "transitRouters" EntityTypeEdgeRouterPolicies = "edgeRouterPolicies" EntityTypeEventLogs = "eventLogs" EntityTypeGeoRegions = "geoRegions" diff --git a/controller/persistence/base_store.go b/controller/persistence/base_store.go index d7a0df0e8..df7c1805a 100644 --- a/controller/persistence/base_store.go +++ b/controller/persistence/base_store.go @@ -55,11 +55,13 @@ func newBaseStore(stores *stores, entityType string) *baseStore { } func newChildBaseStore(stores *stores, parent boltz.CrudStore) *baseStore { + entityNotFoundF := func(id string) error { + return boltz.NewNotFoundError(parent.GetSingularEntityType(), "id", id) + } + return &baseStore{ - stores: stores, - BaseStore: boltz.NewChildBaseStore(parent, func(id string) error { - return boltz.NewNotFoundError(parent.GetSingularEntityType(), "id", id) - }, EdgeBucket), + stores: stores, + BaseStore: boltz.NewChildBaseStore(parent, entityNotFoundF, EdgeBucket), } } diff --git a/controller/persistence/edge_router_policy_store.go b/controller/persistence/edge_router_policy_store.go index 8810eed18..1eaf0bc1c 100644 --- a/controller/persistence/edge_router_policy_store.go +++ b/controller/persistence/edge_router_policy_store.go @@ -2,6 +2,7 @@ package persistence import ( "github.com/google/uuid" + "github.com/openziti/fabric/controller/db" "github.com/openziti/foundation/storage/ast" "github.com/openziti/foundation/storage/boltz" "github.com/openziti/foundation/util/stringz" @@ -122,7 +123,7 @@ func (store *edgeRouterPolicyStoreImpl) initializeLocal() { store.symbolIdentityRoles = store.AddSetSymbol(FieldIdentityRoles, ast.NodeTypeString) store.symbolEdgeRouterRoles = store.AddSetSymbol(FieldEdgeRouterRoles, ast.NodeTypeString) store.symbolIdentities = store.AddFkSetSymbol(EntityTypeIdentities, store.stores.identity) - store.symbolEdgeRouters = store.AddFkSetSymbol(EntityTypeEdgeRouters, store.stores.edgeRouter) + store.symbolEdgeRouters = store.AddFkSetSymbol(db.EntityTypeRouters, store.stores.edgeRouter) } func (store *edgeRouterPolicyStoreImpl) initializeLinked() { diff --git a/controller/persistence/edge_router_policy_store_test.go b/controller/persistence/edge_router_policy_store_test.go index 1d51e03f8..7541330cd 100644 --- a/controller/persistence/edge_router_policy_store_test.go +++ b/controller/persistence/edge_router_policy_store_test.go @@ -3,6 +3,7 @@ package persistence import ( "fmt" "github.com/google/uuid" + "github.com/openziti/fabric/controller/db" "github.com/openziti/foundation/storage/boltz" "github.com/openziti/foundation/util/stringz" "go.etcd.io/bbolt" @@ -30,7 +31,7 @@ func (ctx *TestContext) testCreateEdgeRouterPolicy(_ *testing.T) { ctx.ValidateBaseline(policy) err := ctx.GetDb().View(func(tx *bbolt.Tx) error { - ctx.Equal(0, len(ctx.stores.EdgeRouterPolicy.GetRelatedEntitiesIdList(tx, policy.Id, EntityTypeEdgeRouters))) + ctx.Equal(0, len(ctx.stores.EdgeRouterPolicy.GetRelatedEntitiesIdList(tx, policy.Id, db.EntityTypeRouters))) ctx.Equal(0, len(ctx.stores.EdgeRouterPolicy.GetRelatedEntitiesIdList(tx, policy.Id, EntityTypeIdentities))) testPolicy, err := ctx.stores.EdgeRouterPolicy.LoadOneByName(tx, policy.Name) @@ -78,7 +79,7 @@ func (ctx *TestContext) testEdgeRouterPolicyInvalidValues(_ *testing.T) { policy.IdentityRoles = nil policy.EdgeRouterRoles = []string{entityRef(invalidId)} err = ctx.Create(policy) - ctx.EqualError(err, fmt.Sprintf("the value '[%v]' for 'edgeRouterRoles' is invalid: no edgeRouters found with the given ids", invalidId)) + ctx.EqualError(err, fmt.Sprintf("the value '[%v]' for 'edgeRouterRoles' is invalid: no routers found with the given ids", invalidId)) policy.EdgeRouterRoles = []string{AllRole, roleRef("other")} err = ctx.Create(policy) @@ -89,7 +90,7 @@ func (ctx *TestContext) testEdgeRouterPolicyInvalidValues(_ *testing.T) { policy.EdgeRouterRoles = []string{entityRef(edgeRouter.Id), entityRef(invalidId)} err = ctx.Create(policy) - ctx.EqualError(err, fmt.Sprintf("the value '[%v]' for 'edgeRouterRoles' is invalid: no edgeRouters found with the given ids", invalidId)) + ctx.EqualError(err, fmt.Sprintf("the value '[%v]' for 'edgeRouterRoles' is invalid: no routers found with the given ids", invalidId)) policy.EdgeRouterRoles = []string{entityRef(edgeRouter.Id)} ctx.RequireCreate(policy) @@ -97,7 +98,7 @@ func (ctx *TestContext) testEdgeRouterPolicyInvalidValues(_ *testing.T) { policy.EdgeRouterRoles = append(policy.EdgeRouterRoles, entityRef(invalidId)) err = ctx.Update(policy) - ctx.EqualError(err, fmt.Sprintf("the value '[%v]' for 'edgeRouterRoles' is invalid: no edgeRouters found with the given ids", invalidId)) + ctx.EqualError(err, fmt.Sprintf("the value '[%v]' for 'edgeRouterRoles' is invalid: no routers found with the given ids", invalidId)) ctx.RequireDelete(policy) } @@ -209,7 +210,7 @@ func (ctx *TestContext) testEdgeRouterPolicyRoleEvaluation(_ *testing.T) { policies := ctx.createEdgeRouterPolicies(identityRoles, edgeRouterRoles, identities, edgeRouters, true) for i := 0; i < 9; i++ { - relatedEdgeRouters := ctx.getRelatedIds(policies[i], EntityTypeEdgeRouters) + relatedEdgeRouters := ctx.getRelatedIds(policies[i], db.EntityTypeRouters) relatedIdentities := ctx.getRelatedIds(policies[i], EntityTypeIdentities) if i == 3 { ctx.Equal([]string{edgeRouters[0].Id}, relatedEdgeRouters) @@ -411,7 +412,7 @@ func (ctx *TestContext) validateEdgeRouterPolicyIdentities(identities []*Identit func (ctx *TestContext) validateEdgeRouterPolicyEdgeRouters(edgeRouters []*EdgeRouter, policies []*EdgeRouterPolicy) { for _, policy := range policies { count := 0 - relatedEdgeRouters := ctx.getRelatedIds(policy, EntityTypeEdgeRouters) + relatedEdgeRouters := ctx.getRelatedIds(policy, db.EntityTypeRouters) for _, edgeRouter := range edgeRouters { relatedPolicies := ctx.getRelatedIds(edgeRouter, EntityTypeEdgeRouterPolicies) shouldContain := ctx.policyShouldMatch(policy.Semantic, policy.EdgeRouterRoles, edgeRouter, edgeRouter.RoleAttributes) diff --git a/controller/persistence/edge_router_store.go b/controller/persistence/edge_router_store.go index c8b2d5b24..9e2d73de6 100644 --- a/controller/persistence/edge_router_store.go +++ b/controller/persistence/edge_router_store.go @@ -19,6 +19,7 @@ package persistence import ( "fmt" "github.com/google/uuid" + "github.com/openziti/fabric/controller/db" "github.com/openziti/foundation/storage/ast" "github.com/openziti/foundation/storage/boltz" "github.com/openziti/foundation/util/errorz" @@ -27,7 +28,6 @@ import ( ) const ( - FieldEdgeRouterFingerprint = "fingerprint" FieldEdgeRouterCertPEM = "certPem" FieldEdgeRouterIsVerified = "isVerified" FieldEdgeRouterHostname = "hostname" @@ -39,17 +39,16 @@ const ( func newEdgeRouter(name string, roleAttributes ...string) *EdgeRouter { return &EdgeRouter{ - BaseExtEntity: boltz.BaseExtEntity{Id: uuid.New().String()}, + Router: db.Router{BaseExtEntity: boltz.BaseExtEntity{Id: uuid.New().String()}}, Name: name, RoleAttributes: roleAttributes, } } type EdgeRouter struct { - boltz.BaseExtEntity + db.Router Name string IsVerified bool - Fingerprint *string CertPem *string Hostname *string EdgeRouterProtocols map[string]string @@ -63,10 +62,11 @@ type EdgeRouter struct { EnrollmentExpiresAt *time.Time } -func (entity *EdgeRouter) LoadValues(_ boltz.CrudStore, bucket *boltz.TypedBucket) { - entity.LoadBaseValues(bucket) +func (entity *EdgeRouter) LoadValues(store boltz.CrudStore, bucket *boltz.TypedBucket) { + _, err := store.GetParentStore().BaseLoadOneById(bucket.Tx(), entity.Id, &entity.Router) + bucket.SetError(err) + entity.Name = bucket.GetStringOrError(FieldName) - entity.Fingerprint = bucket.GetString(FieldEdgeRouterFingerprint) entity.CertPem = bucket.GetString(FieldEdgeRouterCertPEM) entity.IsVerified = bucket.GetBoolWithDefault(FieldEdgeRouterIsVerified, false) @@ -78,10 +78,10 @@ func (entity *EdgeRouter) LoadValues(_ boltz.CrudStore, bucket *boltz.TypedBucke } func (entity *EdgeRouter) SetValues(ctx *boltz.PersistContext) { - entity.SetBaseValues(ctx) + entity.Router.SetValues(ctx.GetParentContext()) + store := ctx.Store.(*edgeRouterStoreImpl) ctx.SetString(FieldName, entity.Name) - ctx.SetStringP(FieldEdgeRouterFingerprint, entity.Fingerprint) ctx.SetStringP(FieldEdgeRouterCertPEM, entity.CertPem) ctx.SetBool(FieldEdgeRouterIsVerified, entity.IsVerified) ctx.SetStringP(FieldEdgeRouterHostname, entity.Hostname) @@ -95,10 +95,6 @@ func (entity *EdgeRouter) SetValues(ctx *boltz.PersistContext) { } } -func (entity *EdgeRouter) GetEntityType() string { - return EntityTypeEdgeRouters -} - func (entity *EdgeRouter) GetName() string { return entity.Name } @@ -113,7 +109,7 @@ type EdgeRouterStore interface { func newEdgeRouterStore(stores *stores) *edgeRouterStoreImpl { store := &edgeRouterStoreImpl{ - baseStore: newBaseStore(stores, EntityTypeEdgeRouters), + baseStore: newChildBaseStore(stores, stores.Router), } store.InitImpl(store) return store @@ -139,12 +135,11 @@ func (store *edgeRouterStoreImpl) GetRoleAttributesIndex() boltz.SetReadIndex { } func (store *edgeRouterStoreImpl) initializeLocal() { - store.AddExtEntitySymbols() + store.GetParentStore().GrantSymbols(store) store.indexName = store.addUniqueNameField() store.indexRoleAttributes = store.addRoleAttributesField() - store.AddSymbol(FieldEdgeRouterFingerprint, ast.NodeTypeString) store.AddSymbol(FieldEdgeRouterIsVerified, ast.NodeTypeBool) store.symbolEnrollments = store.AddFkSetSymbol(FieldEdgeRouterEnrollments, store.stores.enrollment) store.symbolEdgeRouterPolicies = store.AddFkSetSymbol(EntityTypeEdgeRouterPolicies, store.stores.edgeRouterPolicy) diff --git a/controller/persistence/edge_service_store.go b/controller/persistence/edge_service_store.go index 2e2021123..f7b065282 100644 --- a/controller/persistence/edge_service_store.go +++ b/controller/persistence/edge_service_store.go @@ -48,7 +48,6 @@ func (entity *EdgeService) LoadValues(store boltz.CrudStore, bucket *boltz.Typed _, err := store.GetParentStore().BaseLoadOneById(bucket.Tx(), entity.Id, &entity.Service) bucket.SetError(err) - entity.LoadBaseValues(bucket) entity.Name = bucket.GetStringOrError(FieldName) entity.RoleAttributes = bucket.GetStringList(FieldRoleAttributes) entity.Configs = bucket.GetStringList(EntityTypeConfigs) @@ -57,7 +56,6 @@ func (entity *EdgeService) LoadValues(store boltz.CrudStore, bucket *boltz.Typed func (entity *EdgeService) SetValues(ctx *boltz.PersistContext) { entity.Service.SetValues(ctx.GetParentContext()) - entity.SetBaseValues(ctx) store := ctx.Store.(*edgeServiceStoreImpl) ctx.SetString(FieldName, entity.Name) ctx.SetStringList(FieldRoleAttributes, entity.RoleAttributes) @@ -69,10 +67,6 @@ func (entity *EdgeService) SetValues(ctx *boltz.PersistContext) { } } -func (entity *EdgeService) GetEntityType() string { - return EntityTypeServices -} - func (entity *EdgeService) GetName() string { return entity.Name } @@ -117,7 +111,6 @@ func (store *edgeServiceStoreImpl) GetRoleAttributesIndex() boltz.SetReadIndex { } func (store *edgeServiceStoreImpl) initializeLocal() { - store.AddExtEntitySymbols() store.GetParentStore().GrantSymbols(store) store.indexName = store.addUniqueNameField() diff --git a/controller/persistence/migration_v7.go b/controller/persistence/migration_v7.go new file mode 100644 index 000000000..2ac8f1df9 --- /dev/null +++ b/controller/persistence/migration_v7.go @@ -0,0 +1,114 @@ +package persistence + +import ( + "github.com/michaelquigley/pfxlog" + "github.com/openziti/fabric/controller/db" + "github.com/openziti/foundation/storage/boltz" + "github.com/openziti/foundation/util/stringz" + "github.com/pkg/errors" + "strings" +) + +const ( + migrationEntityTypeEdgeRouters = "edgeRouters" +) + +func (m *Migrations) moveEdgeRoutersUnderFabricRouters(step *boltz.MigrationStep) { + rootBucket := step.Ctx.Tx().Bucket([]byte(boltz.RootBucket)) + if rootBucket == nil { + step.SetError(errors.New("root bucket not found!")) + return + } + + log := pfxlog.Logger() + + edgeRoutersBucket := rootBucket.Bucket([]byte(migrationEntityTypeEdgeRouters)) + if edgeRoutersBucket == nil { + log.Debugf("old edge routers bucket not found. skipping edge router migration") + return + } + + cursor := edgeRoutersBucket.Cursor() + + for key, _ := cursor.First(); key != nil; key, _ = cursor.Next() { + routerId := string(key) + log.Debugf("converting edge router %v", routerId) + + edgeRouterBucket := boltz.Path(step.Ctx.Tx(), boltz.RootBucket, migrationEntityTypeEdgeRouters, routerId) + + router, _ := m.stores.Router.LoadOneById(step.Ctx.Tx(), routerId) + if router == nil { + fingerprint := edgeRouterBucket.GetString("fingerprint") + if fingerprint != nil { + cfp := strings.Replace(strings.ToLower(*fingerprint), ":", "", -1) + fingerprint = &cfp + } + + createdAt := edgeRouterBucket.GetTimeOrError(boltz.FieldCreatedAt) + updatedAt := edgeRouterBucket.GetTimeOrError(boltz.FieldUpdatedAt) + tags := edgeRouterBucket.GetMap(boltz.FieldTags) + + router = &db.Router{ + BaseExtEntity: boltz.BaseExtEntity{ + Id: routerId, + ExtEntityFields: boltz.ExtEntityFields{ + CreatedAt: createdAt, + UpdatedAt: updatedAt, + Tags: tags, + Migrate: true, + }, + }, + Fingerprint: fingerprint, + } + if step.SetError(m.stores.Router.Create(step.Ctx, router)) { + return + } + } + + edgeBucket := boltz.GetOrCreatePath(step.Ctx.Tx(), boltz.RootBucket, db.EntityTypeRouters, routerId, EdgeBucket) + if edgeBucket.HasError() { + step.SetError(edgeBucket.Err) + return + } + + err := edgeBucket.Copy(edgeRouterBucket, func(path []string) bool { + return !stringz.Contains([]string{boltz.FieldId, boltz.FieldCreatedAt, boltz.FieldUpdatedAt, boltz.FieldTags, db.FieldRouterFingerprint}, path[0]) + }) + + if step.SetError(err) { + return + } + } + + m.fixPolicyEdgeRouterReferences(step, m.stores.EdgeRouterPolicy) + m.fixPolicyEdgeRouterReferences(step, m.stores.ServiceEdgeRouterPolicy) +} + +func (m *Migrations) fixPolicyEdgeRouterReferences(step *boltz.MigrationStep, store boltz.CrudStore) { + ids, _, err := store.QueryIds(step.Ctx.Tx(), "true") + if step.SetError(err) { + return + } + + log := pfxlog.Logger() + + copyAll := func([]string) bool { + return true + } + + for _, id := range ids { + log.Debugf("converting %v %v", store.GetSingularEntityType(), id) + policyBucket := store.GetEntityBucket(step.Ctx.Tx(), []byte(id)) + edgeRoutersBucket := policyBucket.GetBucket(migrationEntityTypeEdgeRouters) + if edgeRoutersBucket == nil { + continue + } + routersBucket := policyBucket.GetOrCreateBucket(db.EntityTypeRouters) + if step.SetError(routersBucket.GetError()) { + return + } + if step.SetError(routersBucket.Copy(edgeRoutersBucket, copyAll)) { + return + } + } +} diff --git a/controller/persistence/migrations.go b/controller/persistence/migrations.go index 27a6f157a..ff49a8444 100644 --- a/controller/persistence/migrations.go +++ b/controller/persistence/migrations.go @@ -22,7 +22,7 @@ import ( ) const ( - CurrentDbVersion = 6 + CurrentDbVersion = 7 FieldVersion = "version" ) @@ -70,6 +70,10 @@ func (m *Migrations) migrate(step *boltz.MigrationStep) int { m.fixIdentityBuckets(step) } + if step.CurrentVersion < 7 { + m.moveEdgeRoutersUnderFabricRouters(step) + } + // current version if step.CurrentVersion <= CurrentDbVersion { return CurrentDbVersion diff --git a/controller/persistence/service_edge_router_policy_store.go b/controller/persistence/service_edge_router_policy_store.go index 1cf79ad86..1a99a5bd8 100644 --- a/controller/persistence/service_edge_router_policy_store.go +++ b/controller/persistence/service_edge_router_policy_store.go @@ -2,6 +2,7 @@ package persistence import ( "github.com/google/uuid" + "github.com/openziti/fabric/controller/db" "github.com/openziti/foundation/storage/ast" "github.com/openziti/foundation/storage/boltz" "github.com/openziti/foundation/util/stringz" @@ -122,7 +123,7 @@ func (store *serviceEdgeRouterPolicyStoreImpl) initializeLocal() { store.symbolServiceRoles = store.AddSetSymbol(FieldServiceRoles, ast.NodeTypeString) store.symbolEdgeRouterRoles = store.AddSetSymbol(FieldEdgeRouterRoles, ast.NodeTypeString) store.symbolServices = store.AddFkSetSymbol(EntityTypeServices, store.stores.edgeService) - store.symbolEdgeRouters = store.AddFkSetSymbol(EntityTypeEdgeRouters, store.stores.edgeRouter) + store.symbolEdgeRouters = store.AddFkSetSymbol(db.EntityTypeRouters, store.stores.edgeRouter) } func (store *serviceEdgeRouterPolicyStoreImpl) initializeLinked() { diff --git a/controller/persistence/service_edge_router_policy_store_test.go b/controller/persistence/service_edge_router_policy_store_test.go index f5afb6497..19e419e56 100644 --- a/controller/persistence/service_edge_router_policy_store_test.go +++ b/controller/persistence/service_edge_router_policy_store_test.go @@ -3,6 +3,7 @@ package persistence import ( "fmt" "github.com/google/uuid" + "github.com/openziti/fabric/controller/db" "github.com/openziti/foundation/util/stringz" "go.etcd.io/bbolt" "sort" @@ -28,7 +29,7 @@ func (ctx *TestContext) testCreateServiceEdgeRouterPolicy(_ *testing.T) { ctx.ValidateBaseline(policy) err := ctx.GetDb().View(func(tx *bbolt.Tx) error { - ctx.Equal(0, len(ctx.stores.ServiceEdgeRouterPolicy.GetRelatedEntitiesIdList(tx, policy.Id, EntityTypeEdgeRouters))) + ctx.Equal(0, len(ctx.stores.ServiceEdgeRouterPolicy.GetRelatedEntitiesIdList(tx, policy.Id, db.EntityTypeRouters))) ctx.Equal(0, len(ctx.stores.ServiceEdgeRouterPolicy.GetRelatedEntitiesIdList(tx, policy.Id, EntityTypeServices))) testPolicy, err := ctx.stores.ServiceEdgeRouterPolicy.LoadOneByName(tx, policy.Name) @@ -75,7 +76,7 @@ func (ctx *TestContext) testServiceEdgeRouterPolicyInvalidValues(_ *testing.T) { policy.ServiceRoles = nil policy.EdgeRouterRoles = []string{entityRef(invalidId)} err = ctx.Create(policy) - ctx.EqualError(err, fmt.Sprintf("the value '[%v]' for 'edgeRouterRoles' is invalid: no edgeRouters found with the given ids", invalidId)) + ctx.EqualError(err, fmt.Sprintf("the value '[%v]' for 'edgeRouterRoles' is invalid: no routers found with the given ids", invalidId)) policy.EdgeRouterRoles = []string{AllRole, roleRef("other")} err = ctx.Create(policy) @@ -86,7 +87,7 @@ func (ctx *TestContext) testServiceEdgeRouterPolicyInvalidValues(_ *testing.T) { policy.EdgeRouterRoles = []string{entityRef(edgeRouter.Id), entityRef(invalidId)} err = ctx.Create(policy) - ctx.EqualError(err, fmt.Sprintf("the value '[%v]' for 'edgeRouterRoles' is invalid: no edgeRouters found with the given ids", invalidId)) + ctx.EqualError(err, fmt.Sprintf("the value '[%v]' for 'edgeRouterRoles' is invalid: no routers found with the given ids", invalidId)) policy.EdgeRouterRoles = []string{entityRef(edgeRouter.Id)} ctx.RequireCreate(policy) @@ -94,7 +95,7 @@ func (ctx *TestContext) testServiceEdgeRouterPolicyInvalidValues(_ *testing.T) { policy.EdgeRouterRoles = append(policy.EdgeRouterRoles, entityRef(invalidId)) err = ctx.Update(policy) - ctx.EqualError(err, fmt.Sprintf("the value '[%v]' for 'edgeRouterRoles' is invalid: no edgeRouters found with the given ids", invalidId)) + ctx.EqualError(err, fmt.Sprintf("the value '[%v]' for 'edgeRouterRoles' is invalid: no routers found with the given ids", invalidId)) ctx.RequireDelete(policy) } @@ -203,7 +204,7 @@ func (ctx *TestContext) testServiceEdgeRouterPolicyRoleEvaluation(_ *testing.T) policies := ctx.createServiceEdgeRouterPolicies(serviceRoles, edgeRouterRoles, services, edgeRouters, true) for i := 0; i < 9; i++ { - relatedEdgeRouters := ctx.getRelatedIds(policies[i], EntityTypeEdgeRouters) + relatedEdgeRouters := ctx.getRelatedIds(policies[i], db.EntityTypeRouters) relatedServices := ctx.getRelatedIds(policies[i], EntityTypeServices) if i == 3 { ctx.Equal([]string{edgeRouters[0].Id}, relatedEdgeRouters) @@ -405,7 +406,7 @@ func (ctx *TestContext) validateServiceEdgeRouterPolicyServices(services []*Edge func (ctx *TestContext) validateServiceEdgeRouterPolicyEdgeRouters(edgeRouters []*EdgeRouter, policies []*ServiceEdgeRouterPolicy) { for _, policy := range policies { count := 0 - relatedEdgeRouters := ctx.getRelatedIds(policy, EntityTypeEdgeRouters) + relatedEdgeRouters := ctx.getRelatedIds(policy, db.EntityTypeRouters) for _, edgeRouter := range edgeRouters { relatedPolicies := ctx.getRelatedIds(edgeRouter, EntityTypeServiceEdgeRouterPolicies) shouldContain := ctx.policyShouldMatch(policy.Semantic, policy.EdgeRouterRoles, edgeRouter, edgeRouter.RoleAttributes) diff --git a/controller/persistence/stores.go b/controller/persistence/stores.go index 902297eae..1c8ed41f0 100644 --- a/controller/persistence/stores.go +++ b/controller/persistence/stores.go @@ -53,7 +53,7 @@ type Stores struct { Enrollment EnrollmentStore Authenticator AuthenticatorStore - storeMap map[string]boltz.CrudStore + storeMap map[reflect.Type]boltz.CrudStore } func (stores *Stores) buildStoreMap() { @@ -62,7 +62,8 @@ func (stores *Stores) buildStoreMap() { f := val.Field(i) if f.CanInterface() { if store, ok := f.Interface().(boltz.CrudStore); ok { - stores.storeMap[store.GetEntityType()] = store + entityType := reflect.TypeOf(store.NewStoreEntity()) + stores.storeMap[entityType] = store } } } @@ -79,7 +80,7 @@ func (stores *Stores) getStoreList() []Store { } func (stores *Stores) GetStoreForEntity(entity boltz.Entity) boltz.CrudStore { - return stores.storeMap[entity.GetEntityType()] + return stores.storeMap[reflect.TypeOf(entity)] } type stores struct { @@ -163,7 +164,7 @@ func NewBoltStores(dbProvider DbProvider) (*Stores, error) { Authenticator: internalStores.authenticator, Enrollment: internalStores.enrollment, - storeMap: make(map[string]boltz.CrudStore), + storeMap: make(map[reflect.Type]boltz.CrudStore), } // The Index store is used for querying indexes. It's a convenient store with only a single value (id), which diff --git a/controller/persistence/transit_router_store.go b/controller/persistence/transit_router_store.go index 7679c13d9..531e10987 100644 --- a/controller/persistence/transit_router_store.go +++ b/controller/persistence/transit_router_store.go @@ -53,7 +53,6 @@ func (entity *TransitRouter) LoadValues(store boltz.CrudStore, bucket *boltz.Typ entity.IsBase = true return } - entity.LoadBaseValues(bucket) entity.Name = bucket.GetStringOrError(FieldName) entity.IsVerified = bucket.GetBoolWithDefault(FieldTransitRouterIsVerified, false) entity.Enrollments = bucket.GetStringList(FieldTransitRouterEnrollments) @@ -61,7 +60,6 @@ func (entity *TransitRouter) LoadValues(store boltz.CrudStore, bucket *boltz.Typ func (entity *TransitRouter) SetValues(ctx *boltz.PersistContext) { entity.Router.SetValues(ctx.GetParentContext()) - entity.SetBaseValues(ctx) if ctx.Bucket != nil { ctx.SetString(FieldName, entity.Name) ctx.SetBool(FieldTransitRouterIsVerified, entity.IsVerified) diff --git a/go.mod b/go.mod index 1817e573f..6165a9f8c 100644 --- a/go.mod +++ b/go.mod @@ -34,7 +34,7 @@ require ( github.com/michaelquigley/pfxlog v0.0.0-20190813191113-2be43bd0dccc github.com/miekg/dns v1.1.29 github.com/mitchellh/mapstructure v1.3.1 - github.com/openziti/fabric v0.11.40 + github.com/openziti/fabric v0.11.43 github.com/openziti/foundation v0.11.5 github.com/openziti/sdk-golang v0.13.7 github.com/pkg/errors v0.9.1 diff --git a/go.sum b/go.sum index 946332d05..7848d9307 100644 --- a/go.sum +++ b/go.sum @@ -284,10 +284,8 @@ github.com/onsi/ginkgo v1.7.0 h1:WSHQ+IS43OoUrWtD1/bbclrwK8TTH5hzp+umCiuxHgs= github.com/onsi/ginkgo v1.7.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= github.com/onsi/gomega v1.4.3 h1:RE1xgDvH7imwFD45h+u2SgIfERHlS2yNG4DObb5BSKU= github.com/onsi/gomega v1.4.3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= -github.com/openziti/fabric v0.11.40 h1:IebmkMrAa7R216cBd1ROhON5RgiPFm9TVyqo7a2Aknk= -github.com/openziti/fabric v0.11.40/go.mod h1:LsIAeOvc0ygIPZ2QCuh2l/nWbt2pp2e431KAhNtixws= -github.com/openziti/foundation v0.11.2 h1:h6jsPLDkNzH1WTVPb8MPaECgYqEwzlXFwLRFeO1Aojk= -github.com/openziti/foundation v0.11.2/go.mod h1:E+z3Ne+G1IrApCxg/+kKLFg5hUubElHyylvfCLJg4fk= +github.com/openziti/fabric v0.11.43 h1:+EEo1xYossvXf7LDLcnw3cJxaZwh+k8ez/Ew9qBUd9s= +github.com/openziti/fabric v0.11.43/go.mod h1:va9H0K20ugtCsMj8/1vdRAWsWlFdy1T+OEdXm0e1LW4= github.com/openziti/foundation v0.11.5 h1:RmhFzKgH9KdztsF1T/70s+ftPpMGu1X3A6RhmPlOFiY= github.com/openziti/foundation v0.11.5/go.mod h1:jfnQ8WWFJGrDD2COPtQ/yX+gRlaiMdwUuXbvEBOpnLc= github.com/openziti/sdk-golang v0.13.7 h1:qDI5B2/lUfWhwhgt8QE/XR71CYkTxN4FRdJiSOkFKoE= @@ -370,8 +368,6 @@ github.com/xeipuuv/gojsonschema v1.2.0/go.mod h1:anYRn/JVcOK2ZgGU+IjEV4nwlhoK5sQ github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2/go.mod h1:UETIi67q53MR2AWcXfiuqkDkRtnGDLqkBTpCHuJHxtU= github.com/xordataexchange/crypt v0.0.3-0.20170626215501-b2862e3d0a77/go.mod h1:aYKd//L2LvnjZzWKhF00oedf4jCCReLcmhLdhm1A27Q= go.etcd.io/bbolt v1.3.2/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU= -go.etcd.io/bbolt v1.3.4 h1:hi1bXHMVrlQh6WwxAy+qZCV/SYIlqo+Ushwdpa4tAKg= -go.etcd.io/bbolt v1.3.4/go.mod h1:G5EMThwa9y8QZGBClrRx5EY+Yw9kAhnjy3bSjsnlVTQ= go.etcd.io/bbolt v1.3.5-0.20200615073812-232d8fc87f50 h1:ASw9n1EHMftwnP3Az4XW6e308+gNsrHzmdhd0Olz9Hs= go.etcd.io/bbolt v1.3.5-0.20200615073812-232d8fc87f50/go.mod h1:G5EMThwa9y8QZGBClrRx5EY+Yw9kAhnjy3bSjsnlVTQ= go.mongodb.org/mongo-driver v1.0.3/go.mod h1:u7ryQJ+DOzQmeO7zB6MHyr8jkEQvC8vH7qLUO4lqsUM= diff --git a/internal/cert/fingerprint.go b/internal/cert/fingerprint.go index 9cfcb884f..3a89244d9 100644 --- a/internal/cert/fingerprint.go +++ b/internal/cert/fingerprint.go @@ -119,8 +119,7 @@ func (fpg *defaultFingerprintGenerator) FromCerts(certs []*x509.Certificate) Fin } func (fpg *defaultFingerprintGenerator) FromRaw(raw []byte) string { - rawFingerprint := sha1.Sum(raw) - return fpg.toHex(rawFingerprint[:]) + return fmt.Sprintf("%x", sha1.Sum(raw)) } func (fpg *defaultFingerprintGenerator) toHex(f []byte) string {