@@ -24,8 +24,11 @@ import (
2424 "os/exec"
2525 "path/filepath"
2626 "regexp"
27+ "strings"
2728 "time"
2829
30+ "github.com/opencontainers/selinux/go-selinux"
31+
2932 corev1 "k8s.io/api/core/v1"
3033 "k8s.io/klog/v2"
3134
@@ -184,6 +187,93 @@ var _ = Describe("[must-gather] NRO data collected", func() {
184187 Expect (podFolderNames ).To (ContainElement (MatchRegexp ("^secondary-scheduler*" )))
185188 }
186189 })
190+
191+ It ("check SELinux data files have been collected" , func (ctx context.Context ) {
192+ destDirContent , err := os .ReadDir (destDir )
193+ Expect (err ).NotTo (HaveOccurred (), "unable to read contents from destDir:%s. error: %w" , destDir , err )
194+
195+ for _ , content := range destDirContent {
196+ if ! content .IsDir () {
197+ continue
198+ }
199+ mgContentFolder := filepath .Join (destDir , content .Name ())
200+
201+ By (fmt .Sprintf ("Checking Folder: %q" , mgContentFolder ))
202+ By ("Looking for SELinux info directory" )
203+
204+ selinuxInfoFolder := filepath .Join (mgContentFolder , "selinux_info" )
205+ _ , err = os .Stat (selinuxInfoFolder )
206+ Expect (err ).ToNot (HaveOccurred (), "selinux_info directory should exist" )
207+
208+ selinuxDirContent , err := os .ReadDir (selinuxInfoFolder )
209+ Expect (err ).NotTo (HaveOccurred ())
210+ Expect (selinuxDirContent ).ToNot (BeEmpty (), "selinux_info directory should contain node directories" )
211+
212+ // Check each node directory
213+ for _ , nodeDir := range selinuxDirContent {
214+ if ! nodeDir .IsDir () {
215+ // We expect only directories in selinux_info, but check defensively
216+ By (fmt .Sprintf ("Warning: unexpected non-directory item in selinux_info: %s" , nodeDir .Name ()))
217+ continue
218+ }
219+
220+ nodeName := nodeDir .Name ()
221+ nodeSelinuxFolder := filepath .Join (selinuxInfoFolder , nodeName )
222+ By (fmt .Sprintf ("Checking SELinux data for node: %s" , nodeName ))
223+
224+ // Check required files exist
225+ requiredFiles := []string {
226+ "contexts" ,
227+ "kubelet.service" ,
228+ "audit_selinux.log" ,
229+ "audit_podresources.log" ,
230+ }
231+ err = checkfilesExist (requiredFiles , nodeSelinuxFolder )
232+ Expect (err ).ToNot (HaveOccurred (), "required SELinux files should exist for node %s" , nodeName )
233+
234+ // Verify contexts file contains kubelet.sock SELinux context
235+ By (fmt .Sprintf ("Verifying kubelet.sock SELinux context for node: %s" , nodeName ))
236+ contextsFile := filepath .Join (nodeSelinuxFolder , "contexts" )
237+ contextsData , err := os .ReadFile (contextsFile )
238+ Expect (err ).ToNot (HaveOccurred ())
239+
240+ contextsContent := string (contextsData )
241+
242+ // Parse SELinux context from the kubelet.sock line using official selinux package
243+ By (fmt .Sprintf ("Parsing SELinux context for kubelet.sock on node: %s" , nodeName ))
244+ found := false
245+ for _ , line := range strings .Split (contextsContent , "\n " ) {
246+ if strings .Contains (line , "/var/lib/kubelet/pod-resources/kubelet.sock" ) {
247+ // Extract SELinux context from ls -Z output (format: "context filename")
248+ parts := strings .Fields (line )
249+ if len (parts ) >= 2 {
250+ selinuxLabel := parts [0 ]
251+ context , err := selinux .NewContext (selinuxLabel )
252+ Expect (err ).ToNot (HaveOccurred (), "should parse SELinux context: %s" , selinuxLabel )
253+
254+ // Check that the type field contains kubelet_var_lib_t
255+ contextType := context ["type" ]
256+ Expect (contextType ).To (Equal ("kubelet_var_lib_t" ), "kubelet.sock should have kubelet_var_lib_t SELinux context type, got: %s" , contextType )
257+
258+ By (fmt .Sprintf ("Found valid SELinux context for kubelet.sock: %s (type: %s)" , selinuxLabel , contextType ))
259+ found = true
260+ break
261+ }
262+ }
263+ }
264+ Expect (found ).To (BeTrue (), "should find kubelet.sock with valid SELinux context in contexts file" )
265+
266+ // Verify kubelet.service file has content
267+ By (fmt .Sprintf ("Verifying kubelet.service content for node: %s" , nodeName ))
268+ kubeletServiceFile := filepath .Join (nodeSelinuxFolder , "kubelet.service" )
269+ kubeletServiceData , err := os .ReadFile (kubeletServiceFile )
270+ Expect (err ).ToNot (HaveOccurred ())
271+
272+ kubeletServiceContent := string (kubeletServiceData )
273+ Expect (kubeletServiceContent ).To (ContainSubstring ("/usr/sbin/restorecon" ), "kubelet.service should contain restorecon command in ExecStartPre" )
274+ }
275+ }
276+ })
187277 })
188278})
189279
0 commit comments