diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index f9a1cad76..3eeae6ab4 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -147,7 +147,7 @@ jobs: - name: Test Ziti Command run: | echo "ZITI_ROOT=$(go env GOPATH)/bin" >> "$GITHUB_ENV" - pushd zititest && go test -v ./tests/... && popd + pushd zititest && go test -timeout 30m -v ./tests/... && popd - name: Test Ziti Command Teardown if: always() diff --git a/zititest/go.mod b/zititest/go.mod index 32ca82574..593c1a6ab 100644 --- a/zititest/go.mod +++ b/zititest/go.mod @@ -11,7 +11,7 @@ require ( github.com/michaelquigley/pfxlog v0.6.10 github.com/openziti/channel/v2 v2.0.81 github.com/openziti/edge v0.24.348 - github.com/openziti/fablab v0.4.58-0.20230614203155-19a2a4d811d3 + github.com/openziti/fablab v0.5.0 github.com/openziti/fabric v0.23.39 github.com/openziti/foundation/v2 v2.0.26 github.com/openziti/identity v1.0.57 diff --git a/zititest/go.sum b/zititest/go.sum index 2ec6a58f4..6add6d731 100644 --- a/zititest/go.sum +++ b/zititest/go.sum @@ -647,10 +647,8 @@ github.com/openziti/edge v0.24.348 h1:m0zh1n5OBj7Tjemu9XfxdYhbKvo6HdGQMHfC/Zledb github.com/openziti/edge v0.24.348/go.mod h1:wcoBVKqW99/CBg7LjzbHT3dJ8JMlRZelPhbjNcjwMr0= github.com/openziti/edge-api v0.25.29 h1:DbZ0GKpch9ik+XnC0qoP1dOg1AmgUEeWH4VIyOIehrQ= github.com/openziti/edge-api v0.25.29/go.mod h1:mqYquh1RYvHjV/M9MGO4Ng0Xq9ixAH8o8cT5kw5XCWY= -github.com/openziti/fablab v0.4.52 h1:X5+NaRnfPxbzhxUh9b4IQmVNVgYWFf8/Ck2sKNz77ho= -github.com/openziti/fablab v0.4.52/go.mod h1:aF8Fu3C8hnnaOJyAZz3AXGY4cMxQyBLhoIlSRJ/VVpc= -github.com/openziti/fablab v0.4.58-0.20230614203155-19a2a4d811d3 h1:Bkiiz5vi0GFezbuNBq21Dgp4oMkSeaPruF6/RlSAcZE= -github.com/openziti/fablab v0.4.58-0.20230614203155-19a2a4d811d3/go.mod h1:6T8sAnRdko8ozxS4pZWCM9rNuGr/fkB7G93N41utpl0= +github.com/openziti/fablab v0.5.0 h1:+CMVE08hS62UR3tIfEvMb3XcWwzD1np//cpHHTboVW8= +github.com/openziti/fablab v0.5.0/go.mod h1:VLvs0AAuKAFqy8jhGvs+FgszYEbB456duPOBfRj4peU= github.com/openziti/fabric v0.23.39 h1:t6npkfBsPr+8GvF9X/rTLHxGsce5FTa4NoA80MInxYc= github.com/openziti/fabric v0.23.39/go.mod h1:px2zUzQrgObmv6sdXgGJ028Wr45aGcgpFvfIP/qgDFo= github.com/openziti/foundation/v2 v2.0.26 h1:RISGM97aIFnnEkxrcVsO6fnGg9W4ByydSnqWAVkJAqY= diff --git a/zititest/models/simple/actions/bootstrap.go b/zititest/models/simple/actions/bootstrap.go index a5f2c5a89..f9c7f4391 100644 --- a/zititest/models/simple/actions/bootstrap.go +++ b/zititest/models/simple/actions/bootstrap.go @@ -17,6 +17,7 @@ package actions import ( + "fmt" "github.com/openziti/ziti/zititest/zitilab" "time" @@ -41,7 +42,7 @@ func (a *bootstrapAction) bind(m *model.Model) model.Action { workflow.AddAction(host.GroupExec("*", 25, "rm -f logs/*")) workflow.AddAction(component.Stop("#ctrl")) - workflow.AddAction(component.Exec("#ctrl", (*zitilab.ControllerType).InitStandalone)) + workflow.AddAction(component.Exec("#ctrl", zitilab.ControllerActionInitStandalone)) workflow.AddAction(component.Start("#ctrl")) workflow.AddAction(edge.ControllerAvailable("#ctrl", 30*time.Second)) @@ -68,56 +69,52 @@ func (a *bootstrapAction) bind(m *model.Model) model.Action { "protocol" : "tcp" }`)) - workflow.AddAction(zitilib_actions.Edge("create", "config", "files-intercept-ert-unencrypted", "intercept.v1", ` + workflow.AddAction(zitilib_actions.Edge("create", "config", "iperf-host", "host.v1", ` { - "addresses": ["ziti-files-ert-unencrypted.s3-us-west-1.amazonaws.ziti"], - "portRanges" : [ { "low": 443, "high": 443 } ], - "protocols": ["tcp"] + "address" : "localhost", + "port" : 5201, + "protocol" : "tcp" }`)) - workflow.AddAction(zitilib_actions.Edge("create", "config", "files-intercept-ert", "intercept.v1", ` - { - "addresses": ["ziti-files-ert.s3-us-west-1.amazonaws.ziti"], - "portRanges" : [ { "low": 443, "high": 443 } ], - "protocols": ["tcp"] - }`)) + for _, encrypted := range []bool{false, true} { + for _, hostType := range []string{"ert", "zet", "ziti-tunnel"} { + suffix := "" + encryptionFlag := "ON" - workflow.AddAction(zitilib_actions.Edge("create", "config", "files-intercept-zet-unencrypted", "intercept.v1", ` - { - "addresses": ["ziti-files-zet-unencrypted.s3-us-west-1.amazonaws.ziti"], - "portRanges" : [ { "low": 443, "high": 443 } ], - "protocols": ["tcp"] - }`)) + if !encrypted { + suffix = "-unencrypted" + encryptionFlag = "OFF" + } - workflow.AddAction(zitilib_actions.Edge("create", "config", "files-intercept-zet", "intercept.v1", ` - { - "addresses": ["ziti-files-zet.s3-us-west-1.amazonaws.ziti"], - "portRanges" : [ { "low": 443, "high": 443 } ], - "protocols": ["tcp"] - }`)) + filesConfigName := fmt.Sprintf("files-intercept-%s%s", hostType, suffix) + filesConfigDef := fmt.Sprintf(` + { + "addresses": ["files-%s%s.s3-us-west-1.amazonaws.ziti"], + "portRanges" : [ { "low": 443, "high": 443 } ], + "protocols": ["tcp"] + }`, hostType, suffix) - workflow.AddAction(zitilib_actions.Edge("create", "config", "files-intercept-ziti-tunnel-unencrypted", "intercept.v1", ` - { - "addresses": ["ziti-files-ziti-tunnel-unencrypted.s3-us-west-1.amazonaws.ziti"], - "portRanges" : [ { "low": 443, "high": 443 } ], - "protocols": ["tcp"] - }`)) + workflow.AddAction(zitilib_actions.Edge("create", "config", filesConfigName, "intercept.v1", filesConfigDef)) - workflow.AddAction(zitilib_actions.Edge("create", "config", "files-intercept-ziti-tunnel", "intercept.v1", ` - { - "addresses": ["ziti-files-ziti-tunnel.s3-us-west-1.amazonaws.ziti"], - "portRanges" : [ { "low": 443, "high": 443 } ], - "protocols": ["tcp"] - }`)) + iperfConfigName := fmt.Sprintf("iperf-intercept-%s%s", hostType, suffix) + iperfConfigDef := fmt.Sprintf(` + { + "addresses": ["iperf-%s%s.ziti"], + "portRanges" : [ { "low": 5201, "high": 5201 } ], + "protocols": ["tcp"] + }`, hostType, suffix) - workflow.AddAction(zitilib_actions.Edge("create", "service", "ert-files-unencrypted", "-c", "files-host,files-intercept-ert-unencrypted", "-e", "OFF", "-a", "ert")) - workflow.AddAction(zitilib_actions.Edge("create", "service", "ert-files", "-c", "files-host,files-intercept-ert", "-a", "ert")) + workflow.AddAction(zitilib_actions.Edge("create", "config", iperfConfigName, "intercept.v1", iperfConfigDef)) - workflow.AddAction(zitilib_actions.Edge("create", "service", "zet-files-unencrypted", "-c", "files-host,files-intercept-zet-unencrypted", "-e", "OFF", "-a", "zet")) - workflow.AddAction(zitilib_actions.Edge("create", "service", "zet-files", "-c", "files-host,files-intercept-zet", "-a", "zet")) + filesServiceName := fmt.Sprintf("%s-files%s", hostType, suffix) + filesConfigs := fmt.Sprintf("files-host,%s", filesConfigName) + workflow.AddAction(zitilib_actions.Edge("create", "service", filesServiceName, "-c", filesConfigs, "-e", encryptionFlag, "-a", hostType)) - workflow.AddAction(zitilib_actions.Edge("create", "service", "ziti-tunnel-files-unencrypted", "-c", "files-host,files-intercept-ziti-tunnel-unencrypted", "-e", "OFF", "-a", "ziti-tunnel")) - workflow.AddAction(zitilib_actions.Edge("create", "service", "ziti-tunnel-files", "-c", "files-host,files-intercept-ziti-tunnel", "-a", "ziti-tunnel")) + iperfServiceName := fmt.Sprintf("%s-iperf%s", hostType, suffix) + iperfConfigs := fmt.Sprintf("iperf-host,%s", iperfConfigName) + workflow.AddAction(zitilib_actions.Edge("create", "service", iperfServiceName, "-c", iperfConfigs, "-e", encryptionFlag, "-a", hostType)) + } + } workflow.AddAction(zitilib_actions.Edge("create", "service-policy", "ert-hosts", "Bind", "--service-roles", "#ert", "--identity-roles", "#ert-host")) workflow.AddAction(zitilib_actions.Edge("create", "service-policy", "zet-hosts", "Bind", "--service-roles", "#zet", "--identity-roles", "#zet-host")) diff --git a/zititest/models/simple/actions/start.go b/zititest/models/simple/actions/start.go index afbed82af..576267706 100644 --- a/zititest/models/simple/actions/start.go +++ b/zititest/models/simple/actions/start.go @@ -41,6 +41,7 @@ func (a *startAction) bind(m *model.Model) model.Action { workflow.AddAction(component.Start("#ctrl")) workflow.AddAction(edge.ControllerAvailable("#ctrl", 30*time.Second)) workflow.AddAction(component.StartInParallel(models.EdgeRouterTag, 25)) + workflow.AddAction(component.StartInParallel(".iperf", 5)) workflow.AddAction(semaphore.Sleep(2 * time.Second)) workflow.AddAction(zitilib_actions.StartMetricbeat("*", a.Metricbeat.ConfigPath, a.Metricbeat.DataPath, a.Metricbeat.LogPath)) @@ -48,6 +49,10 @@ func (a *startAction) bind(m *model.Model) model.Action { workflow.AddAction(semaphore.Sleep(2 * time.Second)) workflow.AddAction(component.StartInParallel(".sdk-app", 5)) + workflow.AddAction(semaphore.Sleep(5 * time.Second)) + workflow.AddAction(zitilib_actions.Edge("list", "edge-routers", "limit none")) + workflow.AddAction(zitilib_actions.Edge("list", "terminators", "limit none")) + return workflow } diff --git a/zititest/models/simple/simple.go b/zititest/models/simple/simple.go index 651566449..a9436c4d0 100644 --- a/zititest/models/simple/simple.go +++ b/zititest/models/simple/simple.go @@ -164,6 +164,10 @@ var Model = &model.Model{ Scope: model.Scope{Tags: model.Tags{"sdk-app", "service"}}, Type: &zitilab.EchoServerType{}, }, + "iperf-server-ert": { + Scope: model.Scope{Tags: model.Tags{"iperf", "service"}}, + Type: &zitilab.IPerfServerType{}, + }, }, }, "ziti-edge-tunnel-host": { @@ -174,6 +178,10 @@ var Model = &model.Model{ Version: "v0.21.4", }, }, + "iperf-server-zet": { + Scope: model.Scope{Tags: model.Tags{"iperf", "service"}}, + Type: &zitilab.IPerfServerType{}, + }, }, }, "ziti-tunnel-host": { @@ -184,6 +192,10 @@ var Model = &model.Model{ Mode: zitilab.ZitiTunnelModeHost, }, }, + "iperf-server-zt": { + Scope: model.Scope{Tags: model.Tags{"iperf", "service"}}, + Type: &zitilab.IPerfServerType{}, + }, }, }, }, @@ -209,8 +221,12 @@ var Model = &model.Model{ Infrastructure: model.Stages{ aws_ssh_key.Express(), - terraform_0.Express(), - semaphore0.Ready(time.Minute), + &terraform_0.Terraform{ + Retries: 3, + ReadyCheck: &semaphore0.ReadyStage{ + MaxWait: 90 * time.Second, + }, + }, }, Distribution: model.Stages{ diff --git a/zititest/tests/files_test.go b/zititest/tests/files_test.go index 5e4d5de14..562025bd4 100644 --- a/zititest/tests/files_test.go +++ b/zititest/tests/files_test.go @@ -32,8 +32,8 @@ var hashes = map[string]string{ } var timeouts = map[string]time.Duration{ - "1KB": 5 * time.Second, - "100KB": 5 * time.Second, + "1KB": 10 * time.Second, + "100KB": 10 * time.Second, "20MB": 40 * time.Second, } @@ -44,38 +44,69 @@ const ( ClientWget httpClient = "wget" ) -func TestCurlFiles(t *testing.T) { +func TestDownloadFiles(t *testing.T) { allZetHostedFailed := true - for _, hostType := range []string{"ert", "zet", "ziti-tunnel"} { - for _, clientType := range []string{"ert", "zet", "ziti-tunnel"} { - for _, encrypted := range []bool{true, false} { - success := testFileDownload(t, clientType, ClientCurl, hostType, encrypted, "1KB") - if hostType == "zet" && success { - allZetHostedFailed = false - } - } - } - } + allZetClientsFailed := true - for _, size := range []string{"100KB", "20MB"} { - for _, clientType := range []string{"ert", "zet"} { - for _, hostType := range []string{"ert", "zet"} { - for _, client := range []httpClient{ClientCurl, ClientWget} { - for _, encrypted := range []bool{true, false} { - success := testFileDownload(t, clientType, client, hostType, encrypted, size) - if hostType == "zet" && success { - allZetHostedFailed = false + t.Run("download-tests", func(t *testing.T) { + t.Run("test-ert-downloads", func(t *testing.T) { + t.Parallel() + + for _, size := range []string{"1KB", "100KB", "20MB"} { + for _, hostType := range []string{"ert", "zet", "ziti-tunnel"} { + for _, client := range []httpClient{ClientCurl, ClientWget} { + for _, encrypted := range []bool{true, false} { + success := testFileDownload(t, "ert", client, hostType, encrypted, size) + if hostType == "zet" && success { + allZetHostedFailed = false + } } } } } - } - } + }) - testFileDownload(t, "ziti-tunnel", ClientCurl, "ziti-tunnel", true, "20MB") + t.Run("test-zet-downloads", func(t *testing.T) { + t.Parallel() + + for _, size := range []string{"1KB", "100KB", "20MB"} { + for _, hostType := range []string{"zet", "ziti-tunnel", "ert"} { + for _, client := range []httpClient{ClientCurl, ClientWget} { + for _, encrypted := range []bool{true, false} { + success := testFileDownload(t, "zet", client, hostType, encrypted, size) + if hostType == "zet" && success { + allZetHostedFailed = false + } + if success { + allZetClientsFailed = false + } + } + } + } + } + }) + + t.Run("test-ziti-tunnel-downloads", func(t *testing.T) { + t.Parallel() + + for _, size := range []string{"1KB", "100KB", "20MB"} { + for _, hostType := range []string{"ziti-tunnel", "ert", "zet"} { + for _, client := range []httpClient{ClientCurl, ClientWget} { + for _, encrypted := range []bool{true, false} { + success := testFileDownload(t, "ziti-tunnel", client, hostType, encrypted, size) + if hostType == "zet" && success { + allZetHostedFailed = false + } + } + } + } + } + }) + }) req := require.New(t) req.False(allZetHostedFailed, "all zet hosted file transfer should not failed, indicates bigger issue") + req.False(allZetClientsFailed, "all zet client file transfers should not failed, indicates bigger issue") } func testFileDownload(t *testing.T, hostSelector string, client httpClient, hostType string, encrypted bool, fileSize string) bool { @@ -96,7 +127,7 @@ func testFileDownload(t *testing.T, hostSelector string, client httpClient, host urlExtra = "-unencrypted" } - url := fmt.Sprintf("https://ziti-files-%s%s.s3-us-west-1.amazonaws.ziti/%s.zip", hostType, urlExtra, fileSize) + url := fmt.Sprintf("https://files-%s%s.s3-us-west-1.amazonaws.ziti/%s.zip", hostType, urlExtra, fileSize) sshConfigFactory := lib.NewSshConfigFactory(host) var cmd string @@ -112,6 +143,13 @@ func testFileDownload(t *testing.T, hostSelector string, client httpClient, host t.Skipf("zet hosted file transfer failed [%v]", err.Error()) return } + + if hostSelector == "zet" && err != nil { + t.Skipf("zet client file transfer failed [%v]", err.Error()) + return + } + + t.Log(o) req.NoError(err) req.Equal(hashes[fileSize], o[0:32]) success = true diff --git a/zititest/tests/iperf_test.go b/zititest/tests/iperf_test.go new file mode 100644 index 000000000..1d339b861 --- /dev/null +++ b/zititest/tests/iperf_test.go @@ -0,0 +1,127 @@ +/* + (c) 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 tests + +import ( + "fmt" + "github.com/openziti/fablab/kernel/lib" + "github.com/openziti/fablab/kernel/model" + "github.com/stretchr/testify/require" + "testing" + "time" +) + +func TestIPerf(t *testing.T) { + t.Run("iperf-tests", func(t *testing.T) { + t.Run("ert-hosted", func(t *testing.T) { + t.Parallel() + + for _, clientType := range []string{"ert", "zet", "ziti-tunnel"} { + for _, encrypted := range []bool{true, false} { + for _, reversed := range []bool{true, false} { + testIPerf(t, clientType, "ert", encrypted, reversed) + } + } + } + }) + + t.Run("zet-hosted", func(t *testing.T) { + t.Parallel() + + for _, clientType := range []string{"zet", "ziti-tunnel", "ert"} { + for _, encrypted := range []bool{true, false} { + for _, reversed := range []bool{true, false} { + testIPerf(t, clientType, "zet", encrypted, reversed) + } + } + } + }) + + t.Run("ziti-tunnel-hosted", func(t *testing.T) { + t.Parallel() + + for _, clientType := range []string{"ziti-tunnel", "ert", "zet"} { + for _, encrypted := range []bool{true, false} { + for _, reversed := range []bool{true, false} { + testIPerf(t, clientType, "ziti-tunnel", encrypted, reversed) + } + } + } + }) + }) +} + +func testIPerf(t *testing.T, hostSelector string, hostType string, encrypted bool, reversed bool) bool { + encDesk := "encrypted" + if !encrypted { + encDesk = "unencrypted" + } + + direction := "->" + if reversed { + direction = "<-" + } + + success := false + + t.Run(fmt.Sprintf("(%s%s%s)-%v", hostSelector, direction, hostType, encDesk), func(t *testing.T) { + host, err := model.GetModel().SelectHost("." + hostSelector + "-client") + req := require.New(t) + req.NoError(err) + + urlExtra := "" + if !encrypted { + urlExtra = "-unencrypted" + } + + addr := fmt.Sprintf("iperf-%s%s.ziti", hostType, urlExtra) + + extraOptions := "" + if reversed { + extraOptions += " -R" + } + + cmd := fmt.Sprintf(`set -o pipefail; iperf3 -c %s -P 1 -t 10 %s`, addr, extraOptions) + + sshConfigFactory := lib.NewSshConfigFactory(host) + o, err := lib.RemoteExecAllWithTimeout(sshConfigFactory, 20*time.Second, cmd) + if hostType == "zet" && err != nil { + t.Skipf("zet hosted iperf test failed [%v]", err.Error()) + return + } + + if hostType == "ziti-tunnel" && err != nil { + t.Skipf("ziti-tunnel hosted iperf test failed [%v]", err.Error()) + return + } + + if hostSelector == "zet" && err != nil { + t.Skipf("zet client iperf test failed [%v]", err.Error()) + return + } + + if hostSelector == "ziti-tunnel" && err != nil { + t.Skipf("ziti-tunnel client iperf test failed [%v]", err.Error()) + return + } + + t.Log(o) + req.NoError(err) + success = true + }) + return success +} diff --git a/zititest/zitilab/actions/edge/ctrl_init.go b/zititest/zitilab/actions/edge/ctrl_init.go index 50c45ca63..823798de5 100644 --- a/zititest/zitilab/actions/edge/ctrl_init.go +++ b/zititest/zitilab/actions/edge/ctrl_init.go @@ -17,7 +17,7 @@ func InitController(componentSpec string) model.Action { } func (init *edgeInit) Execute(run model.Run) error { - return component.Exec(init.componentSpec, (*zitilab.ControllerType).InitStandalone).Execute(run) + return component.Exec(init.componentSpec, zitilab.ControllerActionInitStandalone).Execute(run) } type edgeInit struct { diff --git a/zititest/zitilab/actions/edge/init_routers.go b/zititest/zitilab/actions/edge/init_routers.go index aeff12b06..69281e386 100644 --- a/zititest/zitilab/actions/edge/init_routers.go +++ b/zititest/zitilab/actions/edge/init_routers.go @@ -14,7 +14,7 @@ func InitEdgeRouters(componentSpec string, concurrency int) model.Action { } func (action *initEdgeRoutersAction) Execute(run model.Run) error { - return component.ExecInParallel(action.componentSpec, action.concurrency, (*zitilab.RouterType).CreateAndEnrollRouter).Execute(run) + return component.ExecInParallel(action.componentSpec, action.concurrency, zitilab.RouterActionsCreateAndEnroll).Execute(run) } type initEdgeRoutersAction struct { diff --git a/zititest/zitilab/actions/edge/reenroll_routers.go b/zititest/zitilab/actions/edge/reenroll_routers.go index 164f3bfb6..0b7890211 100644 --- a/zititest/zitilab/actions/edge/reenroll_routers.go +++ b/zititest/zitilab/actions/edge/reenroll_routers.go @@ -14,7 +14,7 @@ func ReEnrollEdgeRouters(componentSpec string, concurrency int) model.Action { } func (action *reEnrollEdgeRoutersAction) Execute(run model.Run) error { - return component.ExecInParallel(action.componentSpec, action.concurrency, (*zitilab.RouterType).ReEnrollRouter).Execute(run) + return component.ExecInParallel(action.componentSpec, action.concurrency, zitilab.RouterActionsReEnroll).Execute(run) } type reEnrollEdgeRoutersAction struct { diff --git a/zititest/zitilab/component_controller.go b/zititest/zitilab/component_controller.go index fea22a1a3..62a9fc154 100644 --- a/zititest/zitilab/component_controller.go +++ b/zititest/zitilab/component_controller.go @@ -21,7 +21,6 @@ import ( "github.com/openziti/fablab/kernel/lib" "github.com/openziti/fablab/kernel/lib/actions/host" "github.com/openziti/fablab/kernel/model" - "github.com/openziti/foundation/v2/concurrenz" "github.com/openziti/ziti/zititest/zitilab/pki" "github.com/openziti/ziti/zititest/zitilab/stageziti" "github.com/pkg/errors" @@ -43,17 +42,12 @@ type ControllerType struct { ConfigName string Version string LocalPath string - actions concurrenz.CopyOnWriteMap[string, model.ComponentAction] } func (self *ControllerType) GetActions() map[string]model.ComponentAction { - if len(self.actions.AsMap()) == 0 { - self.actions.Put(model.ComponentActionStop, model.ComponentActionF(self.Stop)) - self.actions.Put(model.ComponentActionStart, model.ComponentActionF(self.Start)) - self.actions.Put(model.ComponentActionStageFiles, model.ComponentActionF(self.StageFiles)) - self.actions.Put(ControllerActionInitStandalone, model.ComponentActionF(self.InitStandalone)) + return map[string]model.ComponentAction{ + ControllerActionInitStandalone: model.ComponentActionF(self.InitStandalone), } - return self.actions.AsMap() } func (self *ControllerType) Dump() any { diff --git a/zititest/zitilab/component_iperf.go b/zititest/zitilab/component_iperf.go new file mode 100644 index 000000000..af20df11d --- /dev/null +++ b/zititest/zitilab/component_iperf.go @@ -0,0 +1,83 @@ +/* + Copyright 2019 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 zitilab + +import ( + "fmt" + "github.com/openziti/fablab/kernel/lib" + "github.com/openziti/fablab/kernel/model" + "github.com/sirupsen/logrus" + "strings" +) + +var _ model.ComponentType = (*IPerfServerType)(nil) + +type IPerfServerType struct { + Port uint16 +} + +func (self *IPerfServerType) Dump() any { + return map[string]string{ + "type_id": "iperf-server", + "port": fmt.Sprintf("%v", self.GetPort()), + } +} + +func (self *IPerfServerType) GetPort() uint16 { + if self.Port == 0 { + return 5201 + } + return self.Port +} + +func (self *IPerfServerType) getProcessFilter(*model.Component) func(string) bool { + return func(s string) bool { + return strings.Contains(s, fmt.Sprintf("iperf3 -s -p %v", self.GetPort())) + } +} + +func (self *IPerfServerType) IsRunning(_ model.Run, c *model.Component) (bool, error) { + factory := lib.NewSshConfigFactory(c.GetHost()) + pids, err := lib.FindProcesses(factory, self.getProcessFilter(c)) + if err != nil { + return false, err + } + return len(pids) > 0, nil +} + +func (self *IPerfServerType) Start(_ model.Run, c *model.Component) error { + factory := lib.NewSshConfigFactory(c.GetHost()) + + logsPath := fmt.Sprintf("/home/%s/logs/%s.log", factory.User(), c.Id) + serviceCmd := fmt.Sprintf("nohup iperf3 -s -p %v > %s 2>&1 &", self.GetPort(), logsPath) + + value, err := lib.RemoteExec(factory, serviceCmd) + if err != nil { + return err + } + + if len(value) > 0 { + logrus.Infof("output [%s]", strings.Trim(value, " \t\r\n")) + } + + return nil +} + +func (self *IPerfServerType) Stop(_ model.Run, c *model.Component) error { + factory := lib.NewSshConfigFactory(c.GetHost()) + return lib.RemoteKillFilterF(factory, self.getProcessFilter(c)) +} diff --git a/zititest/zitilab/component_router.go b/zititest/zitilab/component_router.go index 78d0e69e6..8103d1359 100644 --- a/zititest/zitilab/component_router.go +++ b/zititest/zitilab/component_router.go @@ -31,6 +31,11 @@ import ( var _ model.ComponentType = (*RouterType)(nil) +const ( + RouterActionsCreateAndEnroll = "createAndEnroll" + RouterActionsReEnroll = "reEnroll" +) + type RouterType struct { ConfigSourceFS fs.FS ConfigSource string @@ -39,6 +44,13 @@ type RouterType struct { LocalPath string } +func (self *RouterType) GetActions() map[string]model.ComponentAction { + return map[string]model.ComponentAction{ + RouterActionsCreateAndEnroll: model.ComponentActionF(self.CreateAndEnroll), + RouterActionsReEnroll: model.ComponentActionF(self.ReEnroll), + } +} + func (self *RouterType) Dump() any { return map[string]string{ "type_id": "router", @@ -119,7 +131,7 @@ func (self *RouterType) Stop(_ model.Run, c *model.Component) error { return lib.RemoteKillFilterF(factory, self.getProcessFilter(c)) } -func (self *RouterType) CreateAndEnrollRouter(run model.Run, c *model.Component) error { +func (self *RouterType) CreateAndEnroll(run model.Run, c *model.Component) error { if err := zitilib_actions.EdgeExec(c.GetModel(), "delete", "edge-router", c.Id); err != nil { pfxlog.Logger(). WithError(err). @@ -165,7 +177,7 @@ func (self *RouterType) CreateAndEnrollRouter(run model.Run, c *model.Component) return host.Exec(c.GetHost(), cmd).Execute(run) } -func (self *RouterType) ReEnrollRouter(run model.Run, c *model.Component) error { +func (self *RouterType) ReEnroll(run model.Run, c *model.Component) error { ssh := lib.NewSshConfigFactory(c.GetHost()) jwtFileName := filepath.Join(model.ConfigBuild(), c.Id+".jwt")