k8s.io/kubernetes@v1.29.3/pkg/apis/autoscaling/v1/conversion.go (about) 1 /* 2 Copyright 2016 The Kubernetes Authors. 3 4 Licensed under the Apache License, Version 2.0 (the "License"); 5 you may not use this file except in compliance with the License. 6 You may obtain a copy of the License at 7 8 http://www.apache.org/licenses/LICENSE-2.0 9 10 Unless required by applicable law or agreed to in writing, software 11 distributed under the License is distributed on an "AS IS" BASIS, 12 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 See the License for the specific language governing permissions and 14 limitations under the License. 15 */ 16 17 package v1 18 19 import ( 20 "encoding/json" 21 22 autoscalingv1 "k8s.io/api/autoscaling/v1" 23 24 v1 "k8s.io/api/core/v1" 25 "k8s.io/apimachinery/pkg/conversion" 26 "k8s.io/kubernetes/pkg/apis/autoscaling" 27 "k8s.io/kubernetes/pkg/apis/core" 28 ) 29 30 func Convert_autoscaling_MetricTarget_To_v1_CrossVersionObjectReference(in *autoscaling.MetricTarget, out *autoscalingv1.CrossVersionObjectReference, s conversion.Scope) error { 31 return nil 32 } 33 34 func Convert_v1_CrossVersionObjectReference_To_autoscaling_MetricTarget(in *autoscalingv1.CrossVersionObjectReference, out *autoscaling.MetricTarget, s conversion.Scope) error { 35 return nil 36 } 37 38 func Convert_autoscaling_ExternalMetricSource_To_v1_ExternalMetricSource(in *autoscaling.ExternalMetricSource, out *autoscalingv1.ExternalMetricSource, s conversion.Scope) error { 39 out.MetricName = in.Metric.Name 40 out.TargetValue = in.Target.Value 41 out.TargetAverageValue = in.Target.AverageValue 42 out.MetricSelector = in.Metric.Selector 43 return nil 44 } 45 46 func Convert_v1_ExternalMetricSource_To_autoscaling_ExternalMetricSource(in *autoscalingv1.ExternalMetricSource, out *autoscaling.ExternalMetricSource, s conversion.Scope) error { 47 value := in.TargetValue 48 averageValue := in.TargetAverageValue 49 var metricType autoscaling.MetricTargetType 50 if value == nil { 51 metricType = autoscaling.AverageValueMetricType 52 } else { 53 metricType = autoscaling.ValueMetricType 54 } 55 out.Target = autoscaling.MetricTarget{ 56 Type: metricType, 57 Value: value, 58 AverageValue: averageValue, 59 } 60 61 out.Metric = autoscaling.MetricIdentifier{ 62 Name: in.MetricName, 63 Selector: in.MetricSelector, 64 } 65 return nil 66 } 67 68 func Convert_autoscaling_ObjectMetricSource_To_v1_ObjectMetricSource(in *autoscaling.ObjectMetricSource, out *autoscalingv1.ObjectMetricSource, s conversion.Scope) error { 69 if in.Target.Value != nil { 70 out.TargetValue = *in.Target.Value 71 } 72 out.AverageValue = in.Target.AverageValue 73 out.Target = autoscalingv1.CrossVersionObjectReference{ 74 Kind: in.DescribedObject.Kind, 75 Name: in.DescribedObject.Name, 76 APIVersion: in.DescribedObject.APIVersion, 77 } 78 out.MetricName = in.Metric.Name 79 out.Selector = in.Metric.Selector 80 return nil 81 } 82 83 func Convert_v1_ObjectMetricSource_To_autoscaling_ObjectMetricSource(in *autoscalingv1.ObjectMetricSource, out *autoscaling.ObjectMetricSource, s conversion.Scope) error { 84 var metricType autoscaling.MetricTargetType 85 if in.AverageValue == nil { 86 metricType = autoscaling.ValueMetricType 87 } else { 88 metricType = autoscaling.AverageValueMetricType 89 } 90 91 out.Target = autoscaling.MetricTarget{ 92 Type: metricType, 93 Value: &in.TargetValue, 94 AverageValue: in.AverageValue, 95 } 96 out.DescribedObject = autoscaling.CrossVersionObjectReference{ 97 Kind: in.Target.Kind, 98 Name: in.Target.Name, 99 APIVersion: in.Target.APIVersion, 100 } 101 out.Metric = autoscaling.MetricIdentifier{ 102 Name: in.MetricName, 103 Selector: in.Selector, 104 } 105 return nil 106 } 107 108 func Convert_autoscaling_PodsMetricSource_To_v1_PodsMetricSource(in *autoscaling.PodsMetricSource, out *autoscalingv1.PodsMetricSource, s conversion.Scope) error { 109 if in.Target.AverageValue != nil { 110 out.TargetAverageValue = *in.Target.AverageValue 111 } 112 113 out.MetricName = in.Metric.Name 114 out.Selector = in.Metric.Selector 115 return nil 116 } 117 118 func Convert_v1_PodsMetricSource_To_autoscaling_PodsMetricSource(in *autoscalingv1.PodsMetricSource, out *autoscaling.PodsMetricSource, s conversion.Scope) error { 119 metricType := autoscaling.AverageValueMetricType 120 121 out.Target = autoscaling.MetricTarget{ 122 Type: metricType, 123 AverageValue: &in.TargetAverageValue, 124 } 125 out.Metric = autoscaling.MetricIdentifier{ 126 Name: in.MetricName, 127 Selector: in.Selector, 128 } 129 return nil 130 } 131 132 func Convert_autoscaling_ExternalMetricStatus_To_v1_ExternalMetricStatus(in *autoscaling.ExternalMetricStatus, out *autoscalingv1.ExternalMetricStatus, s conversion.Scope) error { 133 out.MetricName = in.Metric.Name 134 if in.Current.Value != nil { 135 out.CurrentValue = *in.Current.Value 136 } 137 if in.Current.AverageValue != nil { 138 out.CurrentAverageValue = in.Current.AverageValue 139 } 140 out.MetricSelector = in.Metric.Selector 141 return nil 142 } 143 144 func Convert_v1_ExternalMetricStatus_To_autoscaling_ExternalMetricStatus(in *autoscalingv1.ExternalMetricStatus, out *autoscaling.ExternalMetricStatus, s conversion.Scope) error { 145 value := in.CurrentValue 146 averageValue := in.CurrentAverageValue 147 out.Current = autoscaling.MetricValueStatus{ 148 Value: &value, 149 AverageValue: averageValue, 150 } 151 out.Metric = autoscaling.MetricIdentifier{ 152 Name: in.MetricName, 153 Selector: in.MetricSelector, 154 } 155 return nil 156 } 157 158 func Convert_autoscaling_ObjectMetricStatus_To_v1_ObjectMetricStatus(in *autoscaling.ObjectMetricStatus, out *autoscalingv1.ObjectMetricStatus, s conversion.Scope) error { 159 if in.Current.Value != nil { 160 out.CurrentValue = *in.Current.Value 161 } 162 if in.Current.AverageValue != nil { 163 currentAverageValue := *in.Current.AverageValue 164 out.AverageValue = ¤tAverageValue 165 } 166 out.Target = autoscalingv1.CrossVersionObjectReference{ 167 Kind: in.DescribedObject.Kind, 168 Name: in.DescribedObject.Name, 169 APIVersion: in.DescribedObject.APIVersion, 170 } 171 out.MetricName = in.Metric.Name 172 out.Selector = in.Metric.Selector 173 return nil 174 } 175 176 func Convert_v1_ObjectMetricStatus_To_autoscaling_ObjectMetricStatus(in *autoscalingv1.ObjectMetricStatus, out *autoscaling.ObjectMetricStatus, s conversion.Scope) error { 177 out.Current = autoscaling.MetricValueStatus{ 178 Value: &in.CurrentValue, 179 AverageValue: in.AverageValue, 180 } 181 out.DescribedObject = autoscaling.CrossVersionObjectReference{ 182 Kind: in.Target.Kind, 183 Name: in.Target.Name, 184 APIVersion: in.Target.APIVersion, 185 } 186 out.Metric = autoscaling.MetricIdentifier{ 187 Name: in.MetricName, 188 Selector: in.Selector, 189 } 190 return nil 191 } 192 193 func Convert_autoscaling_PodsMetricStatus_To_v1_PodsMetricStatus(in *autoscaling.PodsMetricStatus, out *autoscalingv1.PodsMetricStatus, s conversion.Scope) error { 194 if in.Current.AverageValue != nil { 195 out.CurrentAverageValue = *in.Current.AverageValue 196 } 197 out.MetricName = in.Metric.Name 198 out.Selector = in.Metric.Selector 199 return nil 200 } 201 202 func Convert_v1_PodsMetricStatus_To_autoscaling_PodsMetricStatus(in *autoscalingv1.PodsMetricStatus, out *autoscaling.PodsMetricStatus, s conversion.Scope) error { 203 out.Current = autoscaling.MetricValueStatus{ 204 AverageValue: &in.CurrentAverageValue, 205 } 206 out.Metric = autoscaling.MetricIdentifier{ 207 Name: in.MetricName, 208 Selector: in.Selector, 209 } 210 return nil 211 } 212 213 func Convert_v1_ResourceMetricSource_To_autoscaling_ResourceMetricSource(in *autoscalingv1.ResourceMetricSource, out *autoscaling.ResourceMetricSource, s conversion.Scope) error { 214 out.Name = core.ResourceName(in.Name) 215 utilization := in.TargetAverageUtilization 216 averageValue := in.TargetAverageValue 217 var metricType autoscaling.MetricTargetType 218 if utilization == nil { 219 metricType = autoscaling.AverageValueMetricType 220 } else { 221 metricType = autoscaling.UtilizationMetricType 222 } 223 out.Target = autoscaling.MetricTarget{ 224 Type: metricType, 225 AverageValue: averageValue, 226 AverageUtilization: utilization, 227 } 228 return nil 229 } 230 231 func Convert_autoscaling_ResourceMetricSource_To_v1_ResourceMetricSource(in *autoscaling.ResourceMetricSource, out *autoscalingv1.ResourceMetricSource, s conversion.Scope) error { 232 out.Name = v1.ResourceName(in.Name) 233 out.TargetAverageUtilization = in.Target.AverageUtilization 234 out.TargetAverageValue = in.Target.AverageValue 235 return nil 236 } 237 238 func Convert_v1_ContainerResourceMetricStatus_To_autoscaling_ContainerResourceMetricStatus(in *autoscalingv1.ContainerResourceMetricStatus, out *autoscaling.ContainerResourceMetricStatus, s conversion.Scope) error { 239 out.Name = core.ResourceName(in.Name) 240 out.Container = in.Container 241 utilization := in.CurrentAverageUtilization 242 averageValue := &in.CurrentAverageValue 243 out.Current = autoscaling.MetricValueStatus{ 244 AverageValue: averageValue, 245 AverageUtilization: utilization, 246 } 247 return nil 248 } 249 250 func Convert_autoscaling_ContainerResourceMetricStatus_To_v1_ContainerResourceMetricStatus(in *autoscaling.ContainerResourceMetricStatus, out *autoscalingv1.ContainerResourceMetricStatus, s conversion.Scope) error { 251 out.Name = v1.ResourceName(in.Name) 252 out.Container = in.Container 253 out.CurrentAverageUtilization = in.Current.AverageUtilization 254 if in.Current.AverageValue != nil { 255 out.CurrentAverageValue = *in.Current.AverageValue 256 } 257 return nil 258 } 259 260 func Convert_v1_ResourceMetricStatus_To_autoscaling_ResourceMetricStatus(in *autoscalingv1.ResourceMetricStatus, out *autoscaling.ResourceMetricStatus, s conversion.Scope) error { 261 out.Name = core.ResourceName(in.Name) 262 utilization := in.CurrentAverageUtilization 263 averageValue := &in.CurrentAverageValue 264 out.Current = autoscaling.MetricValueStatus{ 265 AverageValue: averageValue, 266 AverageUtilization: utilization, 267 } 268 return nil 269 } 270 271 func Convert_autoscaling_ResourceMetricStatus_To_v1_ResourceMetricStatus(in *autoscaling.ResourceMetricStatus, out *autoscalingv1.ResourceMetricStatus, s conversion.Scope) error { 272 out.Name = v1.ResourceName(in.Name) 273 out.CurrentAverageUtilization = in.Current.AverageUtilization 274 if in.Current.AverageValue != nil { 275 out.CurrentAverageValue = *in.Current.AverageValue 276 } 277 return nil 278 } 279 280 func Convert_autoscaling_HorizontalPodAutoscaler_To_v1_HorizontalPodAutoscaler(in *autoscaling.HorizontalPodAutoscaler, out *autoscalingv1.HorizontalPodAutoscaler, s conversion.Scope) error { 281 if err := autoConvert_autoscaling_HorizontalPodAutoscaler_To_v1_HorizontalPodAutoscaler(in, out, s); err != nil { 282 return err 283 } 284 285 // clear any pre-existing round-trip annotations to make sure the only ones set are ones we produced during conversion 286 annotations, copiedAnnotations := autoscaling.DropRoundTripHorizontalPodAutoscalerAnnotations(out.Annotations) 287 out.Annotations = annotations 288 289 otherMetrics := make([]autoscalingv1.MetricSpec, 0, len(in.Spec.Metrics)) 290 for _, metric := range in.Spec.Metrics { 291 if metric.Type == autoscaling.ResourceMetricSourceType && metric.Resource != nil && metric.Resource.Name == core.ResourceCPU && metric.Resource.Target.AverageUtilization != nil { 292 continue 293 } 294 295 convMetric := autoscalingv1.MetricSpec{} 296 if err := Convert_autoscaling_MetricSpec_To_v1_MetricSpec(&metric, &convMetric, s); err != nil { 297 return err 298 } 299 otherMetrics = append(otherMetrics, convMetric) 300 } 301 302 // NB: we need to save the status even if it maps to a CPU utilization status in order to save the raw value as well 303 currentMetrics := make([]autoscalingv1.MetricStatus, len(in.Status.CurrentMetrics)) 304 for i, currentMetric := range in.Status.CurrentMetrics { 305 if err := Convert_autoscaling_MetricStatus_To_v1_MetricStatus(¤tMetric, ¤tMetrics[i], s); err != nil { 306 return err 307 } 308 } 309 310 // store HPA conditions in an annotation 311 currentConditions := make([]autoscalingv1.HorizontalPodAutoscalerCondition, len(in.Status.Conditions)) 312 for i, currentCondition := range in.Status.Conditions { 313 if err := Convert_autoscaling_HorizontalPodAutoscalerCondition_To_v1_HorizontalPodAutoscalerCondition(¤tCondition, ¤tConditions[i], s); err != nil { 314 return err 315 } 316 } 317 318 if len(otherMetrics) > 0 { 319 otherMetricsEnc, err := json.Marshal(otherMetrics) 320 if err != nil { 321 return err 322 } 323 // copy before mutating 324 if !copiedAnnotations { 325 copiedAnnotations = true 326 out.Annotations = autoscaling.DeepCopyStringMap(out.Annotations) 327 } 328 out.Annotations[autoscaling.MetricSpecsAnnotation] = string(otherMetricsEnc) 329 } 330 331 if len(in.Status.CurrentMetrics) > 0 { 332 currentMetricsEnc, err := json.Marshal(currentMetrics) 333 if err != nil { 334 return err 335 } 336 // copy before mutating 337 if !copiedAnnotations { 338 copiedAnnotations = true 339 out.Annotations = autoscaling.DeepCopyStringMap(out.Annotations) 340 } 341 out.Annotations[autoscaling.MetricStatusesAnnotation] = string(currentMetricsEnc) 342 } 343 344 if in.Spec.Behavior != nil { 345 // TODO: this is marshaling an internal type. Fix this without breaking backwards compatibility. 346 behaviorEnc, err := json.Marshal(in.Spec.Behavior) 347 if err != nil { 348 return err 349 } 350 // copy before mutating 351 if !copiedAnnotations { 352 copiedAnnotations = true 353 out.Annotations = autoscaling.DeepCopyStringMap(out.Annotations) 354 } 355 out.Annotations[autoscaling.BehaviorSpecsAnnotation] = string(behaviorEnc) 356 } 357 358 if len(in.Status.Conditions) > 0 { 359 currentConditionsEnc, err := json.Marshal(currentConditions) 360 if err != nil { 361 return err 362 } 363 // copy before mutating 364 if !copiedAnnotations { 365 //nolint:ineffassign 366 copiedAnnotations = true 367 out.Annotations = autoscaling.DeepCopyStringMap(out.Annotations) 368 } 369 out.Annotations[autoscaling.HorizontalPodAutoscalerConditionsAnnotation] = string(currentConditionsEnc) 370 } 371 372 return nil 373 } 374 375 func Convert_v1_HorizontalPodAutoscaler_To_autoscaling_HorizontalPodAutoscaler(in *autoscalingv1.HorizontalPodAutoscaler, out *autoscaling.HorizontalPodAutoscaler, s conversion.Scope) error { 376 if err := autoConvert_v1_HorizontalPodAutoscaler_To_autoscaling_HorizontalPodAutoscaler(in, out, s); err != nil { 377 return err 378 } 379 380 if otherMetricsEnc, hasOtherMetrics := out.Annotations[autoscaling.MetricSpecsAnnotation]; hasOtherMetrics { 381 var otherMetrics []autoscalingv1.MetricSpec 382 if err := json.Unmarshal([]byte(otherMetricsEnc), &otherMetrics); err == nil { 383 // the normal Spec conversion could have populated out.Spec.Metrics with a single element, so deal with that 384 outMetrics := make([]autoscaling.MetricSpec, len(otherMetrics)+len(out.Spec.Metrics)) 385 for i, metric := range otherMetrics { 386 if err := Convert_v1_MetricSpec_To_autoscaling_MetricSpec(&metric, &outMetrics[i], s); err != nil { 387 return err 388 } 389 } 390 if out.Spec.Metrics != nil { 391 outMetrics[len(otherMetrics)] = out.Spec.Metrics[0] 392 } 393 out.Spec.Metrics = outMetrics 394 } 395 } 396 397 if behaviorEnc, hasConstraints := out.Annotations[autoscaling.BehaviorSpecsAnnotation]; hasConstraints { 398 // TODO: this is unmarshaling an internal type. Fix this without breaking backwards compatibility. 399 var behavior autoscaling.HorizontalPodAutoscalerBehavior 400 if err := json.Unmarshal([]byte(behaviorEnc), &behavior); err == nil && behavior != (autoscaling.HorizontalPodAutoscalerBehavior{}) { 401 out.Spec.Behavior = &behavior 402 } 403 } 404 405 if currentMetricsEnc, hasCurrentMetrics := out.Annotations[autoscaling.MetricStatusesAnnotation]; hasCurrentMetrics { 406 // ignore any existing status values -- the ones here have more information 407 var currentMetrics []autoscalingv1.MetricStatus 408 if err := json.Unmarshal([]byte(currentMetricsEnc), ¤tMetrics); err == nil { 409 out.Status.CurrentMetrics = make([]autoscaling.MetricStatus, len(currentMetrics)) 410 for i, currentMetric := range currentMetrics { 411 if err := Convert_v1_MetricStatus_To_autoscaling_MetricStatus(¤tMetric, &out.Status.CurrentMetrics[i], s); err != nil { 412 return err 413 } 414 } 415 } 416 } 417 418 // autoscaling/v1 formerly had an implicit default applied in the controller. In v2beta1, we apply it explicitly. 419 // We apply it here, explicitly, since we have access to the full set of metrics from the annotation. 420 if len(out.Spec.Metrics) == 0 { 421 // no other metrics, no explicit CPU value set 422 out.Spec.Metrics = []autoscaling.MetricSpec{ 423 { 424 Type: autoscaling.ResourceMetricSourceType, 425 Resource: &autoscaling.ResourceMetricSource{ 426 Name: core.ResourceCPU, 427 Target: autoscaling.MetricTarget{ 428 Type: autoscaling.UtilizationMetricType, 429 }, 430 }, 431 }, 432 } 433 out.Spec.Metrics[0].Resource.Target.AverageUtilization = new(int32) 434 *out.Spec.Metrics[0].Resource.Target.AverageUtilization = autoscaling.DefaultCPUUtilization 435 } 436 437 if currentConditionsEnc, hasCurrentConditions := out.Annotations[autoscaling.HorizontalPodAutoscalerConditionsAnnotation]; hasCurrentConditions { 438 var currentConditions []autoscalingv1.HorizontalPodAutoscalerCondition 439 if err := json.Unmarshal([]byte(currentConditionsEnc), ¤tConditions); err == nil { 440 out.Status.Conditions = make([]autoscaling.HorizontalPodAutoscalerCondition, len(currentConditions)) 441 for i, currentCondition := range currentConditions { 442 if err := Convert_v1_HorizontalPodAutoscalerCondition_To_autoscaling_HorizontalPodAutoscalerCondition(¤tCondition, &out.Status.Conditions[i], s); err != nil { 443 return err 444 } 445 } 446 } 447 } 448 449 // drop round-tripping annotations after converting to internal 450 out.Annotations, _ = autoscaling.DropRoundTripHorizontalPodAutoscalerAnnotations(out.Annotations) 451 452 return nil 453 } 454 455 func Convert_autoscaling_HorizontalPodAutoscalerSpec_To_v1_HorizontalPodAutoscalerSpec(in *autoscaling.HorizontalPodAutoscalerSpec, out *autoscalingv1.HorizontalPodAutoscalerSpec, s conversion.Scope) error { 456 if err := Convert_autoscaling_CrossVersionObjectReference_To_v1_CrossVersionObjectReference(&in.ScaleTargetRef, &out.ScaleTargetRef, s); err != nil { 457 return err 458 } 459 460 out.MinReplicas = in.MinReplicas 461 out.MaxReplicas = in.MaxReplicas 462 463 for _, metric := range in.Metrics { 464 if metric.Type == autoscaling.ResourceMetricSourceType && metric.Resource != nil && metric.Resource.Name == core.ResourceCPU && metric.Resource.Target.AverageUtilization != nil { 465 out.TargetCPUUtilizationPercentage = new(int32) 466 *out.TargetCPUUtilizationPercentage = *metric.Resource.Target.AverageUtilization 467 break 468 } 469 } 470 471 return nil 472 } 473 474 func Convert_v1_HorizontalPodAutoscalerSpec_To_autoscaling_HorizontalPodAutoscalerSpec(in *autoscalingv1.HorizontalPodAutoscalerSpec, out *autoscaling.HorizontalPodAutoscalerSpec, s conversion.Scope) error { 475 if err := Convert_v1_CrossVersionObjectReference_To_autoscaling_CrossVersionObjectReference(&in.ScaleTargetRef, &out.ScaleTargetRef, s); err != nil { 476 return err 477 } 478 479 out.MinReplicas = in.MinReplicas 480 out.MaxReplicas = in.MaxReplicas 481 482 if in.TargetCPUUtilizationPercentage != nil { 483 out.Metrics = []autoscaling.MetricSpec{ 484 { 485 Type: autoscaling.ResourceMetricSourceType, 486 Resource: &autoscaling.ResourceMetricSource{ 487 Name: core.ResourceCPU, 488 Target: autoscaling.MetricTarget{ 489 Type: autoscaling.UtilizationMetricType, 490 }, 491 }, 492 }, 493 } 494 out.Metrics[0].Resource.Target.AverageUtilization = new(int32) 495 *out.Metrics[0].Resource.Target.AverageUtilization = *in.TargetCPUUtilizationPercentage 496 } 497 498 return nil 499 } 500 501 func Convert_autoscaling_HorizontalPodAutoscalerStatus_To_v1_HorizontalPodAutoscalerStatus(in *autoscaling.HorizontalPodAutoscalerStatus, out *autoscalingv1.HorizontalPodAutoscalerStatus, s conversion.Scope) error { 502 out.ObservedGeneration = in.ObservedGeneration 503 out.LastScaleTime = in.LastScaleTime 504 505 out.CurrentReplicas = in.CurrentReplicas 506 out.DesiredReplicas = in.DesiredReplicas 507 508 for _, metric := range in.CurrentMetrics { 509 if metric.Type == autoscaling.ResourceMetricSourceType && metric.Resource != nil && metric.Resource.Name == core.ResourceCPU { 510 if metric.Resource.Current.AverageUtilization != nil { 511 512 out.CurrentCPUUtilizationPercentage = new(int32) 513 *out.CurrentCPUUtilizationPercentage = *metric.Resource.Current.AverageUtilization 514 } 515 } 516 } 517 return nil 518 } 519 520 func Convert_v1_HorizontalPodAutoscalerStatus_To_autoscaling_HorizontalPodAutoscalerStatus(in *autoscalingv1.HorizontalPodAutoscalerStatus, out *autoscaling.HorizontalPodAutoscalerStatus, s conversion.Scope) error { 521 out.ObservedGeneration = in.ObservedGeneration 522 out.LastScaleTime = in.LastScaleTime 523 524 out.CurrentReplicas = in.CurrentReplicas 525 out.DesiredReplicas = in.DesiredReplicas 526 527 if in.CurrentCPUUtilizationPercentage != nil { 528 out.CurrentMetrics = []autoscaling.MetricStatus{ 529 { 530 Type: autoscaling.ResourceMetricSourceType, 531 Resource: &autoscaling.ResourceMetricStatus{ 532 Name: core.ResourceCPU, 533 }, 534 }, 535 } 536 out.CurrentMetrics[0].Resource.Current.AverageUtilization = new(int32) 537 *out.CurrentMetrics[0].Resource.Current.AverageUtilization = *in.CurrentCPUUtilizationPercentage 538 } 539 return nil 540 } 541 542 func Convert_v1_ContainerResourceMetricSource_To_autoscaling_ContainerResourceMetricSource(in *autoscalingv1.ContainerResourceMetricSource, out *autoscaling.ContainerResourceMetricSource, s conversion.Scope) error { 543 out.Name = core.ResourceName(in.Name) 544 out.Container = in.Container 545 utilization := in.TargetAverageUtilization 546 averageValue := in.TargetAverageValue 547 var metricType autoscaling.MetricTargetType 548 if utilization == nil { 549 metricType = autoscaling.AverageValueMetricType 550 } else { 551 metricType = autoscaling.UtilizationMetricType 552 } 553 out.Target = autoscaling.MetricTarget{ 554 Type: metricType, 555 AverageValue: averageValue, 556 AverageUtilization: utilization, 557 } 558 return nil 559 } 560 561 func Convert_autoscaling_ContainerResourceMetricSource_To_v1_ContainerResourceMetricSource(in *autoscaling.ContainerResourceMetricSource, out *autoscalingv1.ContainerResourceMetricSource, s conversion.Scope) error { 562 out.Name = v1.ResourceName(in.Name) 563 out.Container = in.Container 564 out.TargetAverageUtilization = in.Target.AverageUtilization 565 out.TargetAverageValue = in.Target.AverageValue 566 return nil 567 }