From f336161a49cdc22c1707c99b00b0ec5ea365c035 Mon Sep 17 00:00:00 2001 From: yair Date: Sun, 31 Dec 2023 18:42:28 +0200 Subject: [PATCH 1/3] creating default pages --- assets/defaults/pages.json | 345 +++++++++++++++++++++++++++++++++++++ pkg/defaults/defaults.go | 100 +++++++++-- pkg/port/cli/page.go | 50 ++++++ pkg/port/models.go | 10 ++ pkg/port/page/page.go | 48 ++++++ 5 files changed, 537 insertions(+), 16 deletions(-) create mode 100644 assets/defaults/pages.json create mode 100644 pkg/port/cli/page.go create mode 100644 pkg/port/page/page.go diff --git a/assets/defaults/pages.json b/assets/defaults/pages.json new file mode 100644 index 0000000..db7026c --- /dev/null +++ b/assets/defaults/pages.json @@ -0,0 +1,345 @@ +[ + { + "identifier": "workload_overview_dashboard", + "icon": "Apps", + "title": "Workload Overview Dashboard", + "widgets": [ + { + "type": "dashboard-widget", + "layout": [ + { + "height": 433, + "columns": [ + { + "id": "explanation", + "size": 6 + }, + { + "id": "workload-health", + "size": 6 + } + ] + }, + { + "height": 400, + "columns": [ + { + "id": "one-replica", + "size": 6 + }, + { + "id": "workloads-namespaces", + "size": 6 + } + ] + } + ], + "widgets": [ + { + "id": "explanation", + "title": "Port Dashboards", + "icon": "port", + "markdown": "[Dashboards](https://docs.getport.io/customize-pages-dashboards-and-plugins/page/dashboard-page) enable you to visualize the data from your catalog. Dashboards contain various widgets that display the data in different ways, such as pie charts, number charts, iframes, and more. You can create pages and dashboards for specific processes and expose them to the relevant people using [page permissions](https://docs.getport.io/customize-pages-dashboards-and-plugins/page/page-permissions).\n\nThis dashboard contains visualizations based on your \"Workload\" catalog. You can edit this dashboard and create new ones. Here are some additional ideas for dashboards\n- [SVP engineering dashboard](https://demo.getport.io/dashboard_svp_engineering)\n- [Security dashboard](https://demo.getport.io/dashboard_security)\n- [SRE dashboard](https://demo.getport.io/dashboard_sre)", + "type": "markdown" + }, + { + "id": "workload-health", + "icon": "PieChart", + "type": "entities-pie-chart", + "description": "According to the \"Workload Health\" indication", + "title": "Deployment status", + "dataset": { + "combinator": "and", + "rules": [ + { + "operator": "=", + "value": "workload", + "property": "$blueprint" + } + ] + }, + "property": "property#isHealthy" + }, + { + "id": "one-replica", + "type": "table-entities-explorer", + "displayMode": "widget", + "title": "Workloads with one replica", + "description": "", + "icon": "Table", + "dataset": { + "combinator": "and", + "rules": [ + { + "operator": "=", + "value": "workload", + "property": "$blueprint" + } + ] + }, + "blueprintConfig": { + "workload": { + "groupSettings": { + "groupBy": [] + }, + "sortSettings": { + "sortBy": [] + }, + "filterSettings": { + "filterBy": { + "combinator": "and", + "rules": [] + } + }, + "propertiesSettings": { + "hidden": [ + "$identifier", + "containers", + "creationTimestamp", + "hasLatest", + "hasLimits", + "hasPrivileged", + "isHealthy", + "kind", + "labels", + "replicas", + "strategy", + "strategyConfig", + "Cluster", + "namespace", + "highAvailability", + "configuration", + "highAvalabilityB", + "highAvalabilityS", + "highAvalabilityG", + "notPrivileged", + "notDefaultNamespace", + "rolloutStrategy", + "imageTag", + "Namespace" + ], + "order": [] + } + } + } + }, + { + "id": "workloads-namespaces", + "icon": "PieChart", + "type": "entities-pie-chart", + "description": "", + "title": "Workloads per namespace", + "dataset": { + "combinator": "and", + "rules": [ + { + "operator": "=", + "value": "workload", + "property": "$blueprint" + } + ] + }, + "property": "mirror-property#namespace" + } + ] + } + ], + "section": "software_catalog", + "type": "dashboard" + }, + { + "identifier": "availability_scorecard_dashboard", + "icon": "Scorecards", + "title": "Availability Scorecard Dashboard", + "widgets": [ + { + "type": "dashboard-widget", + "layout": [ + { + "height": 405, + "columns": [ + { + "id": "explanation", + "size": 6 + }, + { + "id": "levels-summary", + "size": 6 + } + ] + }, + { + "height": 600, + "columns": [ + { + "id": "workloads-by-level", + "size": 12 + } + ] + }, + { + "height": 422, + "columns": [ + { + "id": "one-replica-pie-chart", + "size": 4 + }, + { + "id": "two-replicas-pie-chart", + "size": 4 + }, + { + "id": "three-replicas-pie-chart", + "size": 4 + } + ] + } + ], + "widgets": [ + { + "id": "levels-summary", + "type": "entities-pie-chart", + "property": "scorecard#highAvailability", + "title": "Levels summary", + "dataset": { + "combinator": "and", + "rules": [ + { + "property": "$blueprint", + "operator": "=", + "value": "workload" + } + ] + } + }, + { + "id": "workloads-by-level", + "type": "table-entities-explorer", + "title": "Workloads by level", + "icon": "Users", + "blueprintConfig": { + "workload": { + "groupSettings": { + "groupBy": [ + "highAvailability" + ] + }, + "sortSettings": { + "sortBy": [] + }, + "filterSettings": { + "filterBy": { + "combinator": "and", + "rules": [] + } + }, + "propertiesSettings": { + "hidden": [ + "$identifier", + "$updatedAt", + "$createdAt", + "availableReplicas", + "containers", + "creationTimestamp", + "hasLatest", + "hasLimits", + "hasPrivileged", + "isHealthy", + "kind", + "labels", + "replicas", + "strategy", + "strategyConfig", + "Cluster", + "namespace", + "configuration", + "Namespace", + "notPrivileged", + "notDefaultNamespace", + "rolloutStrategy", + "imageTag" + ], + "order": [] + } + } + }, + "displayMode": "widget", + "dataset": { + "combinator": "and", + "rules": [ + { + "property": "$blueprint", + "operator": "=", + "value": "workload" + } + ] + } + }, + { + "id": "one-replica-pie-chart", + "type": "entities-pie-chart", + "property": "scorecard-rule#highAvailability#highAvalabilityB", + "title": "\"Wanted Replicas\" >= 1", + "icon": "Star", + "dataset": { + "combinator": "and", + "rules": [ + { + "operator": "=", + "value": "workload", + "property": "$blueprint" + } + ] + } + }, + { + "id": "two-replicas-pie-chart", + "type": "entities-pie-chart", + "property": "scorecard-rule#highAvailability#highAvalabilityS", + "title": "\"Wanted Replicas\" >= 2", + "icon": "Star", + "dataset": { + "combinator": "and", + "rules": [ + { + "operator": "=", + "value": "workload", + "property": "$blueprint" + } + ] + }, + "description": "Rule description" + }, + { + "id": "three-replicas-pie-chart", + "type": "entities-pie-chart", + "property": "scorecard-rule#highAvailability#highAvalabilityG", + "title": "\"Wanted Replicas\" >= 3", + "icon": "Star", + "dataset": { + "combinator": "and", + "rules": [ + { + "operator": "=", + "value": "workload", + "property": "$blueprint" + } + ] + }, + "description": "Rule description" + }, + { + "id": "explanation", + "title": "Scorecard dashboard", + "description": "", + "icon": "port", + "markdown": "[Scorecards](https://docs.getport.io/promote-scorecards/) are a way for you and your team to define and measure standards in different categories, such as service maturity, production readiness, quality, productivity, and more. Scorecards contain [rules](https://docs.getport.io/promote-scorecards/#rule-elements) that determine its overall score (such as bronze, silver, and gold).\n\nThis dashboard is based on the \"High Availability\" scorecard we automatically created for your workloads. It contains the following rules:\n- Wanted Replicas >=1 (Bronze rule) \n- Wanted Replicas >=2 (Silver rule)\n- Wanted Replicas >=3 (Gold rule)", + "type": "markdown" + } + ] + } + ], + "section": "software_catalog", + "type": "dashboard" + } +] \ No newline at end of file diff --git a/pkg/defaults/defaults.go b/pkg/defaults/defaults.go index 0e99eb8..4f205ac 100644 --- a/pkg/defaults/defaults.go +++ b/pkg/defaults/defaults.go @@ -7,6 +7,7 @@ import ( "github.com/port-labs/port-k8s-exporter/pkg/port/blueprint" "github.com/port-labs/port-k8s-exporter/pkg/port/cli" "github.com/port-labs/port-k8s-exporter/pkg/port/integration" + "github.com/port-labs/port-k8s-exporter/pkg/port/page" "github.com/port-labs/port-k8s-exporter/pkg/port/scorecards" "gopkg.in/yaml.v3" "k8s.io/klog/v2" @@ -23,10 +24,12 @@ type Defaults struct { Blueprints []port.Blueprint Scorecards []ScorecardDefault AppConfig *port.IntegrationAppConfig + Pages []port.Page } var BlueprintsAsset = "assets/defaults/blueprints.json" var ScorecardsAsset = "assets/defaults/scorecards.json" +var PagesAsset = "assets/defaults/pages.json" var AppConfigAsset = "assets/defaults/appConfig.yaml" func getDefaults() (*Defaults, error) { @@ -63,10 +66,22 @@ func getDefaults() (*Defaults, error) { } } + var pages []port.Page + file, err = os.ReadFile(PagesAsset) + if err != nil { + klog.Infof("No default pages found. Skipping...") + } else { + err = yaml.Unmarshal(file, &pages) + if err != nil { + return nil, err + } + } + return &Defaults{ Blueprints: bp, Scorecards: sc, AppConfig: appConfig, + Pages: pages, }, nil } @@ -108,6 +123,7 @@ func deconstructBlueprintsToCreationSteps(rawBlueprints []port.Blueprint) ([]por type AbortDefaultCreationError struct { BlueprintsToRollback []string + PagesToRollback []string Errors []error } @@ -115,29 +131,52 @@ func (e *AbortDefaultCreationError) Error() string { return "AbortDefaultCreationError" } -func validateBlueprintErrors(createdBlueprints []string, blueprintErrors []error) *AbortDefaultCreationError { - if len(blueprintErrors) > 0 { - for _, err := range blueprintErrors { +func validateResourcesErrors(createdBlueprints []string, createdPages []string, resourceErrors []error) *AbortDefaultCreationError { + if len(resourceErrors) > 0 { + for _, err := range resourceErrors { klog.Infof("Failed to create resources: %v.", err.Error()) } - return &AbortDefaultCreationError{BlueprintsToRollback: createdBlueprints, Errors: blueprintErrors} + return &AbortDefaultCreationError{BlueprintsToRollback: createdBlueprints, PagesToRollback: createdPages, Errors: resourceErrors} } return nil } -func createResources(portClient *cli.PortClient, defaults *Defaults, config *port.Config) *AbortDefaultCreationError { +func validateResourcesDoesNotExist(portClient *cli.PortClient, defaults *Defaults, config *port.Config) *AbortDefaultCreationError { + var errors []error if _, err := integration.GetIntegration(portClient, config.StateKey); err == nil { - return &AbortDefaultCreationError{Errors: []error{ - fmt.Errorf("integration with state key %s already exists", config.StateKey), - }} + + } + + for _, bp := range defaults.Blueprints { + if _, err := blueprint.GetBlueprint(portClient, bp.Identifier); err == nil { + errors = append(errors, fmt.Errorf("blueprint with identifier %s already exists", bp.Identifier)) + } + } + + for _, p := range defaults.Pages { + if _, err := page.GetPage(portClient, p.Identifier); err == nil { + errors = append(errors, fmt.Errorf("page with identifier %s already exists", p.Identifier)) + } + } + + if errors != nil { + return &AbortDefaultCreationError{Errors: errors} + } + return nil +} + +func createResources(portClient *cli.PortClient, defaults *Defaults, config *port.Config) *AbortDefaultCreationError { + if err := validateResourcesDoesNotExist(portClient, defaults, config); err != nil { + return err } bareBlueprints, patchStages := deconstructBlueprintsToCreationSteps(defaults.Blueprints) waitGroup := sync.WaitGroup{} - var blueprintErrors []error + var resourceErrors []error var createdBlueprints []string + var createdPages []string mutex := sync.Mutex{} for _, bp := range bareBlueprints { @@ -148,7 +187,7 @@ func createResources(portClient *cli.PortClient, defaults *Defaults, config *por mutex.Lock() if err != nil { - blueprintErrors = append(blueprintErrors, err) + resourceErrors = append(resourceErrors, err) } else { createdBlueprints = append(createdBlueprints, result.Identifier) } @@ -157,7 +196,7 @@ func createResources(portClient *cli.PortClient, defaults *Defaults, config *por } waitGroup.Wait() - if err := validateBlueprintErrors(createdBlueprints, blueprintErrors); err != nil { + if err := validateResourcesErrors(createdBlueprints, createdPages, resourceErrors); err != nil { return err } @@ -167,14 +206,14 @@ func createResources(portClient *cli.PortClient, defaults *Defaults, config *por go func(bp port.Blueprint) { defer waitGroup.Done() if _, err := blueprint.PatchBlueprint(portClient, bp); err != nil { - blueprintErrors = append(blueprintErrors, err) + resourceErrors = append(resourceErrors, err) } }(bp) } waitGroup.Wait() } - if err := validateBlueprintErrors(createdBlueprints, blueprintErrors); err != nil { + if err := validateResourcesErrors(createdBlueprints, createdPages, resourceErrors); err != nil { return err } @@ -184,20 +223,37 @@ func createResources(portClient *cli.PortClient, defaults *Defaults, config *por go func(blueprintIdentifier string, scorecard port.Scorecard) { defer waitGroup.Done() if err := scorecards.CreateScorecard(portClient, blueprintIdentifier, scorecard); err != nil { - blueprintErrors = append(blueprintErrors, err) + resourceErrors = append(resourceErrors, err) } }(blueprintScorecards.Blueprint, scorecard) } } waitGroup.Wait() - if err := validateBlueprintErrors(createdBlueprints, blueprintErrors); err != nil { + if err := validateResourcesErrors(createdBlueprints, createdPages, resourceErrors); err != nil { + return err + } + + for _, pageToCreate := range defaults.Pages { + waitGroup.Add(1) + go func(p port.Page) { + defer waitGroup.Done() + if err := page.CreatePage(portClient, p); err != nil { + resourceErrors = append(resourceErrors, err) + } else { + createdPages = append(createdPages, p.Identifier) + } + }(pageToCreate) + } + waitGroup.Wait() + + if err := validateResourcesErrors(createdBlueprints, createdPages, resourceErrors); err != nil { return err } if err := integration.CreateIntegration(portClient, config.StateKey, config.EventListenerType, defaults.AppConfig); err != nil { klog.Infof("Failed to create resources: %v.", err.Error()) - return &AbortDefaultCreationError{BlueprintsToRollback: createdBlueprints, Errors: []error{err}} + return &AbortDefaultCreationError{BlueprintsToRollback: createdBlueprints, PagesToRollback: createdPages, Errors: []error{err}} } return nil @@ -222,6 +278,18 @@ func initializeDefaults(portClient *cli.PortClient, config *port.Config) error { }(identifier) } rollbackWg.Wait() + + for _, identifier := range err.PagesToRollback { + rollbackWg.Add(1) + go func(identifier string) { + defer rollbackWg.Done() + if err := page.DeletePage(portClient, identifier); err != nil { + klog.Warningf("Failed to rollback page %s creation: %v", identifier, err) + } + }(identifier) + } + rollbackWg.Wait() + return &ExceptionGroup{Message: err.Error(), Errors: err.Errors} } diff --git a/pkg/port/cli/page.go b/pkg/port/cli/page.go new file mode 100644 index 0000000..d97dd72 --- /dev/null +++ b/pkg/port/cli/page.go @@ -0,0 +1,50 @@ +package cli + +import ( + "fmt" + "github.com/port-labs/port-k8s-exporter/pkg/port" +) + +func (c *PortClient) CreatePage(p port.Page) error { + pb := &port.ResponseBody{} + resp, err := c.Client.R(). + SetBody(p). + SetResult(&pb). + Post("v1/pages") + if err != nil { + return err + } + + if resp.IsError() { + return fmt.Errorf("failed to create page, got: %s", resp.Body()) + } + return nil +} + +func (c *PortClient) GetPage(identifier string) (*port.Page, error) { + pb := &port.ResponseBody{} + resp, err := c.Client.R(). + SetResult(&pb). + SetPathParam("page", identifier). + Get("v1/pages/{page}") + if err != nil { + return nil, err + } + if resp.IsError() { + return nil, fmt.Errorf("failed to get page, got: %s", resp.Body()) + } + return &pb.Pages, nil +} + +func (c *PortClient) DeletePage(identifier string) error { + resp, err := c.Client.R(). + SetPathParam("page", identifier). + Delete("v1/pages/{page}") + if err != nil { + return err + } + if resp.IsError() { + return fmt.Errorf("failed to delete page, got: %s", resp.Body()) + } + return nil +} diff --git a/pkg/port/models.go b/pkg/port/models.go index fa2c952..b5e472c 100644 --- a/pkg/port/models.go +++ b/pkg/port/models.go @@ -108,6 +108,15 @@ type ( Relations map[string]Relation `json:"relations,omitempty"` } + Page struct { + Identifier string `json:"identifier"` + Blueprint string `json:"blueprint,omitempty"` + Title string `json:"title,omitempty"` + Icon string `json:"icon,omitempty"` + Widgets interface{} `json:"widgets,omitempty"` + Type string `json:"type,omitempty"` + } + Action struct { ID string `json:"id,omitempty"` Identifier string `json:"identifier,omitempty"` @@ -165,6 +174,7 @@ type ResponseBody struct { KafkaCredentials OrgKafkaCredentials `json:"credentials"` OrgDetails OrgDetails `json:"organization"` Scorecard Scorecard `json:"scorecard"` + Pages Page `json:"pages"` } type EntityMapping struct { diff --git a/pkg/port/page/page.go b/pkg/port/page/page.go new file mode 100644 index 0000000..2e03047 --- /dev/null +++ b/pkg/port/page/page.go @@ -0,0 +1,48 @@ +package page + +import ( + "context" + "fmt" + "github.com/port-labs/port-k8s-exporter/pkg/port" + "github.com/port-labs/port-k8s-exporter/pkg/port/cli" +) + +func CreatePage(portClient *cli.PortClient, page port.Page) error { + _, err := portClient.Authenticate(context.Background(), portClient.ClientID, portClient.ClientSecret) + if err != nil { + return fmt.Errorf("error authenticating with Port: %v", err) + } + + err = portClient.CreatePage(page) + if err != nil { + return fmt.Errorf("error creating Port page: %v", err) + } + return nil +} + +func GetPage(portClient *cli.PortClient, identifier string) (*port.Page, error) { + _, err := portClient.Authenticate(context.Background(), portClient.ClientID, portClient.ClientSecret) + if err != nil { + return nil, fmt.Errorf("error authenticating with Port: %v", err) + } + + apiPage, err := portClient.GetPage(identifier) + if err != nil { + return nil, fmt.Errorf("error getting Port page: %v", err) + } + + return apiPage, nil +} + +func DeletePage(portClient *cli.PortClient, identifier string) error { + _, err := portClient.Authenticate(context.Background(), portClient.ClientID, portClient.ClientSecret) + if err != nil { + return fmt.Errorf("error authenticating with Port: %v", err) + } + + err = portClient.DeletePage(identifier) + if err != nil { + return fmt.Errorf("error deleting Port page: %v", err) + } + return nil +} From b6db916e94f8cdb1d8baa41d5c6073d74342b3ac Mon Sep 17 00:00:00 2001 From: yair Date: Sun, 31 Dec 2023 18:50:06 +0200 Subject: [PATCH 2/3] tests --- pkg/defaults/defaults_test.go | 78 +++++++++++++++++++++++++++++++---- 1 file changed, 71 insertions(+), 7 deletions(-) diff --git a/pkg/defaults/defaults_test.go b/pkg/defaults/defaults_test.go index c220e7c..444aa57 100644 --- a/pkg/defaults/defaults_test.go +++ b/pkg/defaults/defaults_test.go @@ -8,6 +8,7 @@ import ( "github.com/port-labs/port-k8s-exporter/pkg/port/blueprint" "github.com/port-labs/port-k8s-exporter/pkg/port/cli" "github.com/port-labs/port-k8s-exporter/pkg/port/integration" + "github.com/port-labs/port-k8s-exporter/pkg/port/page" _ "github.com/port-labs/port-k8s-exporter/test_utils" "github.com/stretchr/testify/assert" "testing" @@ -19,7 +20,7 @@ type Fixture struct { stateKey string } -func checkBlueprintsDoesNotExist(f *Fixture, blueprints []string) { +func checkResourcesDoesNotExist(f *Fixture, blueprints []string, pages []string) { for _, bp := range blueprints { _, err := blueprint.GetBlueprint(f.portClient, bp) if err != nil { @@ -27,6 +28,14 @@ func checkBlueprintsDoesNotExist(f *Fixture, blueprints []string) { } assert.NotNil(f.t, err) } + + for _, p := range pages { + _, err := page.GetPage(f.portClient, p) + if err != nil { + _ = page.DeletePage(f.portClient, p) + } + assert.NotNil(f.t, err) + } } func NewFixture(t *testing.T) *Fixture { @@ -64,6 +73,8 @@ func deleteDefaultResources(portClient *cli.PortClient, stateKey string) { _ = blueprint.DeleteBlueprint(portClient, "workload") _ = blueprint.DeleteBlueprint(portClient, "namespace") _ = blueprint.DeleteBlueprint(portClient, "cluster") + _ = page.DeletePage(portClient, "workload_overview_dashboard") + _ = page.DeletePage(portClient, "availability_scorecard_dashboard") } func Test_InitIntegration_InitDefaults(t *testing.T) { @@ -86,6 +97,12 @@ func Test_InitIntegration_InitDefaults(t *testing.T) { _, err = blueprint.GetBlueprint(f.portClient, "cluster") assert.Nil(t, err) + + _, err = page.GetPage(f.portClient, "workload_overview_dashboard") + assert.Nil(t, err) + + _, err = page.GetPage(f.portClient, "availability_scorecard_dashboard") + assert.Nil(t, err) } func Test_InitIntegration_InitDefaults_CreateDefaultResources_False(t *testing.T) { @@ -100,10 +117,10 @@ func Test_InitIntegration_InitDefaults_CreateDefaultResources_False(t *testing.T _, err := integration.GetIntegration(f.portClient, f.stateKey) assert.Nil(t, err) - checkBlueprintsDoesNotExist(f, []string{"workload", "namespace", "cluster"}) + checkResourcesDoesNotExist(f, []string{"workload", "namespace", "cluster"}, []string{"workload_overview_dashboard", "availability_scorecard_dashboard"}) } -func Test_InitIntegration_FailingInitDefaults(t *testing.T) { +func Test_InitIntegration_BlueprintExists(t *testing.T) { f := NewFixture(t) if _, err := blueprint.NewBlueprint(f.portClient, port.Blueprint{ Identifier: "workload", @@ -122,10 +139,57 @@ func Test_InitIntegration_FailingInitDefaults(t *testing.T) { assert.Nil(t, e) i, err := integration.GetIntegration(f.portClient, f.stateKey) - assert.True(t, nil == i.Config.Resources) + assert.Nil(t, i.Config.Resources) + assert.Nil(t, err) + + _, err = blueprint.GetBlueprint(f.portClient, "workload") + assert.Nil(t, err) + + checkResourcesDoesNotExist(f, []string{"namespace", "cluster"}, []string{"workload_overview_dashboard", "availability_scorecard_dashboard"}) +} + +func Test_InitIntegration_PageExists(t *testing.T) { + f := NewFixture(t) + if err := page.CreatePage(f.portClient, port.Page{ + Identifier: "workload_overview_dashboard", + Title: "Workload Overview Dashboard", + }); err != nil { + t.Errorf("Error creating Port page: %s", err.Error()) + } + e := InitIntegration(f.portClient, &port.Config{ + StateKey: f.stateKey, + EventListenerType: "POLLING", + CreateDefaultResources: true, + }) + assert.Nil(t, e) + + i, err := integration.GetIntegration(f.portClient, f.stateKey) + assert.Nil(t, i.Config.Resources) + assert.Nil(t, err) + + _, err = page.GetPage(f.portClient, "workload_overview_dashboard") + assert.Nil(t, err) + + checkResourcesDoesNotExist(f, []string{"workload", "namespace", "cluster"}, []string{"availability_scorecard_dashboard"}) +} + +func Test_InitIntegration_ExistingIntegration(t *testing.T) { + f := NewFixture(t) + err := integration.CreateIntegration(f.portClient, f.stateKey, "", nil) + if err != nil { + t.Errorf("Error creating Port integration: %s", err.Error()) + } + e := InitIntegration(f.portClient, &port.Config{ + StateKey: f.stateKey, + EventListenerType: "POLLING", + CreateDefaultResources: true, + }) + assert.Nil(t, e) + + _, err = integration.GetIntegration(f.portClient, f.stateKey) assert.Nil(t, err) - checkBlueprintsDoesNotExist(f, []string{"namespace", "cluster"}) + checkResourcesDoesNotExist(f, []string{"workload", "namespace", "cluster"}, []string{"workload_overview_dashboard", "availability_scorecard_dashboard"}) } func Test_InitIntegration_DeprecatedResourcesConfiguration(t *testing.T) { @@ -165,7 +229,7 @@ func Test_InitIntegration_DeprecatedResourcesConfiguration(t *testing.T) { assert.Equal(t, expectedResources, i.Config.Resources) assert.Nil(t, err) - checkBlueprintsDoesNotExist(f, []string{"workload", "namespace", "cluster"}) + checkResourcesDoesNotExist(f, []string{"workload", "namespace", "cluster"}, []string{"workload_overview_dashboard", "availability_scorecard_dashboard"}) } func Test_InitIntegration_DeprecatedResourcesConfiguration_ExistingIntegration_EmptyConfiguration(t *testing.T) { @@ -186,5 +250,5 @@ func Test_InitIntegration_DeprecatedResourcesConfiguration_ExistingIntegration_E assert.Nil(t, err) assert.Equal(t, "KAFKA", i.EventListener.Type) - checkBlueprintsDoesNotExist(f, []string{"workload", "namespace", "cluster"}) + checkResourcesDoesNotExist(f, []string{"workload", "namespace", "cluster"}, []string{"workload_overview_dashboard", "availability_scorecard_dashboard"}) } From 76f6a9843a66c0709259dab27714fa1c6f6ab67e Mon Sep 17 00:00:00 2001 From: yair Date: Tue, 2 Jan 2024 14:17:31 +0200 Subject: [PATCH 3/3] fixed empty if statement --- pkg/defaults/defaults.go | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/pkg/defaults/defaults.go b/pkg/defaults/defaults.go index 4f205ac..f0644a1 100644 --- a/pkg/defaults/defaults.go +++ b/pkg/defaults/defaults.go @@ -144,7 +144,9 @@ func validateResourcesErrors(createdBlueprints []string, createdPages []string, func validateResourcesDoesNotExist(portClient *cli.PortClient, defaults *Defaults, config *port.Config) *AbortDefaultCreationError { var errors []error if _, err := integration.GetIntegration(portClient, config.StateKey); err == nil { - + return &AbortDefaultCreationError{Errors: []error{ + fmt.Errorf("integration with state key %s already exists", config.StateKey), + }} } for _, bp := range defaults.Blueprints {