From 10347af2ecf3541f7403cad0959ad8ddd79f16fd Mon Sep 17 00:00:00 2001 From: Lency Qian Date: Thu, 30 May 2024 21:07:25 +0800 Subject: [PATCH 1/6] support versioning --- .../managers/configs/configs-manager.go | 18 +++++++---- .../v1alpha1/managers/jobs/jobs-manager.go | 4 ++- .../config/catalog/catalogprovider.go | 15 +++++++++- .../config/catalog/catalogprovider_test.go | 28 ++++++++--------- .../v1alpha1/providers/stage/create/create.go | 2 ++ .../stage/materialize/materialize.go | 5 +++- .../stage/materialize/materialize_test.go | 22 +++++++------- .../v1alpha1/providers/stage/patch/patch.go | 4 ++- .../v1alpha1/providers/stage/wait/wait.go | 3 ++ api/pkg/apis/v1alpha1/utils/symphony-api.go | 3 +- api/pkg/apis/v1alpha1/utils/utils.go | 17 +++++++++++ .../apis/v1alpha1/vendors/campaigns-vendor.go | 5 +--- .../v1alpha1/vendors/campaigns-vendor_test.go | 22 +++++++------- .../apis/v1alpha1/vendors/catalogs-vendor.go | 5 +--- .../v1alpha1/vendors/catalogs-vendor_test.go | 20 ++++++------- .../apis/v1alpha1/vendors/instances-vendor.go | 24 +++++---------- .../v1alpha1/vendors/instances-vendor_test.go | 30 +++++++++---------- .../apis/v1alpha1/vendors/solutions-vendor.go | 5 ++-- .../v1alpha1/vendors/solutions-vendor_test.go | 12 ++++---- api/pkg/apis/v1alpha1/vendors/stage-vendor.go | 10 +++++-- .../apis/v1alpha1/vendors/targets-vendor.go | 6 ++-- .../v1alpha1/vendors/targets-vendor_test.go | 24 +++++++-------- docs/samples/k8s/hello-world/instance.yaml | 6 ++-- docs/samples/k8s/hello-world/solution.yaml | 2 +- docs/samples/k8s/hello-world/target.yaml | 2 +- docs/samples/multisite/activation.yaml | 2 +- docs/samples/multisite/campaign.yaml | 2 +- docs/samples/multisite/catalog-catalog.yaml | 4 +-- docs/samples/multisite/instance-catalog.yaml | 4 +-- docs/samples/multisite/solution-catalog.yaml | 6 ++-- docs/samples/multisite/target-catalog.yaml | 2 +- .../solution/instance_controller.go | 15 ++++++++-- k8s/utils/symphony-api.go | 30 +++++++++++++++++-- .../manifestTemplates/oss/instance.yaml | 8 ++--- .../manifestTemplates/oss/solution.yaml | 2 +- .../manifestTemplates/oss/target.yaml | 4 +-- .../scenarios/02.basic/magefile.go | 14 +++++---- .../02.basic/manifest/oss/instance.yaml | 4 +-- .../manifest/oss/instance.yaml | 6 ++-- .../manifest/oss/solution.yaml | 2 +- .../manifest/oss/target.yaml | 2 +- .../verify/manifest_test.go | 2 +- .../04.workflow/manifest/activation.yaml | 2 +- .../04.workflow/manifest/campaign.yaml | 10 +++---- .../manifest/instance-catalog.yaml | 4 +-- .../scenarios/05.catalog/catalogs/asset.yaml | 2 +- .../scenarios/05.catalog/catalogs/config.yaml | 4 +-- .../05.catalog/catalogs/instance.yaml | 4 +-- .../scenarios/05.catalog/catalogs/schema.yaml | 2 +- .../05.catalog/catalogs/solution.yaml | 4 +-- .../scenarios/05.catalog/catalogs/target.yaml | 2 +- .../05.catalog/catalogs/wrongconfig.yaml | 4 +-- .../scenarios/05.catalog/magefile.go | 6 ++-- .../scenarios/06.ado/manifest/instance.yaml | 6 ++-- .../scenarios/06.ado/manifest/solution.yaml | 2 +- .../scenarios/06.ado/manifest/target.yaml | 2 +- 56 files changed, 267 insertions(+), 190 deletions(-) diff --git a/api/pkg/apis/v1alpha1/managers/configs/configs-manager.go b/api/pkg/apis/v1alpha1/managers/configs/configs-manager.go index 3a11695e5..48c5b5476 100644 --- a/api/pkg/apis/v1alpha1/managers/configs/configs-manager.go +++ b/api/pkg/apis/v1alpha1/managers/configs/configs-manager.go @@ -58,7 +58,8 @@ func (s *ConfigsManager) Init(context *contexts.VendorContext, cfg managers.Mana return nil } func (s *ConfigsManager) Get(object string, field string, overlays []string, localContext interface{}) (interface{}, error) { - if strings.Index(object, ":") > 0 { + log.Debugf(" M (Config): Get %v, config provider size %d", object, len(s.ConfigProviders)) + if strings.Index(object, ":") > 0 && len(s.ConfigProviders) > 1 { parts := strings.Split(object, ":") if len(parts) != 2 { return "", v1alpha2.NewCOAError(nil, fmt.Sprintf("Invalid object: %s", object), v1alpha2.BadRequest) @@ -122,7 +123,8 @@ func (s *ConfigsManager) getWithOverlay(provider config.IConfigProvider, object } func (s *ConfigsManager) GetObject(object string, overlays []string, localContext interface{}) (map[string]interface{}, error) { - if strings.Index(object, ":") > 0 { + log.Debugf(" M (Config): GetObject %v, config provider size %d", object, len(s.ConfigProviders)) + if strings.Index(object, ":") > 0 && len(s.ConfigProviders) > 1 { parts := strings.Split(object, ":") if len(parts) != 2 { return nil, v1alpha2.NewCOAError(nil, fmt.Sprintf("Invalid object: %s", object), v1alpha2.BadRequest) @@ -161,7 +163,8 @@ func (s *ConfigsManager) getObjectWithOverlay(provider config.IConfigProvider, o return provider.ReadObject(object, localContext) } func (s *ConfigsManager) Set(object string, field string, value interface{}) error { - if strings.Index(object, ":") > 0 { + log.Debugf(" M (Config): Set %v, config provider size %d", object, len(s.ConfigProviders)) + if strings.Index(object, ":") > 0 && len(s.ConfigProviders) > 1 { parts := strings.Split(object, ":") if len(parts) != 2 { return v1alpha2.NewCOAError(nil, fmt.Sprintf("Invalid object: %s", object), v1alpha2.BadRequest) @@ -186,7 +189,8 @@ func (s *ConfigsManager) Set(object string, field string, value interface{}) err return v1alpha2.NewCOAError(nil, fmt.Sprintf("Invalid config object or key: %s, %s", object, field), v1alpha2.BadRequest) } func (s *ConfigsManager) SetObject(object string, values map[string]interface{}) error { - if strings.Index(object, ":") > 0 { + log.Debugf(" M (Config): SetObject %v, config provider size %d", object, len(s.ConfigProviders)) + if strings.Index(object, ":") > 0 && len(s.ConfigProviders) > 1 { parts := strings.Split(object, ":") if len(parts) != 2 { return v1alpha2.NewCOAError(nil, fmt.Sprintf("Invalid object: %s", object), v1alpha2.BadRequest) @@ -211,7 +215,8 @@ func (s *ConfigsManager) SetObject(object string, values map[string]interface{}) return v1alpha2.NewCOAError(nil, fmt.Sprintf("Invalid config object: %s", object), v1alpha2.BadRequest) } func (s *ConfigsManager) Delete(object string, field string) error { - if strings.Index(object, ":") > 0 { + log.Debugf(" M (Config): Delete %v, config provider size %d", object, len(s.ConfigProviders)) + if strings.Index(object, ":") > 0 && len(s.ConfigProviders) > 1 { parts := strings.Split(object, ":") if len(parts) != 2 { return v1alpha2.NewCOAError(nil, fmt.Sprintf("Invalid object: %s", object), v1alpha2.BadRequest) @@ -236,7 +241,8 @@ func (s *ConfigsManager) Delete(object string, field string) error { return v1alpha2.NewCOAError(nil, fmt.Sprintf("Invalid config object or key: %s, %s", object, field), v1alpha2.BadRequest) } func (s *ConfigsManager) DeleteObject(object string) error { - if strings.Index(object, ":") > 0 { + log.Debugf(" M (Config): DeleteObject %v, config provider size %d", object, len(s.ConfigProviders)) + if strings.Index(object, ":") > 0 && len(s.ConfigProviders) > 1 { parts := strings.Split(object, ":") if len(parts) != 2 { return v1alpha2.NewCOAError(nil, fmt.Sprintf("Invalid object: %s", object), v1alpha2.BadRequest) diff --git a/api/pkg/apis/v1alpha1/managers/jobs/jobs-manager.go b/api/pkg/apis/v1alpha1/managers/jobs/jobs-manager.go index 9d41faa7a..b2c18b8e4 100644 --- a/api/pkg/apis/v1alpha1/managers/jobs/jobs-manager.go +++ b/api/pkg/apis/v1alpha1/managers/jobs/jobs-manager.go @@ -14,6 +14,7 @@ import ( "github.com/eclipse-symphony/symphony/api/pkg/apis/v1alpha1/model" "github.com/eclipse-symphony/symphony/api/pkg/apis/v1alpha1/utils" + api_utils "github.com/eclipse-symphony/symphony/api/pkg/apis/v1alpha1/utils" "github.com/eclipse-symphony/symphony/coa/pkg/apis/v1alpha2" "github.com/eclipse-symphony/symphony/coa/pkg/apis/v1alpha2/contexts" "github.com/eclipse-symphony/symphony/coa/pkg/apis/v1alpha2/managers" @@ -379,7 +380,8 @@ func (s *JobsManager) HandleJobEvent(ctx context.Context, event v1alpha2.Event) //get solution var solution model.SolutionState - solution, err = s.apiClient.GetSolution(ctx, instance.Spec.Solution, namespace, s.user, s.password) + solutionName := api_utils.ReplaceSeperator(instance.Spec.Solution) + solution, err = s.apiClient.GetSolution(ctx, solutionName, namespace, s.user, s.password) if err != nil { solution = model.SolutionState{ ObjectMeta: model.ObjectMeta{ diff --git a/api/pkg/apis/v1alpha1/providers/config/catalog/catalogprovider.go b/api/pkg/apis/v1alpha1/providers/config/catalog/catalogprovider.go index 1362a61e1..6ffdb5fde 100644 --- a/api/pkg/apis/v1alpha1/providers/config/catalog/catalogprovider.go +++ b/api/pkg/apis/v1alpha1/providers/config/catalog/catalogprovider.go @@ -14,13 +14,16 @@ import ( "github.com/eclipse-symphony/symphony/api/pkg/apis/v1alpha1/model" "github.com/eclipse-symphony/symphony/api/pkg/apis/v1alpha1/utils" + api_utils "github.com/eclipse-symphony/symphony/api/pkg/apis/v1alpha1/utils" "github.com/eclipse-symphony/symphony/coa/pkg/apis/v1alpha2" "github.com/eclipse-symphony/symphony/coa/pkg/apis/v1alpha2/contexts" "github.com/eclipse-symphony/symphony/coa/pkg/apis/v1alpha2/providers" coa_utils "github.com/eclipse-symphony/symphony/coa/pkg/apis/v1alpha2/utils" + "github.com/eclipse-symphony/symphony/coa/pkg/logger" ) var msLock sync.Mutex +var clog = logger.NewLogger("coa.runtime") type CatalogConfigProviderConfig struct { User string `json:"user"` @@ -87,6 +90,7 @@ func CatalogConfigProviderConfigFromMap(properties map[string]string) (CatalogCo return ret, nil } func (m *CatalogConfigProvider) unwindOverrides(override string, field string, namespace string) (string, error) { + override = api_utils.ReplaceSeperator(override) catalog, err := m.ApiClient.GetCatalog(context.TODO(), override, namespace, m.Config.User, m.Config.Password) if err != nil { return "", err @@ -104,8 +108,9 @@ func (m *CatalogConfigProvider) unwindOverrides(override string, field string, n return "", v1alpha2.NewCOAError(nil, fmt.Sprintf("field '%s' is not found in configuration '%s'", field, override), v1alpha2.NotFound) } func (m *CatalogConfigProvider) Read(object string, field string, localcontext interface{}) (interface{}, error) { + clog.Debug(" M (Catalog): Read, object: %s, field: %s", object, field) namespace := m.getNamespaceFromContext(localcontext) - + object = api_utils.ReplaceSeperator(object) catalog, err := m.ApiClient.GetCatalog(context.TODO(), object, namespace, m.Config.User, m.Config.Password) if err != nil { return "", err @@ -128,7 +133,9 @@ func (m *CatalogConfigProvider) Read(object string, field string, localcontext i } func (m *CatalogConfigProvider) ReadObject(object string, localcontext interface{}) (map[string]interface{}, error) { + clog.Debug(" M (Catalog): ReadObject, object: %s", object) namespace := m.getNamespaceFromContext(localcontext) + object = api_utils.ReplaceSeperator(object) catalog, err := m.ApiClient.GetCatalog(context.TODO(), object, namespace, m.Config.User, m.Config.Password) if err != nil { @@ -221,6 +228,7 @@ func (m *CatalogConfigProvider) traceValue(v interface{}, localcontext interface // TODO: IConfigProvider interface methods should be enhanced to accept namespace as a parameter // so we can get rid of getCatalogInDefaultNamespace. func (m *CatalogConfigProvider) Set(object string, field string, value interface{}) error { + clog.Debug(" M (Catalog): Set, object: %s, field: %s", object, field) catalog, err := m.getCatalogInDefaultNamespace(context.TODO(), object) if err != nil { return err @@ -230,6 +238,7 @@ func (m *CatalogConfigProvider) Set(object string, field string, value interface return m.ApiClient.UpsertCatalog(context.TODO(), object, data, m.Config.User, m.Config.Password) } func (m *CatalogConfigProvider) SetObject(object string, value map[string]interface{}) error { + clog.Debug(" M (Catalog): SetObject, object: %s", object) catalog, err := m.getCatalogInDefaultNamespace(context.TODO(), object) if err != nil { return err @@ -242,6 +251,7 @@ func (m *CatalogConfigProvider) SetObject(object string, value map[string]interf return m.ApiClient.UpsertCatalog(context.TODO(), object, data, m.Config.User, m.Config.Password) } func (m *CatalogConfigProvider) Remove(object string, field string) error { + clog.Debug(" M (Catalog): Remove, object: %s, field: %s", object, field) catlog, err := m.getCatalogInDefaultNamespace(context.TODO(), object) if err != nil { return err @@ -254,9 +264,12 @@ func (m *CatalogConfigProvider) Remove(object string, field string) error { return m.ApiClient.UpsertCatalog(context.TODO(), object, data, m.Config.User, m.Config.Password) } func (m *CatalogConfigProvider) RemoveObject(object string) error { + clog.Debug(" M (Catalog): RemoveObject, object: %s", object) + object = api_utils.ReplaceSeperator(object) return m.ApiClient.DeleteCatalog(context.TODO(), object, m.Config.User, m.Config.Password) } func (m *CatalogConfigProvider) getCatalogInDefaultNamespace(context context.Context, catalog string) (model.CatalogState, error) { + catalog = api_utils.ReplaceSeperator(catalog) return m.ApiClient.GetCatalog(context, catalog, "", m.Config.User, m.Config.Password) } 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 cc1ba829b..93b754a57 100644 --- a/api/pkg/apis/v1alpha1/providers/config/catalog/catalogprovider_test.go +++ b/api/pkg/apis/v1alpha1/providers/config/catalog/catalogprovider_test.go @@ -44,13 +44,13 @@ func TestRead(t *testing.T) { ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { var response interface{} switch r.URL.Path { - case "/catalogs/registry/catalog1": + case "/catalogs/registry/catalog1-v1": response = model.CatalogState{ ObjectMeta: model.ObjectMeta{ - Name: "catalog1", + Name: "catalog1-v1", }, Spec: &model.CatalogSpec{ - ParentName: "parent", + ParentName: "parent:v1", Properties: map[string]interface{}{ "components": []model.ComponentSpec{ { @@ -61,10 +61,10 @@ func TestRead(t *testing.T) { }, }, } - case "/catalogs/registry/parent": + case "/catalogs/registry/parent-v1": response = model.CatalogState{ ObjectMeta: model.ObjectMeta{ - Name: "parent", + Name: "parent-v1", }, Spec: &model.CatalogSpec{ Properties: map[string]interface{}{ @@ -94,7 +94,7 @@ func TestRead(t *testing.T) { } assert.Nil(t, err) - res, err := provider.Read("catalog1", "components", nil) + res, err := provider.Read("catalog1:v1", "components", nil) assert.Nil(t, err) data, err := json.Marshal(res) assert.Nil(t, err) @@ -103,13 +103,13 @@ func TestRead(t *testing.T) { assert.Nil(t, err) assert.Equal(t, "name", summary[0].Name) - res, err = provider.Read("catalog1", "parentAttribute", nil) + res, err = provider.Read("catalog1:v1", "parentAttribute", nil) assert.Nil(t, err) v, ok := res.(string) assert.True(t, ok) assert.Equal(t, "This is father", v) - res, err = provider.Read("catalog1", "notExist", nil) + res, err = provider.Read("catalog1:v1", "notExist", nil) coaErr := err.(v1alpha2.COAError) assert.Equal(t, v1alpha2.NotFound, coaErr.State) assert.Empty(t, res) @@ -119,13 +119,13 @@ func TestReadObject(t *testing.T) { ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { var response interface{} switch r.URL.Path { - case "/catalogs/registry/catalog1": + case "/catalogs/registry/catalog1-v1": response = model.CatalogState{ ObjectMeta: model.ObjectMeta{ - Name: "catalog1", + Name: "catalog1-v1", }, Spec: &model.CatalogSpec{ - ParentName: "parent", + ParentName: "parent:v1", Properties: map[string]interface{}{ "components": map[string]interface{}{ "Name": "name", @@ -134,10 +134,10 @@ func TestReadObject(t *testing.T) { }, }, } - case "/catalogs/registry/parent": + case "/catalogs/registry/parent-v1": response = model.CatalogState{ ObjectMeta: model.ObjectMeta{ - Name: "parent", + Name: "parent-v1", }, Spec: &model.CatalogSpec{ Properties: map[string]interface{}{ @@ -167,7 +167,7 @@ func TestReadObject(t *testing.T) { } assert.Nil(t, err) - res, err := provider.ReadObject("catalog1", nil) + res, err := provider.ReadObject("catalog1:v1", nil) assert.Nil(t, err) assert.Equal(t, "name", res["Name"]) } diff --git a/api/pkg/apis/v1alpha1/providers/stage/create/create.go b/api/pkg/apis/v1alpha1/providers/stage/create/create.go index 414c93b9d..d28206c37 100644 --- a/api/pkg/apis/v1alpha1/providers/stage/create/create.go +++ b/api/pkg/apis/v1alpha1/providers/stage/create/create.go @@ -18,6 +18,7 @@ import ( "github.com/eclipse-symphony/symphony/api/pkg/apis/v1alpha1/model" "github.com/eclipse-symphony/symphony/api/pkg/apis/v1alpha1/providers/stage" "github.com/eclipse-symphony/symphony/api/pkg/apis/v1alpha1/utils" + api_utils "github.com/eclipse-symphony/symphony/api/pkg/apis/v1alpha1/utils" "github.com/eclipse-symphony/symphony/coa/pkg/apis/v1alpha2" "github.com/eclipse-symphony/symphony/coa/pkg/apis/v1alpha2/contexts" "github.com/eclipse-symphony/symphony/coa/pkg/apis/v1alpha2/observability" @@ -135,6 +136,7 @@ func (i *CreateStageProvider) Process(ctx context.Context, mgrContext contexts.M if object != nil { oData, _ = json.Marshal(object) } + objectName = api_utils.ReplaceSeperator(objectName) lastSummaryMessage := "" switch objectType { case "instance": diff --git a/api/pkg/apis/v1alpha1/providers/stage/materialize/materialize.go b/api/pkg/apis/v1alpha1/providers/stage/materialize/materialize.go index 1b4932efc..ecfdaf690 100644 --- a/api/pkg/apis/v1alpha1/providers/stage/materialize/materialize.go +++ b/api/pkg/apis/v1alpha1/providers/stage/materialize/materialize.go @@ -16,6 +16,7 @@ import ( "github.com/eclipse-symphony/symphony/api/pkg/apis/v1alpha1/model" "github.com/eclipse-symphony/symphony/api/pkg/apis/v1alpha1/providers/stage" "github.com/eclipse-symphony/symphony/api/pkg/apis/v1alpha1/utils" + api_utils "github.com/eclipse-symphony/symphony/api/pkg/apis/v1alpha1/utils" "github.com/eclipse-symphony/symphony/coa/pkg/apis/v1alpha2" "github.com/eclipse-symphony/symphony/coa/pkg/apis/v1alpha2/contexts" "github.com/eclipse-symphony/symphony/coa/pkg/apis/v1alpha2/observability" @@ -105,7 +106,8 @@ func (i *MaterializeStageProvider) Process(ctx context.Context, mgrContext conte }) var err error = nil defer observ_utils.CloseSpanWithError(span, &err) - mLog.Info(" P (Materialize Processor): processing inputs") + mLog.Infof(" P (Materialize Processor): processing inputs, traceId: %s", span.SpanContext().TraceID().String()) + outputs := make(map[string]interface{}) objects, ok := inputs["names"].([]interface{}) @@ -142,6 +144,7 @@ func (i *MaterializeStageProvider) Process(ctx context.Context, mgrContext conte creationCount := 0 for _, catalog := range catalogs { for _, object := range prefixedNames { + object := api_utils.ReplaceSeperator(object) if catalog.ObjectMeta.Name == object { objectData, _ := json.Marshal(catalog.Spec.Properties) //TODO: handle errors name := catalog.ObjectMeta.Name diff --git a/api/pkg/apis/v1alpha1/providers/stage/materialize/materialize_test.go b/api/pkg/apis/v1alpha1/providers/stage/materialize/materialize_test.go index db19a196c..8cbd4ed32 100644 --- a/api/pkg/apis/v1alpha1/providers/stage/materialize/materialize_test.go +++ b/api/pkg/apis/v1alpha1/providers/stage/materialize/materialize_test.go @@ -82,7 +82,7 @@ func TestMaterializeProcessWithStageNs(t *testing.T) { }, }) _, paused, err := provider.Process(context.Background(), contexts.ManagerContext{}, map[string]interface{}{ - "names": []interface{}{"instance1", "target1", "solution1", "catalog1"}, + "names": []interface{}{"instance1:v1", "target1:v1", "solution1:v1", "catalog1:v1"}, "__origin": "hq", "objectNamespace": stageNs, }) @@ -107,7 +107,7 @@ func TestMaterializeProcessWithoutStageNs(t *testing.T) { }, }) _, paused, err := provider.Process(context.Background(), contexts.ManagerContext{}, map[string]interface{}{ - "names": []interface{}{"instance1", "target1", "solution1", "catalog1"}, + "names": []interface{}{"instance1:v1", "target1:v1", "solution1:v1", "catalog1:v1"}, "__origin": "hq", }) assert.Nil(t, err) @@ -127,7 +127,7 @@ func TestMaterializeProcessFailedCase(t *testing.T) { assert.Nil(t, err) _, _, err = provider.Process(context.Background(), contexts.ManagerContext{}, map[string]interface{}{ - "names": []interface{}{"instance1", "target1", "solution1, target2"}, + "names": []interface{}{"instance1:v1", "target1:v1", "solution1:v1, target2:v1"}, "__origin": "hq", }) assert.NotNil(t, err) @@ -145,19 +145,19 @@ func InitializeMockSymphonyAPI(t *testing.T, expectNs string) *httptest.Server { var response interface{} body, _ := io.ReadAll(r.Body) switch r.URL.Path { - case "/instances/instance1": + case "/instances/instance1-v1": var instance model.InstanceState err := json.Unmarshal(body, &instance) assert.Nil(t, err) assert.Equal(t, expectNs, instance.ObjectMeta.Namespace) response = instance - case "/targets/registry/target1": + case "/targets/registry/target1-v1": var target model.TargetState err := json.Unmarshal(body, &target) assert.Nil(t, err) assert.Equal(t, expectNs, target.ObjectMeta.Namespace) response = target - case "/solutions/solution1": + case "/solutions/solution1-v1": var solution model.SolutionState err := json.Unmarshal(body, &solution) assert.Nil(t, err) @@ -167,7 +167,7 @@ func InitializeMockSymphonyAPI(t *testing.T, expectNs string) *httptest.Server { response = []model.CatalogState{ { ObjectMeta: model.ObjectMeta{ - Name: "hq-target1", + Name: "hq-target1-v1", }, Spec: &model.CatalogSpec{ Type: "target", @@ -183,7 +183,7 @@ func InitializeMockSymphonyAPI(t *testing.T, expectNs string) *httptest.Server { }, { ObjectMeta: model.ObjectMeta{ - Name: "hq-instance1", + Name: "hq-instance1-v1", }, Spec: &model.CatalogSpec{ Type: "instance", @@ -198,7 +198,7 @@ func InitializeMockSymphonyAPI(t *testing.T, expectNs string) *httptest.Server { }, { ObjectMeta: model.ObjectMeta{ - Name: "hq-solution1", + Name: "hq-solution1-v1", }, Spec: &model.CatalogSpec{ Type: "solution", @@ -214,7 +214,7 @@ func InitializeMockSymphonyAPI(t *testing.T, expectNs string) *httptest.Server { }, { ObjectMeta: model.ObjectMeta{ - Name: "hq-catalog1", + Name: "hq-catalog1-v1", }, Spec: &model.CatalogSpec{ Type: "catalog", @@ -231,7 +231,7 @@ func InitializeMockSymphonyAPI(t *testing.T, expectNs string) *httptest.Server { }, }, } - case "catalogs/registry/catalog1": + case "catalogs/registry/catalog1-v1": var catalog model.CatalogState err := json.Unmarshal(body, &catalog) assert.Nil(t, err) diff --git a/api/pkg/apis/v1alpha1/providers/stage/patch/patch.go b/api/pkg/apis/v1alpha1/providers/stage/patch/patch.go index 6f057c71a..7c1ec06ac 100644 --- a/api/pkg/apis/v1alpha1/providers/stage/patch/patch.go +++ b/api/pkg/apis/v1alpha1/providers/stage/patch/patch.go @@ -14,6 +14,7 @@ import ( "github.com/eclipse-symphony/symphony/api/pkg/apis/v1alpha1/model" "github.com/eclipse-symphony/symphony/api/pkg/apis/v1alpha1/providers/stage" "github.com/eclipse-symphony/symphony/api/pkg/apis/v1alpha1/utils" + api_utils "github.com/eclipse-symphony/symphony/api/pkg/apis/v1alpha1/utils" "github.com/eclipse-symphony/symphony/coa/pkg/apis/v1alpha2" "github.com/eclipse-symphony/symphony/coa/pkg/apis/v1alpha2/contexts" "github.com/eclipse-symphony/symphony/coa/pkg/apis/v1alpha2/observability" @@ -141,7 +142,7 @@ func (i *PatchStageProvider) Process(ctx context.Context, mgrContext contexts.Ma outputs := make(map[string]interface{}) objectType := stage.ReadInputString(inputs, "objectType") - objectName := stage.ReadInputString(inputs, "objectName") + objectName := api_utils.ReplaceSeperator(stage.ReadInputString(inputs, "objectName")) patchSource := stage.ReadInputString(inputs, "patchSource") var patchContent interface{} if v, ok := inputs["patchContent"]; ok { @@ -166,6 +167,7 @@ func (i *PatchStageProvider) Process(ctx context.Context, mgrContext contexts.Ma switch patchSource { case "", "catalog": if v, ok := patchContent.(string); ok { + v := api_utils.ReplaceSeperator(v) catalog, err = i.ApiClient.GetCatalog(ctx, v, objectNamespace, i.Config.User, i.Config.Password) if err != nil { diff --git a/api/pkg/apis/v1alpha1/providers/stage/wait/wait.go b/api/pkg/apis/v1alpha1/providers/stage/wait/wait.go index a4b13cb75..0eda02884 100644 --- a/api/pkg/apis/v1alpha1/providers/stage/wait/wait.go +++ b/api/pkg/apis/v1alpha1/providers/stage/wait/wait.go @@ -18,6 +18,7 @@ import ( "github.com/eclipse-symphony/symphony/api/pkg/apis/v1alpha1/model" "github.com/eclipse-symphony/symphony/api/pkg/apis/v1alpha1/providers/stage" "github.com/eclipse-symphony/symphony/api/pkg/apis/v1alpha1/utils" + api_utils "github.com/eclipse-symphony/symphony/api/pkg/apis/v1alpha1/utils" "github.com/eclipse-symphony/symphony/coa/pkg/apis/v1alpha2" "github.com/eclipse-symphony/symphony/coa/pkg/apis/v1alpha2/contexts" "github.com/eclipse-symphony/symphony/coa/pkg/apis/v1alpha2/observability" @@ -184,6 +185,7 @@ func (i *WaitStageProvider) Process(ctx context.Context, mgrContext contexts.Man } for _, instance := range instances { for _, object := range prefixedNames { + object = api_utils.ReplaceSeperator(object) if instance.ObjectMeta.Name == object { foundCount++ } @@ -212,6 +214,7 @@ func (i *WaitStageProvider) Process(ctx context.Context, mgrContext contexts.Man } for _, catalog := range catalogs { for _, object := range prefixedNames { + object = api_utils.ReplaceSeperator(object) if catalog.ObjectMeta.Name == object { foundCount++ } diff --git a/api/pkg/apis/v1alpha1/utils/symphony-api.go b/api/pkg/apis/v1alpha1/utils/symphony-api.go index 2820825f6..b89cf2791 100644 --- a/api/pkg/apis/v1alpha1/utils/symphony-api.go +++ b/api/pkg/apis/v1alpha1/utils/symphony-api.go @@ -642,7 +642,8 @@ func MatchTargets(instance model.InstanceState, targets []model.TargetState) []m ret := make(map[string]model.TargetState) if instance.Spec.Target.Name != "" { for _, t := range targets { - if matchString(instance.Spec.Target.Name, t.ObjectMeta.Name) { + targetName := ReplaceSeperator(instance.Spec.Target.Name) + if matchString(targetName, t.ObjectMeta.Name) { ret[t.ObjectMeta.Name] = t } } diff --git a/api/pkg/apis/v1alpha1/utils/utils.go b/api/pkg/apis/v1alpha1/utils/utils.go index 32714efae..670857bfd 100644 --- a/api/pkg/apis/v1alpha1/utils/utils.go +++ b/api/pkg/apis/v1alpha1/utils/utils.go @@ -10,6 +10,7 @@ import ( "bytes" "encoding/json" "fmt" + "net/url" "os" "regexp" "strconv" @@ -319,3 +320,19 @@ func jsonPathQuery(obj interface{}, jsonPath string) (interface{}, error) { return result, nil } } + +func GetUnescapaedString(name string) (string, error) { + unescapedId, err := url.PathUnescape(name) + if err != nil { + return "", err + } + id := ReplaceSeperator(unescapedId) + return id, nil +} + +func ReplaceSeperator(name string) string { + if strings.Contains(name, ":") { + name = strings.ReplaceAll(name, ":", "-") + } + return name +} diff --git a/api/pkg/apis/v1alpha1/vendors/campaigns-vendor.go b/api/pkg/apis/v1alpha1/vendors/campaigns-vendor.go index ce8cf30e6..255610463 100644 --- a/api/pkg/apis/v1alpha1/vendors/campaigns-vendor.go +++ b/api/pkg/apis/v1alpha1/vendors/campaigns-vendor.go @@ -77,6 +77,7 @@ func (c *CampaignsVendor) onCampaigns(request v1alpha2.COARequest) v1alpha2.COAR defer span.End() cLog.Infof("V (Campaigns): onCampaigns, method: %s, traceId: %s", string(request.Method), span.SpanContext().TraceID().String()) + id := request.Parameters["__name"] namespace, namespaceSupplied := request.Parameters["namespace"] if !namespaceSupplied { namespace = "default" @@ -85,7 +86,6 @@ func (c *CampaignsVendor) onCampaigns(request v1alpha2.COARequest) v1alpha2.COAR switch request.Method { case fasthttp.MethodGet: ctx, span := observability.StartSpan("onCampaigns-GET", pCtx, nil) - id := request.Parameters["__name"] var err error var state interface{} isArray := false @@ -117,8 +117,6 @@ func (c *CampaignsVendor) onCampaigns(request v1alpha2.COARequest) v1alpha2.COAR return resp case fasthttp.MethodPost: ctx, span := observability.StartSpan("onCampaigns-POST", pCtx, nil) - id := request.Parameters["__name"] - var campaign model.CampaignState err := json.Unmarshal(request.Body, &campaign) @@ -143,7 +141,6 @@ func (c *CampaignsVendor) onCampaigns(request v1alpha2.COARequest) v1alpha2.COAR }) case fasthttp.MethodDelete: ctx, span := observability.StartSpan("onCampaigns-DELETE", pCtx, nil) - id := request.Parameters["__name"] err := c.CampaignsManager.DeleteState(ctx, id, namespace) if err != nil { cLog.Infof("V (Campaigns): onCampaigns failed - %s, traceId: %s", err.Error(), span.SpanContext().TraceID().String()) diff --git a/api/pkg/apis/v1alpha1/vendors/campaigns-vendor_test.go b/api/pkg/apis/v1alpha1/vendors/campaigns-vendor_test.go index 4e26a4cd2..b371da74b 100644 --- a/api/pkg/apis/v1alpha1/vendors/campaigns-vendor_test.go +++ b/api/pkg/apis/v1alpha1/vendors/campaigns-vendor_test.go @@ -75,7 +75,7 @@ func TestCampaignsOnCampaigns(t *testing.T) { Method: fasthttp.MethodPost, Body: data, Parameters: map[string]string{ - "__name": "campaign1", + "__name": "campaign1-v1", }, Context: context.Background(), }) @@ -84,7 +84,7 @@ func TestCampaignsOnCampaigns(t *testing.T) { resp = vendor.onCampaigns(v1alpha2.COARequest{ Method: fasthttp.MethodGet, Parameters: map[string]string{ - "__name": "campaign1", + "__name": "campaign1-v1", }, Context: context.Background(), }) @@ -92,7 +92,7 @@ func TestCampaignsOnCampaigns(t *testing.T) { var campaign model.CampaignState err := json.Unmarshal(resp.Body, &campaign) assert.Nil(t, err) - assert.Equal(t, "campaign1", campaign.ObjectMeta.Name) + assert.Equal(t, "campaign1-v1", campaign.ObjectMeta.Name) resp = vendor.onCampaigns(v1alpha2.COARequest{ Method: fasthttp.MethodGet, @@ -103,12 +103,12 @@ func TestCampaignsOnCampaigns(t *testing.T) { err = json.Unmarshal(resp.Body, &campaigns) assert.Nil(t, err) assert.Equal(t, 1, len(campaigns)) - assert.Equal(t, "campaign1", campaigns[0].ObjectMeta.Name) + assert.Equal(t, "campaign1-v1", campaigns[0].ObjectMeta.Name) resp = vendor.onCampaigns(v1alpha2.COARequest{ Method: fasthttp.MethodDelete, Parameters: map[string]string{ - "__name": "campaign1", + "__name": "campaign1-v1", }, Context: context.Background(), }) @@ -122,18 +122,18 @@ func TestCampaignsOnCampaignsFailure(t *testing.T) { Method: fasthttp.MethodGet, Body: data, Parameters: map[string]string{ - "__name": "campaign1", + "__name": "campaign1-v1", }, Context: context.Background(), }) assert.Equal(t, v1alpha2.InternalError, resp.State) - assert.Equal(t, "Not Found: entry 'campaign1' is not found in namespace default", string(resp.Body)) + assert.Equal(t, "Not Found: entry 'campaign1-v1' is not found in namespace default", string(resp.Body)) resp = vendor.onCampaigns(v1alpha2.COARequest{ Method: fasthttp.MethodPost, Body: []byte("bad data"), Parameters: map[string]string{ - "__name": "campaign1", + "__name": "campaign1-v1", }, Context: context.Background(), }) @@ -144,12 +144,12 @@ func TestCampaignsOnCampaignsFailure(t *testing.T) { Method: fasthttp.MethodDelete, Body: data, Parameters: map[string]string{ - "__name": "campaign1", + "__name": "campaign1-v1", }, Context: context.Background(), }) assert.Equal(t, v1alpha2.InternalError, resp.State) - assert.Equal(t, "Not Found: entry 'campaign1' is not found in namespace default", string(resp.Body)) + assert.Equal(t, "Not Found: entry 'campaign1-v1' is not found in namespace default", string(resp.Body)) } func TestCampaignsWrongMethod(t *testing.T) { @@ -160,7 +160,7 @@ func TestCampaignsWrongMethod(t *testing.T) { Method: fasthttp.MethodPut, Body: data, Parameters: map[string]string{ - "__name": "campaign1", + "__name": "campaign1-v1", }, Context: context.Background(), }) diff --git a/api/pkg/apis/v1alpha1/vendors/catalogs-vendor.go b/api/pkg/apis/v1alpha1/vendors/catalogs-vendor.go index b57ea3b2a..6a8b8bce1 100644 --- a/api/pkg/apis/v1alpha1/vendors/catalogs-vendor.go +++ b/api/pkg/apis/v1alpha1/vendors/catalogs-vendor.go @@ -229,7 +229,6 @@ func (e *CatalogsVendor) onCatalogsGraph(request v1alpha2.COARequest) v1alpha2.C defer span.End() lLog.Infof("V (Catalogs Vendor): onCatalogsGraph, method: %s, traceId: %s", string(request.Method), span.SpanContext().TraceID().String()) - namespace, namesapceSupplied := request.Parameters["namespace"] if !namesapceSupplied { namespace = "" @@ -295,6 +294,7 @@ func (e *CatalogsVendor) onCatalogs(request v1alpha2.COARequest) v1alpha2.COARes lLog.Infof("V (Catalogs Vendor): onCatalogs, method: %s, traceId: %s", string(request.Method), span.SpanContext().TraceID().String()) + id := request.Parameters["__name"] namespace, namesapceSupplied := request.Parameters["namespace"] if !namesapceSupplied { namespace = "default" @@ -303,7 +303,6 @@ func (e *CatalogsVendor) onCatalogs(request v1alpha2.COARequest) v1alpha2.COARes switch request.Method { case fasthttp.MethodGet: ctx, span := observability.StartSpan("onCatalogs-GET", pCtx, nil) - id := request.Parameters["__name"] var err error var state interface{} isArray := false @@ -341,7 +340,6 @@ func (e *CatalogsVendor) onCatalogs(request v1alpha2.COARequest) v1alpha2.COARes return resp case fasthttp.MethodPost: ctx, span := observability.StartSpan("onCatalogs-POST", pCtx, nil) - id := request.Parameters["__name"] if id == "" { return observ_utils.CloseSpanWithCOAResponse(span, v1alpha2.COAResponse{ State: v1alpha2.BadRequest, @@ -370,7 +368,6 @@ func (e *CatalogsVendor) onCatalogs(request v1alpha2.COARequest) v1alpha2.COARes }) case fasthttp.MethodDelete: ctx, span := observability.StartSpan("onCatalogs-DELETE", pCtx, nil) - id := request.Parameters["__name"] err := e.CatalogsManager.DeleteState(ctx, id, namespace) if err != nil { return observ_utils.CloseSpanWithCOAResponse(span, v1alpha2.COAResponse{ diff --git a/api/pkg/apis/v1alpha1/vendors/catalogs-vendor_test.go b/api/pkg/apis/v1alpha1/vendors/catalogs-vendor_test.go index 84852b593..b42114cf4 100644 --- a/api/pkg/apis/v1alpha1/vendors/catalogs-vendor_test.go +++ b/api/pkg/apis/v1alpha1/vendors/catalogs-vendor_test.go @@ -25,7 +25,7 @@ import ( var catalogState = model.CatalogState{ ObjectMeta: model.ObjectMeta{ - Name: "name1", + Name: "name1-v1", }, Spec: &model.CatalogSpec{ Type: "catalog", @@ -198,7 +198,7 @@ func TestCatalogOnCheck(t *testing.T) { assert.Equal(t, v1alpha2.InternalError, response.State) catalogState.ObjectMeta = model.ObjectMeta{ - Name: "test1", + Name: "test1-v1", } catalogState.Spec.Metadata = map[string]string{ "schema": "EmailCheckSchema", @@ -231,7 +231,7 @@ func TestCatalogOnCheck(t *testing.T) { response = vendor.onCatalogs(*requestPost) assert.Equal(t, v1alpha2.OK, response.State) - catalogState.ObjectMeta.Name = "test1" + catalogState.ObjectMeta.Name = "test1-v1" catalogState.Spec.Metadata = map[string]string{ "schema": "EmailCheckSchema", } @@ -264,14 +264,14 @@ func TestCatalogOnCatalogsGet(t *testing.T) { Method: fasthttp.MethodGet, Context: context.Background(), Parameters: map[string]string{ - "__name": "test1", + "__name": "test1-v1", }, } response := vendor.onCatalogs(*requestGet) assert.Equal(t, v1alpha2.NotFound, response.State) - catalogState.ObjectMeta.Name = "test1" + catalogState.ObjectMeta.Name = "test1-v1" b, err := json.Marshal(catalogState) assert.Nil(t, err) requestPost := &v1alpha2.COARequest{ @@ -319,7 +319,7 @@ func TestCatalogOnCatalogsPost(t *testing.T) { response := vendor.onCatalogs(*requestPost) assert.Equal(t, v1alpha2.InternalError, response.State) - catalogState.ObjectMeta.Name = "test1" + catalogState.ObjectMeta.Name = "test1-v1" b, err := json.Marshal(catalogState) assert.Nil(t, err) requestPost.Body = b @@ -337,7 +337,7 @@ func TestCatalogOnCatalogsPost(t *testing.T) { Method: fasthttp.MethodGet, Context: context.Background(), Parameters: map[string]string{ - "__name": "test1", + "__name": "test1-v1", }, } response = vendor.onCatalogs(*requestGet) @@ -359,7 +359,7 @@ func TestCatalogOnCatalogsDelete(t *testing.T) { }, } - catalogState.ObjectMeta.Name = "test1" + catalogState.ObjectMeta.Name = "test1-v1" b, err := json.Marshal(catalogState) assert.Nil(t, err) requestPost.Body = b @@ -376,7 +376,7 @@ func TestCatalogOnCatalogsDelete(t *testing.T) { Method: fasthttp.MethodDelete, Context: context.Background(), Parameters: map[string]string{ - "__name": "test1", + "__name": "test1-v1", }, } response = vendor.onCatalogs(*requestDelete) @@ -386,7 +386,7 @@ func TestCatalogOnCatalogsDelete(t *testing.T) { Method: fasthttp.MethodGet, Context: context.Background(), Parameters: map[string]string{ - "__name": "test1", + "__name": "test1-v1", }, } response = vendor.onCatalogs(*requestGet) diff --git a/api/pkg/apis/v1alpha1/vendors/instances-vendor.go b/api/pkg/apis/v1alpha1/vendors/instances-vendor.go index f3de309c0..cff6ba40b 100644 --- a/api/pkg/apis/v1alpha1/vendors/instances-vendor.go +++ b/api/pkg/apis/v1alpha1/vendors/instances-vendor.go @@ -77,16 +77,18 @@ func (c *InstancesVendor) onInstances(request v1alpha2.COARequest) v1alpha2.COAR "method": "onInstances", }) defer span.End() + iLog.Infof("V (Instances): onInstances, method: %s, traceId: %s", request.Method, span.SpanContext().TraceID().String()) + + id := request.Parameters["__name"] + namespace, exist := request.Parameters["namespace"] + if !exist { + namespace = constants.DefaultScope + } iLog.Infof("V (Instances): onInstances, method: %s, traceId: %s", string(request.Method), span.SpanContext().TraceID().String()) switch request.Method { case fasthttp.MethodGet: ctx, span := observability.StartSpan("onInstances-GET", pCtx, nil) - id := request.Parameters["__name"] - namespace, exist := request.Parameters["namespace"] - if !exist { - namespace = constants.DefaultScope - } var err error var state interface{} isArray := false @@ -101,7 +103,7 @@ func (c *InstancesVendor) onInstances(request v1alpha2.COARequest) v1alpha2.COAR state, err = c.InstancesManager.GetState(ctx, id, namespace) } if err != nil { - iLog.Infof("V (Instances): onInstances failed - %s, traceId: %s", err.Error(), span.SpanContext().TraceID().String()) + iLog.Errorf("V (Instances): onInstances failed - %s, traceId: %s", err.Error(), span.SpanContext().TraceID().String()) return observ_utils.CloseSpanWithCOAResponse(span, v1alpha2.COAResponse{ State: v1alpha2.InternalError, Body: []byte(err.Error()), @@ -119,11 +121,6 @@ func (c *InstancesVendor) onInstances(request v1alpha2.COARequest) v1alpha2.COAR return resp case fasthttp.MethodPost: ctx, span := observability.StartSpan("onInstances-POST", pCtx, nil) - id := request.Parameters["__name"] - namespace, exist := request.Parameters["namespace"] - if !exist { - namespace = constants.DefaultScope - } solution := request.Parameters["solution"] target := request.Parameters["target"] target_selector := request.Parameters["target-selector"] @@ -199,12 +196,7 @@ func (c *InstancesVendor) onInstances(request v1alpha2.COARequest) v1alpha2.COAR }) case fasthttp.MethodDelete: ctx, span := observability.StartSpan("onInstances-DELETE", pCtx, nil) - id := request.Parameters["__name"] direct := request.Parameters["direct"] - namespace, exist := request.Parameters["namespace"] - if !exist { - namespace = constants.DefaultScope - } if c.Config.Properties["useJobManager"] == "true" && direct != "true" { c.Context.Publish("job", v1alpha2.Event{ Metadata: map[string]string{ diff --git a/api/pkg/apis/v1alpha1/vendors/instances-vendor_test.go b/api/pkg/apis/v1alpha1/vendors/instances-vendor_test.go index 31a2b27c9..f2a518fd9 100644 --- a/api/pkg/apis/v1alpha1/vendors/instances-vendor_test.go +++ b/api/pkg/apis/v1alpha1/vendors/instances-vendor_test.go @@ -87,7 +87,7 @@ func TestInstancesOnInstances(t *testing.T) { err := json.Unmarshal(jData, &job) assert.Nil(t, err) assert.Equal(t, "instance", event.Metadata["objectType"]) - assert.Equal(t, "instance1", job.Id) + assert.Equal(t, "instance1-v1", job.Id) assert.Equal(t, true, job.Action == v1alpha2.JobUpdate || job.Action == v1alpha2.JobDelete) succeededCount += 1 sig <- true @@ -99,9 +99,9 @@ func TestInstancesOnInstances(t *testing.T) { Method: fasthttp.MethodPost, Body: data, Parameters: map[string]string{ - "__name": "instance1", - "target": "target1", - "solution": "solution1", + "__name": "instance1-v1", + "target": "target1-v1", + "solution": "solution1-v1", }, Context: context.Background(), }) @@ -111,7 +111,7 @@ func TestInstancesOnInstances(t *testing.T) { resp = vendor.onInstances(v1alpha2.COARequest{ Method: fasthttp.MethodGet, Parameters: map[string]string{ - "__name": "instance1", + "__name": "instance1-v1", }, Context: context.Background(), }) @@ -119,8 +119,8 @@ func TestInstancesOnInstances(t *testing.T) { err := json.Unmarshal(resp.Body, &instance) assert.Nil(t, err) assert.Equal(t, v1alpha2.OK, resp.State) - assert.Equal(t, "instance1", instance.ObjectMeta.Name) - assert.Equal(t, "target1", instance.Spec.Target.Name) + assert.Equal(t, "instance1-v1", instance.ObjectMeta.Name) + assert.Equal(t, "target1-v1", instance.Spec.Target.Name) resp = vendor.onInstances(v1alpha2.COARequest{ Method: fasthttp.MethodGet, @@ -131,13 +131,13 @@ func TestInstancesOnInstances(t *testing.T) { assert.Nil(t, err) assert.Equal(t, v1alpha2.OK, resp.State) assert.Equal(t, 1, len(instances)) - assert.Equal(t, "instance1", instances[0].ObjectMeta.Name) - assert.Equal(t, "target1", instances[0].Spec.Target.Name) + assert.Equal(t, "instance1-v1", instances[0].ObjectMeta.Name) + assert.Equal(t, "target1-v1", instances[0].Spec.Target.Name) resp = vendor.onInstances(v1alpha2.COARequest{ Method: fasthttp.MethodDelete, Parameters: map[string]string{ - "__name": "instance1", + "__name": "instance1-v1", }, Context: context.Background(), }) @@ -152,7 +152,7 @@ func TestInstancesOnInstances(t *testing.T) { resp = vendor.onInstances(v1alpha2.COARequest{ Method: fasthttp.MethodDelete, Parameters: map[string]string{ - "__name": "instance1", + "__name": "instance1-v1", }, Context: context.Background(), }) @@ -181,9 +181,9 @@ func TestInstancesTargetSelector(t *testing.T) { Method: fasthttp.MethodPost, Body: data, Parameters: map[string]string{ - "__name": "instance1", + "__name": "instance1-v1", "target-selector": "property1=value1", - "solution": "solution1", + "solution": "solution1-v1", }, Context: context.Background(), }) @@ -192,7 +192,7 @@ func TestInstancesTargetSelector(t *testing.T) { resp = vendor.onInstances(v1alpha2.COARequest{ Method: fasthttp.MethodGet, Parameters: map[string]string{ - "__name": "instance1", + "__name": "instance1-v1", }, Context: context.Background(), }) @@ -200,7 +200,7 @@ func TestInstancesTargetSelector(t *testing.T) { err := json.Unmarshal(resp.Body, &instance) assert.Nil(t, err) assert.Equal(t, v1alpha2.OK, resp.State) - assert.Equal(t, "instance1", instance.ObjectMeta.Name) + assert.Equal(t, "instance1-v1", instance.ObjectMeta.Name) assert.Equal(t, "value1", instance.Spec.Target.Selector["property1"]) } diff --git a/api/pkg/apis/v1alpha1/vendors/solutions-vendor.go b/api/pkg/apis/v1alpha1/vendors/solutions-vendor.go index 304181a09..c120bf7c8 100644 --- a/api/pkg/apis/v1alpha1/vendors/solutions-vendor.go +++ b/api/pkg/apis/v1alpha1/vendors/solutions-vendor.go @@ -77,6 +77,8 @@ func (c *SolutionsVendor) onSolutions(request v1alpha2.COARequest) v1alpha2.COAR }) defer span.End() uLog.Infof("V (Solutions): onSolutions, method: %s, traceId: %s", request.Method, span.SpanContext().TraceID().String()) + + id := request.Parameters["__name"] namespace, exist := request.Parameters["namespace"] if !exist { namespace = constants.DefaultScope @@ -84,7 +86,6 @@ func (c *SolutionsVendor) onSolutions(request v1alpha2.COARequest) v1alpha2.COAR switch request.Method { case fasthttp.MethodGet: ctx, span := observability.StartSpan("onSolutions-GET", pCtx, nil) - id := request.Parameters["__name"] var err error var state interface{} isArray := false @@ -117,7 +118,6 @@ func (c *SolutionsVendor) onSolutions(request v1alpha2.COARequest) v1alpha2.COAR return resp case fasthttp.MethodPost: ctx, span := observability.StartSpan("onSolutions-POST", pCtx, nil) - id := request.Parameters["__name"] embed_type := request.Parameters["embed-type"] embed_component := request.Parameters["embed-component"] embed_property := request.Parameters["embed-property"] @@ -191,7 +191,6 @@ func (c *SolutionsVendor) onSolutions(request v1alpha2.COARequest) v1alpha2.COAR }) case fasthttp.MethodDelete: ctx, span := observability.StartSpan("onSolutions-DELETE", pCtx, nil) - id := request.Parameters["__name"] err := c.SolutionsManager.DeleteState(ctx, id, namespace) if err != nil { uLog.Infof("V (Solutions): onSolutions failed - %s, traceId: %s", err.Error(), span.SpanContext().TraceID().String()) diff --git a/api/pkg/apis/v1alpha1/vendors/solutions-vendor_test.go b/api/pkg/apis/v1alpha1/vendors/solutions-vendor_test.go index 54d319f1d..b5766bcd1 100644 --- a/api/pkg/apis/v1alpha1/vendors/solutions-vendor_test.go +++ b/api/pkg/apis/v1alpha1/vendors/solutions-vendor_test.go @@ -82,7 +82,7 @@ func TestSolutionsOnSolutions(t *testing.T) { solution := model.SolutionState{ Spec: &model.SolutionSpec{}, ObjectMeta: model.ObjectMeta{ - Name: "solutions1", + Name: "solutions1-v1", Namespace: "scope1", }, } @@ -91,7 +91,7 @@ func TestSolutionsOnSolutions(t *testing.T) { Method: fasthttp.MethodPost, Body: data, Parameters: map[string]string{ - "__name": "solutions1", + "__name": "solutions1-v1", "namespace": "scope1", }, Context: context.Background(), @@ -101,7 +101,7 @@ func TestSolutionsOnSolutions(t *testing.T) { resp = vendor.onSolutions(v1alpha2.COARequest{ Method: fasthttp.MethodGet, Parameters: map[string]string{ - "__name": "solutions1", + "__name": "solutions1-v1", "namespace": "scope1", }, Context: context.Background(), @@ -110,7 +110,7 @@ func TestSolutionsOnSolutions(t *testing.T) { assert.Equal(t, v1alpha2.OK, resp.State) err := json.Unmarshal(resp.Body, &solutions) assert.Nil(t, err) - assert.Equal(t, "solutions1", solutions.ObjectMeta.Name) + assert.Equal(t, "solutions1-v1", solutions.ObjectMeta.Name) assert.Equal(t, "scope1", solutions.ObjectMeta.Namespace) resp = vendor.onSolutions(v1alpha2.COARequest{ @@ -125,13 +125,13 @@ func TestSolutionsOnSolutions(t *testing.T) { err = json.Unmarshal(resp.Body, &solutionsList) assert.Nil(t, err) assert.Equal(t, 1, len(solutionsList)) - assert.Equal(t, "solutions1", solutionsList[0].ObjectMeta.Name) + assert.Equal(t, "solutions1-v1", solutionsList[0].ObjectMeta.Name) assert.Equal(t, "scope1", solutionsList[0].ObjectMeta.Namespace) resp = vendor.onSolutions(v1alpha2.COARequest{ Method: fasthttp.MethodDelete, Parameters: map[string]string{ - "__name": "solutions1", + "__name": "solutions1-v1", "namespace": "scope1", }, Context: context.Background(), diff --git a/api/pkg/apis/v1alpha1/vendors/stage-vendor.go b/api/pkg/apis/v1alpha1/vendors/stage-vendor.go index a9beab6dc..a0860f2e8 100644 --- a/api/pkg/apis/v1alpha1/vendors/stage-vendor.go +++ b/api/pkg/apis/v1alpha1/vendors/stage-vendor.go @@ -19,6 +19,7 @@ import ( "github.com/eclipse-symphony/symphony/api/pkg/apis/v1alpha1/providers/stage/mock" "github.com/eclipse-symphony/symphony/api/pkg/apis/v1alpha1/providers/stage/wait" "github.com/eclipse-symphony/symphony/api/pkg/apis/v1alpha1/utils" + api_utils "github.com/eclipse-symphony/symphony/api/pkg/apis/v1alpha1/utils" "github.com/eclipse-symphony/symphony/coa/pkg/apis/v1alpha2" "github.com/eclipse-symphony/symphony/coa/pkg/apis/v1alpha2/managers" "github.com/eclipse-symphony/symphony/coa/pkg/apis/v1alpha2/providers" @@ -81,7 +82,8 @@ func (s *StageVendor) Init(config vendors.VendorConfig, factories []managers.IMa if err != nil { return v1alpha2.NewCOAError(nil, "event body is not an activation job", v1alpha2.BadRequest) } - campaign, err := s.CampaignsManager.GetState(context.TODO(), actData.Campaign, actData.Namespace) + campaignName := api_utils.ReplaceSeperator(actData.Campaign) + campaign, err := s.CampaignsManager.GetState(context.TODO(), campaignName, actData.Namespace) if err != nil { log.Error("V (Stage): unable to find campaign: %+v", err) return err @@ -132,7 +134,8 @@ func (s *StageVendor) Init(config vendors.VendorConfig, factories []managers.IMa } status.Outputs["__namespace"] = triggerData.Namespace - campaign, err := s.CampaignsManager.GetState(context.TODO(), triggerData.Campaign, triggerData.Namespace) + campaignName := api_utils.ReplaceSeperator(triggerData.Campaign) + campaign, err := s.CampaignsManager.GetState(context.TODO(), campaignName, triggerData.Namespace) if err != nil { status.Status = v1alpha2.BadRequest status.StatusMessage = v1alpha2.BadRequest.String() @@ -206,7 +209,8 @@ func (s *StageVendor) Init(config vendors.VendorConfig, factories []managers.IMa return fmt.Errorf("job-report: activation is not valid") } if status.Status == v1alpha2.Done || status.Status == v1alpha2.OK { - campaign, err := s.CampaignsManager.GetState(context.TODO(), campaign, namespace) + campaignName := api_utils.ReplaceSeperator(campaign) + campaign, err := s.CampaignsManager.GetState(context.TODO(), campaignName, namespace) if err != nil { sLog.Errorf("V (Stage): failed to get campaign spec '%s': %v", campaign, err) return err diff --git a/api/pkg/apis/v1alpha1/vendors/targets-vendor.go b/api/pkg/apis/v1alpha1/vendors/targets-vendor.go index 1901cfca8..db406a404 100644 --- a/api/pkg/apis/v1alpha1/vendors/targets-vendor.go +++ b/api/pkg/apis/v1alpha1/vendors/targets-vendor.go @@ -116,14 +116,16 @@ func (c *TargetsVendor) onRegistry(request v1alpha2.COARequest) v1alpha2.COAResp }) defer span.End() tLog.Infof("V (Targets) : onRegistry, method: %s, traceId: %s", request.Method, span.SpanContext().TraceID().String()) + + id := request.Parameters["__name"] namespace, exist := request.Parameters["namespace"] if !exist { namespace = constants.DefaultScope } + switch request.Method { case fasthttp.MethodGet: ctx, span := observability.StartSpan("onRegistry-GET", pCtx, nil) - id := request.Parameters["__name"] var err error var state interface{} isArray := false @@ -156,7 +158,6 @@ func (c *TargetsVendor) onRegistry(request v1alpha2.COARequest) v1alpha2.COAResp return resp case fasthttp.MethodPost: ctx, span := observability.StartSpan("onRegistry-POST", pCtx, nil) - id := request.Parameters["__name"] binding := request.Parameters["with-binding"] var target model.TargetState err := json.Unmarshal(request.Body, &target) @@ -238,7 +239,6 @@ func (c *TargetsVendor) onRegistry(request v1alpha2.COARequest) v1alpha2.COAResp }) case fasthttp.MethodDelete: ctx, span := observability.StartSpan("onRegistry-DELETE", pCtx, nil) - id := request.Parameters["__name"] direct := request.Parameters["direct"] if c.Config.Properties["useJobManager"] == "true" && direct != "true" { diff --git a/api/pkg/apis/v1alpha1/vendors/targets-vendor_test.go b/api/pkg/apis/v1alpha1/vendors/targets-vendor_test.go index b1d70ae65..b3051d160 100644 --- a/api/pkg/apis/v1alpha1/vendors/targets-vendor_test.go +++ b/api/pkg/apis/v1alpha1/vendors/targets-vendor_test.go @@ -77,7 +77,7 @@ func TestTargetsOnRegistry(t *testing.T) { vendor := createTargetsVendor() target := model.TargetState{ Spec: &model.TargetSpec{ - DisplayName: "target1", + DisplayName: "target1-v1", Topologies: []model.TopologySpec{ { Bindings: []model.BindingSpec{ @@ -98,7 +98,7 @@ func TestTargetsOnRegistry(t *testing.T) { Method: fasthttp.MethodPost, Body: data, Parameters: map[string]string{ - "__name": "target1", + "__name": "target1-v1", "with-binding": "staging", }, Context: context.Background(), @@ -108,14 +108,14 @@ func TestTargetsOnRegistry(t *testing.T) { resp = vendor.onRegistry(v1alpha2.COARequest{ Method: fasthttp.MethodGet, Parameters: map[string]string{ - "__name": "target1", + "__name": "target1-v1", }, Context: context.Background(), }) var targets model.TargetState json.Unmarshal(resp.Body, &targets) assert.Equal(t, v1alpha2.OK, resp.State) - assert.Equal(t, "target1", targets.ObjectMeta.Name) + assert.Equal(t, "target1-v1", targets.ObjectMeta.Name) assert.Equal(t, 1, len(targets.Spec.Topologies)) resp = vendor.onRegistry(v1alpha2.COARequest{ @@ -130,7 +130,7 @@ func TestTargetsOnRegistry(t *testing.T) { resp = vendor.onRegistry(v1alpha2.COARequest{ Method: fasthttp.MethodDelete, Parameters: map[string]string{ - "__name": "target1", + "__name": "target1-v1", }, Context: context.Background(), }) @@ -168,7 +168,7 @@ func TestTargetsOnStatus(t *testing.T) { target := model.TargetState{ Spec: &model.TargetSpec{ - DisplayName: "target1", + DisplayName: "target1-v1", Topologies: []model.TopologySpec{ { Bindings: []model.BindingSpec{ @@ -189,7 +189,7 @@ func TestTargetsOnStatus(t *testing.T) { Method: fasthttp.MethodPost, Body: data, Parameters: map[string]string{ - "__name": "target1", + "__name": "target1-v1", "with-binding": "staging", }, Context: context.Background(), @@ -209,7 +209,7 @@ func TestTargetsOnStatus(t *testing.T) { Method: fasthttp.MethodPut, Body: data, Parameters: map[string]string{ - "__name": "target1", + "__name": "target1-v1", }, Context: context.Background(), }) @@ -223,7 +223,7 @@ func TestTargetsOnHeartbeats(t *testing.T) { target := model.TargetState{ Spec: &model.TargetSpec{ - DisplayName: "target1", + DisplayName: "target1-v1", Topologies: []model.TopologySpec{ { Bindings: []model.BindingSpec{ @@ -244,7 +244,7 @@ func TestTargetsOnHeartbeats(t *testing.T) { Method: fasthttp.MethodPost, Body: data, Parameters: map[string]string{ - "__name": "target1", + "__name": "target1-v1", "with-binding": "staging", }, Context: context.Background(), @@ -254,7 +254,7 @@ func TestTargetsOnHeartbeats(t *testing.T) { resp = vendor.onHeartBeat(v1alpha2.COARequest{ Method: fasthttp.MethodPost, Parameters: map[string]string{ - "__name": "target1", + "__name": "target1-v1", }, Context: context.Background(), }) @@ -263,7 +263,7 @@ func TestTargetsOnHeartbeats(t *testing.T) { resp = vendor.onRegistry(v1alpha2.COARequest{ Method: fasthttp.MethodGet, Parameters: map[string]string{ - "__name": "target1", + "__name": "target1-v1", }, Context: context.Background(), }) diff --git a/docs/samples/k8s/hello-world/instance.yaml b/docs/samples/k8s/hello-world/instance.yaml index 6f565c7e4..b4883c06c 100644 --- a/docs/samples/k8s/hello-world/instance.yaml +++ b/docs/samples/k8s/hello-world/instance.yaml @@ -1,9 +1,9 @@ apiVersion: solution.symphony/v1 kind: Instance metadata: - name: sample-prometheus-instance + name: sample-prometheus-instance-v1 spec: scope: sample-k8s-scope - solution: sample-prometheus-server + solution: sample-prometheus-server:v1 target: - name: sample-k8s-target \ No newline at end of file + name: sample-k8s-target:v1 \ No newline at end of file diff --git a/docs/samples/k8s/hello-world/solution.yaml b/docs/samples/k8s/hello-world/solution.yaml index b18f7a4cf..047059954 100644 --- a/docs/samples/k8s/hello-world/solution.yaml +++ b/docs/samples/k8s/hello-world/solution.yaml @@ -1,7 +1,7 @@ apiVersion: solution.symphony/v1 kind: Solution metadata: - name: sample-prometheus-server + name: sample-prometheus-server-v1 spec: metadata: deployment.replicas: "#1" diff --git a/docs/samples/k8s/hello-world/target.yaml b/docs/samples/k8s/hello-world/target.yaml index 3d4da3548..e9422dc11 100644 --- a/docs/samples/k8s/hello-world/target.yaml +++ b/docs/samples/k8s/hello-world/target.yaml @@ -1,7 +1,7 @@ apiVersion: fabric.symphony/v1 kind: Target metadata: - name: sample-k8s-target + name: sample-k8s-target-v1 spec: forceRedeploy: true topologies: diff --git a/docs/samples/multisite/activation.yaml b/docs/samples/multisite/activation.yaml index 13ff05d5d..bc4e5ad2d 100644 --- a/docs/samples/multisite/activation.yaml +++ b/docs/samples/multisite/activation.yaml @@ -3,5 +3,5 @@ kind: Activation metadata: name: multisite-deploy spec: - campaign: "site-apps" + campaign: "site-apps:v1" \ No newline at end of file diff --git a/docs/samples/multisite/campaign.yaml b/docs/samples/multisite/campaign.yaml index a5c41b7dc..9993174e3 100644 --- a/docs/samples/multisite/campaign.yaml +++ b/docs/samples/multisite/campaign.yaml @@ -1,7 +1,7 @@ apiVersion: workflow.symphony/v1 kind: Campaign metadata: - name: site-apps + name: site-apps-v1 spec: firstStage: list stages: diff --git a/docs/samples/multisite/catalog-catalog.yaml b/docs/samples/multisite/catalog-catalog.yaml index e6bf85774..a9354a65c 100644 --- a/docs/samples/multisite/catalog-catalog.yaml +++ b/docs/samples/multisite/catalog-catalog.yaml @@ -1,12 +1,12 @@ apiVersion: federation.symphony/v1 kind: Catalog metadata: - name: site-catalog + name: site-catalog-v1 spec: type: catalog properties: metadata: - name: web-app-config + name: web-app-config-v1 spec: type: config properties: diff --git a/docs/samples/multisite/instance-catalog.yaml b/docs/samples/multisite/instance-catalog.yaml index 6d36603e6..c433dfc65 100644 --- a/docs/samples/multisite/instance-catalog.yaml +++ b/docs/samples/multisite/instance-catalog.yaml @@ -1,12 +1,12 @@ apiVersion: federation.symphony/v1 kind: Catalog metadata: - name: site-instance + name: site-instance-v1 spec: type: instance properties: spec: - solution: site-app + solution: site-app:v1 target: selector: group: site \ No newline at end of file diff --git a/docs/samples/multisite/solution-catalog.yaml b/docs/samples/multisite/solution-catalog.yaml index d38d3443b..a8dbb6635 100644 --- a/docs/samples/multisite/solution-catalog.yaml +++ b/docs/samples/multisite/solution-catalog.yaml @@ -1,7 +1,7 @@ apiVersion: federation.symphony/v1 kind: Catalog metadata: - name: site-app + name: site-app-v1 spec: type: solution properties: @@ -11,8 +11,8 @@ spec: type: container metadata: service.ports: "[{\"name\":\"port3011\",\"port\": 3011,\"targetPort\":5000}]" - service.type: "${{$config('web-app-config','serviceType')}}" + service.type: "${{$config('web-app-config:v1','serviceType')}}" properties: deployment.replicas: "#1" container.ports: "[{\"containerPort\":5000,\"protocol\":\"TCP\"}]" - container.image: "${{$config('web-app-config','image')}}" \ No newline at end of file + container.image: "${{$config('web-app-config:v1','image')}}" \ No newline at end of file diff --git a/docs/samples/multisite/target-catalog.yaml b/docs/samples/multisite/target-catalog.yaml index 5a2032cd1..f2c6b185c 100644 --- a/docs/samples/multisite/target-catalog.yaml +++ b/docs/samples/multisite/target-catalog.yaml @@ -1,7 +1,7 @@ apiVersion: federation.symphony/v1 kind: Catalog metadata: - name: site-k8s-target + name: site-k8s-target-v1 spec: type: target properties: diff --git a/k8s/controllers/solution/instance_controller.go b/k8s/controllers/solution/instance_controller.go index e4a010d08..827f29295 100644 --- a/k8s/controllers/solution/instance_controller.go +++ b/k8s/controllers/solution/instance_controller.go @@ -138,7 +138,8 @@ func (r *InstanceReconciler) deploymentBuilder(ctx context.Context, object recon TargetCandidates: []fabric_v1.Target{}, } - if err := r.Get(ctx, types.NamespacedName{Name: instance.Spec.Solution, Namespace: instance.Namespace}, &deploymentResources.Solution); err != nil { + solutionName := utils.ReplaceLastSeperator(instance.Spec.Solution, ":", "-") + if err := r.Get(ctx, types.NamespacedName{Name: solutionName, Namespace: instance.Namespace}, &deploymentResources.Solution); err != nil { log.Error(v1alpha2.NewCOAError(err, "failed to get solution", v1alpha2.SolutionGetFailed), "proceed with no solution found") } // Get targets @@ -212,6 +213,10 @@ func (r *InstanceReconciler) handleTarget(obj client.Object) []ctrl.Request { updatedInstanceNames := make([]string, 0) for _, instance := range instances.Items { + if !utils.NeedWatchInstance(instance) { + continue + } + targetCandidates := utils.MatchTargets(instance, targetList) if len(targetCandidates) > 0 { ret = append(ret, ctrl.Request{ @@ -235,9 +240,11 @@ func (r *InstanceReconciler) handleSolution(obj client.Object) []ctrl.Request { ret := make([]ctrl.Request, 0) solObj := obj.(*solution_v1.Solution) var instances solution_v1.InstanceList + + solutionName := utils.ReplaceLastSeperator(solObj.Name, "-", ":") options := []client.ListOption{ client.InNamespace(solObj.Namespace), - client.MatchingFields{"spec.solution": solObj.Name}, + client.MatchingFields{"spec.solution": solutionName}, } error := r.List(context.Background(), &instances, options...) if error != nil { @@ -247,6 +254,10 @@ func (r *InstanceReconciler) handleSolution(obj client.Object) []ctrl.Request { updatedInstanceNames := make([]string, 0) for _, instance := range instances.Items { + if !utils.NeedWatchInstance(instance) { + continue + } + ret = append(ret, ctrl.Request{ NamespacedName: types.NamespacedName{ Name: instance.Name, diff --git a/k8s/utils/symphony-api.go b/k8s/utils/symphony-api.go index 2856b6973..496ad4397 100644 --- a/k8s/utils/symphony-api.go +++ b/k8s/utils/symphony-api.go @@ -14,6 +14,7 @@ import ( "regexp" "strconv" "strings" + "time" apimodel "github.com/eclipse-symphony/symphony/api/pkg/apis/v1alpha1/model" api_utils "github.com/eclipse-symphony/symphony/api/pkg/apis/v1alpha1/utils" @@ -164,8 +165,8 @@ func MatchTargets(instance solution_v1.Instance, targets fabric_v1.TargetList) [ ret := make(map[string]fabric_v1.Target) if instance.Spec.Target.Name != "" { for _, t := range targets.Items { - - if matchString(instance.Spec.Target.Name, t.ObjectMeta.Name) { + targetName := ReplaceLastSeperator(instance.Spec.Target.Name, ":", "-") + if matchString(targetName, t.ObjectMeta.Name) { ret[t.ObjectMeta.Name] = t } } @@ -238,3 +239,28 @@ func CreateSymphonyDeployment(ctx context.Context, instance solution_v1.Instance return ret, err } + +func NeedWatchInstance(instance solution_v1.Instance) bool { + var interval time.Duration = 30 + if instance.Spec.ReconciliationPolicy != nil && instance.Spec.ReconciliationPolicy.Interval != nil { + parsedInterval, err := time.ParseDuration(*instance.Spec.ReconciliationPolicy.Interval) + if err != nil { + parsedInterval = 30 + } + interval = parsedInterval + } + + if instance.Spec.ReconciliationPolicy != nil && instance.Spec.ReconciliationPolicy.State.IsInActive() || interval == 0 { + return false + } + + return true +} + +func ReplaceLastSeperator(name string, seperatorBefore string, seperatorAfter string) string { + i := strings.LastIndex(name, seperatorBefore) + if i == -1 { + return name + } + return name[:i] + seperatorAfter + name[i+1:] +} diff --git a/test/integration/scenarios/01.update/manifestTemplates/oss/instance.yaml b/test/integration/scenarios/01.update/manifestTemplates/oss/instance.yaml index 394e83be7..cd7d716d0 100755 --- a/test/integration/scenarios/01.update/manifestTemplates/oss/instance.yaml +++ b/test/integration/scenarios/01.update/manifestTemplates/oss/instance.yaml @@ -7,10 +7,10 @@ apiVersion: solution.symphony/v1 kind: Instance metadata: annotations: {} - name: instance + name: instance-v1 spec: - displayName: instance + displayName: instance-v1 scope: alice-springs - solution: my-sol + solution: my-sol:v1 target: - name: self + name: self:v1 diff --git a/test/integration/scenarios/01.update/manifestTemplates/oss/solution.yaml b/test/integration/scenarios/01.update/manifestTemplates/oss/solution.yaml index d7b6c2576..9525ba151 100755 --- a/test/integration/scenarios/01.update/manifestTemplates/oss/solution.yaml +++ b/test/integration/scenarios/01.update/manifestTemplates/oss/solution.yaml @@ -7,6 +7,6 @@ apiVersion: solution.symphony/v1 kind: Solution metadata: annotations: {} - name: my-sol + name: my-sol-v1 spec: displayName: My solution diff --git a/test/integration/scenarios/01.update/manifestTemplates/oss/target.yaml b/test/integration/scenarios/01.update/manifestTemplates/oss/target.yaml index d2e786bbe..0679581a7 100755 --- a/test/integration/scenarios/01.update/manifestTemplates/oss/target.yaml +++ b/test/integration/scenarios/01.update/manifestTemplates/oss/target.yaml @@ -6,10 +6,10 @@ apiVersion: fabric.symphony/v1 kind: Target metadata: - name: self + name: self-v1 annotations: {} spec: - displayName: int-virtual-02 + displayName: int-virtual-02-v1 scope: alice-springs topologies: - bindings: diff --git a/test/integration/scenarios/02.basic/magefile.go b/test/integration/scenarios/02.basic/magefile.go index e45597dd2..075fbe348 100644 --- a/test/integration/scenarios/02.basic/magefile.go +++ b/test/integration/scenarios/02.basic/magefile.go @@ -120,10 +120,12 @@ func DeployManifests(namespace string) error { return err } stringYaml := string(data) - stringYaml = strings.ReplaceAll(stringYaml, "INSTANCENAME", namespace+"instance") + stringYaml = strings.ReplaceAll(stringYaml, "INSTANCENAME", namespace+"instance-v1") stringYaml = strings.ReplaceAll(stringYaml, "SCOPENAME", namespace+"scope") - stringYaml = strings.ReplaceAll(stringYaml, "TARGETNAME", namespace+"target") - stringYaml = strings.ReplaceAll(stringYaml, "SOLUTIONNAME", namespace+"solution") + stringYaml = strings.ReplaceAll(stringYaml, "TARGETNAME", namespace+"target-v1") + stringYaml = strings.ReplaceAll(stringYaml, "SOLUTIONNAME", namespace+"solution-v1") + stringYaml = strings.ReplaceAll(stringYaml, "TARGETREFNAME", namespace+"target:v1") + stringYaml = strings.ReplaceAll(stringYaml, "SOLUTIONREFNAME", namespace+"solution:v1") err = writeYamlStringsToFile(stringYaml, "./test.yaml") if err != nil { @@ -157,9 +159,9 @@ func Verify() error { } func CleanUpSymphonyObjects(namespace string) error { - instanceName := namespace + "instance" - targetName := namespace + "target" - solutionName := namespace + "solution" + instanceName := namespace + "instance-v1" + targetName := namespace + "target-v1" + solutionName := namespace + "solution-v1" err := shellcmd.Command(fmt.Sprintf("kubectl delete instances.solution.symphony %s -n %s", instanceName, namespace)).Run() if err != nil { return err diff --git a/test/integration/scenarios/02.basic/manifest/oss/instance.yaml b/test/integration/scenarios/02.basic/manifest/oss/instance.yaml index 9443b50de..f235f2776 100755 --- a/test/integration/scenarios/02.basic/manifest/oss/instance.yaml +++ b/test/integration/scenarios/02.basic/manifest/oss/instance.yaml @@ -11,6 +11,6 @@ metadata: spec: displayName: INSTANCENAME scope: SCOPENAME - solution: SOLUTIONNAME + solution: SOLUTIONREFNAME target: - name: TARGETNAME + name: TARGETREFNAME diff --git a/test/integration/scenarios/03.basicWithNsDelete/manifest/oss/instance.yaml b/test/integration/scenarios/03.basicWithNsDelete/manifest/oss/instance.yaml index 50c0be3df..c82578dd4 100644 --- a/test/integration/scenarios/03.basicWithNsDelete/manifest/oss/instance.yaml +++ b/test/integration/scenarios/03.basicWithNsDelete/manifest/oss/instance.yaml @@ -1,9 +1,9 @@ apiVersion: solution.symphony/v1 kind: Instance metadata: - name: instance03 + name: instance03-v1 spec: scope: k8s-scope - solution: solution03 + solution: solution03:v1 target: - name: target03 + name: target03:v1 diff --git a/test/integration/scenarios/03.basicWithNsDelete/manifest/oss/solution.yaml b/test/integration/scenarios/03.basicWithNsDelete/manifest/oss/solution.yaml index 53ddbce36..9d40631ba 100644 --- a/test/integration/scenarios/03.basicWithNsDelete/manifest/oss/solution.yaml +++ b/test/integration/scenarios/03.basicWithNsDelete/manifest/oss/solution.yaml @@ -1,7 +1,7 @@ apiVersion: solution.symphony/v1 kind: Solution metadata: - name: solution03 + name: solution03-v1 spec: metadata: deployment.replicas: "#1" diff --git a/test/integration/scenarios/03.basicWithNsDelete/manifest/oss/target.yaml b/test/integration/scenarios/03.basicWithNsDelete/manifest/oss/target.yaml index edce481ca..9e55dec64 100644 --- a/test/integration/scenarios/03.basicWithNsDelete/manifest/oss/target.yaml +++ b/test/integration/scenarios/03.basicWithNsDelete/manifest/oss/target.yaml @@ -1,7 +1,7 @@ apiVersion: fabric.symphony/v1 kind: Target metadata: - name: target03 + name: target03-v1 spec: forceRedeploy: true topologies: diff --git a/test/integration/scenarios/03.basicWithNsDelete/verify/manifest_test.go b/test/integration/scenarios/03.basicWithNsDelete/verify/manifest_test.go index b33a9bd49..0388f3c41 100644 --- a/test/integration/scenarios/03.basicWithNsDelete/verify/manifest_test.go +++ b/test/integration/scenarios/03.basicWithNsDelete/verify/manifest_test.go @@ -129,7 +129,7 @@ func TestBasic_InstanceDeletion(t *testing.T) { fmt.Println("Get namespace before deletion: ", len(namespacesBefore.Items)) // Run a mage command to delete instance - execCmd := exec.Command("sh", "-c", "cd ../../../../localenv && mage remove instances.solution.symphony instance03") + execCmd := exec.Command("sh", "-c", "cd ../../../../localenv && mage remove instances.solution.symphony instance03-v1") execCmd.Stdout = os.Stdout execCmd.Stderr = os.Stderr cmdErr := execCmd.Run() diff --git a/test/integration/scenarios/04.workflow/manifest/activation.yaml b/test/integration/scenarios/04.workflow/manifest/activation.yaml index 95c490e15..a2eea5407 100644 --- a/test/integration/scenarios/04.workflow/manifest/activation.yaml +++ b/test/integration/scenarios/04.workflow/manifest/activation.yaml @@ -3,5 +3,5 @@ kind: Activation metadata: name: 04workflow spec: - campaign: "04campaign" + campaign: "04campaign:v1" \ No newline at end of file diff --git a/test/integration/scenarios/04.workflow/manifest/campaign.yaml b/test/integration/scenarios/04.workflow/manifest/campaign.yaml index c16d2450f..c37bab654 100644 --- a/test/integration/scenarios/04.workflow/manifest/campaign.yaml +++ b/test/integration/scenarios/04.workflow/manifest/campaign.yaml @@ -1,7 +1,7 @@ apiVersion: workflow.symphony/v1 kind: Campaign metadata: - name: 04campaign + name: 04campaign-v1 spec: firstStage: wait stages: @@ -16,10 +16,10 @@ spec: inputs: objectType: catalogs names: - - site-catalog - - site-app - - site-k8s-target - - site-instance + - site-catalog:v1 + - site-app:v1 + - site-k8s-target:v1 + - site-instance:v1 list: name: list provider: providers.stage.list diff --git a/test/integration/scenarios/04.workflow/manifest/instance-catalog.yaml b/test/integration/scenarios/04.workflow/manifest/instance-catalog.yaml index aa157d3c8..931fcc199 100644 --- a/test/integration/scenarios/04.workflow/manifest/instance-catalog.yaml +++ b/test/integration/scenarios/04.workflow/manifest/instance-catalog.yaml @@ -1,12 +1,12 @@ apiVersion: federation.symphony/v1 kind: Catalog metadata: - name: site-instance + name: site-instance-v1 spec: type: instance properties: spec: - solution: site-app + solution: site-app:v1 scope: SCOPENAME target: selector: diff --git a/test/integration/scenarios/05.catalog/catalogs/asset.yaml b/test/integration/scenarios/05.catalog/catalogs/asset.yaml index 5d2135fc9..5457db984 100644 --- a/test/integration/scenarios/05.catalog/catalogs/asset.yaml +++ b/test/integration/scenarios/05.catalog/catalogs/asset.yaml @@ -1,7 +1,7 @@ apiVersion: federation.symphony/v1 kind: Catalog metadata: - name: asset + name: asset-v1 spec: type: asset properties: diff --git a/test/integration/scenarios/05.catalog/catalogs/config.yaml b/test/integration/scenarios/05.catalog/catalogs/config.yaml index 6a5231ddf..f6c6a27c6 100644 --- a/test/integration/scenarios/05.catalog/catalogs/config.yaml +++ b/test/integration/scenarios/05.catalog/catalogs/config.yaml @@ -1,10 +1,10 @@ apiVersion: federation.symphony/v1 kind: Catalog metadata: - name: config + name: config-v1 spec: type: config metadata: - schema: schema + schema: schema-v1 properties: email: "sample@sample.com" \ No newline at end of file diff --git a/test/integration/scenarios/05.catalog/catalogs/instance.yaml b/test/integration/scenarios/05.catalog/catalogs/instance.yaml index d77bd9ea0..8f2aca5da 100644 --- a/test/integration/scenarios/05.catalog/catalogs/instance.yaml +++ b/test/integration/scenarios/05.catalog/catalogs/instance.yaml @@ -1,12 +1,12 @@ apiVersion: federation.symphony/v1 kind: Catalog metadata: - name: instance + name: instance-v1 spec: type: instance properties: spec: - solution: app + solution: app:v1 target: selector: group: site \ No newline at end of file diff --git a/test/integration/scenarios/05.catalog/catalogs/schema.yaml b/test/integration/scenarios/05.catalog/catalogs/schema.yaml index c3f2faedb..810db90c4 100644 --- a/test/integration/scenarios/05.catalog/catalogs/schema.yaml +++ b/test/integration/scenarios/05.catalog/catalogs/schema.yaml @@ -1,7 +1,7 @@ apiVersion: federation.symphony/v1 kind: Catalog metadata: - name: schema + name: schema-v1 spec: type: schema properties: diff --git a/test/integration/scenarios/05.catalog/catalogs/solution.yaml b/test/integration/scenarios/05.catalog/catalogs/solution.yaml index bf04bb044..7c14018fd 100644 --- a/test/integration/scenarios/05.catalog/catalogs/solution.yaml +++ b/test/integration/scenarios/05.catalog/catalogs/solution.yaml @@ -1,12 +1,12 @@ apiVersion: federation.symphony/v1 kind: Catalog metadata: - name: solution + name: solution-v1 spec: type: solution properties: spec: - displayName: site-app + displayName: site-app-v1 components: - name: influxdb type: container diff --git a/test/integration/scenarios/05.catalog/catalogs/target.yaml b/test/integration/scenarios/05.catalog/catalogs/target.yaml index c7e42f8b6..02eb26162 100644 --- a/test/integration/scenarios/05.catalog/catalogs/target.yaml +++ b/test/integration/scenarios/05.catalog/catalogs/target.yaml @@ -1,7 +1,7 @@ apiVersion: federation.symphony/v1 kind: Catalog metadata: - name: target + name: target-v1 spec: type: target properties: diff --git a/test/integration/scenarios/05.catalog/catalogs/wrongconfig.yaml b/test/integration/scenarios/05.catalog/catalogs/wrongconfig.yaml index 4a9ea9185..363742125 100644 --- a/test/integration/scenarios/05.catalog/catalogs/wrongconfig.yaml +++ b/test/integration/scenarios/05.catalog/catalogs/wrongconfig.yaml @@ -1,10 +1,10 @@ apiVersion: federation.symphony/v1 kind: Catalog metadata: - name: wrongconfig + name: wrongconfig-v1 spec: type: config metadata: - schema: schema + schema: schema-v1 properties: email: "this is an invalid email" \ No newline at end of file diff --git a/test/integration/scenarios/05.catalog/magefile.go b/test/integration/scenarios/05.catalog/magefile.go index 8a529802d..a907b2723 100644 --- a/test/integration/scenarios/05.catalog/magefile.go +++ b/test/integration/scenarios/05.catalog/magefile.go @@ -127,7 +127,7 @@ func Verify() error { return errors.New("Catalogs not created") } // read catalog - err, catalog := readCatalog("asset", namespace, dynamicClient) + err, catalog := readCatalog("asset-v1", namespace, dynamicClient) if err != nil { return err } @@ -136,7 +136,7 @@ func Verify() error { } // Update catalog catalog.Object["spec"].(map[string]interface{})["properties"].(map[string]interface{})["name"] = "大阪" - err, catalog = updateCatalog("asset", namespace, catalog, dynamicClient) + err, catalog = updateCatalog("asset-v1", namespace, catalog, dynamicClient) if err != nil { return err } @@ -144,7 +144,7 @@ func Verify() error { return errors.New("Catalog not updated.") } // Delete catalog - err = shellcmd.Command(fmt.Sprintf("kubectl delete catalog asset -n %s", namespace)).Run() + err = shellcmd.Command(fmt.Sprintf("kubectl delete catalog asset-v1 -n %s", namespace)).Run() if err != nil { return err } diff --git a/test/integration/scenarios/06.ado/manifest/instance.yaml b/test/integration/scenarios/06.ado/manifest/instance.yaml index 3e82335dd..3a4664e13 100644 --- a/test/integration/scenarios/06.ado/manifest/instance.yaml +++ b/test/integration/scenarios/06.ado/manifest/instance.yaml @@ -1,9 +1,9 @@ apiVersion: solution.symphony/v1 kind: Instance metadata: - name: instance + name: instance-v1 spec: target: - name: target - solution: solution + name: target:v1 + solution: solution:v1 scope: azure-iot-operations diff --git a/test/integration/scenarios/06.ado/manifest/solution.yaml b/test/integration/scenarios/06.ado/manifest/solution.yaml index c78e09cae..9f08c5cad 100644 --- a/test/integration/scenarios/06.ado/manifest/solution.yaml +++ b/test/integration/scenarios/06.ado/manifest/solution.yaml @@ -1,6 +1,6 @@ apiVersion: solution.symphony/v1 kind: Solution metadata: - name: solution + name: solution-v1 spec: components: [] \ No newline at end of file diff --git a/test/integration/scenarios/06.ado/manifest/target.yaml b/test/integration/scenarios/06.ado/manifest/target.yaml index 2b36d6f17..f50475837 100644 --- a/test/integration/scenarios/06.ado/manifest/target.yaml +++ b/test/integration/scenarios/06.ado/manifest/target.yaml @@ -1,7 +1,7 @@ apiVersion: fabric.symphony/v1 kind: Target metadata: - name: target + name: target-v1 spec: scope: azure-iot-operations components: [] From 1b309efa0e4af4e83afc92eebdb1bd7e60e95362 Mon Sep 17 00:00:00 2001 From: Lency Qian Date: Fri, 31 May 2024 11:57:16 +0800 Subject: [PATCH 2/6] update config manager --- .../managers/configs/configs-manager.go | 24 ++++----- .../managers/configs/configs-manager_test.go | 51 +++++++++++++++++-- api/pkg/apis/v1alpha1/utils/utils.go | 10 ---- 3 files changed, 58 insertions(+), 27 deletions(-) diff --git a/api/pkg/apis/v1alpha1/managers/configs/configs-manager.go b/api/pkg/apis/v1alpha1/managers/configs/configs-manager.go index 48c5b5476..ae04346fb 100644 --- a/api/pkg/apis/v1alpha1/managers/configs/configs-manager.go +++ b/api/pkg/apis/v1alpha1/managers/configs/configs-manager.go @@ -59,8 +59,8 @@ func (s *ConfigsManager) Init(context *contexts.VendorContext, cfg managers.Mana } func (s *ConfigsManager) Get(object string, field string, overlays []string, localContext interface{}) (interface{}, error) { log.Debugf(" M (Config): Get %v, config provider size %d", object, len(s.ConfigProviders)) - if strings.Index(object, ":") > 0 && len(s.ConfigProviders) > 1 { - parts := strings.Split(object, ":") + if strings.Index(object, "::") > 0 { + parts := strings.Split(object, "::") if len(parts) != 2 { return "", v1alpha2.NewCOAError(nil, fmt.Sprintf("Invalid object: %s", object), v1alpha2.BadRequest) } @@ -124,8 +124,8 @@ func (s *ConfigsManager) getWithOverlay(provider config.IConfigProvider, object func (s *ConfigsManager) GetObject(object string, overlays []string, localContext interface{}) (map[string]interface{}, error) { log.Debugf(" M (Config): GetObject %v, config provider size %d", object, len(s.ConfigProviders)) - if strings.Index(object, ":") > 0 && len(s.ConfigProviders) > 1 { - parts := strings.Split(object, ":") + if strings.Index(object, "::") > 0 { + parts := strings.Split(object, "::") if len(parts) != 2 { return nil, v1alpha2.NewCOAError(nil, fmt.Sprintf("Invalid object: %s", object), v1alpha2.BadRequest) } @@ -164,8 +164,8 @@ func (s *ConfigsManager) getObjectWithOverlay(provider config.IConfigProvider, o } func (s *ConfigsManager) Set(object string, field string, value interface{}) error { log.Debugf(" M (Config): Set %v, config provider size %d", object, len(s.ConfigProviders)) - if strings.Index(object, ":") > 0 && len(s.ConfigProviders) > 1 { - parts := strings.Split(object, ":") + if strings.Index(object, "::") > 0 { + parts := strings.Split(object, "::") if len(parts) != 2 { return v1alpha2.NewCOAError(nil, fmt.Sprintf("Invalid object: %s", object), v1alpha2.BadRequest) } @@ -190,8 +190,8 @@ func (s *ConfigsManager) Set(object string, field string, value interface{}) err } func (s *ConfigsManager) SetObject(object string, values map[string]interface{}) error { log.Debugf(" M (Config): SetObject %v, config provider size %d", object, len(s.ConfigProviders)) - if strings.Index(object, ":") > 0 && len(s.ConfigProviders) > 1 { - parts := strings.Split(object, ":") + if strings.Index(object, "::") > 0 { + parts := strings.Split(object, "::") if len(parts) != 2 { return v1alpha2.NewCOAError(nil, fmt.Sprintf("Invalid object: %s", object), v1alpha2.BadRequest) } @@ -216,8 +216,8 @@ func (s *ConfigsManager) SetObject(object string, values map[string]interface{}) } func (s *ConfigsManager) Delete(object string, field string) error { log.Debugf(" M (Config): Delete %v, config provider size %d", object, len(s.ConfigProviders)) - if strings.Index(object, ":") > 0 && len(s.ConfigProviders) > 1 { - parts := strings.Split(object, ":") + if strings.Index(object, "::") > 0 { + parts := strings.Split(object, "::") if len(parts) != 2 { return v1alpha2.NewCOAError(nil, fmt.Sprintf("Invalid object: %s", object), v1alpha2.BadRequest) } @@ -242,8 +242,8 @@ func (s *ConfigsManager) Delete(object string, field string) error { } func (s *ConfigsManager) DeleteObject(object string) error { log.Debugf(" M (Config): DeleteObject %v, config provider size %d", object, len(s.ConfigProviders)) - if strings.Index(object, ":") > 0 && len(s.ConfigProviders) > 1 { - parts := strings.Split(object, ":") + if strings.Index(object, "::") > 0 { + parts := strings.Split(object, "::") if len(parts) != 2 { return v1alpha2.NewCOAError(nil, fmt.Sprintf("Invalid object: %s", object), v1alpha2.BadRequest) } diff --git a/api/pkg/apis/v1alpha1/managers/configs/configs-manager_test.go b/api/pkg/apis/v1alpha1/managers/configs/configs-manager_test.go index 7729c6753..03cae7228 100644 --- a/api/pkg/apis/v1alpha1/managers/configs/configs-manager_test.go +++ b/api/pkg/apis/v1alpha1/managers/configs/configs-manager_test.go @@ -336,19 +336,19 @@ func TestObjectDeleteWithProviderSpecified(t *testing.T) { "key2": 42, "key3": true, } - manager.SetObject("memory:obj", object) + manager.SetObject("memory::obj", object) // Delete field - err = manager.Delete("memory:obj", "key1") + err = manager.Delete("memory::obj", "key1") assert.Nil(t, err) - val, err := manager.Get("memory:obj", "key1", nil, nil) + val, err := manager.Get("memory::obj", "key1", nil, nil) assert.NotNil(t, err) assert.Empty(t, val) // Delete object - err2 := manager.DeleteObject("memory:obj") + err2 := manager.DeleteObject("memory::obj") assert.Nil(t, err2) - val2, err2 := manager.GetObject("memory:obj", nil, nil) + val2, err2 := manager.GetObject("memory::obj", nil, nil) assert.NotNil(t, err2) assert.Empty(t, val2) } @@ -421,5 +421,46 @@ func TestObjectDeleteWithMoreProviders(t *testing.T) { val2, err2 := manager.GetObject("obj", nil, nil) assert.NotNil(t, err2) assert.Empty(t, val2) +} + +func TestObjectReference(t *testing.T) { + provider1 := memory.MemoryConfigProvider{} + err := provider1.Init(memory.MemoryConfigProviderConfig{}) + assert.Nil(t, err) + provider2 := memory.MemoryConfigProvider{} + err = provider2.Init(memory.MemoryConfigProviderConfig{}) + assert.Nil(t, err) + manager := ConfigsManager{ + ConfigProviders: map[string]config.IConfigProvider{ + "memory1": &provider1, + "memory2": &provider2, + }, + Precedence: []string{"memory1", "memory2"}, + } + assert.Nil(t, err) + object := map[string]interface{}{ + "key1": "value1", + "key2": 42, + "key3": true, + } + // Get field + manager.SetObject("memory1::obj:v1", object) + val, err := manager.Get("obj:v1", "key1", nil, nil) + assert.Nil(t, err) + assert.Equal(t, "value1", val) + + // Delete field + err = manager.Delete("memory1::obj:v1", "key1") + assert.Nil(t, err) + val, err = manager.Get("memory1::obj:v1", "key1", nil, nil) + assert.NotNil(t, err) + assert.Empty(t, val) + + // Delete object + err2 := manager.DeleteObject("memory1::obj:v1") + assert.Nil(t, err2) + val2, err2 := manager.GetObject("memory1::obj:v1", nil, nil) + assert.NotNil(t, err2) + assert.Empty(t, val2) } diff --git a/api/pkg/apis/v1alpha1/utils/utils.go b/api/pkg/apis/v1alpha1/utils/utils.go index 670857bfd..1b3feacac 100644 --- a/api/pkg/apis/v1alpha1/utils/utils.go +++ b/api/pkg/apis/v1alpha1/utils/utils.go @@ -10,7 +10,6 @@ import ( "bytes" "encoding/json" "fmt" - "net/url" "os" "regexp" "strconv" @@ -321,15 +320,6 @@ func jsonPathQuery(obj interface{}, jsonPath string) (interface{}, error) { } } -func GetUnescapaedString(name string) (string, error) { - unescapedId, err := url.PathUnescape(name) - if err != nil { - return "", err - } - id := ReplaceSeperator(unescapedId) - return id, nil -} - func ReplaceSeperator(name string) string { if strings.Contains(name, ":") { name = strings.ReplaceAll(name, ":", "-") From 848fecbe707a571ef1131602f0150e48ce28a0cc Mon Sep 17 00:00:00 2001 From: Lency Qian Date: Fri, 31 May 2024 15:05:33 +0800 Subject: [PATCH 3/6] fix suite test --- .../scenarios/06.ado/create_update_fallback_test.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/integration/scenarios/06.ado/create_update_fallback_test.go b/test/integration/scenarios/06.ado/create_update_fallback_test.go index 8b837822e..aa50337b4 100644 --- a/test/integration/scenarios/06.ado/create_update_fallback_test.go +++ b/test/integration/scenarios/06.ado/create_update_fallback_test.go @@ -101,7 +101,7 @@ var _ = Describe("Create/update resources for rollback testing", Ordered, func() By("preparing the instance bytes with a new operation id for Solution V2") instanceBytes, err = testhelpers.PatchInstance(defaultInstanceManifest, testhelpers.InstanceOptions{ - Solution: "solution-v2", + Solution: "solution:v2", }) Expect(err).ToNot(HaveOccurred()) @@ -115,7 +115,7 @@ var _ = Describe("Create/update resources for rollback testing", Ordered, func() By("reverting the Instance to use Solution V1") instanceBytes, err = testhelpers.PatchInstance(defaultInstanceManifest, testhelpers.InstanceOptions{ - Solution: "solution", + Solution: "solution:v1", }) Expect(err).ToNot(HaveOccurred()) From b4b86ff0950e666c7140a2da8ab3bcd23bf9ab6d Mon Sep 17 00:00:00 2001 From: Lency Qian Date: Fri, 31 May 2024 17:54:14 +0800 Subject: [PATCH 4/6] fix ado test issue --- .../06.ado/create_update_fallback_test.go | 2 +- .../scenarios/06.ado/create_update_test.go | 40 +++++++++---------- .../scenarios/06.ado/suite_test.go | 12 +++--- 3 files changed, 27 insertions(+), 27 deletions(-) diff --git a/test/integration/scenarios/06.ado/create_update_fallback_test.go b/test/integration/scenarios/06.ado/create_update_fallback_test.go index aa50337b4..17e9acdaf 100644 --- a/test/integration/scenarios/06.ado/create_update_fallback_test.go +++ b/test/integration/scenarios/06.ado/create_update_fallback_test.go @@ -134,7 +134,7 @@ var _ = Describe("Create/update resources for rollback testing", Ordered, func() SolutionComponents: []string{"simple-chart-2"}, SolutionComponentsV2: []string{"simple-chart-2-nonexistent"}, PostUpdateExpectation: expectations.All( - kube.Must(kube.Instance("instance", "default", kube.WithCondition(conditions.All( // make sure the instance named 'instance' is present in the 'default' namespace + kube.Must(kube.Instance("instance-v1", "default", kube.WithCondition(conditions.All( // make sure the instance named 'instance-v1' is present in the 'default' namespace kube.ProvisioningFailedCondition, // and it is failed //jq.Equality(".status.provisioningStatus.error.details[0].details[0].code", "Update Failed"), )))), diff --git a/test/integration/scenarios/06.ado/create_update_test.go b/test/integration/scenarios/06.ado/create_update_test.go index 5bfcefa4b..c40d270e1 100644 --- a/test/integration/scenarios/06.ado/create_update_test.go +++ b/test/integration/scenarios/06.ado/create_update_test.go @@ -119,7 +119,7 @@ var _ = Describe("Create resources with sequential changes", Ordered, func() { TargetComponents: []string{"simple-chart-1"}, SolutionComponents: []string{}, Expectation: expectations.All( - kube.Must(kube.Target("target", "default", kube.WithCondition(conditions.All( // make sure the target named 'target' is present in the 'default' namespace + kube.Must(kube.Target("target-v1", "default", kube.WithCondition(conditions.All( // make sure the target named 'target-v1' is present in the 'default' namespace kube.ProvisioningSucceededCondition, // and it is successfully provisioned ////kube.OperationIdMatchCondition, // and the status operation id matches the metadata operation id //kube.ProvisioningStatusComponentOutput("target.simple-chart-1", "Updated"), // and the target component 'simple-chart-1' status is updated. OSS has no provisioning status yet @@ -136,12 +136,12 @@ var _ = Describe("Create resources with sequential changes", Ordered, func() { TargetComponents: []string{"simple-chart-1"}, // (same as previous entry) SolutionComponents: []string{"simple-chart-2"}, Expectation: expectations.All( - kube.Must(kube.Target("target", "default", kube.WithCondition(conditions.All( // make sure the target named 'target' is present in the 'default' namespace + kube.Must(kube.Target("target-v1", "default", kube.WithCondition(conditions.All( // make sure the target named 'target-v1' is present in the 'default' namespace kube.ProvisioningSucceededCondition, // and it is successfully provisioned ////kube.OperationIdMatchCondition, // and the status operation id matches the metadata operation id //kube.ProvisioningStatusComponentOutput("target.simple-chart-1", nil), // Because nothing changed, the output should be nil )))), - kube.Must(kube.Instance("instance", "default", kube.WithCondition(conditions.All( // make sure the instance named 'instance' is present in the 'default' namespace + kube.Must(kube.Instance("instance-v1", "default", kube.WithCondition(conditions.All( // make sure the instance named 'instance-v1' is present in the 'default' namespace kube.ProvisioningSucceededCondition, // and it is successfully provisioned ////kube.OperationIdMatchCondition, // and the status operation id matches the metadata operation id //kube.ProvisioningStatusComponentOutput("target.simple-chart-2", "Updated"), // and the solution component 'simple-chart-2' is created @@ -163,12 +163,12 @@ var _ = Describe("Create resources with sequential changes", Ordered, func() { TargetComponents: []string{"simple-chart-1"}, // (same as previous entry) SolutionComponents: []string{"simple-chart-2", "basic-configmap-1"}, // Expectation: expectations.All( - kube.Must(kube.Target("target", "default", kube.WithCondition(conditions.All( // make sure the target named 'target' is present in the 'default' namespace + kube.Must(kube.Target("target-v1", "default", kube.WithCondition(conditions.All( // make sure the target named 'target-v1' is present in the 'default' namespace kube.ProvisioningSucceededCondition, // and it is successfully provisioned ////kube.OperationIdMatchCondition, // and the status operation id matches the metadata operation id //kube.ProvisioningStatusComponentOutput("target.simple-chart-1", nil), // Because the component didn't change )))), - kube.Must(kube.Instance("instance", "default", kube.WithCondition(conditions.All( // make sure the instance named 'instance' is present in the 'default' namespace + kube.Must(kube.Instance("instance-v1", "default", kube.WithCondition(conditions.All( // make sure the instance named 'instance-v1' is present in the 'default' namespace kube.ProvisioningSucceededCondition, // and it is successfully provisioned ////kube.OperationIdMatchCondition, // and the status operation id matches the metadata operation id //kube.ProvisioningStatusComponentOutput("target.simple-chart-2", nil), // Because the component didn't change @@ -189,13 +189,13 @@ var _ = Describe("Create resources with sequential changes", Ordered, func() { TargetComponents: []string{"simple-chart-1", "basic-clusterrole"}, // SolutionComponents: []string{"simple-chart-2", "basic-configmap-1"}, // (same as previous entry) Expectation: expectations.All( - kube.Must(kube.Target("target", "default", kube.WithCondition(conditions.All( // make sure the target named 'target' is present in the 'default' namespace + kube.Must(kube.Target("target-v1", "default", kube.WithCondition(conditions.All( // make sure the target named 'target-v1' is present in the 'default' namespace kube.ProvisioningSucceededCondition, // and it is successfully provisioned ////kube.OperationIdMatchCondition, // and the status operation id matches the metadata operation id //kube.ProvisioningStatusComponentOutput("target.simple-chart-1", nil), // Because the component didn't change //kube.ProvisioningStatusComponentOutput("target.basic-clusterrole", "Updated"), // and the target component 'basic-clusterrole' is created )))), - kube.Must(kube.Instance("instance", "default", kube.WithCondition(conditions.All( // make sure the instance named 'instance' is present in the 'default' namespace + kube.Must(kube.Instance("instance-v1", "default", kube.WithCondition(conditions.All( // make sure the instance named 'instance-v1' is present in the 'default' namespace kube.ProvisioningSucceededCondition, // and it is successfully provisioned ////kube.OperationIdMatchCondition, // and the status operation id matches the metadata operation id //kube.ProvisioningStatusComponentOutput("target.simple-chart-2", nil), // Because the component didn't change @@ -217,13 +217,13 @@ var _ = Describe("Create resources with sequential changes", Ordered, func() { TargetComponents: []string{"simple-chart-1", "basic-clusterrole"}, // (same as previous entry) SolutionComponents: []string{"simple-chart-2", "basic-configmap-1"}, // (same as previous entry) Expectation: expectations.All( - kube.Must(kube.Target("target", "default", kube.WithCondition(conditions.All( // make sure the target named 'target' is present in the 'default' namespace + kube.Must(kube.Target("target-v1", "default", kube.WithCondition(conditions.All( // make sure the target named 'target-v1' is present in the 'default' namespace kube.ProvisioningSucceededCondition, // and it is successfully provisioned ////kube.OperationIdMatchCondition, // and the status operation id matches the metadata operation id //kube.ProvisioningStatusComponentOutput("target.simple-chart-1", nil), // Because the component didn't change //kube.ProvisioningStatusComponentOutput("target.basic-clusterrole", nil), // Because the component didn't change )))), - kube.Must(kube.Instance("instance", "default", kube.WithCondition(conditions.All( // make sure the instance named 'instance' is present in the 'default' namespace + kube.Must(kube.Instance("instance-v1", "default", kube.WithCondition(conditions.All( // make sure the instance named 'instance-v1' is present in the 'default' namespace kube.ProvisioningSucceededCondition, // and it is successfully provisioned ////kube.OperationIdMatchCondition, // and the status operation id matches the metadata operation id //kube.ProvisioningStatusComponentOutput("target.simple-chart-2", nil), // Because the component didn't change @@ -245,13 +245,13 @@ var _ = Describe("Create resources with sequential changes", Ordered, func() { TargetComponents: []string{"simple-chart-1"}, SolutionComponents: []string{"simple-chart-2", "basic-configmap-1"}, // (same as previous entry) Expectation: expectations.All( - kube.Must(kube.Target("target", "default", kube.WithCondition(conditions.All( // make sure the target named 'target' is present in the 'default' namespace + kube.Must(kube.Target("target-v1", "default", kube.WithCondition(conditions.All( // make sure the target named 'target-v1' is present in the 'default' namespace kube.ProvisioningSucceededCondition, // and it is successfully provisioned ////kube.OperationIdMatchCondition, // and the status operation id matches the metadata operation id //kube.ProvisioningStatusComponentOutput("target.simple-chart-1", nil), // Because the component didn't change //kube.ProvisioningStatusComponentOutput("target.basic-clusterrole", "Deleted"), // and the target component 'basic-clusterrole' is deleted )))), - kube.Must(kube.Instance("instance", "default", kube.WithCondition(conditions.All( // make sure the instance named 'instance' is present in the 'default' namespace + kube.Must(kube.Instance("instance-v1", "default", kube.WithCondition(conditions.All( // make sure the instance named 'instance-v1' is present in the 'default' namespace kube.ProvisioningSucceededCondition, // and it is successfully provisioned //kube.OperationIdMatchCondition, // and the status operation id matches the metadata operation id //kube.ProvisioningStatusComponentOutput("target.simple-chart-2", nil), // Because the component didn't change @@ -273,13 +273,13 @@ var _ = Describe("Create resources with sequential changes", Ordered, func() { TargetComponents: []string{"simple-chart-1"}, // (same as previous entry) SolutionComponents: []string{"basic-configmap-1"}, Expectation: expectations.All( - kube.Must(kube.Target("target", "default", kube.WithCondition(conditions.All( // make sure the target named 'target' is present in the 'default' namespace + kube.Must(kube.Target("target-v1", "default", kube.WithCondition(conditions.All( // make sure the target named 'target-v1' is present in the 'default' namespace kube.ProvisioningSucceededCondition, // and it is successfully provisioned //kube.OperationIdMatchCondition, // and the status operation id matches the metadata operation id //kube.ProvisioningStatusComponentOutput("target.simple-chart-1", nil), // Because the component didn't change //kube.ProvisioningStatusComponentOutput("target.basic-clusterrole", nil), // Because it was deleted in the previous reconciliation )))), - kube.Must(kube.Instance("instance", "default", kube.WithCondition(conditions.All( // make sure the instance named 'instance' is present in the 'default' namespace + kube.Must(kube.Instance("instance-v1", "default", kube.WithCondition(conditions.All( // make sure the instance named 'instance-v1' is present in the 'default' namespace kube.ProvisioningSucceededCondition, // and it is successfully provisioned //kube.OperationIdMatchCondition, // and the status operation id matches the metadata operation id //kube.ProvisioningStatusComponentOutput("target.simple-chart-2", "Deleted"), // and the solution component 'simple-chart-2' is deleted @@ -302,12 +302,12 @@ var _ = Describe("Create resources with sequential changes", Ordered, func() { TargetComponents: []string{"simple-chart-1"}, // (same as previous entry) SolutionComponents: []string{"basic-configmap-1-modified"}, // (same as previous entry but with new data) Expectation: expectations.All( - kube.Must(kube.Target("target", "default", kube.WithCondition(conditions.All( // make sure the target named 'target' is present in the 'default' namespace + kube.Must(kube.Target("target-v1", "default", kube.WithCondition(conditions.All( // make sure the target named 'target-v1' is present in the 'default' namespace kube.ProvisioningSucceededCondition, // and it is successfully provisioned //kube.OperationIdMatchCondition, // and the status operation id matches the metadata operation id //kube.ProvisioningStatusComponentOutput("target.simple-chart-1", nil), // Because the component didn't change )))), - kube.Must(kube.Instance("instance", "default", kube.WithCondition(conditions.All( // make sure the instance named 'instance' is present in the 'default' namespace + kube.Must(kube.Instance("instance-v1", "default", kube.WithCondition(conditions.All( // make sure the instance named 'instance-v1' is present in the 'default' namespace kube.ProvisioningSucceededCondition, // and it is successfully provisioned //kube.OperationIdMatchCondition, // and the status operation id matches the metadata operation id //kube.ProvisioningStatusComponentOutput("target.basic-configmap-1", "Updated"), // and the solution component 'basic-configmap-1' is updated @@ -334,7 +334,7 @@ var _ = Describe("Create resources with sequential changes", Ordered, func() { TargetComponents: []string{"simple-chart-1-nonexistent"}, // SolutionComponents: []string{"basic-configmap-1-modified"}, // (same as previous entry) Expectation: expectations.All( - kube.Must(kube.Target("target", "default", kube.WithCondition(conditions.All( // make sure the target named 'target' is present in the 'default' namespace + kube.Must(kube.Target("target-v1", "default", kube.WithCondition(conditions.All( // make sure the target named 'target-v1' is present in the 'default' namespace kube.ProvisioningFailedCondition, // and it is failed //jq.Equality(".status.provisioningStatus.error.details[0].code", "Update Failed"), //jq.Equality(".status.provisioningStatus.error.details[0].target", "simple-chart-1"), @@ -350,12 +350,12 @@ var _ = Describe("Create resources with sequential changes", Ordered, func() { TargetComponents: []string{"simple-chart-1-nonexistent"}, // (same as previous entry) SolutionComponents: []string{"simple-chart-2-nonexistent"}, // Expectation: expectations.All( - kube.Must(kube.Target("target", "default", kube.WithCondition(conditions.All( // make sure the target named 'target' is present in the 'default' namespace + kube.Must(kube.Target("target-v1", "default", kube.WithCondition(conditions.All( // make sure the target named 'target-v1' is present in the 'default' namespace kube.ProvisioningFailedCondition, // and it is failed //jq.Equality(".status.provisioningStatus.error.details[0].code", "Update Failed"), //jq.Equality(".status.provisioningStatus.error.details[0].target", "simple-chart-1"), )))), - kube.Must(kube.Instance("instance", "default", kube.WithCondition(conditions.All( // make sure the instance named 'instance' is present in the 'default' namespace + kube.Must(kube.Instance("instance-v1", "default", kube.WithCondition(conditions.All( // make sure the instance named 'instance-v1' is present in the 'default' namespace kube.ProvisioningFailedCondition, // and it is failed //jq.Equality(".status.provisioningStatus.error.details[0].details[0].code", "Update Failed"), //jq.Equality(".status.provisioningStatus.error.details[0].details[0].target", "simple-chart-2"), @@ -369,7 +369,7 @@ var _ = Describe("Create resources with sequential changes", Ordered, func() { TargetComponents: []string{"simple-http"}, SolutionComponents: []string{}, Expectation: expectations.All( - kube.Must(kube.Target("target", "default", kube.WithCondition(conditions.All( // make sure the target named 'target' is present in the 'default' namespace + kube.Must(kube.Target("target-v1", "default", kube.WithCondition(conditions.All( // make sure the target named 'target-v1' is present in the 'default' namespace kube.ProvisioningSucceededCondition, // and it is successfully provisioned //kube.OperationIdMatchCondition, // and the status operation id matches the metadata operation id //kube.ProvisioningStatusComponentOutput("target.simple-http", "Updated"), // and the target component 'simple-http' status is updated @@ -384,7 +384,7 @@ var _ = Describe("Create resources with sequential changes", Ordered, func() { TargetComponents: []string{"simple-http-invalid-url"}, SolutionComponents: []string{}, Expectation: expectations.All( - kube.Must(kube.Target("target", "default", kube.WithCondition(conditions.All( // make sure the target named 'target' is present in the 'default' namespace + kube.Must(kube.Target("target-v1", "default", kube.WithCondition(conditions.All( // make sure the target named 'target-v1' is present in the 'default' namespace kube.ProvisioningFailedCondition, // and it is failed //kube.OperationIdMatchCondition, // and the status operation id matches the metadata operation id //kube.ProvisioningStatusComponentOutput("target.simple-http", nil), // and the target component 'simple-http-invalid-url' status is failed to update diff --git a/test/integration/scenarios/06.ado/suite_test.go b/test/integration/scenarios/06.ado/suite_test.go index 27767e959..43688d565 100644 --- a/test/integration/scenarios/06.ado/suite_test.go +++ b/test/integration/scenarios/06.ado/suite_test.go @@ -24,28 +24,28 @@ var defaultTargetManifest []byte //go:embed manifest/solution.yaml var defaultSolutionManifest []byte -var successfullTargetExpectation = kube.Must(kube.Target("target", "default", kube.WithCondition(conditions.All( +var successfullTargetExpectation = kube.Must(kube.Target("target-v1", "default", kube.WithCondition(conditions.All( kube.ProvisioningSucceededCondition, //kube.OperationIdMatchCondition, )))) -var successfullInstanceExpectation = kube.Must(kube.Instance("instance", "default", kube.WithCondition(conditions.All( +var successfullInstanceExpectation = kube.Must(kube.Instance("instance-v1", "default", kube.WithCondition(conditions.All( kube.ProvisioningSucceededCondition, //kube.OperationIdMatchCondition, )))) -var failedTargetExpectation = kube.Must(kube.Target("target", "default", kube.WithCondition(conditions.All( +var failedTargetExpectation = kube.Must(kube.Target("target-v1", "default", kube.WithCondition(conditions.All( kube.ProvisioningFailedCondition, //kube.OperationIdMatchCondition, )))) -var failedInstanceExpectation = kube.Must(kube.Instance("instance", "default", kube.WithCondition(conditions.All( +var failedInstanceExpectation = kube.Must(kube.Instance("instance-v1", "default", kube.WithCondition(conditions.All( kube.ProvisioningFailedCondition, //kube.OperationIdMatchCondition, )))) -var absentInstanceExpectation = kube.Must(kube.AbsentInstance("instance", "default")) -var absentTargetExpectation = kube.Must(kube.AbsentTarget("target", "default")) +var absentInstanceExpectation = kube.Must(kube.AbsentInstance("instance-v1", "default")) +var absentTargetExpectation = kube.Must(kube.AbsentTarget("target-v1", "default")) var _ = BeforeSuite(func(ctx context.Context) { // err := shell.LocalenvCmd(ctx, "mage cluster:load") From 7ffe2a51db0c963e07eb971924b40adbd9de509a Mon Sep 17 00:00:00 2001 From: Lency Qian Date: Mon, 3 Jun 2024 13:06:58 +0800 Subject: [PATCH 5/6] fix k8s test issue after rebase --- k8s/testing/mocks.go | 13 ++++++++----- .../04.workflow/manifest/catalog-catalog.yaml | 4 ++-- .../04.workflow/manifest/solution-catalog.yaml | 6 +++--- .../04.workflow/manifest/target-catalog.yaml | 2 +- 4 files changed, 14 insertions(+), 11 deletions(-) diff --git a/k8s/testing/mocks.go b/k8s/testing/mocks.go index 1473371f9..8d401ed94 100644 --- a/k8s/testing/mocks.go +++ b/k8s/testing/mocks.go @@ -63,9 +63,12 @@ var ( ) var ( - DefaultTargetNamepsacedName = types.NamespacedName{Name: "test-target", Namespace: TestNamespace} - DefaultInstanceNamespacedName = types.NamespacedName{Name: "test-instance", Namespace: TestNamespace} - DefaultSolutionNamespacedName = types.NamespacedName{Name: "test-solution", Namespace: TestNamespace} + DefaultTargetNamepsacedName = types.NamespacedName{Name: "target-v1", Namespace: TestNamespace} + DefaultInstanceNamespacedName = types.NamespacedName{Name: "instance-v1", Namespace: TestNamespace} + DefaultSolutionNamespacedName = types.NamespacedName{Name: "solution-v1", Namespace: TestNamespace} + + SolutionReferenceName = "solution:v1" + TagetReferenceName = "target:v1" TerminalError = v1alpha2.NewCOAError(errors.New(""), "timed out", v1alpha2.TimedOut) NotFoundError = v1alpha2.NewCOAError(errors.New(""), "not found", v1alpha2.NotFound) @@ -325,9 +328,9 @@ func BuildDefaultInstance() *solution_v1.Instance { }, Spec: k8smodel.InstanceSpec{ Target: model.TargetSelector{ - Name: DefaultTargetNamepsacedName.Name, + Name: TagetReferenceName, }, - Solution: DefaultSolutionNamespacedName.Name, + Solution: SolutionReferenceName, }, } } diff --git a/test/integration/scenarios/04.workflow/manifest/catalog-catalog.yaml b/test/integration/scenarios/04.workflow/manifest/catalog-catalog.yaml index e6bf85774..a9354a65c 100644 --- a/test/integration/scenarios/04.workflow/manifest/catalog-catalog.yaml +++ b/test/integration/scenarios/04.workflow/manifest/catalog-catalog.yaml @@ -1,12 +1,12 @@ apiVersion: federation.symphony/v1 kind: Catalog metadata: - name: site-catalog + name: site-catalog-v1 spec: type: catalog properties: metadata: - name: web-app-config + name: web-app-config-v1 spec: type: config properties: diff --git a/test/integration/scenarios/04.workflow/manifest/solution-catalog.yaml b/test/integration/scenarios/04.workflow/manifest/solution-catalog.yaml index d38d3443b..a8dbb6635 100644 --- a/test/integration/scenarios/04.workflow/manifest/solution-catalog.yaml +++ b/test/integration/scenarios/04.workflow/manifest/solution-catalog.yaml @@ -1,7 +1,7 @@ apiVersion: federation.symphony/v1 kind: Catalog metadata: - name: site-app + name: site-app-v1 spec: type: solution properties: @@ -11,8 +11,8 @@ spec: type: container metadata: service.ports: "[{\"name\":\"port3011\",\"port\": 3011,\"targetPort\":5000}]" - service.type: "${{$config('web-app-config','serviceType')}}" + service.type: "${{$config('web-app-config:v1','serviceType')}}" properties: deployment.replicas: "#1" container.ports: "[{\"containerPort\":5000,\"protocol\":\"TCP\"}]" - container.image: "${{$config('web-app-config','image')}}" \ No newline at end of file + container.image: "${{$config('web-app-config:v1','image')}}" \ No newline at end of file diff --git a/test/integration/scenarios/04.workflow/manifest/target-catalog.yaml b/test/integration/scenarios/04.workflow/manifest/target-catalog.yaml index 5a2032cd1..f2c6b185c 100644 --- a/test/integration/scenarios/04.workflow/manifest/target-catalog.yaml +++ b/test/integration/scenarios/04.workflow/manifest/target-catalog.yaml @@ -1,7 +1,7 @@ apiVersion: federation.symphony/v1 kind: Catalog metadata: - name: site-k8s-target + name: site-k8s-target-v1 spec: type: target properties: From 4a8c62dc1bd7987d46d9808c638fba18051e8939 Mon Sep 17 00:00:00 2001 From: Lency Qian Date: Mon, 3 Jun 2024 13:13:45 +0800 Subject: [PATCH 6/6] change reconcile timeout to 1s --- k8s/reconcilers/update_test.go | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/k8s/reconcilers/update_test.go b/k8s/reconcilers/update_test.go index e7a543f8b..9d02a4e43 100644 --- a/k8s/reconcilers/update_test.go +++ b/k8s/reconcilers/update_test.go @@ -139,7 +139,7 @@ var _ = Describe("Calling 'AttemptUpdate' on object", func() { Expect(object.Status.ProvisioningStatus.Status).To(Equal("Succeeded")) }) It("should requue after some time", func() { - Expect(reconcileResult.RequeueAfter).To(BeWithin("10ms").Of(TestReconcileInterval)) + Expect(reconcileResult.RequeueAfter).To(BeWithin("1s").Of(TestReconcileInterval)) }) }) @@ -163,7 +163,7 @@ var _ = Describe("Calling 'AttemptUpdate' on object", func() { }) It("should requue after some time", func() { - Expect(reconcileResult.RequeueAfter).To(BeWithin("10ms").Of(TestPollInterval)) + Expect(reconcileResult.RequeueAfter).To(BeWithin("1s").Of(TestPollInterval)) }) }) @@ -181,7 +181,7 @@ var _ = Describe("Calling 'AttemptUpdate' on object", func() { }) It("should requue after some time", func() { - Expect(reconcileResult.RequeueAfter).To(BeWithin("10ms").Of(TestPollInterval)) + Expect(reconcileResult.RequeueAfter).To(BeWithin("1s").Of(TestPollInterval)) }) }) @@ -252,7 +252,7 @@ var _ = Describe("Calling 'AttemptUpdate' on object", func() { Expect(object.Status.ProvisioningStatus.Status).To(Equal("Reconciling")) }) It("should requue after some time", func() { - Expect(reconcileResult.RequeueAfter).To(BeWithin("10ms").Of(TestPollInterval)) + Expect(reconcileResult.RequeueAfter).To(BeWithin("1s").Of(TestPollInterval)) }) It("should updpate the compoent status with progress", func() { Expect(object.Status.Properties["targets.default-target.comp1"]).To(ContainSubstring("updated")) @@ -282,7 +282,7 @@ var _ = Describe("Calling 'AttemptUpdate' on object", func() { Expect(object.Status.ProvisioningStatus.Status).To(ContainSubstring("Reconciling")) }) It("should requue after some time", func() { - Expect(reconcileResult.RequeueAfter).To(BeWithin("10ms").Of(TestPollInterval)) + Expect(reconcileResult.RequeueAfter).To(BeWithin("1s").Of(TestPollInterval)) }) }) @@ -330,7 +330,7 @@ var _ = Describe("Calling 'AttemptUpdate' on object", func() { Expect(object.Status.ProvisioningStatus.Status).To(ContainSubstring("Reconciling")) }) It("should requue after some time", func() { - Expect(reconcileResult.RequeueAfter).To(BeWithin("10ms").Of(TestPollInterval)) + Expect(reconcileResult.RequeueAfter).To(BeWithin("1s").Of(TestPollInterval)) }) })