mirror of
https://github.com/hanzozt/zt.git
synced 2026-11-02 11:38:22 +00:00
325 lines
8.9 KiB
Go
325 lines
8.9 KiB
Go
package main
|
|
|
|
import (
|
|
"embed"
|
|
_ "embed"
|
|
"fmt"
|
|
"github.com/openziti/fablab"
|
|
"github.com/openziti/fablab/kernel/lib/actions"
|
|
"github.com/openziti/fablab/kernel/lib/actions/component"
|
|
"github.com/openziti/fablab/kernel/lib/actions/host"
|
|
"github.com/openziti/fablab/kernel/lib/actions/semaphore"
|
|
"github.com/openziti/fablab/kernel/lib/binding"
|
|
"github.com/openziti/fablab/kernel/lib/runlevel/0_infrastructure/aws_ssh_key"
|
|
"github.com/openziti/fablab/kernel/lib/runlevel/0_infrastructure/semaphore"
|
|
"github.com/openziti/fablab/kernel/lib/runlevel/0_infrastructure/terraform"
|
|
distribution "github.com/openziti/fablab/kernel/lib/runlevel/3_distribution"
|
|
"github.com/openziti/fablab/kernel/lib/runlevel/3_distribution/rsync"
|
|
aws_ssh_key2 "github.com/openziti/fablab/kernel/lib/runlevel/6_disposal/aws_ssh_key"
|
|
"github.com/openziti/fablab/kernel/lib/runlevel/6_disposal/terraform"
|
|
"github.com/openziti/fablab/kernel/model"
|
|
"github.com/openziti/fablab/resources"
|
|
"github.com/openziti/ziti/controller/db"
|
|
"github.com/openziti/ziti/zititest/models/test_resources"
|
|
"github.com/openziti/ziti/zititest/zitilab"
|
|
"github.com/openziti/ziti/zititest/zitilab/actions/edge"
|
|
"github.com/openziti/ziti/zititest/zitilab/models"
|
|
"go.etcd.io/bbolt"
|
|
"os"
|
|
"path"
|
|
"strings"
|
|
"time"
|
|
)
|
|
|
|
// const TargetZitiVersion = "v0.31.0"
|
|
|
|
const TargetZitiVersion = ""
|
|
const TargetZitiEdgeTunnelVersion = ""
|
|
|
|
//const TargetZitiEdgeTunnelVersion = "0.22.12"
|
|
|
|
var TunnelType = "!zet"
|
|
|
|
//go:embed configs
|
|
var configResource embed.FS
|
|
|
|
type dbStrategy struct{}
|
|
|
|
func (d dbStrategy) GetDbFile(m *model.Model) string {
|
|
return m.MustStringVariable("db_file")
|
|
}
|
|
|
|
func (d dbStrategy) GetSite(router *db.EdgeRouter) (string, bool) {
|
|
if strings.Contains(strings.ToLower(router.Name), "london") {
|
|
return "eu-west-2a", true // london region
|
|
}
|
|
if strings.Contains(strings.ToLower(router.Name), "virginia") {
|
|
return "us-east-1a", true // london region
|
|
}
|
|
if strings.Contains(strings.ToLower(router.Name), "melbourne") {
|
|
return "ap-southeast-2a", true // sydney region
|
|
}
|
|
|
|
return "us-east-1a", true
|
|
}
|
|
|
|
func (d dbStrategy) PostProcess(router *db.EdgeRouter, c *model.Component) {
|
|
if router.IsTunnelerEnabled {
|
|
c.Scope.Tags = append(c.Scope.Tags, "tunneler")
|
|
}
|
|
c.Scope.Tags = append(c.Scope.Tags, "edge-router")
|
|
c.Scope.Tags = append(c.Scope.Tags, "pre-created")
|
|
c.Host.InstanceType = "c5.xlarge"
|
|
c.Type.(*zitilab.RouterType).Version = TargetZitiVersion
|
|
}
|
|
|
|
func (d dbStrategy) ProcessDbModel(tx *bbolt.Tx, m *model.Model, builder *models.ZitiDbBuilder) error {
|
|
if err := builder.CreateEdgeRouterHosts(tx, m, d); err != nil {
|
|
return err
|
|
}
|
|
return d.CreateIdentityHosts(tx, m, builder)
|
|
}
|
|
|
|
func (d dbStrategy) CreateIdentityHosts(tx *bbolt.Tx, m *model.Model, builder *models.ZitiDbBuilder) error {
|
|
stores := builder.GetStores()
|
|
ids, _, err := stores.Identity.QueryIds(tx, "true limit none")
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
servicesCount := 0
|
|
hostingIdentities := map[string]int{}
|
|
|
|
for _, identityId := range ids {
|
|
cursorProvider := stores.Identity.GetIdentityServicesCursorProvider(identityId)
|
|
cursor := cursorProvider(tx, true)
|
|
identityServiceCount := 0
|
|
for cursor.IsValid() {
|
|
serviceId := string(cursor.Current())
|
|
if stores.EdgeService.IsBindableByIdentity(tx, serviceId, identityId) {
|
|
identityServiceCount++
|
|
}
|
|
cursor.Next()
|
|
}
|
|
if identityServiceCount > 0 {
|
|
servicesCount += identityServiceCount
|
|
hostingIdentities[identityId] = identityServiceCount
|
|
}
|
|
}
|
|
|
|
fmt.Printf("service count: %v\n", servicesCount)
|
|
|
|
regionCount := len(m.Regions)
|
|
|
|
perRegion := servicesCount / regionCount
|
|
idIdx := 0
|
|
|
|
avgTunnelsPerHost := 15
|
|
|
|
m.RangeSortedRegions(func(regionId string, region *model.Region) {
|
|
regionServiceCount := 0
|
|
|
|
var regionIdentityIds []string
|
|
|
|
for {
|
|
if idIdx >= len(ids) {
|
|
break
|
|
}
|
|
identityId := ids[idIdx]
|
|
idIdx++
|
|
|
|
svcCount, found := hostingIdentities[identityId]
|
|
if !found {
|
|
continue
|
|
}
|
|
regionServiceCount += svcCount
|
|
regionIdentityIds = append(regionIdentityIds, identityId)
|
|
if regionServiceCount > perRegion {
|
|
break
|
|
}
|
|
}
|
|
|
|
hostCount := len(regionIdentityIds) / avgTunnelsPerHost
|
|
var hosts []*model.Host
|
|
|
|
for i := 0; i < hostCount; i++ {
|
|
tunnelsHost := &model.Host{
|
|
Scope: model.Scope{Tags: model.Tags{}},
|
|
Region: region,
|
|
Components: model.Components{},
|
|
InstanceType: "t3.xlarge",
|
|
}
|
|
hostId := fmt.Sprintf("%s_svc_hosts_%v", regionId, i)
|
|
region.Hosts[hostId] = tunnelsHost
|
|
hosts = append(hosts, tunnelsHost)
|
|
}
|
|
|
|
hostIdx := 0
|
|
for _, identityId := range regionIdentityIds {
|
|
tunnelHost := hosts[hostIdx%len(hosts)]
|
|
hostIdx++
|
|
|
|
svcCount := hostingIdentities[identityId]
|
|
|
|
getConfigPath := func(c *model.Component) string {
|
|
user := c.GetHost().GetSshUser()
|
|
return fmt.Sprintf("/home/%s/etc/%s.json", user, c.Id)
|
|
}
|
|
|
|
var tunnelType model.ComponentType
|
|
if TunnelType == "zet" {
|
|
tunnelType = &zitilab.ZitiEdgeTunnelType{
|
|
Version: TargetZitiEdgeTunnelVersion,
|
|
LogConfig: "'2;bind.c=6'",
|
|
ConfigPathF: getConfigPath,
|
|
}
|
|
} else {
|
|
tunnelType = &zitilab.ZitiTunnelType{
|
|
Mode: zitilab.ZitiTunnelModeHost,
|
|
Version: TargetZitiVersion,
|
|
ConfigPathF: getConfigPath,
|
|
}
|
|
}
|
|
|
|
tunnelComponent := &model.Component{
|
|
Scope: model.Scope{Tags: model.Tags{"client", "pre-created", fmt.Sprintf("serviceCount=%v", svcCount)}},
|
|
Type: tunnelType,
|
|
Host: tunnelHost,
|
|
}
|
|
tunnelHost.Components[identityId] = tunnelComponent
|
|
}
|
|
})
|
|
|
|
return nil
|
|
}
|
|
|
|
var dbStrategyInstance = dbStrategy{}
|
|
|
|
var m = &model.Model{
|
|
Id: "db-sdk-hosting-test",
|
|
Scope: model.Scope{
|
|
Defaults: model.Variables{
|
|
"environment": "db-sdk-hosting-test",
|
|
"credentials": model.Variables{
|
|
"aws": model.Variables{
|
|
"managed_key": true,
|
|
},
|
|
"ssh": model.Variables{
|
|
"username": "ubuntu",
|
|
},
|
|
"edge": model.Variables{
|
|
"username": "admin",
|
|
"password": "admin",
|
|
},
|
|
},
|
|
"metrics": model.Variables{
|
|
"influxdb": model.Variables{
|
|
"url": "http://localhost:8086",
|
|
"db": "ziti",
|
|
},
|
|
},
|
|
},
|
|
},
|
|
StructureFactories: []model.Factory{
|
|
&models.ZitiDbBuilder{Strategy: dbStrategyInstance},
|
|
},
|
|
Resources: model.Resources{
|
|
resources.Configs: resources.SubFolder(configResource, "configs"),
|
|
resources.Binaries: os.DirFS(path.Join(os.Getenv("GOPATH"), "bin")),
|
|
resources.Terraform: test_resources.TerraformResources(),
|
|
},
|
|
Regions: model.Regions{
|
|
"us-east-1": {
|
|
Region: "us-east-1",
|
|
Site: "us-east-1a",
|
|
Hosts: model.Hosts{
|
|
"ctrl": {
|
|
InstanceType: "c5.xlarge",
|
|
Components: model.Components{
|
|
"ctrl": {
|
|
Scope: model.Scope{Tags: model.Tags{"ctrl"}},
|
|
Type: &zitilab.ControllerType{
|
|
Version: TargetZitiVersion,
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
|
|
Actions: model.ActionBinders{
|
|
"bootstrap": model.ActionBinder(func(m *model.Model) model.Action {
|
|
workflow := actions.Workflow()
|
|
|
|
workflow.AddAction(component.Start("#ctrl"))
|
|
workflow.AddAction(semaphore.Sleep(2 * time.Second))
|
|
|
|
workflow.AddAction(edge.Login("#ctrl"))
|
|
|
|
workflow.AddAction(edge.ReEnrollEdgeRouters(".edge-router .pre-created", 2))
|
|
if quickRun, _ := m.GetBoolVariable("quick_run"); !quickRun {
|
|
workflow.AddAction(edge.ReEnrollIdentities(".client .pre-created", 10))
|
|
}
|
|
return workflow
|
|
}),
|
|
"stop": model.Bind(component.StopInParallelHostExclusive("*", 15)),
|
|
"clean": model.Bind(actions.Workflow(
|
|
component.StopInParallelHostExclusive("*", 15),
|
|
host.GroupExec("*", 25, "rm -f logs/*"),
|
|
)),
|
|
"login": model.Bind(edge.Login("#ctrl")),
|
|
"restart": model.ActionBinder(func(run *model.Model) model.Action {
|
|
workflow := actions.Workflow()
|
|
workflow.AddAction(component.StopInParallel("*", 100))
|
|
workflow.AddAction(component.Start(".ctrl"))
|
|
workflow.AddAction(semaphore.Sleep(2 * time.Second))
|
|
workflow.AddAction(component.StartInParallel(".edge-router", 10))
|
|
workflow.AddAction(semaphore.Sleep(2 * time.Second))
|
|
workflow.AddAction(component.StartInParallel(".client", 50))
|
|
return workflow
|
|
}),
|
|
},
|
|
|
|
Infrastructure: model.Stages{
|
|
aws_ssh_key.Express(),
|
|
&terraform_0.Terraform{
|
|
Retries: 3,
|
|
ReadyCheck: &semaphore_0.ReadyStage{
|
|
MaxWait: 90 * time.Second,
|
|
},
|
|
},
|
|
},
|
|
|
|
Distribution: model.Stages{
|
|
distribution.DistributeSshKey("*"),
|
|
rsync.RsyncStaged(),
|
|
model.StageActionF(func(run model.Run) error {
|
|
quickRun, _ := run.GetModel().GetBoolVariable("quick_run")
|
|
_, targetedSync := run.GetModel().Scope.GetVariable("sync.target")
|
|
|
|
if !quickRun && !targetedSync {
|
|
dbFile := dbStrategyInstance.GetDbFile(run.GetModel())
|
|
deferred := rsync.NewRsyncHost("#ctrl", dbFile, "/home/ubuntu/ctrl.db")
|
|
return deferred.Execute(run)
|
|
}
|
|
return nil
|
|
}),
|
|
},
|
|
|
|
Disposal: model.Stages{
|
|
terraform.Dispose(),
|
|
aws_ssh_key2.Dispose(),
|
|
},
|
|
}
|
|
|
|
func main() {
|
|
m.AddActivationActions("stop", "bootstrap")
|
|
|
|
model.AddBootstrapExtension(binding.AwsCredentialsLoader)
|
|
model.AddBootstrapExtension(aws_ssh_key.KeyManager)
|
|
|
|
fablab.InitModel(m)
|
|
fablab.Run()
|
|
}
|