Skip to content

Commit

Permalink
refactor: component property lookup flow
Browse files Browse the repository at this point in the history
  • Loading branch information
yashmehrotra committed Oct 5, 2023
1 parent 8fbe884 commit 2f5902e
Showing 1 changed file with 127 additions and 37 deletions.
164 changes: 127 additions & 37 deletions pkg/topology/run.go
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,16 @@ func forEachComponent(ctx *ComponentContext, spec *v1.ComponentSpec, component *
continue
}

for _, p := range props {
// TODO: Ask Moshe Can for each handle component list
if err := mergeComponentProperties(pkg.Components{component}, props); err != nil {
continue
}

var properties pkg.Properties
if err := json.Unmarshal(props, &properties); err != nil {
return err
}
for _, p := range properties {
found := component.Properties.Find(p.Name)
if found != nil {
found.Merge(p)
Expand Down Expand Up @@ -159,18 +168,17 @@ func lookupComponents(ctx *ComponentContext, component v1.ComponentSpec) (compon
components = append(components, pkgComp)
}

for _, comp := range components {
for _, property := range component.Properties {
props, err := lookupProperty(ctx.WithComponents(&components, comp), property)
if err != nil {
errMsg := fmt.Sprintf("Failed to lookup property: %s. Error in lookup: %v", property, err)
logger.Errorf(errMsg)
ctx.JobHistory.AddError(errMsg)
continue
}
comp.Properties = append(comp.Properties, props...)
for _, property := range component.Properties {
props, err := lookupProperty(ctx, property)
if err != nil {
return nil, fmt.Errorf("error with property lookup: %w", err)
}
if err := mergeComponentProperties(components, props); err != nil {
return nil, fmt.Errorf("error with merging component properties: %w", err)
}
}

for _, comp := range components {
if comp.Icon == "" {
comp.Icon = component.Icon
}
Expand All @@ -193,7 +201,7 @@ func lookupComponents(ctx *ComponentContext, component v1.ComponentSpec) (compon
}

func lookup(ctx *ComponentContext, name string, spec v1.CanarySpec) ([]interface{}, error) {
results := []interface{}{}
var results []any

canaryCtx := context.New(ctx.Kommons, ctx.Kubernetes, db.Gorm, v1.NewCanaryFromSpec(name, spec))
canaryCtx.Context = ctx
Expand All @@ -217,9 +225,9 @@ func lookup(ctx *ComponentContext, name string, spec v1.CanarySpec) ([]interface
results = append(results, result.Message)
} else if result.Detail != nil {
switch result.Detail.(type) {
case []interface{}:
case []any:
results = append(results, result.Detail.([]interface{})...)
case interface{}:
case any:
results = append(results, result.Detail)
default:
return nil, fmt.Errorf("unknown type %T", result.Detail)
Expand Down Expand Up @@ -284,7 +292,7 @@ func toMapStringAny(m map[string]string) map[string]any {
return r
}

func lookupProperty(ctx *ComponentContext, property *v1.Property) (pkg.Properties, error) {
func lookupPropertyOld(ctx *ComponentContext, property *v1.Property) (pkg.Properties, error) {

Check failure on line 295 in pkg/topology/run.go

View workflow job for this annotation

GitHub Actions / lint

func `lookupPropertyOld` is unused (unused)
prop := pkg.NewProperty(*property)

if property.ConfigLookup != nil {
Expand All @@ -299,6 +307,8 @@ func lookupProperty(ctx *ComponentContext, property *v1.Property) (pkg.Propertie
}

results, err := lookup(ctx, property.Name, *property.Lookup)
lp, _ := json.Marshal(property.Lookup)
logger.Infof("Results of %v are %v", string(lp), results)
if err != nil {
return nil, err
}
Expand All @@ -322,8 +332,13 @@ func lookupProperty(ctx *ComponentContext, property *v1.Property) (pkg.Propertie
}
for _, component := range components {
found := ctx.Components.Find(component.Name)
logger.Infof("HERE YASH")
if found == nil {
//logger.Errorf("YASH LOG ERROR FOR NAME %s", component.Name)
continue
return nil, fmt.Errorf("component %s not found", component.Name)

Check failure on line 339 in pkg/topology/run.go

View workflow job for this annotation

GitHub Actions / lint

unreachable: unreachable code (govet)
} else {
logger.Infof("FOUND")
}
for _, property := range component.Properties {
foundProperty := found.Properties.Find(property.Name)
Expand All @@ -335,15 +350,83 @@ func lookupProperty(ctx *ComponentContext, property *v1.Property) (pkg.Propertie
}
return nil, nil
} else if isPropertyList(data) {
logger.Infof("YOLOLO 1")
properties := pkg.Properties{}
err = json.Unmarshal([]byte(results[0].(string)), &properties)
return properties, err
} else {
logger.Infof("YOLOLO 2 %s", string(data))
prop.Text = string(data)
return pkg.Properties{prop}, nil
}
}

func lookupProperty(ctx *ComponentContext, property *v1.Property) ([]byte, error) {
if property.ConfigLookup != nil {
prop, err := lookupConfig(ctx, property)
if err != nil {
return nil, errors.Wrapf(err, "property config lookup failed: %s", property)
}
return json.Marshal(pkg.Properties{prop})
}

if property.Lookup != nil {
results, err := lookup(ctx, property.Name, *property.Lookup)
lp, _ := json.Marshal(property.Lookup)
logger.Infof("Results of %v are %v", string(lp), results)
if err != nil {
return nil, err
}
if len(results) == 0 {
return nil, nil
}

var dataStr string
var ok bool
if dataStr, ok = results[0].(string); !ok {
return nil, fmt.Errorf("unknown property type %T", results)
}
data := []byte(dataStr)
return data, nil
}

return json.Marshal(pkg.Properties{pkg.NewProperty(*property)})
}

func mergeComponentProperties(components pkg.Components, propertiesRaw []byte) error {
if isComponentList(propertiesRaw) {
// the result is map of components to properties, find the existing component
// and then merge the property into it
var componentsWithProperties pkg.Components
err := json.Unmarshal(propertiesRaw, &componentsWithProperties)
if err != nil {
return err
}
for _, component := range componentsWithProperties {
found := components.Find(component.Name)
if found == nil {
continue
}
for _, property := range component.Properties {
foundProperty := found.Properties.Find(property.Name)
if foundProperty == nil {
return fmt.Errorf("property %s not found", property.Name)
}
foundProperty.Merge(property)
}
}
} else if isPropertyList(propertiesRaw) {
var properties pkg.Properties
if err := json.Unmarshal(propertiesRaw, &properties); err != nil {
return err
}
for _, comp := range components {
comp.Properties = append(comp.Properties, properties...)
}
}
return nil
}

type TopologyRunOptions struct {
*kommons.Client
Kubernetes kubernetes.Interface
Expand All @@ -364,7 +447,7 @@ func Run(opts TopologyRunOptions, t v1.Topology) []*pkg.Component {
ctx.JobHistory = jobHistory

var results pkg.Components
component := &pkg.Component{
rootComponent := &pkg.Component{
Name: ctx.Topology.Spec.Text,
Namespace: ctx.Topology.GetNamespace(),
Labels: ctx.Topology.Labels,
Expand All @@ -375,8 +458,8 @@ func Run(opts TopologyRunOptions, t v1.Topology) []*pkg.Component {
Schedule: ctx.Topology.Spec.Schedule,
}

if component.Name == "" {
component.Name = ctx.Topology.Name
if rootComponent.Name == "" {
rootComponent.Name = ctx.Topology.Name
}

ignoreLabels := []string{"kustomize.toolkit.fluxcd.io/name", "kustomize.toolkit.fluxcd.io/namespace"}
Expand Down Expand Up @@ -408,62 +491,69 @@ func Run(opts TopologyRunOptions, t v1.Topology) []*pkg.Component {
}
}
if comp.Lookup == nil {
component.Components = append(component.Components, components...)
rootComponent.Components = append(rootComponent.Components, components...)
continue
}

component.Components = append(component.Components, components...)
rootComponent.Components = append(rootComponent.Components, components...)
}
}

if len(component.Components) == 1 && component.Components[0].Type == "virtual" {
if len(rootComponent.Components) == 1 && rootComponent.Components[0].Type == "virtual" {
// if there is only one component and it is virtual, then we don't need to show it
ctx.Components = &component.Components[0].Components
ctx.Components = &rootComponent.Components[0].Components
return *ctx.Components
}

ctx.Components = &component.Components
ctx.Components = &rootComponent.Components

for _, property := range ctx.Topology.Spec.Properties {
// TODO Yash: Usecase for this
props, err := lookupProperty(ctx, &property)
if err != nil {
errMsg := fmt.Sprintf("Failed to lookup property %s: %v", property.Name, err)
logger.Errorf(errMsg)
jobHistory.AddError(errMsg)
continue
}
component.Properties = append(component.Properties, props...)
if err := mergeComponentProperties(pkg.Components{rootComponent}, props); err != nil {
errMsg := fmt.Sprintf("Failed to merge component property %s: %v", property.Name, err)
logger.Errorf(errMsg)
jobHistory.AddError(errMsg)
continue

Check failure on line 524 in pkg/topology/run.go

View workflow job for this annotation

GitHub Actions / lint

unnecessary trailing newline (whitespace)
}
}

if len(component.Components) > 0 {
component.Summary = component.Components.Summarize()
if len(rootComponent.Components) > 0 {
rootComponent.Summary = rootComponent.Components.Summarize()
}
if component.ID.String() == "" && ctx.Topology.Spec.Id != nil {
id, err := gomplate.RunTemplate(component.GetAsEnvironment(), ctx.Topology.Spec.Id.Gomplate())
if rootComponent.ID.String() == "" && ctx.Topology.Spec.Id != nil {
id, err := gomplate.RunTemplate(rootComponent.GetAsEnvironment(), ctx.Topology.Spec.Id.Gomplate())
if err != nil {
errMsg := fmt.Sprintf("Failed to lookup id: %v", err)
logger.Errorf(errMsg)
jobHistory.AddError(errMsg)
} else {
component.ID, _ = uuid.Parse(id)
rootComponent.ID, _ = uuid.Parse(id)
}
}

// TODO: Ask Moshe why we do this ?
if component.ID.String() == "" {
component.ID, _ = uuid.Parse(component.Name)
if rootComponent.ID.String() == "" {
rootComponent.ID, _ = uuid.Parse(rootComponent.Name)
}

if component.ExternalId == "" {
component.ExternalId = component.Name
if rootComponent.ExternalId == "" {
rootComponent.ExternalId = rootComponent.Name
}

component.Status = pkg.ComponentStatus(component.Summary.GetStatus())
rootComponent.Status = pkg.ComponentStatus(rootComponent.Summary.GetStatus())

logger.Debugf(component.Components.Debug(""))
logger.Debugf(rootComponent.Components.Debug(""))

results = append(results, component)
logger.Infof("%s id=%s external_id=%s status=%s", component.Name, component.ID, component.ExternalId, component.Status)
results = append(results, rootComponent)
logger.Infof("%s id=%s external_id=%s status=%s", rootComponent.Name, rootComponent.ID, rootComponent.ExternalId, rootComponent.Status)
for _, c := range results.Walk() {
if c.Namespace == "" {
c.Namespace = ctx.Topology.GetNamespace()
Expand Down

0 comments on commit 2f5902e

Please sign in to comment.