From f4bc380d4ceff74794a4af50ff36e84b2ab0bc6f Mon Sep 17 00:00:00 2001 From: Jesse Date: Fri, 22 Nov 2024 13:40:38 +0800 Subject: [PATCH 1/2] Catalog evaluate shows parent properties (#560) * catalog evaluate parent properties * fix typo --- .../config/catalog/catalogprovider.go | 54 ++++++++++++++++++- .../config/catalog/catalogprovider_test.go | 3 ++ .../scenarios/10.catalogEval/magefile.go | 10 ++++ .../manifest/catalog-catalog4.yaml | 13 +++++ .../10.catalogEval/manifest/eval04.yaml | 12 +++++ .../10.catalogEval/verify/manifest_test.go | 46 +++++++++++++++- 6 files changed, 136 insertions(+), 2 deletions(-) create mode 100644 test/integration/scenarios/10.catalogEval/manifest/catalog-catalog4.yaml create mode 100644 test/integration/scenarios/10.catalogEval/manifest/eval04.yaml diff --git a/api/pkg/apis/v1alpha1/providers/config/catalog/catalogprovider.go b/api/pkg/apis/v1alpha1/providers/config/catalog/catalogprovider.go index 63ca27597..bcc223a60 100644 --- a/api/pkg/apis/v1alpha1/providers/config/catalog/catalogprovider.go +++ b/api/pkg/apis/v1alpha1/providers/config/catalog/catalogprovider.go @@ -173,8 +173,9 @@ func (m *CatalogConfigProvider) ReadObject(ctx context.Context, object string, l return nil, err } errList := make([]error, 0) + allProperties, err := m.getCatalogPropertiesAll(ctx, catalog, namespace) ret := map[string]interface{}{} - for k, v := range catalog.Spec.Properties { + for k, v := range allProperties { tv, err := m.traceValue(ctx, v, localcontext, nil) if err != nil { // Wrap the error using fmt.Errorf("%w", err) @@ -198,6 +199,57 @@ func (m *CatalogConfigProvider) ReadObject(ctx context.Context, object string, l } } +func (m *CatalogConfigProvider) getCatalogPropertiesAll(ctx context.Context, catalog model.CatalogState, namespace string) (map[string]interface{}, error) { + ret := map[string]interface{}{} + if catalog.Spec.ParentName != "" { + metaName := utils.ConvertReferenceToObjectName(catalog.Spec.ParentName) + parent, err := m.ApiClient.GetCatalog(ctx, metaName, namespace, m.Config.User, m.Config.Password) + if err != nil { + return nil, err + } + parentProperties, err := m.getCatalogPropertiesAll(ctx, parent, namespace) + if err != nil { + return nil, err + } + for k, v := range parentProperties { + ret[k] = v + } + } + for k, v := range catalog.Spec.Properties { + // we should deep extend the properties + // if the property is a map, we should deep extend the map + // if the property is a list, we should deep extend the list + // if the property is a string, we should just set the string + // if the property is a number, we should just set the number + // if the property is a boolean, we should just set the boolean + // if the property is a null, we should just set the null + ret[k] = deepExtend(ret[k], v) + } + return ret, nil +} + +func deepExtend(dst, src interface{}) interface{} { + switch src := src.(type) { + case map[string]interface{}: + if dstMap, ok := dst.(map[string]interface{}); ok { + for k, v := range src { + // if the key is not in the dstMap, just set the key + if _, ok := dstMap[k]; !ok { + dstMap[k] = v + } else { + dstMap[k] = deepExtend(dstMap[k], v) + } + } + return dstMap + } + return src + case []interface{}: + return src + default: + return src + } +} + func (m *CatalogConfigProvider) traceValue(ctx context.Context, v interface{}, localcontext interface{}, dependencyList map[string]map[string]bool) (interface{}, error) { switch val := v.(type) { case string: diff --git a/api/pkg/apis/v1alpha1/providers/config/catalog/catalogprovider_test.go b/api/pkg/apis/v1alpha1/providers/config/catalog/catalogprovider_test.go index 96f62b7d8..4deb46673 100644 --- a/api/pkg/apis/v1alpha1/providers/config/catalog/catalogprovider_test.go +++ b/api/pkg/apis/v1alpha1/providers/config/catalog/catalogprovider_test.go @@ -169,6 +169,9 @@ func TestReadObject(t *testing.T) { Spec: &model.CatalogSpec{ Properties: map[string]interface{}{ "parentAttribute": "This is father", + "components": map[string]interface{}{ + "Name": "notaname", + }, }, }, } diff --git a/test/integration/scenarios/10.catalogEval/magefile.go b/test/integration/scenarios/10.catalogEval/magefile.go index 5238aac34..029588678 100644 --- a/test/integration/scenarios/10.catalogEval/magefile.go +++ b/test/integration/scenarios/10.catalogEval/magefile.go @@ -41,6 +41,7 @@ var ( "test/integration/scenarios/10.catalogEval/manifest/catalog-catalog.yaml", "test/integration/scenarios/10.catalogEval/manifest/catalog-catalog2.yaml", "test/integration/scenarios/10.catalogEval/manifest/catalog-catalog3.yaml", + "test/integration/scenarios/10.catalogEval/manifest/catalog-catalog4.yaml", } // Tests to run @@ -55,6 +56,8 @@ var ( testEvalUpdate = "test/integration/scenarios/10.catalogEval/manifest/evalUpdate.yaml" testEval03 = "test/integration/scenarios/10.catalogEval/manifest/eval03.yaml" + + testEval04 = "test/integration/scenarios/10.catalogEval/manifest/eval04.yaml" ) // Entry point for running the tests @@ -138,6 +141,13 @@ func DeployManifests() error { return err } + // create eval catalog evaluateevalcatalog04 + eval04C := filepath.Join(repoPath, testEval04) + err = shellcmd.Command(fmt.Sprintf("kubectl apply -f %s -n %s", eval04C, namespace)).Run() + if err != nil { + return err + } + return nil } diff --git a/test/integration/scenarios/10.catalogEval/manifest/catalog-catalog4.yaml b/test/integration/scenarios/10.catalogEval/manifest/catalog-catalog4.yaml new file mode 100644 index 000000000..a352a45c8 --- /dev/null +++ b/test/integration/scenarios/10.catalogEval/manifest/catalog-catalog4.yaml @@ -0,0 +1,13 @@ +apiVersion: federation.symphony/v1 +kind: Catalog +metadata: + name: evalcatalog-v-v4 +spec: + rootResource: evalcatalog + catalogType: catalog + parentName: evalcatalog:v1 + properties: + city: "${{$config('evalcatalog:v2','city')}}" + country: "${{$config('evalcatalog:v2','country')}}" + from: + state: Virginia \ No newline at end of file diff --git a/test/integration/scenarios/10.catalogEval/manifest/eval04.yaml b/test/integration/scenarios/10.catalogEval/manifest/eval04.yaml new file mode 100644 index 000000000..5ac4f572c --- /dev/null +++ b/test/integration/scenarios/10.catalogEval/manifest/eval04.yaml @@ -0,0 +1,12 @@ +apiVersion: federation.symphony/v1 +kind: CatalogEvalExpression +metadata: + name: evaluateevalcatalog04 + annotations: + management.azure.com/operationId: "3" +spec: + resourceRef: + apiGroup: federation.symphony + kind: Catalog + name: evalcatalog-v-v4 + namespace: default diff --git a/test/integration/scenarios/10.catalogEval/verify/manifest_test.go b/test/integration/scenarios/10.catalogEval/verify/manifest_test.go index 56630bc47..b650bddbc 100644 --- a/test/integration/scenarios/10.catalogEval/verify/manifest_test.go +++ b/test/integration/scenarios/10.catalogEval/verify/manifest_test.go @@ -44,7 +44,7 @@ func TestBasic_Catalogs(t *testing.T) { catalogs = append(catalogs, item.GetName()) } fmt.Printf("Catalogs: %v\n", catalogs) - if len(resources.Items) == 3 { + if len(resources.Items) == 4 { break } @@ -146,6 +146,50 @@ func Test_CatalogsEvals(t *testing.T) { require.NoError(t, err) require.Equal(t, "Sydney", city) + // check evaluateevalcatalog04 + retryWithTimeout(func() (any, error) { + evaluateevalcatalog, err = dyn.Resource(schema.GroupVersionResource{ + Group: "federation.symphony", + Version: "v1", + Resource: "catalogevalexpressions", + }).Namespace(namespace).Get(context.Background(), "evaluateevalcatalog04", metav1.GetOptions{}) + require.NoError(t, err) + status, _, err := unstructured.NestedString(evaluateevalcatalog.Object, "status", "actionStatus", "status") + require.NoError(t, err) + require.Contains(t, []string{"Succeeded", "Failed"}, status) + return evaluateevalcatalog, nil + }, time.Minute*1) + status, _, err = unstructured.NestedString(evaluateevalcatalog.Object, "status", "actionStatus", "output", "evaluationStatus") + require.NoError(t, err) + require.Equal(t, "Failed", status) + + address, _, err = unstructured.NestedString(evaluateevalcatalog.Object, "status", "actionStatus", "output", "address") + require.NoError(t, err) + require.Equal(t, "1st Avenue", address) + + city, _, err = unstructured.NestedString(evaluateevalcatalog.Object, "status", "actionStatus", "output", "city") + require.NoError(t, err) + require.Equal(t, "Sydney", city) + + zipcode, _, err = unstructured.NestedString(evaluateevalcatalog.Object, "status", "actionStatus", "output", "zipcode") + require.NoError(t, err) + require.Contains(t, zipcode, "Not Found") + + county, _, err = unstructured.NestedString(evaluateevalcatalog.Object, "status", "actionStatus", "output", "county") + require.NoError(t, err) + require.Contains(t, county, "Not Found") + + country, _, err = unstructured.NestedString(evaluateevalcatalog.Object, "status", "actionStatus", "output", "country") + require.NoError(t, err) + require.Equal(t, "Australia", country) + + fromCountry, _, err = unstructured.NestedString(evaluateevalcatalog.Object, "status", "actionStatus", "output", "from", "country") + require.NoError(t, err) + require.Equal(t, "Australia", fromCountry) + + fromState, _, err := unstructured.NestedString(evaluateevalcatalog.Object, "status", "actionStatus", "output", "from", "state") + require.NoError(t, err) + require.Equal(t, "Virginia", fromState) } func retryWithTimeout(fn func() (any, error), timeout time.Duration) (any, error) { From c3024715c0c8358261d6e02ed460abbd9e19b027 Mon Sep 17 00:00:00 2001 From: Oliver Kopp Date: Fri, 22 Nov 2024 11:45:48 +0100 Subject: [PATCH 2/2] Remove silent/quite from curl/wget at install.sh (#565) --- cli/install/install.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/cli/install/install.sh b/cli/install/install.sh index 9b4401df3..eed61b0b7 100644 --- a/cli/install/install.sh +++ b/cli/install/install.sh @@ -119,9 +119,9 @@ downloadFile() { echo "Downloading $DOWNLOAD_URL ..." if [ "$SYMPHONY_HTTP_REQUEST_CLI" == "curl" ]; then - curl -SsL "$DOWNLOAD_URL" -o "$ARTIFACT_TMP_FILE" + curl -SL "$DOWNLOAD_URL" -o "$ARTIFACT_TMP_FILE" else - wget -q -O "$ARTIFACT_TMP_FILE" "$DOWNLOAD_URL" + wget -O "$ARTIFACT_TMP_FILE" "$DOWNLOAD_URL" fi if [ ! -f "$ARTIFACT_TMP_FILE" ]; then