Skip to content

Commit

Permalink
Merge pull request #107 from swatisehgal/selinux-policy-update
Browse files Browse the repository at this point in the history
selinuxpolicy: updates to enable support for OCP 4.11+/K8s 1.24+
  • Loading branch information
ffromani authored Jul 15, 2022
2 parents eb5c3f2 + fb42881 commit 2f9de87
Show file tree
Hide file tree
Showing 13 changed files with 237 additions and 55 deletions.
25 changes: 23 additions & 2 deletions pkg/assets/rte/assets.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,16 +2,37 @@ package rte

import (
_ "embed"

"github.com/k8stopologyawareschedwg/deployer/pkg/deployer/platform"
)

const (
OCPVersion411 = "v4.11"
)

//go:embed selinuxinstall.service.template
var SELinuxInstallSystemdServiceTemplate []byte

//go:embed selinuxpolicy.cil
var SELinuxPolicy []byte
//go:embed selinuxpolicy-ocp410.cil
var SELinuxPolicyOCP410 []byte

//go:embed selinuxpolicy-ocp411.cil
var SELinuxPolicyOCP411 []byte

//go:embed hookconfigrtenotifier.json.template
var HookConfigRTENotifier []byte

//go:embed rte-notifier.sh
var NotifierScript []byte

func GetSELinuxPolicy(ver platform.Version) ([]byte, error) {
// error should never happen: we control the input here
ok, err := ver.AtLeastString(OCPVersion411)
if err != nil {
return nil, err
}
if ok {
return SELinuxPolicyOCP411, nil
}
return SELinuxPolicyOCP410, nil
}
File renamed without changes.
21 changes: 21 additions & 0 deletions pkg/assets/rte/selinuxpolicy-ocp411.cil
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
(block rte
(type process)
(roletype system_r process)
(typeattributeset domain (process))
;
; Giving rte.process the same attributes as container_t
(typeattributeset container_domain (process))
(typeattributeset container_net_domain (process))
(typeattributeset svirt_sandbox_domain (process))
(typeattributeset sandbox_net_domain (process))

;
; Allow to RTE pod access to /run/rte directory
(allow process container_var_run_t (dir (add_name write)))
(allow process container_var_run_t (file (create read write open)))

;
; Allow to RTE pod connect, read and write permissions to /var/lib/kubelet/pod-resource/kubelet.sock
(allow process container_var_lib_t (sock_file (open getattr read write ioctl lock append)))
(allow process kubelet_t (unix_stream_socket (connectto)))
)
54 changes: 53 additions & 1 deletion pkg/commands/deploy.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ import (

type DeployOptions struct {
clusterPlatform platform.Platform
clusterVersion platform.Version
waitCompletion bool
}

Expand Down Expand Up @@ -64,6 +65,12 @@ func NewRemoveCommand(commonOpts *CommonOptions) *cobra.Command {
if opts.clusterPlatform == platform.Unknown {
return fmt.Errorf("cannot autodetect the platform, and no platform given")
}
versionDetect, source := detect.FindVersion(platDetect.Discovered, commonOpts.UserPlatformVersion)
commonOpts.DebugLog.Printf("Version detection source: %s", source)
opts.clusterVersion = versionDetect.Discovered
if opts.clusterVersion == platform.MissingVersion {
return fmt.Errorf("cannot autodetect the platform version, and no version given")
}

var err error
err = sched.Remove(la, sched.Options{
Expand All @@ -78,6 +85,7 @@ func NewRemoveCommand(commonOpts *CommonOptions) *cobra.Command {
}
err = updaters.Remove(la, commonOpts.UpdaterType, updaters.Options{
Platform: opts.clusterPlatform,
PlatformVersion: opts.clusterVersion,
WaitCompletion: opts.waitCompletion,
PullIfNotPresent: commonOpts.PullIfNotPresent,
RTEConfigData: commonOpts.RTEConfigData,
Expand Down Expand Up @@ -116,6 +124,12 @@ func NewDeployAPICommand(commonOpts *CommonOptions, opts *DeployOptions) *cobra.
if opts.clusterPlatform == platform.Unknown {
return fmt.Errorf("cannot autodetect the platform, and no platform given")
}
versionDetect, source := detect.FindVersion(platDetect.Discovered, commonOpts.UserPlatformVersion)
commonOpts.DebugLog.Printf("Version detection source: %s", source)
opts.clusterVersion = versionDetect.Discovered
if opts.clusterVersion == platform.MissingVersion {
return fmt.Errorf("cannot autodetect the platform version, and no version given")
}
if err := api.Deploy(la, api.Options{Platform: opts.clusterPlatform}); err != nil {
return err
}
Expand All @@ -138,6 +152,12 @@ func NewDeploySchedulerPluginCommand(commonOpts *CommonOptions, opts *DeployOpti
if opts.clusterPlatform == platform.Unknown {
return fmt.Errorf("cannot autodetect the platform, and no platform given")
}
versionDetect, source := detect.FindVersion(platDetect.Discovered, commonOpts.UserPlatformVersion)
commonOpts.DebugLog.Printf("Version detection source: %s", source)
opts.clusterVersion = versionDetect.Discovered
if opts.clusterVersion == platform.MissingVersion {
return fmt.Errorf("cannot autodetect the platform version, and no version given")
}
return sched.Deploy(la, sched.Options{
Platform: opts.clusterPlatform,
WaitCompletion: opts.waitCompletion,
Expand All @@ -162,8 +182,15 @@ func NewDeployTopologyUpdaterCommand(commonOpts *CommonOptions, opts *DeployOpti
if opts.clusterPlatform == platform.Unknown {
return fmt.Errorf("cannot autodetect the platform, and no platform given")
}
versionDetect, source := detect.FindVersion(platDetect.Discovered, commonOpts.UserPlatformVersion)
commonOpts.DebugLog.Printf("Version detection source: %s", source)
opts.clusterVersion = versionDetect.Discovered
if opts.clusterVersion == platform.MissingVersion {
return fmt.Errorf("cannot autodetect the platform version, and no version given")
}
return updaters.Deploy(la, commonOpts.UpdaterType, updaters.Options{
Platform: opts.clusterPlatform,
PlatformVersion: opts.clusterVersion,
WaitCompletion: opts.waitCompletion,
PullIfNotPresent: commonOpts.PullIfNotPresent,
RTEConfigData: commonOpts.RTEConfigData,
Expand All @@ -186,7 +213,12 @@ func NewRemoveAPICommand(commonOpts *CommonOptions, opts *DeployOptions) *cobra.
if opts.clusterPlatform == platform.Unknown {
return fmt.Errorf("cannot autodetect the platform, and no platform given")
}

versionDetect, source := detect.FindVersion(platDetect.Discovered, commonOpts.UserPlatformVersion)
commonOpts.DebugLog.Printf("Version detection source: %s", source)
opts.clusterVersion = versionDetect.Discovered
if opts.clusterVersion == platform.MissingVersion {
return fmt.Errorf("cannot autodetect the platform version, and no version given")
}
if err := api.Remove(la, api.Options{Platform: opts.clusterPlatform}); err != nil {
return err
}
Expand All @@ -209,6 +241,12 @@ func NewRemoveSchedulerPluginCommand(commonOpts *CommonOptions, opts *DeployOpti
if opts.clusterPlatform == platform.Unknown {
return fmt.Errorf("cannot autodetect the platform, and no platform given")
}
versionDetect, source := detect.FindVersion(platDetect.Discovered, commonOpts.UserPlatformVersion)
commonOpts.DebugLog.Printf("Version detection source: %s", source)
opts.clusterVersion = versionDetect.Discovered
if opts.clusterVersion == platform.MissingVersion {
return fmt.Errorf("cannot autodetect the platform version, and no version given")
}
return sched.Remove(la, sched.Options{
Platform: opts.clusterPlatform,
WaitCompletion: opts.waitCompletion,
Expand All @@ -233,8 +271,15 @@ func NewRemoveTopologyUpdaterCommand(commonOpts *CommonOptions, opts *DeployOpti
if opts.clusterPlatform == platform.Unknown {
return fmt.Errorf("cannot autodetect the platform, and no platform given")
}
versionDetect, source := detect.FindVersion(platDetect.Discovered, commonOpts.UserPlatformVersion)
commonOpts.DebugLog.Printf("Version detection source: %s", source)
opts.clusterVersion = versionDetect.Discovered
if opts.clusterVersion == platform.MissingVersion {
return fmt.Errorf("cannot autodetect the platform version, and no version given")
}
return updaters.Remove(la, commonOpts.UpdaterType, updaters.Options{
Platform: opts.clusterPlatform,
PlatformVersion: opts.clusterVersion,
WaitCompletion: opts.waitCompletion,
PullIfNotPresent: commonOpts.PullIfNotPresent,
RTEConfigData: commonOpts.RTEConfigData,
Expand All @@ -253,13 +298,20 @@ func deployOnCluster(commonOpts *CommonOptions, opts *DeployOptions) error {
if opts.clusterPlatform == platform.Unknown {
return fmt.Errorf("cannot autodetect the platform, and no platform given")
}
versionDetect, source := detect.FindVersion(platDetect.Discovered, commonOpts.UserPlatformVersion)
commonOpts.DebugLog.Printf("Version detection source: %s", source)
opts.clusterVersion = versionDetect.Discovered
if opts.clusterVersion == platform.MissingVersion {
return fmt.Errorf("cannot autodetect the platform version, and no version given")
}
if err := api.Deploy(la, api.Options{
Platform: opts.clusterPlatform,
}); err != nil {
return err
}
if err := updaters.Deploy(la, commonOpts.UpdaterType, updaters.Options{
Platform: opts.clusterPlatform,
PlatformVersion: opts.clusterVersion,
WaitCompletion: opts.waitCompletion,
PullIfNotPresent: commonOpts.PullIfNotPresent,
RTEConfigData: commonOpts.RTEConfigData,
Expand Down
1 change: 1 addition & 0 deletions pkg/commands/render.go
Original file line number Diff line number Diff line change
Expand Up @@ -128,6 +128,7 @@ func makeUpdaterObjects(commonOpts *CommonOptions) ([]client.Object, string, err
}

opts := updaters.Options{
PlatformVersion: commonOpts.UserPlatformVersion,
Platform: commonOpts.UserPlatform,
PullIfNotPresent: commonOpts.PullIfNotPresent,
RTEConfigData: commonOpts.RTEConfigData,
Expand Down
7 changes: 4 additions & 3 deletions pkg/deployer/updaters/objects.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,9 @@ import (
)

func GetObjects(opts Options, updaterType, namespace string) ([]client.Object, error) {

if updaterType == RTE {
mf, err := rtemanifests.GetManifests(opts.Platform, namespace)
mf, err := rtemanifests.GetManifests(opts.Platform, opts.PlatformVersion, namespace)
if err != nil {
return nil, err
}
Expand All @@ -47,7 +48,7 @@ func GetObjects(opts Options, updaterType, namespace string) ([]client.Object, e

func getCreatableObjects(opts Options, hp *deployer.Helper, log tlog.Logger, updaterType, namespace string) ([]deployer.WaitableObject, error) {
if updaterType == RTE {
mf, err := rtemanifests.GetManifests(opts.Platform, namespace)
mf, err := rtemanifests.GetManifests(opts.Platform, opts.PlatformVersion, namespace)
if err != nil {
return nil, err
}
Expand All @@ -65,7 +66,7 @@ func getCreatableObjects(opts Options, hp *deployer.Helper, log tlog.Logger, upd

func getDeletableObjects(opts Options, hp *deployer.Helper, log tlog.Logger, updaterType, namespace string) ([]deployer.WaitableObject, error) {
if updaterType == RTE {
mf, err := rtemanifests.GetManifests(opts.Platform, namespace)
mf, err := rtemanifests.GetManifests(opts.Platform, opts.PlatformVersion, namespace)
if err != nil {
return nil, err
}
Expand Down
1 change: 1 addition & 0 deletions pkg/deployer/updaters/updaters.go
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ const (

type Options struct {
Platform platform.Platform
PlatformVersion platform.Version
WaitCompletion bool
PullIfNotPresent bool
RTEConfigData string
Expand Down
14 changes: 10 additions & 4 deletions pkg/manifests/manifests.go
Original file line number Diff line number Diff line change
Expand Up @@ -429,7 +429,7 @@ func DaemonSet(component, subComponent string, plat platform.Platform, namespace
return ds, nil
}

func MachineConfig(component string) (*machineconfigv1.MachineConfig, error) {
func MachineConfig(component string, ver platform.Version) (*machineconfigv1.MachineConfig, error) {
if component != ComponentResourceTopologyExporter {
return nil, fmt.Errorf("component %q is not an %q component", component, ComponentResourceTopologyExporter)
}
Expand All @@ -444,7 +444,7 @@ func MachineConfig(component string) (*machineconfigv1.MachineConfig, error) {
return nil, fmt.Errorf("unexpected type, got %t", obj)
}

ignitionConfig, err := getIgnitionConfig()
ignitionConfig, err := getIgnitionConfig(ver)
if err != nil {
return nil, err
}
Expand All @@ -453,11 +453,17 @@ func MachineConfig(component string) (*machineconfigv1.MachineConfig, error) {
return mc, nil
}

func getIgnitionConfig() ([]byte, error) {
func getIgnitionConfig(ver platform.Version) ([]byte, error) {
var files []igntypes.File

// get SELinux policy
selinuxPolicy, err := rteassets.GetSELinuxPolicy(ver)
if err != nil {
return nil, err
}

// load SELinux policy
files = addFileToIgnitionConfig(files, rteassets.SELinuxPolicy, 0644, seLinuxRTEPolicyDst)
files = addFileToIgnitionConfig(files, selinuxPolicy, 0644, seLinuxRTEPolicyDst)

// load RTE notifier OCI hook config
notifierHookConfigContent, err := getTemplateContent(rteassets.HookConfigRTENotifier, map[string]string{
Expand Down
62 changes: 46 additions & 16 deletions pkg/manifests/manifests_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -558,29 +558,59 @@ func TestDaemonSet(t *testing.T) {
}

func TestMachineConfig(t *testing.T) {
mc, err := MachineConfig(ComponentResourceTopologyExporter)
if err != nil {
t.Fatalf("unexpected error: %v", err)
}

ignitionConfig := &igntypes.Config{}
if err := json.Unmarshal(mc.Spec.Config.Raw, ignitionConfig); err != nil {
t.Fatalf("failed to unmarshal ignition config: %v", err)
type testCase struct {
name string
platformVersion platform.Version
expectedFileNum int
expectedUnitNum int
}

// In both these cases:
// we are expecting to have 3 files
// 1. OCI hook configuration
// 2. OCI hook script
// 3. SELinux policy
if len(ignitionConfig.Storage.Files) != 3 {
klog.Errorf("ignition config files: %+v", ignitionConfig.Storage.Files)
t.Fatalf("the ignition config has %d files when it should have %d", len(ignitionConfig.Storage.Files), 3)
}

// we are expecting only one systemd unit
// One systemd unit
// 1. Systemd unit to install the SELinux policy
if len(ignitionConfig.Systemd.Units) != 1 {
klog.Errorf("ignition config systemd units: %+v", ignitionConfig.Systemd.Units)
t.Fatalf("the ignition config has %d systemd units when it should have %d", len(ignitionConfig.Systemd.Units), 1)

// TODO: Check SELinuxPolicy in the various cases
testCases := []testCase{
{
name: "OCP 4.10",
platformVersion: "v4.10",
expectedFileNum: 3,
expectedUnitNum: 1,
},
{
name: "OCP 4.11",
platformVersion: "v4.11",
expectedFileNum: 3,
expectedUnitNum: 1,
},
}

for _, tc := range testCases {
t.Run(tc.name, func(t *testing.T) {
mc, err := MachineConfig(ComponentResourceTopologyExporter, platform.Version(tc.platformVersion))
if err != nil {
t.Fatalf("unexpected error: %v", err)
}

ignitionConfig := &igntypes.Config{}
if err := json.Unmarshal(mc.Spec.Config.Raw, ignitionConfig); err != nil {
t.Fatalf("failed to unmarshal ignition config: %v", err)
}

if len(ignitionConfig.Storage.Files) != tc.expectedFileNum {
klog.Errorf("ignition config files: %+v", ignitionConfig.Storage.Files)
t.Fatalf("the ignition config has %d files when it should have %d", len(ignitionConfig.Storage.Files), tc.expectedFileNum)
}

if len(ignitionConfig.Systemd.Units) != tc.expectedUnitNum {
klog.Errorf("ignition config systemd units: %+v", ignitionConfig.Systemd.Units)
t.Fatalf("the ignition config has %d systemd units when it should have %d", len(ignitionConfig.Systemd.Units), tc.expectedUnitNum)
}
})
}
}
4 changes: 2 additions & 2 deletions pkg/manifests/rte/rte.go
Original file line number Diff line number Diff line change
Expand Up @@ -245,12 +245,12 @@ func New(plat platform.Platform) Manifests {
return mf
}

func GetManifests(plat platform.Platform, namespace string) (Manifests, error) {
func GetManifests(plat platform.Platform, version platform.Version, namespace string) (Manifests, error) {
var err error
mf := New(plat)

if plat == platform.OpenShift {
mf.MachineConfig, err = manifests.MachineConfig(manifests.ComponentResourceTopologyExporter)
mf.MachineConfig, err = manifests.MachineConfig(manifests.ComponentResourceTopologyExporter, version)
if err != nil {
return mf, err
}
Expand Down
Loading

0 comments on commit 2f9de87

Please sign in to comment.