Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Automated cherry pick of #37594 #38276 #37009 upstream release 1.5 #38343

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
Expand Up @@ -25,7 +25,7 @@
"containers": [
{
"name": "cluster-autoscaler",
"image": "gcr.io/google_containers/cluster-autoscaler:v0.4.0-beta1",
"image": "gcr.io/google_containers/cluster-autoscaler:v0.4.0",
"command": [
"/bin/sh",
"-c",
Expand Down
8 changes: 8 additions & 0 deletions pkg/util/iptables/iptables.go
Expand Up @@ -374,6 +374,12 @@ func (runner *runner) checkRule(table Table, chain Chain, args ...string) (bool,
}
}

var hexnumRE = regexp.MustCompile("0x0+([0-9])")

func trimhex(s string) string {
return hexnumRE.ReplaceAllString(s, "0x$1")
}

// Executes the rule check without using the "-C" flag, instead parsing iptables-save.
// Present for compatibility with <1.4.11 versions of iptables. This is full
// of hack and half-measures. We should nix this ASAP.
Expand All @@ -392,6 +398,7 @@ func (runner *runner) checkRuleWithoutCheck(table Table, chain Chain, args ...st
var argsCopy []string
for i := range args {
tmpField := strings.Trim(args[i], "\"")
tmpField = trimhex(tmpField)
argsCopy = append(argsCopy, strings.Fields(tmpField)...)
}
argset := sets.NewString(argsCopy...)
Expand All @@ -409,6 +416,7 @@ func (runner *runner) checkRuleWithoutCheck(table Table, chain Chain, args ...st
// Just remove all quotes.
for i := range fields {
fields[i] = strings.Trim(fields[i], "\"")
fields[i] = trimhex(fields[i])
}

// TODO: This misses reorderings e.g. "-x foo ! -y bar" will match "! -x foo -y bar"
Expand Down
9 changes: 7 additions & 2 deletions pkg/util/iptables/iptables_test.go
Expand Up @@ -470,7 +470,7 @@ func TestCheckRuleWithoutCheckPresent(t *testing.T) {
:PREROUTING ACCEPT [2136997:197881818]
:POSTROUTING ACCEPT [4284525:258542680]
:OUTPUT ACCEPT [5901660:357267963]
-A PREROUTING -m addrtype --dst-type LOCAL -j DOCKER
-A PREROUTING -m addrtype --dst-type LOCAL -m mark --mark 0x00004000/0x00004000 -j DOCKER
COMMIT
# Completed on Wed Oct 29 14:56:01 2014`

Expand All @@ -487,7 +487,12 @@ COMMIT
},
}
runner := &runner{exec: &fexec}
exists, err := runner.checkRuleWithoutCheck(TableNAT, ChainPrerouting, "-m", "addrtype", "-j", "DOCKER", "--dst-type", "LOCAL")
exists, err := runner.checkRuleWithoutCheck(
TableNAT, ChainPrerouting,
"-m", "addrtype",
"-m", "mark", "--mark", "0x4000/0x4000",
"-j", "DOCKER",
"--dst-type", "LOCAL")
if err != nil {
t.Errorf("expected success, got %v", err)
}
Expand Down
11 changes: 11 additions & 0 deletions pkg/volume/volume_linux.go
Expand Up @@ -51,6 +51,17 @@ func SetVolumeOwnership(mounter Mounter, fsGroup *int64) error {
return err
}

// chown and chmod pass through to the underlying file for symlinks.
// Symlinks have a mode of 777 but this really doesn't mean anything.
// The permissions of the underlying file are what matter.
// However, if one reads the mode of a symlink then chmods the symlink
// with that mode, it changes the mode of the underlying file, overridden
// the defaultMode and permissions initialized by the volume plugin, which
// is not what we want; thus, we skip chown/chmod for symlinks.
if info.Mode()&os.ModeSymlink != 0 {
return nil
}

stat, ok := info.Sys().(*syscall.Stat_t)
if !ok {
return nil
Expand Down
13 changes: 7 additions & 6 deletions test/e2e/common/configmap.go
Expand Up @@ -41,6 +41,11 @@ var _ = framework.KubeDescribe("ConfigMap", func() {
doConfigMapE2EWithoutMappings(f, 0, 0, &defaultMode)
})

It("should be consumable from pods in volume as non-root with defaultMode and fsGroup set [Feature:FSGroup]", func() {
defaultMode := int32(0440) /* setting fsGroup sets mode to at least 440 */
doConfigMapE2EWithoutMappings(f, 1000, 1001, &defaultMode)
})

It("should be consumable from pods in volume as non-root [Conformance]", func() {
doConfigMapE2EWithoutMappings(f, 1000, 0, nil)
})
Expand Down Expand Up @@ -343,14 +348,10 @@ func doConfigMapE2EWithoutMappings(f *framework.Framework, uid, fsGroup int64, d
defaultMode = &mode
}

// Just check file mode if fsGroup is not set. If fsGroup is set, the
// final mode is adjusted and we are not testing that case.
modeString := fmt.Sprintf("%v", os.FileMode(*defaultMode))
output := []string{
"content of file \"/etc/configmap-volume/data-1\": value-1",
}
if fsGroup == 0 {
modeString := fmt.Sprintf("%v", os.FileMode(*defaultMode))
output = append(output, "mode of file \"/etc/configmap-volume/data-1\": "+modeString)
"mode of file \"/etc/configmap-volume/data-1\": " + modeString,
}
f.TestContainerOutput("consume configMaps", pod, 0, output)

Expand Down
15 changes: 15 additions & 0 deletions test/e2e/common/downwardapi_volume.go
Expand Up @@ -81,6 +81,21 @@ var _ = framework.KubeDescribe("Downward API volume", func() {
})
})

It("should provide podname as non-root with fsgroup and defaultMode [Feature:FSGroup]", func() {
podName := "metadata-volume-" + string(uuid.NewUUID())
uid := int64(1001)
gid := int64(1234)
mode := int32(0440) /* setting fsGroup sets mode to at least 440 */
pod := downwardAPIVolumePodForModeTest(podName, "/etc/podname", &mode, nil)
pod.Spec.SecurityContext = &api.PodSecurityContext{
RunAsUser: &uid,
FSGroup: &gid,
}
f.TestContainerOutput("downward API volume plugin", pod, 0, []string{
"mode of file \"/etc/podname\": -r--r-----",
})
})

It("should update labels on modification [Conformance]", func() {
labels := map[string]string{}
labels["key1"] = "value1"
Expand Down
22 changes: 18 additions & 4 deletions test/e2e/common/secrets.go
Expand Up @@ -31,12 +31,19 @@ var _ = framework.KubeDescribe("Secrets", func() {
f := framework.NewDefaultFramework("secrets")

It("should be consumable from pods in volume [Conformance]", func() {
doSecretE2EWithoutMapping(f, nil /* default mode */, "secret-test-"+string(uuid.NewUUID()))
doSecretE2EWithoutMapping(f, nil /* default mode */, "secret-test-"+string(uuid.NewUUID()), nil, nil)
})

It("should be consumable from pods in volume with defaultMode set [Conformance]", func() {
defaultMode := int32(0400)
doSecretE2EWithoutMapping(f, &defaultMode, "secret-test-"+string(uuid.NewUUID()))
doSecretE2EWithoutMapping(f, &defaultMode, "secret-test-"+string(uuid.NewUUID()), nil, nil)
})

It("should be consumable from pods in volume as non-root with defaultMode and fsGroup set [Conformance]", func() {
defaultMode := int32(0440) /* setting fsGroup sets mode to at least 440 */
fsGroup := int64(1001)
uid := int64(1000)
doSecretE2EWithoutMapping(f, &defaultMode, "secret-test-"+string(uuid.NewUUID()), &fsGroup, &uid)
})

It("should be consumable from pods in volume with mappings [Conformance]", func() {
Expand Down Expand Up @@ -66,7 +73,7 @@ var _ = framework.KubeDescribe("Secrets", func() {
if secret2, err = f.ClientSet.Core().Secrets(namespace2.Name).Create(secret2); err != nil {
framework.Failf("unable to create test secret %s: %v", secret2.Name, err)
}
doSecretE2EWithoutMapping(f, nil /* default mode */, secret2.Name)
doSecretE2EWithoutMapping(f, nil /* default mode */, secret2.Name, nil, nil)
})

It("should be consumable in multiple volumes in a pod [Conformance]", func() {
Expand Down Expand Up @@ -201,7 +208,7 @@ func secretForTest(namespace, name string) *api.Secret {
}
}

func doSecretE2EWithoutMapping(f *framework.Framework, defaultMode *int32, secretName string) {
func doSecretE2EWithoutMapping(f *framework.Framework, defaultMode *int32, secretName string, fsGroup *int64, uid *int64) {
var (
volumeName = "secret-volume"
volumeMountPath = "/etc/secret-volume"
Expand Down Expand Up @@ -256,6 +263,13 @@ func doSecretE2EWithoutMapping(f *framework.Framework, defaultMode *int32, secre
defaultMode = &mode
}

if fsGroup != nil || uid != nil {
pod.Spec.SecurityContext = &api.PodSecurityContext{
FSGroup: fsGroup,
RunAsUser: uid,
}
}

modeString := fmt.Sprintf("%v", os.FileMode(*defaultMode))
expectedOutput := []string{
"content of file \"/etc/secret-volume/data-1\": value-1",
Expand Down