diff --git a/metadata/interface.go b/metadata/interface.go index 4f860e91780b7b58c48000ea3aa62be98256b8fb..d4f5495b16a3bd6e47c098ccd0eb5d23b7d6097a 100644 --- a/metadata/interface.go +++ b/metadata/interface.go @@ -45,6 +45,7 @@ type Manager interface { CreateComponent(name string, text string, params map[string]string, templateType prototype.TemplateType) error LibPaths(envName string) (libPath, envLibPath, envComponentPath, envParamsPath AbsPath) SetComponentParams(component string, params map[string]string) error + GetComponentParams(name string) (map[string]string, error) CreateEnvironment(name, uri, namespace string, spec ClusterSpec) error DeleteEnvironment(name string) error GetEnvironments() ([]*Environment, error) @@ -57,7 +58,6 @@ type Manager interface { // GetPrototype(id string) Protoype // SearchPrototypes(query string) []Protoype // VendorLibrary(uri, version string) error - // GetComponentParams(name string) map[string]string // SetEnvironmentParams(component, env string, params map[string]string) error // GetEnvironmentParams(env string) (map[string]map[string]string, error) } diff --git a/metadata/manager.go b/metadata/manager.go index 10e63b8a4a6d921688763f7106c71f459808e887..fdcbd706d6a614da7225cb71e2d1f83dbfaf17d8 100644 --- a/metadata/manager.go +++ b/metadata/manager.go @@ -194,6 +194,15 @@ func (m *manager) LibPaths(envName string) (libPath, envLibPath, envComponentPat appendToAbsPath(envPath, path.Base(envName)+".jsonnet"), appendToAbsPath(envPath, componentParamsFile) } +func (m *manager) GetComponentParams(component string) (map[string]string, error) { + text, err := afero.ReadFile(m.appFS, string(m.componentParamsPath)) + if err != nil { + return nil, err + } + + return snippet.GetComponentParams(component, string(text)) +} + func (m *manager) SetComponentParams(component string, params map[string]string) error { text, err := afero.ReadFile(m.appFS, string(m.componentParamsPath)) if err != nil { diff --git a/metadata/snippet/interface.go b/metadata/snippet/interface.go index e5461e86a48b491945396986cdd17e31977f498e..7d6175cc8d33148502f7b5abe5759d8b8dea8ce7 100644 --- a/metadata/snippet/interface.go +++ b/metadata/snippet/interface.go @@ -26,6 +26,19 @@ func AppendComponent(component, snippet string, params map[string]string) (strin return appendComponent(component, snippet, params) } +// GetComponentParams takes +// +// component: the name of the component to retrieve params for. +// snippet: the jsonnet snippet containing the component parameters. +// +// and returns a map of key-value param pairs corresponding to that component. +// +// An error will be returned if the component is not found in the snippet. +func GetComponentParams(component, snippet string) (map[string]string, error) { + params, _, err := getComponentParams(component, snippet) + return params, err +} + // SetComponentParams takes // // component: the name of the new component to be modified. diff --git a/metadata/snippet/params.go b/metadata/snippet/params.go index a02a4d6fb58228b8f00b302bcca8adaf5014b884..c63917eb83d2eb32916738d93b85e96f952cbf35 100644 --- a/metadata/snippet/params.go +++ b/metadata/snippet/params.go @@ -148,31 +148,30 @@ func appendComponent(component, snippet string, params map[string]string) (strin return strings.Join(lines, "\n"), nil } -func setComponentParams(component, snippet string, params map[string]string) (string, error) { +func getComponentParams(component, snippet string) (map[string]string, *ast.LocationRange, error) { componentsNode, err := visitComponentsObj(component, snippet) if err != nil { - return "", err + return nil, nil, err } - var loc *ast.LocationRange - var currentParams map[string]string - switch n := (*componentsNode).(type) { case *ast.Object: for _, field := range n.Fields { if field.Id != nil && string(*field.Id) == component { - currentParams, loc, err = visitComponentParams(field.Expr2) - if err != nil { - return "", err - } + return visitComponentParams(field.Expr2) } } default: - return "", fmt.Errorf("Expected component node type to be object") + return nil, nil, fmt.Errorf("Expected component node type to be object") } - if loc == nil { - return "", fmt.Errorf("Could not find component identifier '%s' when attempting to set params", component) + return nil, nil, fmt.Errorf("Could not find component identifier '%s' when attempting to set params", component) +} + +func setComponentParams(component, snippet string, params map[string]string) (string, error) { + currentParams, loc, err := getComponentParams(component, snippet) + if err != nil { + return "", err } for k, v := range currentParams { diff --git a/metadata/snippet/params_test.go b/metadata/snippet/params_test.go index 9249a6f46cbcfa52caaec51d6fa0d4c903eae776..88765d70fcd7eed01cb20426fdeb39a4955b5b6d 100644 --- a/metadata/snippet/params_test.go +++ b/metadata/snippet/params_test.go @@ -16,6 +16,7 @@ package snippet import ( + "reflect" "testing" ) @@ -175,6 +176,96 @@ func TestAppendComponentParams(t *testing.T) { } } +func TestGetComponentParams(t *testing.T) { + tests := []struct { + componentName string + jsonnet string + expected map[string]string + }{ + // Test getting the parameters where there is a single component + { + "foo", + ` +{ + global: {}, + components: { + foo: { + name: "foo", + replicas: 1, + }, + }, +}`, + map[string]string{"name": `"foo"`, "replicas": "1"}, + }, + // Test getting the parameters where there are multiple components + { + "foo", + ` +{ + global: {}, + components: { + bar: { + replicas: 5 + }, + foo: { + name: "foo", + replicas: 1, + }, + }, +}`, + map[string]string{"name": `"foo"`, "replicas": "1"}, + }, + } + + errors := []struct { + componentName string + jsonnet string + }{ + // Test case where component doesn't exist + { + "baz", + ` +{ + components: { + foo: { + name: "foo", + }, + }, +}`, + }, + // Test case where components isn't a top level object + { + "baz", + ` +{ + global: { + // User-defined global parameters; accessible to all component and environments, Ex: + // replicas: 4, + components: {}, + }, +}`, + }, + } + + for _, s := range tests { + params, err := GetComponentParams(s.componentName, s.jsonnet) + if err != nil { + t.Errorf("Unexpected error\n input: %v\n error: %v", s.jsonnet, err) + } + + if !reflect.DeepEqual(params, s.expected) { + t.Errorf("Wrong conversion\n expected:%v\n got:%v", s.expected, params) + } + } + + for _, e := range errors { + params, err := GetComponentParams(e.componentName, e.jsonnet) + if err == nil { + t.Errorf("Expected error but not found\n input: %v got: %v", e, params) + } + } +} + func TestSetComponentParams(t *testing.T) { tests := []struct { componentName string