mirror of
https://github.com/kubernetes-sigs/kustomize.git
synced 2026-05-17 18:25:26 +00:00
117 lines
3.2 KiB
Go
117 lines
3.2 KiB
Go
// Copyright 2019 The Kubernetes Authors.
|
|
// SPDX-License-Identifier: Apache-2.0
|
|
|
|
// Package main implements an injection function for resource reservations and
|
|
// is run with `kustomize config run -- DIR/`.
|
|
package main
|
|
|
|
import (
|
|
"fmt"
|
|
"os"
|
|
|
|
"sigs.k8s.io/kustomize/kyaml/kio"
|
|
"sigs.k8s.io/kustomize/kyaml/yaml"
|
|
)
|
|
|
|
func main() {
|
|
rw := &kio.ByteReadWriter{Reader: os.Stdin, Writer: os.Stdout, KeepReaderAnnotations: true}
|
|
p := kio.Pipeline{
|
|
Inputs: []kio.Reader{rw}, // read the inputs into a slice
|
|
Filters: []kio.Filter{filter{}}, // run the inject into the inputs
|
|
Outputs: []kio.Writer{rw}} // copy the inputs to the output
|
|
if err := p.Execute(); err != nil {
|
|
os.Exit(1)
|
|
}
|
|
}
|
|
|
|
// filter implements kio.Filter
|
|
type filter struct{}
|
|
|
|
// Filter injects cpu and memory resource reservations into containers for
|
|
// Resources containing the `tshirt-size` annotation.
|
|
func (filter) Filter(in []*yaml.RNode) ([]*yaml.RNode, error) {
|
|
// inject the resource reservations into each Resource
|
|
for _, r := range in {
|
|
if err := inject(r); err != nil {
|
|
return nil, err
|
|
}
|
|
}
|
|
return in, nil
|
|
}
|
|
|
|
// cpuSizes is the mapping from tshirt-size to cpu reservation quantity
|
|
var cpuSizes = map[string]string{
|
|
"small": "200m",
|
|
"medium": "4",
|
|
"large": "16",
|
|
}
|
|
|
|
// memorySizes is the mapping from tshirt-size to memory reservation quantity
|
|
var memorySizes = map[string]string{
|
|
"small": "50M",
|
|
"medium": "1G",
|
|
"large": "32G",
|
|
}
|
|
|
|
// inject sets the cpu and memory reservations on all containers for Resources annotated
|
|
// with `tshirt-size: small|medium|large`
|
|
func inject(r *yaml.RNode) error {
|
|
// lookup the containers field
|
|
containers, err := r.Pipe(yaml.Lookup("spec", "template", "spec", "containers"))
|
|
if err != nil {
|
|
s, _ := r.String()
|
|
return fmt.Errorf("%v: %s", err, s)
|
|
}
|
|
if containers == nil {
|
|
// doesn't have containers, skip the Resource
|
|
return nil
|
|
}
|
|
|
|
// check for the tshirt-size annotations
|
|
meta, err := r.GetMeta()
|
|
if err != nil {
|
|
return err
|
|
}
|
|
var memorySize, cpuSize string
|
|
if size, found := meta.Annotations["tshirt-size"]; !found {
|
|
// not a tshirt-sized Resource, ignore it
|
|
return nil
|
|
} else {
|
|
// lookup the memory and cpu quantities based on the tshirt size
|
|
memorySize = memorySizes[size]
|
|
cpuSize = cpuSizes[size]
|
|
if memorySize == "" || cpuSize == "" {
|
|
return fmt.Errorf("unsupported tshirt-size: " + size)
|
|
}
|
|
}
|
|
|
|
// visit each container and apply the cpu and memory reservations
|
|
return containers.VisitElements(func(node *yaml.RNode) error {
|
|
// set cpu
|
|
err := node.PipeE(
|
|
// lookup resources.requests.cpu, creating the field as a
|
|
// ScalarNode if it doesn't exist
|
|
yaml.LookupCreate(yaml.ScalarNode, "resources", "requests", "cpu"),
|
|
// set the field value to the cpuSize
|
|
yaml.Set(yaml.NewScalarRNode(cpuSize)))
|
|
if err != nil {
|
|
s, _ := r.String()
|
|
return fmt.Errorf("%v: %s", err, s)
|
|
}
|
|
|
|
// set memory
|
|
err = node.PipeE(
|
|
// lookup resources.requests.memory, creating the field as a
|
|
// ScalarNode if it doesn't exist
|
|
yaml.LookupCreate(yaml.ScalarNode, "resources", "requests", "memory"),
|
|
// set the field value to the memorySize
|
|
yaml.Set(yaml.NewScalarRNode(memorySize)))
|
|
if err != nil {
|
|
s, _ := r.String()
|
|
return fmt.Errorf("%v: %s", err, s)
|
|
}
|
|
|
|
return nil
|
|
})
|
|
}
|