mirror of
https://github.com/openziti/ziti.git
synced 2026-10-26 21:47:05 +00:00
f18ce1b580
- collapses the edge service boltz child store into the unified service store:
EdgeService becomes a type alias for Service, and RoleAttributes, Configs, and
EncryptionRequired become top-level Service fields
- adds an IsFabricOnly discriminator separating pure-fabric ("management")
services from edge services
- adds a forward-only, irreversible migration that moves edge service data out of
the edge child bucket, classifies pre-existing services (fabric -> IsFabricOnly
with encryptionRequired=false; edge -> IsFabricOnly=false), deletes the old edge
bucket and its index, and rebuilds the role-attributes index via CheckIntegrity
- guards every edge-facing path on the unified store against fabric-only services
so they stay invisible to the edge API: by-id Read/ReadByName/Delete, list/query
and the detail lister, ReadForIdentity, identity service-config overrides,
service policy / SERP @id and #all/role denormalization, the association-list
routes (terminators, policies, configs), and the router data-model sync
- rejects edge-surface updates of fabric-only services, and preserves edge fields
on fabric-surface updates of edge services
- marks the fabric-only guards TEMPORARY(fabric-edge-collapse): they exist only to
keep seldom-used management services hidden, and are removed when the fabric/edge
distinction is erased
- adds in-CI migration tests (forward plus a round-trip asserting FK sub-bucket
relocation and forward/reverse refcount preservation), durable fabric-only
behavior tests, and store-level policy-exclusion tests
- adds one-time authentic-migration gate tooling under zititest/migration-test
(create-model.sh, query, verify) and its operator runbook
87 lines
3.0 KiB
Go
87 lines
3.0 KiB
Go
/*
|
|
Copyright NetFoundry Inc.
|
|
|
|
Licensed under the Apache License, Version 2.0 (the "License");
|
|
you may not use this file except in compliance with the License.
|
|
You may obtain a copy of the License at
|
|
|
|
https://www.apache.org/licenses/LICENSE-2.0
|
|
|
|
Unless required by applicable law or agreed to in writing, software
|
|
distributed under the License is distributed on an "AS IS" BASIS,
|
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
See the License for the specific language governing permissions and
|
|
limitations under the License.
|
|
*/
|
|
|
|
package model
|
|
|
|
import (
|
|
"time"
|
|
|
|
"github.com/openziti/ziti/v2/controller/storage/boltz"
|
|
"github.com/openziti/ziti/v2/controller/db"
|
|
"github.com/openziti/ziti/v2/controller/models"
|
|
"go.etcd.io/bbolt"
|
|
)
|
|
|
|
type Service struct {
|
|
models.BaseEntity
|
|
Name string
|
|
TerminatorStrategy string
|
|
Terminators []*Terminator
|
|
MaxIdleTime time.Duration
|
|
}
|
|
|
|
func (entity *Service) GetName() string {
|
|
return entity.Name
|
|
}
|
|
|
|
func (entity *Service) toBoltEntityForUpdate(tx *bbolt.Tx, env Env, _ boltz.FieldChecker) (*db.Service, error) {
|
|
// Since the edge/fabric service collapse, the edge fields (RoleAttributes, Configs,
|
|
// EncryptionRequired) and the IsFabricOnly discriminator share the service entity bucket with
|
|
// the fabric fields. Load the existing entity and overlay only the fabric-owned fields so a
|
|
// fabric update preserves the rest. Without this, a full PUT (nil field checker) would persist
|
|
// zero values for the edge fields and flip an existing edge service to fabric-only.
|
|
existing, err := env.GetStores().Service.LoadById(tx, entity.Id)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
existing.Name = entity.Name
|
|
existing.MaxIdleTime = entity.MaxIdleTime
|
|
existing.TerminatorStrategy = entity.TerminatorStrategy
|
|
existing.Tags = entity.Tags
|
|
return existing, nil
|
|
}
|
|
|
|
func (entity *Service) toBoltEntityForCreate(*bbolt.Tx, Env) (*db.Service, error) {
|
|
return &db.Service{
|
|
BaseExtEntity: *boltz.NewExtEntity(entity.Id, entity.Tags),
|
|
Name: entity.Name,
|
|
MaxIdleTime: entity.MaxIdleTime,
|
|
TerminatorStrategy: entity.TerminatorStrategy,
|
|
IsFabricOnly: true,
|
|
// The fabric surface does not model encryptionRequired, so apply the secure default.
|
|
// The field is unreachable for fabric-only services today, but when fabric and edge
|
|
// services fully merge, fabric services should require encryption unless explicitly
|
|
// opted out.
|
|
EncryptionRequired: true,
|
|
}, nil
|
|
}
|
|
|
|
func (entity *Service) fillFrom(env Env, tx *bbolt.Tx, boltService *db.Service) error {
|
|
entity.Name = boltService.Name
|
|
entity.MaxIdleTime = boltService.MaxIdleTime
|
|
entity.TerminatorStrategy = boltService.TerminatorStrategy
|
|
entity.FillCommon(boltService)
|
|
|
|
terminatorIds := env.GetStores().Service.GetRelatedEntitiesIdList(tx, entity.Id, db.EntityTypeTerminators)
|
|
for _, terminatorId := range terminatorIds {
|
|
if terminator, _ := env.GetManagers().Terminator.readInTx(tx, terminatorId); terminator != nil {
|
|
entity.Terminators = append(entity.Terminators, terminator)
|
|
}
|
|
}
|
|
|
|
return nil
|
|
}
|