Skip to content

Commit

Permalink
feat: merge multiple property lookups (#2379)
Browse files Browse the repository at this point in the history
* feat: merge multiple property lookups

* chore: fix topology property test
  • Loading branch information
yashmehrotra authored Dec 23, 2024
1 parent 879df62 commit 91a57a0
Show file tree
Hide file tree
Showing 4 changed files with 98 additions and 3 deletions.
28 changes: 28 additions & 0 deletions fixtures/topology/component-with-property-list.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
apiVersion: canaries.flanksource.com/v1
kind: Topology
metadata:
name: test-topology-property-list
spec:
schedule: "@every 10m"
components:
- name: RootComponent
properties:
- name: error_percentage
min: 0

# Test property lookup merge as components
- name: error_percentage_lookup
lookup:
http:
- url: https://httpbin.demo.aws.flanksource.com/status/200
name: error_percentage_lookup_max
display:
expr: |
[
{'name': 'error_percentage', 'max': 100}
].toJSON()
- url: https://httpbin.demo.aws.flanksource.com/status/200
name: error_percentage_lookup_value
display:
expr: |
{'name': 'error_percentage', 'value': 10}.toJSON()
50 changes: 48 additions & 2 deletions pkg/topology/run.go
Original file line number Diff line number Diff line change
Expand Up @@ -318,6 +318,46 @@ func lookupProperty(ctx *ComponentContext, property *v1.Property) ([]byte, error
return nil, err
}

// Multiple results signify that the lookup has returned
// more than one property and they are flattened
if len(results) > 1 {
var props types.Properties
for _, r := range results {
var dataStr string
var ok bool
if dataStr, ok = r.(string); !ok {
return nil, fmt.Errorf("unknown property type %T", results)
}
dataStr = strings.TrimSpace(dataStr)
if strings.HasPrefix(dataStr, "[") && strings.HasSuffix(dataStr, "]") {
if isPropertyList([]byte(dataStr)) {
var prop types.Properties
if err := json.Unmarshal([]byte(dataStr), &prop); err != nil {
return nil, fmt.Errorf("error marshaling property: %w", err)
}
if prop != nil {
props = append(props, prop...)
}
}
} else {
var msa map[string]any
if err := json.Unmarshal([]byte(dataStr), &msa); err != nil {
return nil, fmt.Errorf("error unmarshaling: %w", err)
}
if isProperty(msa) {
var prop *types.Property
if err := json.Unmarshal([]byte(dataStr), &prop); err != nil {
return nil, fmt.Errorf("error marshaling property: %w", err)
}
if prop != nil {
props = append(props, prop)
}
}
}
}
return json.Marshal(props)
}

var dataStr string
var ok bool
if dataStr, ok = results[0].(string); !ok {
Expand Down Expand Up @@ -366,8 +406,14 @@ func mergeComponentProperties(components pkg.Components, propertiesRaw []byte) e
if err := json.Unmarshal(propertiesRaw, &properties); err != nil {
return err
}
for _, comp := range components {
comp.Properties = append(comp.Properties, properties...)
for _, p := range properties {
for _, comp := range components {
if cProp := comp.Properties.Find(p.Name); cProp == nil {
comp.Properties = append(comp.Properties, p)
} else {
cProp.Merge(p)
}
}
}
}
return nil
Expand Down
19 changes: 19 additions & 0 deletions pkg/topology/run_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -174,6 +174,25 @@ var _ = ginkgo.Describe("Topology run", ginkgo.Ordered, func() {
Expect(len(demoCluster.Components[0].Components)).To(Equal(1))
Expect(demoCluster.Components[0].Components[0].Name).To(Equal(lo.FromPtr(dummy.KubernetesNodeAKSPool1.Name)))
})

ginkgo.It("should correctly merge multiple property lookup", func() {
t, err := yamlFileToTopology("../../fixtures/topology/component-with-property-list.yml")
if err != nil {
ginkgo.Fail("Error converting yaml to v1.Topology:" + err.Error())
}

rootComponent, history, err := Run(DefaultContext.WithTrace(), *t)
Expect(err).To(BeNil())

Expect(history.Errors).To(HaveLen(0))

Expect(len(rootComponent[0].Components)).To(Equal(1))

componentA := rootComponent[0].Components[0]

Expect(string(componentA.Properties.AsJSON())).To(MatchJSON(`[{"name":"error_percentage","value":10,"min":0,"max":100}]`))
})

})

func yamlFileToTopology(file string) (*pkg.Topology, error) {
Expand Down
4 changes: 3 additions & 1 deletion pkg/topology/utils.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
package topology

import "strings"
import (
"strings"
)

func isComponent(s map[string]interface{}) bool {
_, name := s["name"]
Expand Down

0 comments on commit 91a57a0

Please sign in to comment.