in operator/pkg/controllers/utils.go [197:266]
func ApplyContainerResourceCustomization(isNamespaced bool, m *manifest.Objects, controllerName string, controllerGVK schema.GroupVersionKind, containers []customizev1beta1.ContainerResourceSpec, replicas *int64) error {
if err := checkForDuplicateContainers(containers); err != nil {
return err
}
cMap := make(map[string]customizev1beta1.ResourceRequirements, len(containers)) // cMap is a map of container name to its corresponding resource customization.
cMapApplied := make(map[string]bool) // cMapApplied is a map of container name to a boolean indicating whether the customization for this container is applied.
for _, c := range containers {
cMap[c.Name] = c.Resources
cMapApplied[c.Name] = false
}
var shouldUpdateHPA bool // shouldUpdateHPA is a boolean indicating if we need to update the "minReplicas" field in the HorizontalPodAutoscaler for webhook manager
// apply customization to the matching controller in the manifest
for _, item := range m.Items {
if item.GroupVersionKind() == controllerGVK { // match GVK
if (!isNamespaced && item.GetName() == controllerName) || // match exact controller name for cluster-scoped controller
(isNamespaced && strings.HasPrefix(item.GetName(), controllerName)) { // match the prefix for namespace-scoped controller, ignore the namespace ID suffix
// apply container resource customization for this controller.
if err := item.MutateContainers(customizeContainerResourcesFn(cMap, cMapApplied)); err != nil {
return err
}
// apply replicas customization for this controller.
if replicas != nil && controllerName == "cnrm-webhook-manager" { // currently only support customizing replicas for cnrm-webhook-manager.
if err := item.SetNestedField(*replicas, "spec", "replicas"); err != nil {
return err
}
shouldUpdateHPA = true
}
break // we already found the matching controller, no need to keep looking.
}
}
}
// if we update replicas for webhook manager deployment, we need to adjust its HPA as well.
if shouldUpdateHPA {
HPAGVK := schema.GroupVersionKind{
Group: autoscalingv1.SchemeGroupVersion.Group,
Version: autoscalingv1.SchemeGroupVersion.Version,
Kind: "HorizontalPodAutoscaler",
}
for _, item := range m.Items {
if item.GroupVersionKind() == HPAGVK && item.GetName() == "cnrm-webhook" {
// update "minReplicas".
if err := item.SetNestedField(*replicas, "spec", "minReplicas"); err != nil {
return err
}
// update "maxReplicas" to match "minReplicas" if it is smaller than "minReplicas".
maxReplicas, found, err := unstructured.NestedInt64(item.UnstructuredObject().Object, "spec", "maxReplicas")
if err != nil {
return err
}
if found && (maxReplicas < *replicas) {
if err := item.SetNestedField(*replicas, "spec", "maxReplicas"); err != nil {
return err
}
}
break // we already found the HPA, no need to keep looking.
}
}
}
// check if all container resource customizations are applied
var notApplied []string
for c, applied := range cMapApplied {
if !applied {
notApplied = append(notApplied, c)
}
}
if len(notApplied) > 0 {
return fmt.Errorf("resource customization failed for the following containers because there are no matching containers in the manifest: %s", strings.Join(notApplied, ", "))
}
return nil
}