Skip to content
This repository has been archived by the owner on Jun 12, 2024. It is now read-only.

Commit

Permalink
added servo.yaml formatted output
Browse files Browse the repository at this point in the history
  • Loading branch information
pnickolov committed Sep 21, 2021
1 parent 7569cff commit dba37e1
Show file tree
Hide file tree
Showing 2 changed files with 112 additions and 1 deletion.
110 changes: 110 additions & 0 deletions cmd/output.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ package cmd
import (
"fmt"
"io"
"math"
"strings"

"github.com/olekukonko/tablewriter"
Expand All @@ -34,6 +35,7 @@ func getDisplayMethods() map[string]DisplayMethods {
OUTPUT_TABLE: {(*AppTable).outputTableHeader, (*AppTable).outputTableApp, (*AppTable).outputAnyTableOut},
OUTPUT_DETAIL: {(*AppTable).outputDetailHeader, (*AppTable).outputDetailApp, (*AppTable).outputAnyTableOut},
OUTPUT_YAML: {(*AppTable).outputYamlHeader, (*AppTable).outputYamlApp, (*AppTable).outputYamlOut},
OUTPUT_SERVO: {(*AppTable).outputYamlHeader, (*AppTable).outputServoYamlApp, (*AppTable).outputYamlOut},
}
}

Expand Down Expand Up @@ -175,6 +177,114 @@ func (table *AppTable) outputYamlOut() {
table.yaml.Close()
}

func alignedResourceValue(v float64, up bool) float64 {
const step = 0.125

// take care of edge cases
if v <= step {
if v < step {
log.Warnf("resource value %v is less than the step %v; assuming step", v, step)
}
return step
}

// calculate alignment
n := math.Floor(v / 0.125)
if n*step == v {
return v // aligned already
}

// align up or down, as requested
if up {
n += 1
}
return n * step
}

func selectResourceValue(r *appmodel.AppContainerResourceInfo) float64 {
if r.Request > 0 {
return r.Request
}
if r.Limit > 0 {
return r.Limit
}
if r.Usage > 0 {
return r.Usage
}
return 0
}

func (table *AppTable) outputServoYamlApp(app *appmodel.App) {
type ResourceRange struct {
Min string `yaml:"min,omitempty"`
Max string `yaml:"max,omitempty"`
}
type OpsaniDev struct {
Namespace string
Deployment string
Container string
Service string `yaml:"service,omitempty"`
Cpu ResourceRange `yaml:"cpu,omitempty"`
Memory ResourceRange `yaml:"memory,omitempty"`
}

if app.Analysis.MainContainer == "" {
log.Errorf("Cannot produce servo.yaml output for application %v: no main container identified", app.Metadata)
return
}
cIndex, ok := app.ContainerIndexByName(app.Analysis.MainContainer)
if !ok { // shouldn't happen
log.Errorf("Cannot produce servo.yaml output for application %v: main container %q not found", app.Metadata, app.Analysis.MainContainer)
return
}

var opsaniDev OpsaniDev
opsaniDev.Namespace = app.Metadata.Namespace
opsaniDev.Deployment = app.Metadata.Workload
opsaniDev.Container = app.Analysis.MainContainer
opsaniDev.Service = app.Metadata.Workload // TODO: get the real service, this is a stub

c := &app.Containers[cIndex]
cpuCores := selectResourceValue(&c.Cpu.AppContainerResourceInfo)
opsaniDev.Cpu.Min = fmt.Sprintf("%g", alignedResourceValue(cpuCores/4.0, false))
opsaniDev.Cpu.Max = fmt.Sprintf("%g", alignedResourceValue(cpuCores*2.0, true))
memGib := selectResourceValue(&c.Cpu.AppContainerResourceInfo)
opsaniDev.Memory.Min = fmt.Sprintf("%gGi", alignedResourceValue(memGib/4.0, false))
opsaniDev.Memory.Max = fmt.Sprintf("%gGi", alignedResourceValue(memGib*2.0, true))

configRoot := make(map[string]OpsaniDev, 1)
configRoot["opsani_dev"] = opsaniDev
configRootBuf, err := yaml.Marshal(configRoot)
if err != nil {
log.Errorf("Failed to marshal %#v to yaml: %v", configRoot, err)
return
}

servoYaml := make(map[string]string, 1)
servoYaml["servo.yaml"] = string(configRootBuf)

if err := table.yaml.Encode(servoYaml); err != nil {
log.Errorf("Failed to write app %v to yaml: %v", app.Metadata, err)
}
}

func newAppTable(wr io.Writer) *AppTable {
return &AppTable{wr, *tablewriter.NewWriter(wr), nil}
}

/*
servo.yaml: |
opsani_dev:
{%- raw %}
namespace: {{ NAMESPACE }}
deployment: {{ DEPLOYMENT }}
container: {{ CONTAINER }}
service: {{ SERVICE }}
{% endraw %}
cpu:
min: 250m
max: '3.0'
memory:
min: 128.0MiB
max: 3.0GiB
*/
3 changes: 2 additions & 1 deletion cmd/root.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,11 +28,12 @@ const (
OUTPUT_TABLE = "table"
OUTPUT_DETAIL = "detail"
OUTPUT_YAML = "yaml"
OUTPUT_SERVO = "servo.yaml"
)

// constant table - format types, keep in sync with OUTPUT_xxx constants above
func getOutputFormats() []string {
return []string{OUTPUT_TABLE, OUTPUT_DETAIL, OUTPUT_YAML}
return []string{OUTPUT_TABLE, OUTPUT_DETAIL, OUTPUT_YAML, OUTPUT_SERVO}
}

// rootCmd represents the base command when called without any subcommands
Expand Down

0 comments on commit dba37e1

Please sign in to comment.