Add pods/attach to long running requests, protect in admission for privileged pods

This commit is contained in:
Jordan Liggitt 2015-09-08 23:58:36 -04:00
parent 891cef4efa
commit b2268574c5
4 changed files with 30 additions and 11 deletions

View File

@ -57,7 +57,7 @@ const (
// Set to a value larger than the timeouts in each watch server. // Set to a value larger than the timeouts in each watch server.
ReadWriteTimeout = time.Minute * 60 ReadWriteTimeout = time.Minute * 60
//TODO: This can be tightened up. It still matches objects named watch or proxy. //TODO: This can be tightened up. It still matches objects named watch or proxy.
defaultLongRunningRequestRE = "(/|^)((watch|proxy)(/|$)|(logs|portforward|exec)/?$)" defaultLongRunningRequestRE = "(/|^)((watch|proxy)(/|$)|(logs?|portforward|exec|attach)/?$)"
) )
// APIServer runs a kubernetes api server. // APIServer runs a kubernetes api server.

View File

@ -38,12 +38,16 @@ func TestLongRunningRequestRegexp(t *testing.T) {
"/api/v1/watch/stuff", "/api/v1/watch/stuff",
"/api/v1/default/service/proxy", "/api/v1/default/service/proxy",
"/api/v1/pods/proxy/path/to/thing", "/api/v1/pods/proxy/path/to/thing",
"/api/v1/namespaces/myns/pods/mypod/log",
"/api/v1/namespaces/myns/pods/mypod/logs", "/api/v1/namespaces/myns/pods/mypod/logs",
"/api/v1/namespaces/myns/pods/mypod/portforward", "/api/v1/namespaces/myns/pods/mypod/portforward",
"/api/v1/namespaces/myns/pods/mypod/exec", "/api/v1/namespaces/myns/pods/mypod/exec",
"/api/v1/namespaces/myns/pods/mypod/attach",
"/api/v1/namespaces/myns/pods/mypod/log/",
"/api/v1/namespaces/myns/pods/mypod/logs/", "/api/v1/namespaces/myns/pods/mypod/logs/",
"/api/v1/namespaces/myns/pods/mypod/portforward/", "/api/v1/namespaces/myns/pods/mypod/portforward/",
"/api/v1/namespaces/myns/pods/mypod/exec/", "/api/v1/namespaces/myns/pods/mypod/exec/",
"/api/v1/namespaces/myns/pods/mypod/attach/",
"/api/v1/watch/namespaces/myns/pods", "/api/v1/watch/namespaces/myns/pods",
} }
for _, path := range dontMatch { for _, path := range dontMatch {

View File

@ -45,8 +45,8 @@ func (d *denyExecOnPrivileged) Admit(a admission.Attributes) (err error) {
if !ok { if !ok {
return errors.NewBadRequest("a connect request was received, but could not convert the request object.") return errors.NewBadRequest("a connect request was received, but could not convert the request object.")
} }
// Only handle exec requests on pods // Only handle exec or attach requests on pods
if connectRequest.ResourcePath != "pods/exec" { if connectRequest.ResourcePath != "pods/exec" && connectRequest.ResourcePath != "pods/attach" {
return nil return nil
} }
pod, err := d.client.Pods(a.GetNamespace()).Get(connectRequest.Name) pod, err := d.client.Pods(a.GetNamespace()).Get(connectRequest.Name)
@ -54,7 +54,7 @@ func (d *denyExecOnPrivileged) Admit(a admission.Attributes) (err error) {
return admission.NewForbidden(a, err) return admission.NewForbidden(a, err)
} }
if isPrivileged(pod) { if isPrivileged(pod) {
return admission.NewForbidden(a, fmt.Errorf("Cannot exec into a privileged container")) return admission.NewForbidden(a, fmt.Errorf("Cannot exec into or attach to a privileged container"))
} }
return nil return nil
} }

View File

@ -47,6 +47,9 @@ func testAdmission(t *testing.T, pod *api.Pod, shouldAccept bool) {
handler := &denyExecOnPrivileged{ handler := &denyExecOnPrivileged{
client: mockClient, client: mockClient,
} }
// pods/exec
{
req := &rest.ConnectRequest{Name: pod.Name, ResourcePath: "pods/exec"} req := &rest.ConnectRequest{Name: pod.Name, ResourcePath: "pods/exec"}
err := handler.Admit(admission.NewAttributesRecord(req, "Pod", "test", "name", "pods", "exec", admission.Connect, nil)) err := handler.Admit(admission.NewAttributesRecord(req, "Pod", "test", "name", "pods", "exec", admission.Connect, nil))
if shouldAccept && err != nil { if shouldAccept && err != nil {
@ -55,7 +58,19 @@ func testAdmission(t *testing.T, pod *api.Pod, shouldAccept bool) {
if !shouldAccept && err == nil { if !shouldAccept && err == nil {
t.Errorf("An error was expected from the admission handler. Received nil") t.Errorf("An error was expected from the admission handler. Received nil")
} }
}
// pods/attach
{
req := &rest.ConnectRequest{Name: pod.Name, ResourcePath: "pods/attach"}
err := handler.Admit(admission.NewAttributesRecord(req, "Pod", "test", "name", "pods", "attach", admission.Connect, nil))
if shouldAccept && err != nil {
t.Errorf("Unexpected error returned from admission handler: %v", err)
}
if !shouldAccept && err == nil {
t.Errorf("An error was expected from the admission handler. Received nil")
}
}
} }
func acceptPod(name string) *api.Pod { func acceptPod(name string) *api.Pod {