Skip to content

Commit e9e095f

Browse files
test: adding function to build kubectl plugin
Signed-off-by: Venkatesh Jayagopal <venkatesh.jayagopal@suse.com>
1 parent 8307d01 commit e9e095f

2 files changed

Lines changed: 32 additions & 189 deletions

File tree

test/e2e/e2e_suite_test.go

Lines changed: 16 additions & 173 deletions
Original file line numberDiff line numberDiff line change
@@ -2,16 +2,11 @@ package e2e_test
22

33
import (
44
"context"
5-
"crypto/sha256"
6-
"encoding/hex"
75
"fmt"
8-
"io"
96
"log/slog"
10-
"net/http"
117
"os"
128
"os/exec"
139
"path/filepath"
14-
"runtime"
1510
"slices"
1611
"strings"
1712
"testing"
@@ -56,6 +51,19 @@ func installDependencies() bool {
5651
return os.Getenv("E2E_SKIP_DEPENDENCIES") != "true"
5752
}
5853

54+
func makeKubectlPlugin() error {
55+
projectRoot := filepath.Join("..", "..")
56+
cmd := exec.Command("make", "kubectl-plugin")
57+
cmd.Dir = projectRoot
58+
cmd.Stdout = os.Stdout
59+
cmd.Stderr = os.Stderr
60+
61+
if err := cmd.Run(); err != nil {
62+
return fmt.Errorf("failed to run make kubectl-plugin: %w", err)
63+
}
64+
return nil
65+
}
66+
5967
type helmChart struct {
6068
name string
6169
namespace string
@@ -122,13 +130,15 @@ func getCharts() []helmChart {
122130
}
123131

124132
func TestMain(m *testing.M) {
133+
// we build kubectl_runtime-enforcer binary to run plugin e2e tests
134+
makeKubectlPlugin()
135+
125136
charts := getCharts()
126137

127138
commonSetupFuncs := []env.Func{
128139
// we uninstall here as a defensive check but nothing should be left behind
129140
uninstallHelmRepos(charts),
130141
installHelmRepos(charts),
131-
installKubectlRuntimeEnforcer(),
132142
}
133143

134144
commonFinishFuncs := []env.Func{
@@ -275,170 +285,3 @@ func installHelmRepos(charts []helmChart) env.Func {
275285
}
276286
}
277287

278-
// installKubectlRuntimeEnforcer downloads and installs the kubectl runtime-enforcer plugin.
279-
func installKubectlRuntimeEnforcer() env.Func {
280-
return func(ctx context.Context, _ *envconf.Config) (context.Context, error) {
281-
version := "v0.6.0"
282-
installDir := "/usr/local/bin"
283-
284-
logger := slog.New(slog.NewJSONHandler(os.Stdout, nil))
285-
goos := runtime.GOOS
286-
goarch := runtime.GOARCH
287-
288-
if !isSupportedPlatform(goos, goarch) {
289-
return ctx, fmt.Errorf(
290-
"unsupported platform: %s/%s (supported: linux/amd64, linux/arm64, darwin/amd64, darwin/arm64)",
291-
goos,
292-
goarch,
293-
)
294-
}
295-
296-
logger.InfoContext(ctx, "Downloading and installing kubectl runtime-enforcer plugin.")
297-
298-
pluginName := "kubectl-runtime_enforcer"
299-
binaryName := fmt.Sprintf("%s-%s-%s", pluginName, goos, goarch)
300-
downloadURL := fmt.Sprintf(
301-
"https://github.com/rancher-sandbox/runtime-enforcer/releases/download/%s/%s",
302-
version,
303-
binaryName,
304-
)
305-
checksumURL := fmt.Sprintf("%s.sha256", downloadURL)
306-
307-
tempDir, err := os.MkdirTemp("", "runtime-enforcer-install-")
308-
if err != nil {
309-
return ctx, fmt.Errorf("failed to create temp directory: %w", err)
310-
}
311-
defer os.RemoveAll(tempDir)
312-
313-
binaryPath := filepath.Join(tempDir, binaryName)
314-
checksumPath := filepath.Join(tempDir, binaryName+".sha256")
315-
316-
if err1 := downloadFile(downloadURL, binaryPath); err1 != nil {
317-
return ctx, fmt.Errorf("failed to download binary: %w", err1)
318-
}
319-
320-
if err2 := downloadFile(checksumURL, checksumPath); err2 != nil {
321-
return ctx, fmt.Errorf("failed to download checksum: %w", err2)
322-
}
323-
324-
if err3 := verifyChecksum(binaryPath, checksumPath); err3 != nil {
325-
return ctx, fmt.Errorf("checksum verification failed: %w", err3)
326-
}
327-
328-
if err4 := os.Chmod(binaryPath, 0755); err4 != nil {
329-
return ctx, fmt.Errorf("failed to make binary executable: %w", err4)
330-
}
331-
332-
installPath := filepath.Join(installDir, pluginName)
333-
if err5 := moveFile(binaryPath, installPath); err5 != nil {
334-
return ctx, fmt.Errorf("failed to install binary: %w", err5)
335-
}
336-
337-
cmd := exec.Command(pluginName, "-v")
338-
if output, err6 := cmd.CombinedOutput(); err6 != nil {
339-
return ctx, fmt.Errorf(
340-
"installation verification failed: %w\nOutput: %s",
341-
err6,
342-
string(output),
343-
)
344-
}
345-
346-
return ctx, nil
347-
}
348-
}
349-
350-
func isSupportedPlatform(goos, goarch string) bool {
351-
supported := map[string][]string{
352-
"linux": {"amd64", "arm64"},
353-
"darwin": {"amd64", "arm64"},
354-
}
355-
356-
if archs, ok := supported[goos]; ok {
357-
for _, arch := range archs {
358-
if arch == goarch {
359-
return true
360-
}
361-
if slices.Contains(archs, goarch) {
362-
return true
363-
}
364-
}
365-
}
366-
return false
367-
}
368-
369-
func downloadFile(url, filepath string) error {
370-
resp, err := http.Get(url)
371-
if err != nil {
372-
return err
373-
}
374-
defer resp.Body.Close()
375-
376-
if resp.StatusCode != http.StatusOK {
377-
return fmt.Errorf("bad status: %s", resp.Status)
378-
}
379-
380-
out, err := os.Create(filepath)
381-
if err != nil {
382-
return err
383-
}
384-
defer out.Close()
385-
386-
_, err = io.Copy(out, resp.Body)
387-
return err
388-
}
389-
390-
func verifyChecksum(binaryPath, checksumPath string) error {
391-
checksumData, err := os.ReadFile(checksumPath)
392-
if err != nil {
393-
return err
394-
}
395-
396-
var expected string
397-
fmt.Sscanf(string(checksumData), "%s", &expected)
398-
399-
file, err := os.Open(binaryPath)
400-
if err != nil {
401-
return err
402-
}
403-
defer file.Close()
404-
405-
hash := sha256.New()
406-
if _, err1 := io.Copy(hash, file); err1 != nil {
407-
return err1
408-
}
409-
actual := hex.EncodeToString(hash.Sum(nil))
410-
411-
if actual != expected {
412-
return fmt.Errorf("checksum mismatch: expected %s, got %s", expected, actual)
413-
}
414-
415-
return nil
416-
}
417-
418-
func moveFile(src, dst string) error {
419-
if err := os.Rename(src, dst); err == nil {
420-
return nil
421-
}
422-
423-
srcFile, err := os.Open(src)
424-
if err != nil {
425-
return err
426-
}
427-
defer srcFile.Close()
428-
429-
dstFile, err := os.Create(dst)
430-
if err != nil {
431-
return err
432-
}
433-
defer dstFile.Close()
434-
435-
if _, err1 := io.Copy(dstFile, srcFile); err1 != nil {
436-
return err1
437-
}
438-
439-
if err2 := dstFile.Sync(); err2 != nil {
440-
return err2
441-
}
442-
443-
return os.Remove(src)
444-
}

test/e2e/kubectl_plugin_test.go

Lines changed: 16 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -103,7 +103,7 @@ func getKubectlPluginProposalPromoteTest() types.Feature {
103103
}).
104104
Assess("dry-run flag works correctly",
105105
func(ctx context.Context, t *testing.T, _ *envconf.Config) context.Context {
106-
temp := "kubectl runtime-enforcer proposal promote " + proposalName + " --namespace " + getNamespace(
106+
temp := "./../../bin/kubectl-runtime_enforcer proposal promote " + proposalName + " --namespace " + getNamespace(
107107
ctx,
108108
) + " --dry-run"
109109
cmd := exec.Command("bash", "-c", temp)
@@ -120,7 +120,7 @@ func getKubectlPluginProposalPromoteTest() types.Feature {
120120
}).
121121
Assess("kubectl plugin promotes proposal successfully",
122122
func(ctx context.Context, t *testing.T, _ *envconf.Config) context.Context {
123-
temp := "kubectl runtime-enforcer proposal promote " + proposalName + " --namespace " + getNamespace(
123+
temp := "./../../bin/kubectl-runtime_enforcer proposal promote " + proposalName + " --namespace " + getNamespace(
124124
ctx,
125125
)
126126
cmd := exec.Command("bash", "-c", temp)
@@ -224,7 +224,7 @@ func getKubectlPluginPolicyModeTest() types.Feature {
224224
Assess("required resources become available", IfRequiredResourcesAreCreated).
225225
Assess("kubectl plugin switches mode to protect",
226226
func(ctx context.Context, t *testing.T, _ *envconf.Config) context.Context {
227-
temp := "kubectl runtime-enforcer policy protect " + policyName + " --namespace " + getNamespace(
227+
temp := "./../../bin/kubectl-runtime_enforcer policy protect " + policyName + " --namespace " + getNamespace(
228228
ctx,
229229
)
230230
cmd := exec.Command("bash", "-c", temp)
@@ -257,7 +257,7 @@ func getKubectlPluginPolicyModeTest() types.Feature {
257257
}).
258258
Assess("kubectl plugin switches mode back to monitor",
259259
func(ctx context.Context, t *testing.T, _ *envconf.Config) context.Context {
260-
temp := "kubectl runtime-enforcer policy monitor " + policyName + " --namespace " + getNamespace(
260+
temp := "./../../bin/kubectl-runtime_enforcer policy monitor " + policyName + " --namespace " + getNamespace(
261261
ctx,
262262
)
263263
cmd := exec.Command("bash", "-c", temp)
@@ -288,7 +288,7 @@ func getKubectlPluginPolicyModeTest() types.Feature {
288288
}).
289289
Assess("setting mode to same value is idempotent",
290290
func(ctx context.Context, t *testing.T, _ *envconf.Config) context.Context {
291-
temp := "kubectl runtime-enforcer policy monitor " + policyName + " --namespace " + getNamespace(
291+
temp := "./../../bin/kubectl-runtime_enforcer policy monitor " + policyName + " --namespace " + getNamespace(
292292
ctx,
293293
)
294294
cmd := exec.Command("bash", "-c", temp)
@@ -305,7 +305,7 @@ func getKubectlPluginPolicyModeTest() types.Feature {
305305
}).
306306
Assess("dry-run flag works for mode change",
307307
func(ctx context.Context, t *testing.T, _ *envconf.Config) context.Context {
308-
temp := "kubectl runtime-enforcer policy protect " + policyName + " --namespace " + getNamespace(
308+
temp := "./../../bin/kubectl-runtime_enforcer policy protect " + policyName + " --namespace " + getNamespace(
309309
ctx,
310310
) + " --dry-run"
311311
cmd := exec.Command("bash", "-c", temp)
@@ -339,7 +339,7 @@ func getKubectlPluginPolicyModeTest() types.Feature {
339339
}).
340340
Assess("error handling for non-existent policy",
341341
func(ctx context.Context, t *testing.T, _ *envconf.Config) context.Context {
342-
temp := "kubectl runtime-enforcer policy protect non-existent-policy" + " --namespace " + getNamespace(
342+
temp := "./../../bin/kubectl-runtime_enforcer policy protect non-existent-policy" + " --namespace " + getNamespace(
343343
ctx,
344344
)
345345
cmd := exec.Command("bash", "-c", temp)
@@ -399,7 +399,7 @@ func getKubectlPluginPolicyExecAllowTest() types.Feature {
399399
Assess("required resources become available", IfRequiredResourcesAreCreated).
400400
Assess("kubectl plugin allows new executables",
401401
func(ctx context.Context, t *testing.T, _ *envconf.Config) context.Context {
402-
temp := "kubectl runtime-enforcer policy allow " + policyName + " " + containerName + " /usr/bin/cat /usr/bin/grep " + " --namespace " + getNamespace(
402+
temp := "./../../bin/kubectl-runtime_enforcer policy allow " + policyName + " " + containerName + " /usr/bin/cat /usr/bin/grep " + " --namespace " + getNamespace(
403403
ctx,
404404
)
405405
cmd := exec.Command("bash", "-c", temp)
@@ -436,7 +436,7 @@ func getKubectlPluginPolicyExecAllowTest() types.Feature {
436436
}).
437437
Assess("allowing already-allowed executable is idempotent",
438438
func(ctx context.Context, t *testing.T, _ *envconf.Config) context.Context {
439-
temp := "kubectl runtime-enforcer policy allow " + policyName + " " + containerName + " /usr/bin/cat " + " --namespace " + getNamespace(
439+
temp := "./../../bin/kubectl-runtime_enforcer policy allow " + policyName + " " + containerName + " /usr/bin/cat " + " --namespace " + getNamespace(
440440
ctx,
441441
)
442442
cmd := exec.Command("bash", "-c", temp)
@@ -468,7 +468,7 @@ func getKubectlPluginPolicyExecAllowTest() types.Feature {
468468
require.NoError(t, err)
469469
beforeAllowed := policy.Spec.RulesByContainer[containerName].Executables.Allowed
470470

471-
temp := "kubectl runtime-enforcer policy allow " + policyName + " " + containerName + " /usr/bin/awk " + " --namespace " + getNamespace(
471+
temp := "./../../bin/kubectl-runtime_enforcer policy allow " + policyName + " " + containerName + " /usr/bin/awk " + " --namespace " + getNamespace(
472472
ctx,
473473
) + " --dry-run"
474474
cmd := exec.Command("bash", "-c", temp)
@@ -537,7 +537,7 @@ func getKubectlPluginPolicyExecDenyTest() types.Feature {
537537
Assess("required resources become available", IfRequiredResourcesAreCreated).
538538
Assess("kubectl plugin denies executables",
539539
func(ctx context.Context, t *testing.T, _ *envconf.Config) context.Context {
540-
temp := "kubectl runtime-enforcer policy deny " + policyName + " " + containerName + " /usr/bin/awk /usr/bin/sed " + " --namespace " + getNamespace(
540+
temp := "./../../bin/kubectl-runtime_enforcer policy deny " + policyName + " " + containerName + " /usr/bin/awk /usr/bin/sed " + " --namespace " + getNamespace(
541541
ctx,
542542
)
543543
cmd := exec.Command("bash", "-c", temp)
@@ -575,7 +575,7 @@ func getKubectlPluginPolicyExecDenyTest() types.Feature {
575575
}).
576576
Assess("denying non-existent executable is idempotent",
577577
func(ctx context.Context, t *testing.T, _ *envconf.Config) context.Context {
578-
temp := "kubectl runtime-enforcer policy deny " + policyName + " " + containerName + " /usr/bin/nonexistent " + " --namespace " + getNamespace(
578+
temp := "./../../bin/kubectl-runtime_enforcer policy deny " + policyName + " " + containerName + " /usr/bin/nonexistent " + " --namespace " + getNamespace(
579579
ctx,
580580
) + " --dry-run"
581581
cmd := exec.Command("bash", "-c", temp)
@@ -602,7 +602,7 @@ func getKubectlPluginPolicyExecDenyTest() types.Feature {
602602
err := r.Get(ctx, policyName, getNamespace(ctx), &policy)
603603
require.NoError(t, err)
604604
beforeAllowed := policy.Spec.RulesByContainer[containerName].Executables.Allowed
605-
temp := "kubectl runtime-enforcer policy deny " + policyName + " " + containerName + " /usr/bin/ls " + " --namespace " + getNamespace(
605+
temp := "./../../bin/kubectl-runtime_enforcer policy deny " + policyName + " " + containerName + " /usr/bin/ls " + " --namespace " + getNamespace(
606606
ctx,
607607
) + " --dry-run"
608608
cmd := exec.Command("bash", "-c", temp)
@@ -641,7 +641,7 @@ func getKubectlPluginErrorHandlingTest() types.Feature {
641641
Assess("required resources become available", IfRequiredResourcesAreCreated).
642642
Assess("error when promoting non-existent proposal",
643643
func(ctx context.Context, t *testing.T, _ *envconf.Config) context.Context {
644-
temp := "kubectl runtime-enforcer proposal promote non-existent-proposal " + " --namespace " + getNamespace(
644+
temp := "./../../bin/kubectl-runtime_enforcer proposal promote non-existent-proposal " + " --namespace " + getNamespace(
645645
ctx,
646646
)
647647
cmd := exec.Command("bash", "-c", temp)
@@ -661,7 +661,7 @@ func getKubectlPluginErrorHandlingTest() types.Feature {
661661
}).
662662
Assess("error when modifying non-existent policy",
663663
func(ctx context.Context, t *testing.T, _ *envconf.Config) context.Context {
664-
temp := "kubectl runtime-enforcer policy protect non-existent-proposal " + " --namespace " + getNamespace(
664+
temp := "./../../bin/kubectl-runtime_enforcer policy protect non-existent-proposal " + " --namespace " + getNamespace(
665665
ctx,
666666
)
667667
cmd := exec.Command("bash", "-c", temp)
@@ -697,7 +697,7 @@ func getKubectlPluginErrorHandlingTest() types.Feature {
697697
r := getClient(ctx)
698698
err := r.Create(ctx, &policy)
699699
require.NoError(t, err)
700-
temp := "kubectl runtime-enforcer policy allow test-policy non-existent-container /usr/bin/ls" + " --namespace " + getNamespace(
700+
temp := "./../../bin/kubectl-runtime_enforcer policy allow test-policy non-existent-container /usr/bin/ls" + " --namespace " + getNamespace(
701701
ctx,
702702
)
703703
cmd := exec.Command("bash", "-c", temp)

0 commit comments

Comments
 (0)