mirror of
				https://github.com/optim-enterprises-bv/kubernetes.git
				synced 2025-11-03 19:58:17 +00:00 
			
		
		
		
	Start adding tests for verifying correct modes
Add an example for permission bits checking
This commit is contained in:
		@@ -19,12 +19,17 @@ limitations under the License.
 | 
			
		||||
package volume
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"fmt"
 | 
			
		||||
	"os"
 | 
			
		||||
	"path/filepath"
 | 
			
		||||
	"syscall"
 | 
			
		||||
	"testing"
 | 
			
		||||
 | 
			
		||||
	v1 "k8s.io/api/core/v1"
 | 
			
		||||
	utilfeature "k8s.io/apiserver/pkg/util/feature"
 | 
			
		||||
	utiltesting "k8s.io/client-go/util/testing"
 | 
			
		||||
	featuregatetesting "k8s.io/component-base/featuregate/testing"
 | 
			
		||||
	"k8s.io/kubernetes/pkg/features"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
type localFakeMounter struct {
 | 
			
		||||
@@ -57,8 +62,8 @@ func (l *localFakeMounter) GetMetrics() (*Metrics, error) {
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func TestSkipPermissionChange(t *testing.T) {
 | 
			
		||||
	always := v1.AlwaysChangeVolumePermission
 | 
			
		||||
	onrootMismatch := v1.OnRootMismatch
 | 
			
		||||
	always := v1.FSGroupChangeAlways
 | 
			
		||||
	onrootMismatch := v1.FSGroupChangeOnRootMismatch
 | 
			
		||||
	tests := []struct {
 | 
			
		||||
		description         string
 | 
			
		||||
		fsGroupChangePolicy *v1.PodFSGroupChangePolicy
 | 
			
		||||
@@ -76,6 +81,18 @@ func TestSkipPermissionChange(t *testing.T) {
 | 
			
		||||
			fsGroupChangePolicy: &always,
 | 
			
		||||
			skipPermssion:       false,
 | 
			
		||||
		},
 | 
			
		||||
		{
 | 
			
		||||
			description:         "skippermission=false, policy=always, gidmatch=true",
 | 
			
		||||
			fsGroupChangePolicy: &always,
 | 
			
		||||
			skipPermssion:       false,
 | 
			
		||||
			gidOwnerMatch:       true,
 | 
			
		||||
		},
 | 
			
		||||
		{
 | 
			
		||||
			description:         "skippermission=false, policy=nil, gidmatch=true",
 | 
			
		||||
			fsGroupChangePolicy: nil,
 | 
			
		||||
			skipPermssion:       false,
 | 
			
		||||
			gidOwnerMatch:       true,
 | 
			
		||||
		},
 | 
			
		||||
		{
 | 
			
		||||
			description:         "skippermission=false, policy=onrootmismatch, gidmatch=false",
 | 
			
		||||
			fsGroupChangePolicy: &onrootMismatch,
 | 
			
		||||
@@ -158,5 +175,173 @@ func TestSkipPermissionChange(t *testing.T) {
 | 
			
		||||
 | 
			
		||||
		})
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func TestSetVolumeOwnership(t *testing.T) {
 | 
			
		||||
	always := v1.FSGroupChangeAlways
 | 
			
		||||
	onrootMismatch := v1.FSGroupChangeOnRootMismatch
 | 
			
		||||
	expectedMask := rwMask | os.ModeSetgid | execMask
 | 
			
		||||
 | 
			
		||||
	tests := []struct {
 | 
			
		||||
		description         string
 | 
			
		||||
		fsGroupChangePolicy *v1.PodFSGroupChangePolicy
 | 
			
		||||
		setupFunc           func(path string) error
 | 
			
		||||
		assertFunc          func(path string) error
 | 
			
		||||
		featureGate         bool
 | 
			
		||||
	}{
 | 
			
		||||
		{
 | 
			
		||||
			description:         "featuregate=on, fsgroupchangepolicy=always",
 | 
			
		||||
			fsGroupChangePolicy: &always,
 | 
			
		||||
			featureGate:         true,
 | 
			
		||||
			setupFunc: func(path string) error {
 | 
			
		||||
				info, err := os.Lstat(path)
 | 
			
		||||
				if err != nil {
 | 
			
		||||
					return err
 | 
			
		||||
				}
 | 
			
		||||
				// change mode of root folder to be right
 | 
			
		||||
				err = os.Chmod(path, info.Mode()|expectedMask)
 | 
			
		||||
				if err != nil {
 | 
			
		||||
					return err
 | 
			
		||||
				}
 | 
			
		||||
 | 
			
		||||
				// create a subdirectory with invalid permissions
 | 
			
		||||
				rogueDir := filepath.Join(path, "roguedir")
 | 
			
		||||
				err = os.Mkdir(rogueDir, info.Mode())
 | 
			
		||||
				if err != nil {
 | 
			
		||||
					return err
 | 
			
		||||
				}
 | 
			
		||||
				return nil
 | 
			
		||||
			},
 | 
			
		||||
			assertFunc: func(path string) error {
 | 
			
		||||
				rogueDir := filepath.Join(path, "roguedir")
 | 
			
		||||
				hasCorrectPermissions := verifyDirectoryPermission(rogueDir, false /*readOnly*/)
 | 
			
		||||
				if !hasCorrectPermissions {
 | 
			
		||||
					return fmt.Errorf("invalid permissions on %s", rogueDir)
 | 
			
		||||
				}
 | 
			
		||||
				return nil
 | 
			
		||||
			},
 | 
			
		||||
		},
 | 
			
		||||
		{
 | 
			
		||||
			description:         "featuregate=on, fsgroupchangepolicy=onrootmismatch,rootdir=validperm",
 | 
			
		||||
			fsGroupChangePolicy: &onrootMismatch,
 | 
			
		||||
			featureGate:         true,
 | 
			
		||||
			setupFunc: func(path string) error {
 | 
			
		||||
				info, err := os.Lstat(path)
 | 
			
		||||
				if err != nil {
 | 
			
		||||
					return err
 | 
			
		||||
				}
 | 
			
		||||
				// change mode of root folder to be right
 | 
			
		||||
				err = os.Chmod(path, info.Mode()|expectedMask)
 | 
			
		||||
				if err != nil {
 | 
			
		||||
					return err
 | 
			
		||||
				}
 | 
			
		||||
 | 
			
		||||
				// create a subdirectory with invalid permissions
 | 
			
		||||
				rogueDir := filepath.Join(path, "roguedir")
 | 
			
		||||
				err = os.Mkdir(rogueDir, rwMask)
 | 
			
		||||
				if err != nil {
 | 
			
		||||
					return err
 | 
			
		||||
				}
 | 
			
		||||
				return nil
 | 
			
		||||
			},
 | 
			
		||||
			assertFunc: func(path string) error {
 | 
			
		||||
				rogueDir := filepath.Join(path, "roguedir")
 | 
			
		||||
				hasCorrectPermissions := verifyDirectoryPermission(rogueDir, false /*readOnly*/)
 | 
			
		||||
				if hasCorrectPermissions {
 | 
			
		||||
					return fmt.Errorf("invalid permissions on %s", rogueDir)
 | 
			
		||||
				}
 | 
			
		||||
				return nil
 | 
			
		||||
			},
 | 
			
		||||
		},
 | 
			
		||||
		{
 | 
			
		||||
			description:         "featuregate=on, fsgroupchangepolicy=onrootmismatch,rootdir=invalidperm",
 | 
			
		||||
			fsGroupChangePolicy: &onrootMismatch,
 | 
			
		||||
			featureGate:         true,
 | 
			
		||||
			setupFunc: func(path string) error {
 | 
			
		||||
				// change mode of root folder to be right
 | 
			
		||||
				err := os.Chmod(path, 0770)
 | 
			
		||||
				if err != nil {
 | 
			
		||||
					return err
 | 
			
		||||
				}
 | 
			
		||||
 | 
			
		||||
				// create a subdirectory with invalid permissions
 | 
			
		||||
				rogueDir := filepath.Join(path, "roguedir")
 | 
			
		||||
				err = os.Mkdir(rogueDir, rwMask)
 | 
			
		||||
				if err != nil {
 | 
			
		||||
					return err
 | 
			
		||||
				}
 | 
			
		||||
				return nil
 | 
			
		||||
			},
 | 
			
		||||
			assertFunc: func(path string) error {
 | 
			
		||||
				rogueDir := filepath.Join(path, "roguedir")
 | 
			
		||||
				hasCorrectPermissions := verifyDirectoryPermission(rogueDir, false /*readOnly*/)
 | 
			
		||||
				if !hasCorrectPermissions {
 | 
			
		||||
					return fmt.Errorf("invalid permissions on %s", rogueDir)
 | 
			
		||||
				}
 | 
			
		||||
				return nil
 | 
			
		||||
			},
 | 
			
		||||
		},
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	for _, test := range tests {
 | 
			
		||||
		t.Run(test.description, func(t *testing.T) {
 | 
			
		||||
			defer featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.ConfigurableFSGroupPolicy, test.featureGate)()
 | 
			
		||||
			tmpDir, err := utiltesting.MkTmpdir("volume_linux_ownership")
 | 
			
		||||
			if err != nil {
 | 
			
		||||
				t.Fatalf("error creating temp dir: %v", err)
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			defer os.RemoveAll(tmpDir)
 | 
			
		||||
			info, err := os.Lstat(tmpDir)
 | 
			
		||||
			if err != nil {
 | 
			
		||||
				t.Fatalf("error reading permission of tmpdir: %v", err)
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			stat, ok := info.Sys().(*syscall.Stat_t)
 | 
			
		||||
			if !ok || stat == nil {
 | 
			
		||||
				t.Fatalf("error reading permission stats for tmpdir: %s", tmpDir)
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			var expectedGid int64 = int64(stat.Gid)
 | 
			
		||||
			err = test.setupFunc(tmpDir)
 | 
			
		||||
			if err != nil {
 | 
			
		||||
				t.Errorf("for %s error running setup with: %v", test.description, err)
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			mounter := &localFakeMounter{path: tmpDir}
 | 
			
		||||
			err = SetVolumeOwnership(mounter, &expectedGid, test.fsGroupChangePolicy)
 | 
			
		||||
			if err != nil {
 | 
			
		||||
				t.Errorf("for %s error changing ownership with: %v", test.description, err)
 | 
			
		||||
			}
 | 
			
		||||
			err = test.assertFunc(tmpDir)
 | 
			
		||||
			if err != nil {
 | 
			
		||||
				t.Errorf("for %s error verifying permissions with: %v", test.description, err)
 | 
			
		||||
			}
 | 
			
		||||
		})
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// verifyDirectoryPermission checks if given path has directory permissions
 | 
			
		||||
// that is expected by k8s. If returns true if it does otherwise false
 | 
			
		||||
func verifyDirectoryPermission(path string, readonly bool) bool {
 | 
			
		||||
	info, err := os.Lstat(path)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return false
 | 
			
		||||
	}
 | 
			
		||||
	stat, ok := info.Sys().(*syscall.Stat_t)
 | 
			
		||||
	if !ok || stat == nil {
 | 
			
		||||
		return false
 | 
			
		||||
	}
 | 
			
		||||
	unixPerms := rwMask
 | 
			
		||||
 | 
			
		||||
	if readonly {
 | 
			
		||||
		unixPerms = roMask
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	unixPerms |= execMask
 | 
			
		||||
	filePerm := info.Mode().Perm()
 | 
			
		||||
	if (unixPerms&filePerm == unixPerms) && (info.Mode()&os.ModeSetgid != 0) {
 | 
			
		||||
		return true
 | 
			
		||||
	}
 | 
			
		||||
	return false
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user