diff --git a/cluster-autoscaler/cloudprovider/gce/templates.go b/cluster-autoscaler/cloudprovider/gce/templates.go index 678d8002cf02..d54c876c527d 100644 --- a/cluster-autoscaler/cloudprovider/gce/templates.go +++ b/cluster-autoscaler/cloudprovider/gce/templates.go @@ -438,14 +438,39 @@ func extractExtendedResourcesFromKubeEnv(kubeEnv KubeEnv) (apiv1.ResourceList, e klog.Warningf("error while obtaining extended_resources from AUTOSCALER_ENV_VARS; %v", err) return nil, err } - - if !found { - return apiv1.ResourceList{}, nil + var extendedResourcesMap map[string]string + if found { + extendedResourcesMap, err = parseKeyValueListToMap(extendedResourcesAsString) + if err != nil { + return apiv1.ResourceList{}, err + } + } else { + extendedResourcesMap = make(map[string]string) } - - extendedResourcesMap, err := parseKeyValueListToMap(extendedResourcesAsString) + nodeLabelsAsString, found, err := extractAutoscalerVarFromKubeEnv(kubeEnv, "node_labels") if err != nil { - return apiv1.ResourceList{}, err + klog.Warningf("error while obtaining node_labels from AUTOSCALER_ENV_VARS; %v", err) + return nil, err + } + if found { + nodeLabelsMap, err := parseKeyValueListToMap(nodeLabelsAsString) + if err != nil { + return apiv1.ResourceList{}, err + } + const extendedResourcesKeyPrefix = "clusterautoscaler-nodetemplate-resources." + for key, value := range nodeLabelsMap { + if strings.HasPrefix(key, extendedResourcesKeyPrefix) { + key = strings.TrimPrefix(key, extendedResourcesKeyPrefix) + if _, existsBefore := extendedResourcesMap[key]; existsBefore { + klog.Warningf("extended resource %s defined twice in template", key) + } + extendedResourcesMap[key] = value + } + } + } + + if len(extendedResourcesMap) == 0 { + return apiv1.ResourceList{}, nil } extendedResources := apiv1.ResourceList{} @@ -453,7 +478,7 @@ func extractExtendedResourcesFromKubeEnv(kubeEnv KubeEnv) (apiv1.ResourceList, e if q, err := resource.ParseQuantity(quantity); err == nil && q.Sign() >= 0 { extendedResources[apiv1.ResourceName(name)] = q } else if err != nil { - klog.Warningf("ignoring invalid value in extended_resources defined in AUTOSCALER_ENV_VARS; %v", err) + klog.Warningf("ignoring invalid value in extended_resources or node_labels defined in AUTOSCALER_ENV_VARS; %v", err) } } return extendedResources, nil diff --git a/cluster-autoscaler/cloudprovider/gce/templates_test.go b/cluster-autoscaler/cloudprovider/gce/templates_test.go index 4fa96f407e38..ebaf2eaa1ab9 100644 --- a/cluster-autoscaler/cloudprovider/gce/templates_test.go +++ b/cluster-autoscaler/cloudprovider/gce/templates_test.go @@ -1304,6 +1304,18 @@ func TestExtractExtendedResourcesFromKubeEnv(t *testing.T) { expectedExtendedResources: apiv1.ResourceList{}, expectedErr: true, }, + { + name: "two valid values one of them defined in node labels", + kubeEnvValue: "AUTOSCALER_ENV_VARS: node_labels=a=b,c=d,clusterautoscaler-nodetemplate-resources.test.co/test-resource=3,cloud.google.com/gke-nodepool=pool-3,cloud.google.com/gke-preemptible=true;" + + "node_taints='dedicated=ml:NoSchedule,test=dev:PreferNoSchedule,a=b:c';" + + "kube_reserved=cpu=1000m,memory=300000Mi;" + + "extended_resources=foo=bar,baz=10G", + expectedExtendedResources: apiv1.ResourceList{ + apiv1.ResourceName("baz"): *resource.NewQuantity(10*units.GB, resource.DecimalSI), + apiv1.ResourceName("test.co/test-resource"): *resource.NewQuantity(3, resource.DecimalSI), + }, + expectedErr: false, + }, } for _, tc := range testCases {