Skip to content

Commit 263e1e4

Browse files
Merge pull request #4824 from isabella-janssen/ocpbugs-34586
[release-4.17] OCPBUGS-49363: Auto-recover from MC with invalid extension
2 parents 11006a4 + afa9f52 commit 263e1e4

File tree

4 files changed

+81
-35
lines changed

4 files changed

+81
-35
lines changed

pkg/controller/common/helpers.go

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -609,9 +609,50 @@ func ValidateMachineConfig(cfg mcfgv1.MachineConfigSpec) error {
609609
return err
610610
}
611611
}
612+
613+
// Validate MC extensions are in allowlist
614+
if len(cfg.Extensions) > 0 {
615+
if err := ValidateMachineConfigExtensions(cfg); err != nil {
616+
return err
617+
}
618+
}
619+
return nil
620+
}
621+
622+
// Validates that a given MachineConfig's extensions are supported.
623+
func ValidateMachineConfigExtensions(cfg mcfgv1.MachineConfigSpec) error {
624+
return validateExtensions(cfg.Extensions)
625+
}
626+
func validateExtensions(exts []string) error {
627+
supportedExtensions := SupportedExtensions()
628+
invalidExts := []string{}
629+
for _, ext := range exts {
630+
if _, ok := supportedExtensions[ext]; !ok {
631+
invalidExts = append(invalidExts, ext)
632+
}
633+
}
634+
if len(invalidExts) != 0 {
635+
return fmt.Errorf("invalid extensions found: %v", invalidExts)
636+
}
612637
return nil
613638
}
614639

640+
// Returns list of extensions possible to install on a CoreOS based system.
641+
func SupportedExtensions() map[string][]string {
642+
// In future when list of extensions grow, it will make
643+
// more sense to populate it in a dynamic way.
644+
// These are RHCOS supported extensions.
645+
// Each extension keeps a list of packages required to get enabled on host.
646+
return map[string][]string{
647+
"wasm": {"crun-wasm"},
648+
"ipsec": {"NetworkManager-libreswan", "libreswan"},
649+
"usbguard": {"usbguard"},
650+
"kerberos": {"krb5-workstation", "libkadm5"},
651+
"kernel-devel": {"kernel-devel", "kernel-headers"},
652+
"sandboxed-containers": {"kata-containers"},
653+
}
654+
}
655+
615656
// IgnParseWrapper parses rawIgn for both V2 and V3 ignition configs and returns
616657
// a V2 or V3 Config or an error. This wrapper is necessary since V2 and V3 use different parsers.
617658
func IgnParseWrapper(rawIgn []byte) (interface{}, error) {

pkg/controller/common/helpers_test.go

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -793,3 +793,40 @@ func TestParseAndConvertGzippedConfig(t *testing.T) {
793793
})
794794
}
795795
}
796+
797+
func TestValidateMachineConfigExtensions(t *testing.T) {
798+
t.Parallel()
799+
testCases := []struct {
800+
name string
801+
extensions []string
802+
errExpected bool
803+
}{
804+
{
805+
name: "Supported",
806+
extensions: []string{"kerberos", "sandboxed-containers"},
807+
},
808+
{
809+
name: "Unsupported",
810+
extensions: []string{"unsupported1", "unsupported2"},
811+
errExpected: true,
812+
},
813+
}
814+
for _, testCase := range testCases {
815+
testCase := testCase
816+
t.Run(testCase.name, func(t *testing.T) {
817+
t.Parallel()
818+
mcfgSpec := mcfgv1.MachineConfigSpec{
819+
Extensions: testCase.extensions,
820+
}
821+
err := ValidateMachineConfigExtensions(mcfgSpec)
822+
if testCase.errExpected {
823+
assert.Error(t, err)
824+
for _, ext := range testCase.extensions {
825+
assert.Contains(t, err.Error(), ext)
826+
}
827+
} else {
828+
assert.NoError(t, err)
829+
}
830+
})
831+
}
832+
}

pkg/daemon/daemon.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2862,7 +2862,7 @@ func (dn *Daemon) getUnsupportedPackages() {
28622862
}
28632863

28642864
supportedPackages := make(map[string]bool)
2865-
for _, packages := range getSupportedExtensions() {
2865+
for _, packages := range ctrlcommon.SupportedExtensions() {
28662866
for _, pkg := range packages {
28672867
supportedPackages[pkg] = true
28682868
}

pkg/daemon/update.go

Lines changed: 2 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -1663,7 +1663,7 @@ func (dn *Daemon) generateExtensionsArgs(oldConfig, newConfig *mcfgv1.MachineCon
16631663
extArgs := []string{"update"}
16641664

16651665
if dn.os.IsEL() {
1666-
extensions := getSupportedExtensions()
1666+
extensions := ctrlcommon.SupportedExtensions()
16671667
for _, ext := range added {
16681668
for _, pkg := range extensions[ext] {
16691669
extArgs = append(extArgs, "--install", pkg)
@@ -1693,38 +1693,6 @@ func (dn *Daemon) generateExtensionsArgs(oldConfig, newConfig *mcfgv1.MachineCon
16931693
return extArgs
16941694
}
16951695

1696-
// Returns list of extensions possible to install on a CoreOS based system.
1697-
func getSupportedExtensions() map[string][]string {
1698-
// In future when list of extensions grow, it will make
1699-
// more sense to populate it in a dynamic way.
1700-
1701-
// These are RHCOS supported extensions.
1702-
// Each extension keeps a list of packages required to get enabled on host.
1703-
return map[string][]string{
1704-
"wasm": {"crun-wasm"},
1705-
"ipsec": {"NetworkManager-libreswan", "libreswan"},
1706-
"usbguard": {"usbguard"},
1707-
"kerberos": {"krb5-workstation", "libkadm5"},
1708-
"kernel-devel": {"kernel-devel", "kernel-headers"},
1709-
"sandboxed-containers": {"kata-containers"},
1710-
}
1711-
}
1712-
1713-
func validateExtensions(exts []string) error {
1714-
supportedExtensions := getSupportedExtensions()
1715-
invalidExts := []string{}
1716-
for _, ext := range exts {
1717-
if _, ok := supportedExtensions[ext]; !ok {
1718-
invalidExts = append(invalidExts, ext)
1719-
}
1720-
}
1721-
if len(invalidExts) != 0 {
1722-
return fmt.Errorf("invalid extensions found: %v", invalidExts)
1723-
}
1724-
return nil
1725-
1726-
}
1727-
17281696
func (dn *CoreOSDaemon) applyExtensions(oldConfig, newConfig *mcfgv1.MachineConfig) error {
17291697
extensionsEmpty := len(oldConfig.Spec.Extensions) == 0 && len(newConfig.Spec.Extensions) == 0
17301698
if (extensionsEmpty) ||
@@ -1733,7 +1701,7 @@ func (dn *CoreOSDaemon) applyExtensions(oldConfig, newConfig *mcfgv1.MachineConf
17331701
}
17341702

17351703
// Validate extensions allowlist on RHCOS nodes
1736-
if err := validateExtensions(newConfig.Spec.Extensions); err != nil && dn.os.IsEL() {
1704+
if err := ctrlcommon.ValidateMachineConfigExtensions(newConfig.Spec); err != nil && dn.os.IsEL() {
17371705
return err
17381706
}
17391707

0 commit comments

Comments
 (0)