eliminate cross-namespace HPA escalation attack

This commit is contained in:
deads2k 2015-11-02 09:26:48 -05:00
parent 1b437272ba
commit fd1c8e096a
20 changed files with 9797 additions and 9913 deletions

View File

@ -2513,10 +2513,6 @@
"type": "string", "type": "string",
"description": "Kind of the referent; More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#types-kinds\"" "description": "Kind of the referent; More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#types-kinds\""
}, },
"namespace": {
"type": "string",
"description": "Namespace of the referent; More info: http://releases.k8s.io/HEAD/docs/user-guide/namespaces.md"
},
"name": { "name": {
"type": "string", "type": "string",
"description": "Name of the referent; More info: http://releases.k8s.io/HEAD/docs/user-guide/identifiers.md#names" "description": "Name of the referent; More info: http://releases.k8s.io/HEAD/docs/user-guide/identifiers.md#names"

View File

@ -3998,13 +3998,6 @@ Populated by the system when a graceful deletion is requested. Read-only. More i
<td class="tableblock halign-left valign-top"></td> <td class="tableblock halign-left valign-top"></td>
</tr> </tr>
<tr> <tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">namespace</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Namespace of the referent; More info: <a href="http://releases.k8s.io/HEAD/docs/user-guide/namespaces.md">http://releases.k8s.io/HEAD/docs/user-guide/namespaces.md</a></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">false</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">string</p></td>
<td class="tableblock halign-left valign-top"></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">name</p></td> <td class="tableblock halign-left valign-top"><p class="tableblock">name</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Name of the referent; More info: <a href="http://releases.k8s.io/HEAD/docs/user-guide/identifiers.md#names">http://releases.k8s.io/HEAD/docs/user-guide/identifiers.md#names</a></p></td> <td class="tableblock halign-left valign-top"><p class="tableblock">Name of the referent; More info: <a href="http://releases.k8s.io/HEAD/docs/user-guide/identifiers.md#names">http://releases.k8s.io/HEAD/docs/user-guide/identifiers.md#names</a></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">false</p></td> <td class="tableblock halign-left valign-top"><p class="tableblock">false</p></td>
@ -4247,7 +4240,7 @@ Populated by the system when a graceful deletion is requested. Read-only. More i
</div> </div>
<div id="footer"> <div id="footer">
<div id="footer-text"> <div id="footer-text">
Last updated 2015-10-26 09:18:25 UTC Last updated 2015-11-02 14:28:45 UTC
</div> </div>
</div> </div>
</body> </body>

View File

@ -5095,7 +5095,7 @@ span.icon > [class^="icon-"], span.icon > [class*=" icon-"] { cursor: default; }
</div> </div>
<div id="footer"> <div id="footer">
<div id="footer-text"> <div id="footer-text">
Last updated 2015-10-26 09:18:25 UTC Last updated 2015-11-02 14:28:45 UTC
</div> </div>
</div> </div>
</body> </body>

View File

@ -6866,7 +6866,7 @@ The resulting set of endpoints can be viewed as:<br>
</div> </div>
<div id="footer"> <div id="footer">
<div id="footer-text"> <div id="footer-text">
Last updated 2015-10-26 09:18:19 UTC Last updated 2015-11-02 14:28:36 UTC
</div> </div>
</div> </div>
</body> </body>

View File

@ -23664,7 +23664,7 @@ span.icon > [class^="icon-"], span.icon > [class*=" icon-"] { cursor: default; }
</div> </div>
<div id="footer"> <div id="footer">
<div id="footer-text"> <div id="footer-text">
Last updated 2015-10-26 09:18:19 UTC Last updated 2015-11-02 14:28:36 UTC
</div> </div>
</div> </div>
</body> </body>

View File

@ -1483,7 +1483,6 @@ func deepCopy_extensions_ScaleStatus(in ScaleStatus, out *ScaleStatus, c *conver
func deepCopy_extensions_SubresourceReference(in SubresourceReference, out *SubresourceReference, c *conversion.Cloner) error { func deepCopy_extensions_SubresourceReference(in SubresourceReference, out *SubresourceReference, c *conversion.Cloner) error {
out.Kind = in.Kind out.Kind = in.Kind
out.Namespace = in.Namespace
out.Name = in.Name out.Name = in.Name
out.APIVersion = in.APIVersion out.APIVersion = in.APIVersion
out.Subresource = in.Subresource out.Subresource = in.Subresource

File diff suppressed because it is too large Load Diff

View File

@ -71,8 +71,6 @@ type ReplicationControllerDummy struct {
type SubresourceReference struct { type SubresourceReference struct {
// Kind of the referent; More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#types-kinds" // Kind of the referent; More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#types-kinds"
Kind string `json:"kind,omitempty"` Kind string `json:"kind,omitempty"`
// Namespace of the referent; More info: http://releases.k8s.io/HEAD/docs/user-guide/namespaces.md
Namespace string `json:"namespace,omitempty"`
// Name of the referent; More info: http://releases.k8s.io/HEAD/docs/user-guide/identifiers.md#names // Name of the referent; More info: http://releases.k8s.io/HEAD/docs/user-guide/identifiers.md#names
Name string `json:"name,omitempty"` Name string `json:"name,omitempty"`
// API version of the referent // API version of the referent

View File

@ -3019,7 +3019,6 @@ func autoconvert_extensions_SubresourceReference_To_v1beta1_SubresourceReference
defaulting.(func(*extensions.SubresourceReference))(in) defaulting.(func(*extensions.SubresourceReference))(in)
} }
out.Kind = in.Kind out.Kind = in.Kind
out.Namespace = in.Namespace
out.Name = in.Name out.Name = in.Name
out.APIVersion = in.APIVersion out.APIVersion = in.APIVersion
out.Subresource = in.Subresource out.Subresource = in.Subresource
@ -3983,7 +3982,6 @@ func autoconvert_v1beta1_SubresourceReference_To_extensions_SubresourceReference
defaulting.(func(*SubresourceReference))(in) defaulting.(func(*SubresourceReference))(in)
} }
out.Kind = in.Kind out.Kind = in.Kind
out.Namespace = in.Namespace
out.Name = in.Name out.Name = in.Name
out.APIVersion = in.APIVersion out.APIVersion = in.APIVersion
out.Subresource = in.Subresource out.Subresource = in.Subresource

View File

@ -1505,7 +1505,6 @@ func deepCopy_v1beta1_ScaleStatus(in ScaleStatus, out *ScaleStatus, c *conversio
func deepCopy_v1beta1_SubresourceReference(in SubresourceReference, out *SubresourceReference, c *conversion.Cloner) error { func deepCopy_v1beta1_SubresourceReference(in SubresourceReference, out *SubresourceReference, c *conversion.Cloner) error {
out.Kind = in.Kind out.Kind = in.Kind
out.Namespace = in.Namespace
out.Name = in.Name out.Name = in.Name
out.APIVersion = in.APIVersion out.APIVersion = in.APIVersion
out.Subresource = in.Subresource out.Subresource = in.Subresource

File diff suppressed because it is too large Load Diff

View File

@ -59,8 +59,6 @@ type ReplicationControllerDummy struct {
type SubresourceReference struct { type SubresourceReference struct {
// Kind of the referent; More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#types-kinds" // Kind of the referent; More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#types-kinds"
Kind string `json:"kind,omitempty"` Kind string `json:"kind,omitempty"`
// Namespace of the referent; More info: http://releases.k8s.io/HEAD/docs/user-guide/namespaces.md
Namespace string `json:"namespace,omitempty"`
// Name of the referent; More info: http://releases.k8s.io/HEAD/docs/user-guide/identifiers.md#names // Name of the referent; More info: http://releases.k8s.io/HEAD/docs/user-guide/identifiers.md#names
Name string `json:"name,omitempty"` Name string `json:"name,omitempty"`
// API version of the referent // API version of the referent

View File

@ -445,7 +445,6 @@ func (ScaleStatus) SwaggerDoc() map[string]string {
var map_SubresourceReference = map[string]string{ var map_SubresourceReference = map[string]string{
"": "SubresourceReference contains enough information to let you inspect or modify the referred subresource.", "": "SubresourceReference contains enough information to let you inspect or modify the referred subresource.",
"kind": "Kind of the referent; More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#types-kinds\"", "kind": "Kind of the referent; More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#types-kinds\"",
"namespace": "Namespace of the referent; More info: http://releases.k8s.io/HEAD/docs/user-guide/namespaces.md",
"name": "Name of the referent; More info: http://releases.k8s.io/HEAD/docs/user-guide/identifiers.md#names", "name": "Name of the referent; More info: http://releases.k8s.io/HEAD/docs/user-guide/identifiers.md#names",
"apiVersion": "API version of the referent", "apiVersion": "API version of the referent",
"subresource": "Subresource name of the referent", "subresource": "Subresource name of the referent",

View File

@ -68,8 +68,7 @@ func (a *HorizontalController) Run(syncPeriod time.Duration) {
}, syncPeriod, util.NeverStop) }, syncPeriod, util.NeverStop)
} }
func (a *HorizontalController) computeReplicasForCPUUtilization(hpa extensions.HorizontalPodAutoscaler, func (a *HorizontalController) computeReplicasForCPUUtilization(hpa extensions.HorizontalPodAutoscaler, scale *extensions.Scale) (int, *int, error) {
scale *extensions.Scale) (int, *int, error) {
if hpa.Spec.CPUUtilization == nil { if hpa.Spec.CPUUtilization == nil {
// If CPUTarget is not specified than we should return some default values. // If CPUTarget is not specified than we should return some default values.
// Since we always take maximum number of replicas from all policies it is safe // Since we always take maximum number of replicas from all policies it is safe
@ -77,7 +76,7 @@ func (a *HorizontalController) computeReplicasForCPUUtilization(hpa extensions.H
return 0, nil, nil return 0, nil, nil
} }
currentReplicas := scale.Status.Replicas currentReplicas := scale.Status.Replicas
currentUtilization, err := a.metricsClient.GetCPUUtilization(hpa.Spec.ScaleRef.Namespace, scale.Status.Selector) currentUtilization, err := a.metricsClient.GetCPUUtilization(hpa.Namespace, scale.Status.Selector)
// TODO: what to do on partial errors (like metrics obtained for 75% of pods). // TODO: what to do on partial errors (like metrics obtained for 75% of pods).
if err != nil { if err != nil {
@ -94,9 +93,9 @@ func (a *HorizontalController) computeReplicasForCPUUtilization(hpa extensions.H
} }
func (a *HorizontalController) reconcileAutoscaler(hpa extensions.HorizontalPodAutoscaler) error { func (a *HorizontalController) reconcileAutoscaler(hpa extensions.HorizontalPodAutoscaler) error {
reference := fmt.Sprintf("%s/%s/%s", hpa.Spec.ScaleRef.Kind, hpa.Spec.ScaleRef.Namespace, hpa.Spec.ScaleRef.Name) reference := fmt.Sprintf("%s/%s/%s", hpa.Spec.ScaleRef.Kind, hpa.Namespace, hpa.Spec.ScaleRef.Name)
scale, err := a.client.Extensions().Scales(hpa.Spec.ScaleRef.Namespace).Get(hpa.Spec.ScaleRef.Kind, hpa.Spec.ScaleRef.Name) scale, err := a.client.Extensions().Scales(hpa.Namespace).Get(hpa.Spec.ScaleRef.Kind, hpa.Spec.ScaleRef.Name)
if err != nil { if err != nil {
a.eventRecorder.Event(&hpa, "FailedGetScale", err.Error()) a.eventRecorder.Event(&hpa, "FailedGetScale", err.Error())
return fmt.Errorf("failed to query scale subresource for %s: %v", reference, err) return fmt.Errorf("failed to query scale subresource for %s: %v", reference, err)

View File

@ -90,7 +90,6 @@ func (tc *testCase) prepareTestClient(t *testing.T) *testclient.Fake {
ScaleRef: extensions.SubresourceReference{ ScaleRef: extensions.SubresourceReference{
Kind: "replicationController", Kind: "replicationController",
Name: rcName, Name: rcName,
Namespace: namespace,
Subresource: "scale", Subresource: "scale",
}, },
MinReplicas: &tc.minReplicas, MinReplicas: &tc.minReplicas,

View File

@ -36,7 +36,6 @@ func (HorizontalPodAutoscalerV1Beta1) ParamNames() []GeneratorParam {
{"default-name", true}, {"default-name", true},
{"name", false}, {"name", false},
{"scaleRef-kind", false}, {"scaleRef-kind", false},
{"scaleRef-namespace", false},
{"scaleRef-name", false}, {"scaleRef-name", false},
{"scaleRef-apiVersion", false}, {"scaleRef-apiVersion", false},
{"scaleRef-subresource", false}, {"scaleRef-subresource", false},
@ -94,7 +93,6 @@ func (HorizontalPodAutoscalerV1Beta1) Generate(genericParams map[string]interfac
Spec: extensions.HorizontalPodAutoscalerSpec{ Spec: extensions.HorizontalPodAutoscalerSpec{
ScaleRef: extensions.SubresourceReference{ ScaleRef: extensions.SubresourceReference{
Kind: params["scaleRef-kind"], Kind: params["scaleRef-kind"],
Namespace: params["scaleRef-namespace"],
Name: params["scaleRef-name"], Name: params["scaleRef-name"],
APIVersion: params["scaleRef-apiVersion"], APIVersion: params["scaleRef-apiVersion"],
Subresource: scaleSubResource, Subresource: scaleSubResource,

View File

@ -111,7 +111,6 @@ func RunAutoscale(f *cmdutil.Factory, out io.Writer, cmd *cobra.Command, args []
params["default-name"] = name params["default-name"] = name
params["scaleRef-kind"] = mapping.Kind params["scaleRef-kind"] = mapping.Kind
params["scaleRef-namespace"] = namespace
params["scaleRef-name"] = name params["scaleRef-name"] = name
params["scaleRef-apiVersion"] = mapping.APIVersion params["scaleRef-apiVersion"] = mapping.APIVersion

View File

@ -1295,9 +1295,8 @@ func (d *HorizontalPodAutoscalerDescriber) Describe(namespace, name string) (str
fmt.Fprintf(out, "Namespace:\t%s\n", hpa.Namespace) fmt.Fprintf(out, "Namespace:\t%s\n", hpa.Namespace)
fmt.Fprintf(out, "Labels:\t%s\n", labels.FormatLabels(hpa.Labels)) fmt.Fprintf(out, "Labels:\t%s\n", labels.FormatLabels(hpa.Labels))
fmt.Fprintf(out, "CreationTimestamp:\t%s\n", hpa.CreationTimestamp.Time.Format(time.RFC1123Z)) fmt.Fprintf(out, "CreationTimestamp:\t%s\n", hpa.CreationTimestamp.Time.Format(time.RFC1123Z))
fmt.Fprintf(out, "Reference:\t%s/%s/%s/%s\n", fmt.Fprintf(out, "Reference:\t%s/%s/%s\n",
hpa.Spec.ScaleRef.Kind, hpa.Spec.ScaleRef.Kind,
hpa.Spec.ScaleRef.Namespace,
hpa.Spec.ScaleRef.Name, hpa.Spec.ScaleRef.Name,
hpa.Spec.ScaleRef.Subresource) hpa.Spec.ScaleRef.Subresource)
if hpa.Spec.CPUUtilization != nil { if hpa.Spec.CPUUtilization != nil {
@ -1319,7 +1318,7 @@ func (d *HorizontalPodAutoscalerDescriber) Describe(namespace, name string) (str
// TODO: switch to scale subresource once the required code is submitted. // TODO: switch to scale subresource once the required code is submitted.
if strings.ToLower(hpa.Spec.ScaleRef.Kind) == "replicationcontroller" { if strings.ToLower(hpa.Spec.ScaleRef.Kind) == "replicationcontroller" {
fmt.Fprintf(out, "ReplicationController pods:\t") fmt.Fprintf(out, "ReplicationController pods:\t")
rc, err := d.client.ReplicationControllers(hpa.Spec.ScaleRef.Namespace).Get(hpa.Spec.ScaleRef.Name) rc, err := d.client.ReplicationControllers(hpa.Namespace).Get(hpa.Spec.ScaleRef.Name)
if err == nil { if err == nil {
fmt.Fprintf(out, "%d current / %d desired\n", rc.Status.Replicas, rc.Spec.Replicas) fmt.Fprintf(out, "%d current / %d desired\n", rc.Status.Replicas, rc.Spec.Replicas)
} else { } else {

View File

@ -1376,9 +1376,8 @@ func printDeploymentList(list *extensions.DeploymentList, w io.Writer, withNames
func printHorizontalPodAutoscaler(hpa *extensions.HorizontalPodAutoscaler, w io.Writer, withNamespace bool, wide bool, showAll bool, columnLabels []string) error { func printHorizontalPodAutoscaler(hpa *extensions.HorizontalPodAutoscaler, w io.Writer, withNamespace bool, wide bool, showAll bool, columnLabels []string) error {
namespace := hpa.Namespace namespace := hpa.Namespace
name := hpa.Name name := hpa.Name
reference := fmt.Sprintf("%s/%s/%s/%s", reference := fmt.Sprintf("%s/%s/%s",
hpa.Spec.ScaleRef.Kind, hpa.Spec.ScaleRef.Kind,
hpa.Spec.ScaleRef.Namespace,
hpa.Spec.ScaleRef.Name, hpa.Spec.ScaleRef.Name,
hpa.Spec.ScaleRef.Subresource) hpa.Spec.ScaleRef.Subresource)
target := "<unset>" target := "<unset>"

View File

@ -68,7 +68,6 @@ func createCPUHorizontalPodAutoscaler(rc *ResourceConsumer, cpu int) {
ScaleRef: extensions.SubresourceReference{ ScaleRef: extensions.SubresourceReference{
Kind: kind, Kind: kind,
Name: rc.name, Name: rc.name,
Namespace: rc.framework.Namespace.Name,
Subresource: subresource, Subresource: subresource,
}, },
MinReplicas: &minReplicas, MinReplicas: &minReplicas,