From 0808a2b9750a915c263ff83bf5b2515b3fa80a3f Mon Sep 17 00:00:00 2001 From: Yasmin Valim Date: Fri, 20 Oct 2023 20:27:00 -0300 Subject: [PATCH] Feat: add import selinux module cmd in the function --- config/fcos/v1_6_exp/translate.go | 58 +++----- config/fcos/v1_6_exp/translate_test.go | 183 +++++++++++++++++++++++++ config/fcos/v1_6_exp/validate_test.go | 2 +- 3 files changed, 203 insertions(+), 40 deletions(-) diff --git a/config/fcos/v1_6_exp/translate.go b/config/fcos/v1_6_exp/translate.go index b028d53d..dba56ede 100644 --- a/config/fcos/v1_6_exp/translate.go +++ b/config/fcos/v1_6_exp/translate.go @@ -16,6 +16,7 @@ package v1_6_exp import ( "fmt" + "os/exec" "strings" baseutil "github.com/coreos/butane/base/util" @@ -389,15 +390,15 @@ func (c Config) handleSelinux(options common.TranslateOptions) (types.Config, tr Path: util.StrToPtr("/boot"), }) - selinuxModule := []byte(buildModuleConfig(c.Selinux)) - src, compression, err := baseutil.MakeDataURL(selinuxModule, nil, !options.NoResourceAutoCompression) - if err != nil { - r.AddOnError(yamlPath, err) - return rendered, ts, r - } // this should happen as many times as there are modules for _, module := range c.Selinux.Module { + src, compression, err := baseutil.MakeDataURL([]byte(module.Content), nil, !options.NoResourceAutoCompression) + if err != nil { + r.AddOnError(yamlPath, err) + return rendered, ts, r + } + filePath := fmt.Sprintf("/etc/selinux/targeted/modules/active/extra/%s.cil", module.Name) rendered.Storage.Files = append(rendered.Storage.Files, @@ -415,41 +416,20 @@ func (c Config) handleSelinux(options common.TranslateOptions) (types.Config, tr }, }) - ts.AddFromCommonSource(yamlPath, path.New("json", "storage"), rendered.Storage) - } + if module.Name != "" { + commandToExecute := "semodule -i" + cmd := exec.Command(commandToExecute, filePath) + err := cmd.Run() + if err != nil { + fmt.Printf("Error running semodule %v", module.Name) + } - return rendered, ts, r -} + fmt.Printf("SELinux module file imported successfully\n") + + } + ts.AddFromCommonSource(yamlPath, path.New("json", "storage"), rendered.Storage) -func buildModuleConfig(selinux Selinux) string { - // TODO: this needs to be updated to handle multiple modules and render a file per module - for _, module := range selinux.Module { - return module.Content } - return "" + return rendered, ts, r } - -// add a function to transform the module name into the path -// add a function to run the command to import selinux module - -// func ImportSelinuxFile(se SelinuxModule) (string, error) { -// //execute SElinux semodule command -// if se.Path == "" { -// return "", fmt.Errorf("The SELinux costum module path cannot be empty.") -// } -// commandToExecute := "semodule -i" -// cmd := exec.Command(commandToExecute, se.Path) -// err := cmd.Run() -// if err != nil { -// return "", fmt.Errorf("Error running semodule: %v", err) -// } -// return "SELinux module file imported successfully\n", nil -// func BuildPath(selinux Selinux, name string) (string, error) { -// for _, module := range selinux.Module { -// if module.Name == name { -// return "/etc/selinux/targeted/modules/active/extra/" + module.Name + ".cil", nil -// } -// } -// return "", fmt.Errorf("Name not found: %s", name) -// } diff --git a/config/fcos/v1_6_exp/translate_test.go b/config/fcos/v1_6_exp/translate_test.go index 0ba27bf4..c05f2b87 100644 --- a/config/fcos/v1_6_exp/translate_test.go +++ b/config/fcos/v1_6_exp/translate_test.go @@ -1655,7 +1655,90 @@ func TestTranslateSelinux(t *testing.T) { {From: path.New("yaml", "selinux", "module"), To: path.New("json", "storage", "files", 0, "append", 0, "source")}, {From: path.New("yaml", "selinux", "module"), To: path.New("json", "storage", "files", 0, "append", 0, "compression")}, } + tests := []struct { + in Config + out types.Config + exceptions []translate.Translation + report report.Report + }{ + // config with one module + { + Config{ + Selinux: Selinux{ + Module: []Module{ + { + Name: "some_name", + Content: "some content here", + }, + }, + }, + }, + types.Config{ + Ignition: types.Ignition{ + Version: "3.5.0-experimental", + }, + Storage: types.Storage{ + Filesystems: []types.Filesystem{ + { + Device: "/dev/disk/by-label/boot", + Format: util.StrToPtr("ext4"), + Path: util.StrToPtr("/boot"), + }, + }, + Files: []types.File{ + { + Node: types.Node{ + Path: "/etc/selinux/targeted/modules/active/extra/some_name.cil", + }, + FileEmbedded1: types.FileEmbedded1{ + Append: []types.Resource{ + { + Source: util.StrToPtr("data:,some%20content%20here"), + Compression: util.StrToPtr(""), + }, + }, + }, + }, + }, + }, + }, + translations, + report.Report{}, + }, + } + + for i, test := range tests { + t.Run(fmt.Sprintf("translate %d", i), func(t *testing.T) { + actual, translations, r := test.in.ToIgn3_5Unvalidated(common.TranslateOptions{}) + r = confutil.TranslateReportPaths(r, translations) + baseutil.VerifyReport(t, test.in, r) + assert.Equal(t, test.out, actual, "translation mismatch") + assert.Equal(t, test.report, r, "report mismatch") + baseutil.VerifyTranslations(t, translations, test.exceptions) + assert.NoError(t, translations.DebugVerifyCoverage(actual), "incomplete TranslationSet coverage") + }) + } +} + +func TestTranslateSelinuxaaa(t *testing.T) { + translations := []translate.Translation{ + {From: path.New("yaml", "version"), To: path.New("json", "ignition", "version")}, + {From: path.New("yaml", "selinux", "module"), To: path.New("json", "storage")}, + {From: path.New("yaml", "selinux", "module"), To: path.New("json", "storage", "filesystems")}, + {From: path.New("yaml", "selinux", "module"), To: path.New("json", "storage", "filesystems", 0)}, + {From: path.New("yaml", "selinux", "module"), To: path.New("json", "storage", "filesystems", 0, "path")}, + {From: path.New("yaml", "selinux", "module"), To: path.New("json", "storage", "filesystems", 0, "device")}, + {From: path.New("yaml", "selinux", "module"), To: path.New("json", "storage", "filesystems", 0, "format")}, + {From: path.New("yaml", "selinux", "module"), To: path.New("json", "storage", "files")}, + {From: path.New("yaml", "selinux", "module"), To: path.New("json", "storage", "files", 0)}, + {From: path.New("yaml", "selinux", "module"), To: path.New("json", "storage", "files", 0, "path")}, + {From: path.New("yaml", "selinux", "module"), To: path.New("json", "storage", "files", 0, "append")}, + {From: path.New("yaml", "selinux", "module"), To: path.New("json", "storage", "files", 0, "append", 0)}, + {From: path.New("yaml", "selinux", "module"), To: path.New("json", "storage", "files", 0, "append", 0, "source")}, + {From: path.New("yaml", "selinux", "module"), To: path.New("json", "storage", "files", 0, "append", 0, "compression")}, + } + // With one module in := Config{ Selinux: Selinux{ Module: []Module{ @@ -1718,3 +1801,103 @@ func TestTranslateSelinux(t *testing.T) { assert.NoError(t, translations.DebugVerifyCoverage(actual), "incomplete TranslationSet coverage") }) } + +// TODO: testing with two modules and merge those two tests and other scenerios +func TestTranslateModule(t *testing.T) { + translations := []translate.Translation{ + {From: path.New("yaml", "version"), To: path.New("json", "ignition", "version")}, + {From: path.New("yaml", "selinux", "module"), To: path.New("json", "storage")}, + {From: path.New("yaml", "selinux", "module"), To: path.New("json", "storage", "filesystems")}, + {From: path.New("yaml", "selinux", "module"), To: path.New("json", "storage", "filesystems", 0)}, + {From: path.New("yaml", "selinux", "module"), To: path.New("json", "storage", "filesystems", 0, "path")}, + {From: path.New("yaml", "selinux", "module"), To: path.New("json", "storage", "filesystems", 0, "device")}, + {From: path.New("yaml", "selinux", "module"), To: path.New("json", "storage", "filesystems", 0, "format")}, + {From: path.New("yaml", "selinux", "module"), To: path.New("json", "storage", "files")}, + {From: path.New("yaml", "selinux", "module"), To: path.New("json", "storage", "files", 0)}, + {From: path.New("yaml", "selinux", "module"), To: path.New("json", "storage", "files", 0, "path")}, + {From: path.New("yaml", "selinux", "module"), To: path.New("json", "storage", "files", 0, "append")}, + {From: path.New("yaml", "selinux", "module"), To: path.New("json", "storage", "files", 0, "append", 0)}, + {From: path.New("yaml", "selinux", "module"), To: path.New("json", "storage", "files", 0, "append", 0, "source")}, + {From: path.New("yaml", "selinux", "module"), To: path.New("json", "storage", "files", 0, "append", 0, "compression")}, + } + + // With 2 modules + in := Config{ + Selinux: Selinux{ + Module: []Module{ + { + Name: "some_name", + Content: "some content here", + }, + { + Name: "another_name", + Content: "some content here", + }, + }, + }, + } + out := types.Config{ + Ignition: types.Ignition{ + Version: "3.5.0-experimental", + }, + Storage: types.Storage{ + Filesystems: []types.Filesystem{ + { + Device: "/dev/disk/by-label/boot", + Format: util.StrToPtr("ext4"), + Path: util.StrToPtr("/boot"), + }, + }, + Files: []types.File{ + { + Node: types.Node{ + Path: "/etc/selinux/targeted/modules/active/extra/some_name.cil", + }, + FileEmbedded1: types.FileEmbedded1{ + Append: []types.Resource{ + { + Source: util.StrToPtr("data:,some%20content%20here"), + Compression: util.StrToPtr(""), + }, + }, + }, + }, + { + Node: types.Node{ + Path: "/etc/selinux/targeted/modules/active/extra/another_name.cil", + }, + FileEmbedded1: types.FileEmbedded1{ + Append: []types.Resource{ + { + Source: util.StrToPtr("data:,some%20content%20here"), + Compression: util.StrToPtr(""), + }, + }, + }, + }, + }, + }, + } + + test := struct { + in Config + out types.Config + exceptions []translate.Translation + report report.Report + }{ + in, + out, + translations, + report.Report{}, + } + + t.Run(fmt.Sprintf("translate %d", 0), func(t *testing.T) { + actual, translations, r := test.in.ToIgn3_5Unvalidated(common.TranslateOptions{}) + r = confutil.TranslateReportPaths(r, translations) + baseutil.VerifyReport(t, test.in, r) + assert.Equal(t, test.out, actual, "translation mismatch") + assert.Equal(t, test.report, r, "report mismatch") + baseutil.VerifyTranslations(t, translations, test.exceptions) + assert.NoError(t, translations.DebugVerifyCoverage(actual), "incomplete TranslationSet coverage") + }) +} diff --git a/config/fcos/v1_6_exp/validate_test.go b/config/fcos/v1_6_exp/validate_test.go index 9cf76774..98d8369b 100644 --- a/config/fcos/v1_6_exp/validate_test.go +++ b/config/fcos/v1_6_exp/validate_test.go @@ -487,7 +487,7 @@ func TestValidateModule(t *testing.T) { errPath path.ContextPath }{ { - // name is empty, path is specified + // content is empty, path is specified in: Module{ Content: "", Name: "some name",