diff --git a/docs/resources/port_action_permissions.md b/docs/resources/port_action_permissions.md
index 6d5c6a39..c2ffb9c4 100644
--- a/docs/resources/port_action_permissions.md
+++ b/docs/resources/port_action_permissions.md
@@ -26,7 +26,7 @@ description: |-
}
}
}
-
+
Example Usage with Policy
Port allows setting dynamic permissions for executing and/or approving execution of self-service actions, based on any properties/relations of an action's corresponding blueprint.
Docs about the Policy language can be found here https://docs.getport.io/create-self-service-experiences/set-self-service-actions-rbac/dynamic-permissions#configuring-permissions.
@@ -75,7 +75,7 @@ description: |-
}
)
}
-
+
}
}
```
@@ -170,7 +170,7 @@ resource "port_action_permissions" "restart_microservice_permissions" {
}
```
-## Disclaimer
+## Disclaimer
- Action permissions are created by default when creating a new action, this means that you should use this resource when you want to change the default permissions of an action.
- When deleting an action permissions resource using terraform, the action permissions will not be deleted from Port, as they are required for the action to work, instead, the action permissions will be removed from the terraform state.
@@ -221,4 +221,4 @@ Optional:
- `policy` (String) The policy to use for execution
- `roles` (List of String) The roles with execution permission
- `teams` (List of String) The teams with execution permission
-- `users` (List of String) The users with execution permission
+- `users` (List of String) The users with execution permission
\ No newline at end of file
diff --git a/docs/resources/port_aggregation_property.md b/docs/resources/port_aggregation_properties.md
similarity index 50%
rename from docs/resources/port_aggregation_property.md
rename to docs/resources/port_aggregation_properties.md
index 50c21e80..b3c4f83d 100644
--- a/docs/resources/port_aggregation_property.md
+++ b/docs/resources/port_aggregation_properties.md
@@ -1,11 +1,11 @@
---
# generated by https://github.com/hashicorp/terraform-plugin-docs
-page_title: "port_aggregation_property Resource - terraform-provider-port-labs"
+page_title: "port_aggregation_properties Resource - terraform-provider-port-labs"
subcategory: ""
description: |-
Aggregation Property
This resource allows you to manage an aggregation property.
- See the Port documentation https://docs.getport.io/build-your-software-catalog/define-your-data-model/setup-blueprint/properties/aggregation-property/ for more information about aggregation properties.
+ See the Port documentation https://docs.getport.io/build-your-software-catalog/define-your-data-model/setup-blueprint/properties/aggregation-properties/ for more information about aggregation properties.
Supported Methods:
count_entities - Count the entities of the target blueprintaverage_entities - Average the entities of the target blueprint by time periodsaveragebyproperty - Calculate the average by property value of the target entitiesaggregatebyproperty - Calculate the aggregate by property value of the target entities, such as sum, min, max, median
Example Usage
@@ -43,15 +43,18 @@ description: |-
}
}
}
- resource "portaggregationproperty" "countkids" {
- aggregationidentifier = "countkids"
+ resource "portaggregationproperties" "parentaggregationproperties" {
blueprintidentifier = portblueprint.parentblueprint.identifier
- targetblueprintidentifier = portblueprint.childblueprint.identifier
- title = "Count Kids"
- icon = "Terraform"
- description = "Count Kids"
- method = {
- count_entities = true
+ properties = {
+ "countkids" = {
+ targetblueprintidentifier = portblueprint.childblueprint.identifier
+ title = "Count Kids"
+ icon = "Terraform"
+ description = "Count Kids"
+ method = {
+ count_entities = true
+ }
+ }
}
}
```
@@ -89,18 +92,21 @@ description: |-
}
}
}
- resource "portaggregationproperty" "averagekidsage" {
- aggregationidentifier = "averagekidsage"
- blueprintidentifier = portblueprint.parentblueprint.identifier
- targetblueprintidentifier = portblueprint.childblueprint.identifier
- title = "Average Kids Age"
- icon = "Terraform"
- description = "Average Kids Age"
- method = {
- averagebyproperty = {
- averageof = "total"
- measuretime_by = "$createdAt"
- property = "age"
+ resource "portaggregationproperties" "parentaggregationproperties" {
+ blueprintidentifier = portblueprint.parentblueprint.identifier
+ properties = {
+ averagekidsage = {
+ targetblueprintidentifier = portblueprint.childblueprint.identifier
+ title = "Average Kids Age"
+ icon = "Terraform"
+ description = "Average Kids Age"
+ method = {
+ averagebyproperty = {
+ averageof = "total"
+ measuretimeby = "$createdAt"
+ property = "age"
+ }
+ }
}
}
}
@@ -132,17 +138,20 @@ description: |-
}
}
}
- resource "portaggregationproperty" "pullrequestsperday" {
- aggregationidentifier = "pullrequestsperday"
- blueprintidentifier = portblueprint.repositoryblueprint.identifier
- targetblueprintidentifier = portblueprint.pullrequestblueprint.identifier
- title = "Pull Requests Per Day"
- icon = "Terraform"
- description = "Pull Requests Per Day"
- method = {
- averageentities = {
- averageof = "day"
- measuretime_by = "$createdAt"
+ resource "portaggregationproperties" "repositoryaggregationproperties" {
+ blueprintidentifier = portblueprint.repositoryblueprint.identifier
+ properties = {
+ "pullrequestsperday" = {
+ targetblueprintidentifier = portblueprint.pullrequestblueprint.identifier
+ title = "Pull Requests Per Day"
+ icon = "Terraform"
+ description = "Pull Requests Per Day"
+ method = {
+ averageentities = {
+ averageof = "day"
+ measuretime_by = "$createdAt"
+ }
+ }
}
}
}
@@ -175,42 +184,99 @@ description: |-
}
}
}
- resource "portaggregationproperty" "fixpullrequestsperday" {
- aggregationidentifier = "fixpullrequestscount"
- blueprintidentifier = portblueprint.repositoryblueprint.identifier
- targetblueprintidentifier = portblueprint.pullrequestblueprint.identifier
- title = "Pull Requests Per Day"
- icon = "Terraform"
- description = "Pull Requests Per Day"
- method = {
- averageentities = {
- averageof = "month"
- measuretimeby = "$createdAt"
+ resource "portaggregationproperties" "repositoryaggregationproperties" {
+ blueprintidentifier = portblueprint.repositoryblueprint.identifier
+ properties = {
+ "fixpullrequestscount" = {
+ targetblueprintidentifier = portblueprint.pullrequestblueprint.identifier
+ title = "Pull Requests Per Day"
+ icon = "Terraform"
+ description = "Pull Requests Per Day"
+ method = {
+ averageentities = {
+ averageof = "month"
+ measuretime_by = "$createdAt"
+ }
+ }
+ query = jsonencode(
+ {
+ "combinator" : "and",
+ "rules" : [
+ {
+ "property" : "$title",
+ "operator" : "ContainsAny",
+ "value" : ["fix", "fixed", "fixing", "Fix"]
+ }
+ ]
+ }
+ )
}
}
- query = jsonencode(
- {
- "combinator" : "and",
- "rules" : [
- {
- "property" : "$title",
- "operator" : "ContainsAny",
- "value" : ["fix", "fixed", "fixing", "Fix"]
+ }
+ ```
+ Create multiple aggregation properties in one resource:
+ ```hcl
+ resource "portblueprint" "repositoryblueprint" {
+ title = "Repository Blueprint"
+ icon = "Terraform"
+ identifier = "repository"
+ description = ""
+ }
+ resource "portblueprint" "pullrequestblueprint" {
+ title = "Pull Request Blueprint"
+ icon = "Terraform"
+ identifier = "pullrequest"
+ description = ""
+ properties = {
+ stringprops = {
+ "status" = {
+ title = "Status"
+ }
+ }
+ }
+ relations = {
+ "repository" = {
+ title = "Repository"
+ target = portblueprint.repository_blueprint.identifier
+ }
+ }
+ }
+ resource "portaggregationproperties" "repositoryaggregationproperties" {
+ blueprintidentifier = portblueprint.repositoryblueprint.identifier
+ properties = {
+ "pullrequestsperday" = {
+ targetblueprintidentifier = portblueprint.pullrequestblueprint.identifier
+ title = "Pull Requests Per Day"
+ icon = "Terraform"
+ description = "Pull Requests Per Day"
+ method = {
+ averageentities = {
+ averageof = "day"
+ measuretimeby = "$createdAt"
}
- ]
+ }
}
- )
+ "overallpullrequestscount" = {
+ targetblueprintidentifier = portblueprint.pullrequestblueprint.identifier
+ title = "Overall Pull Requests Count"
+ icon = "Terraform"
+ description = "Overall Pull Requests Count"
+ method = {
+ countentities = true
+ }
+ }
+ }
}
```
---
-# port_aggregation_property (Resource)
+# port_aggregation_properties (Resource)
# Aggregation Property
This resource allows you to manage an aggregation property.
-See the [Port documentation](https://docs.getport.io/build-your-software-catalog/define-your-data-model/setup-blueprint/properties/aggregation-property/) for more information about aggregation properties.
+See the [Port documentation](https://docs.getport.io/build-your-software-catalog/define-your-data-model/setup-blueprint/properties/aggregation-properties/) for more information about aggregation properties.
Supported Methods:
@@ -260,17 +326,21 @@ resource "port_blueprint" "child_blueprint" {
}
}
-resource "port_aggregation_property" "count_kids" {
- aggregation_identifier = "count_kids"
+resource "port_aggregation_properties" "parent_aggregation_properties" {
blueprint_identifier = port_blueprint.parent_blueprint.identifier
- target_blueprint_identifier = port_blueprint.child_blueprint.identifier
- title = "Count Kids"
- icon = "Terraform"
- description = "Count Kids"
- method = {
- count_entities = true
+ properties = {
+ "count_kids" = {
+ target_blueprint_identifier = port_blueprint.child_blueprint.identifier
+ title = "Count Kids"
+ icon = "Terraform"
+ description = "Count Kids"
+ method = {
+ count_entities = true
+ }
+ }
}
}
+
```
Create a parent blueprint with a child blueprint and an aggregation property to calculate the average avg of the parent kids age:
@@ -311,22 +381,26 @@ resource "port_blueprint" "child_blueprint" {
}
}
-resource "port_aggregation_property" "average_kids_age" {
- aggregation_identifier = "average_kids_age"
- blueprint_identifier = port_blueprint.parent_blueprint.identifier
- target_blueprint_identifier = port_blueprint.child_blueprint.identifier
- title = "Average Kids Age"
- icon = "Terraform"
- description = "Average Kids Age"
- method = {
- average_by_property = {
- average_of = "total"
- measure_time_by = "$createdAt"
- property = "age"
+resource "port_aggregation_properties" "parent_aggregation_properties" {
+ blueprint_identifier = port_blueprint.parent_blueprint.identifier
+ properties = {
+ average_kids_age = {
+ target_blueprint_identifier = port_blueprint.child_blueprint.identifier
+ title = "Average Kids Age"
+ icon = "Terraform"
+ description = "Average Kids Age"
+ method = {
+ average_by_property = {
+ average_of = "total"
+ measure_time_by = "$createdAt"
+ property = "age"
+ }
+ }
}
}
}
+
```
Create a repository blueprint and a pull request blueprint and an aggregation property to calculate the average of pull requests created per day:
@@ -360,17 +434,20 @@ resource "port_blueprint" "pull_request_blueprint" {
}
}
-resource "port_aggregation_property" "pull_requests_per_day" {
- aggregation_identifier = "pull_requests_per_day"
- blueprint_identifier = port_blueprint.repository_blueprint.identifier
- target_blueprint_identifier = port_blueprint.pull_request_blueprint.identifier
- title = "Pull Requests Per Day"
- icon = "Terraform"
- description = "Pull Requests Per Day"
- method = {
- average_entities = {
- average_of = "day"
- measure_time_by = "$createdAt"
+resource "port_aggregation_properties" "repository_aggregation_properties" {
+ blueprint_identifier = port_blueprint.repository_blueprint.identifier
+ properties = {
+ "pull_requests_per_day" = {
+ target_blueprint_identifier = port_blueprint.pull_request_blueprint.identifier
+ title = "Pull Requests Per Day"
+ icon = "Terraform"
+ description = "Pull Requests Per Day"
+ method = {
+ average_entities = {
+ average_of = "day"
+ measure_time_by = "$createdAt"
+ }
+ }
}
}
}
@@ -410,31 +487,95 @@ resource "port_blueprint" "pull_request_blueprint" {
}
}
-resource "port_aggregation_property" "fix_pull_requests_per_day" {
- aggregation_identifier = "fix_pull_requests_count"
- blueprint_identifier = port_blueprint.repository_blueprint.identifier
- target_blueprint_identifier = port_blueprint.pull_request_blueprint.identifier
- title = "Pull Requests Per Day"
- icon = "Terraform"
- description = "Pull Requests Per Day"
- method = {
- average_entities = {
- average_of = "month"
- measure_time_by = "$createdAt"
- }
- }
- query = jsonencode(
- {
- "combinator" : "and",
- "rules" : [
+resource "port_aggregation_properties" "repository_aggregation_properties" {
+ blueprint_identifier = port_blueprint.repository_blueprint.identifier
+ properties = {
+ "fix_pull_requests_count" = {
+ target_blueprint_identifier = port_blueprint.pull_request_blueprint.identifier
+ title = "Pull Requests Per Day"
+ icon = "Terraform"
+ description = "Pull Requests Per Day"
+ method = {
+ average_entities = {
+ average_of = "month"
+ measure_time_by = "$createdAt"
+ }
+ }
+ query = jsonencode(
{
- "property" : "$title",
- "operator" : "ContainsAny",
- "value" : ["fix", "fixed", "fixing", "Fix"]
+ "combinator" : "and",
+ "rules" : [
+ {
+ "property" : "$title",
+ "operator" : "ContainsAny",
+ "value" : ["fix", "fixed", "fixing", "Fix"]
+ }
+ ]
+ }
+ )
+ }
+ }
+}
+
+```
+
+
+Create multiple aggregation properties in one resource:
+
+```hcl
+
+resource "port_blueprint" "repository_blueprint" {
+ title = "Repository Blueprint"
+ icon = "Terraform"
+ identifier = "repository"
+ description = ""
+}
+
+resource "port_blueprint" "pull_request_blueprint" {
+ title = "Pull Request Blueprint"
+ icon = "Terraform"
+ identifier = "pull_request"
+ description = ""
+ properties = {
+ string_props = {
+ "status" = {
+ title = "Status"
+ }
+ }
+ }
+ relations = {
+ "repository" = {
+ title = "Repository"
+ target = port_blueprint.repository_blueprint.identifier
+ }
+ }
+}
+
+resource "port_aggregation_properties" "repository_aggregation_properties" {
+ blueprint_identifier = port_blueprint.repository_blueprint.identifier
+ properties = {
+ "pull_requests_per_day" = {
+ target_blueprint_identifier = port_blueprint.pull_request_blueprint.identifier
+ title = "Pull Requests Per Day"
+ icon = "Terraform"
+ description = "Pull Requests Per Day"
+ method = {
+ average_entities = {
+ average_of = "day"
+ measure_time_by = "$createdAt"
}
- ]
+ }
+ }
+ "overall_pull_requests_count" = {
+ target_blueprint_identifier = port_blueprint.pull_request_blueprint.identifier
+ title = "Overall Pull Requests Count"
+ icon = "Terraform"
+ description = "Overall Pull Requests Count"
+ method = {
+ count_entities = true
+ }
}
- )
+ }
}
```
@@ -446,34 +587,40 @@ resource "port_aggregation_property" "fix_pull_requests_per_day" {
### Required
-- `aggregation_identifier` (String) The identifier of the aggregation property in the blueprint
- `blueprint_identifier` (String) The identifier of the blueprint the aggregation property will be added to
-- `method` (Attributes) The aggregation method to perform on the target blueprint, one of count_entities, average_entities, average_by_property, aggregate_by_property (see [below for nested schema](#nestedatt--method))
+- `properties` (Attributes Map) The aggregation property of the blueprint (see [below for nested schema](#nestedatt--properties))
+
+### Read-Only
+
+- `id` (String) The ID of this resource.
+
+
+### Nested Schema for `properties`
+
+Required:
+
+- `method` (Attributes) The aggregation method to perform on the target blueprint, one of count_entities, average_entities, average_by_property, aggregate_by_property (see [below for nested schema](#nestedatt--properties--method))
- `target_blueprint_identifier` (String) The identifier of the blueprint to perform the aggregation on
-### Optional
+Optional:
- `description` (String) The description of the aggregation property
- `icon` (String) The icon of the aggregation property
- `query` (String) Query to filter the target entities
- `title` (String) The title of the aggregation property
-### Read-Only
-
-- `id` (String) The ID of this resource.
-
-
-### Nested Schema for `method`
+
+### Nested Schema for `properties.method`
Optional:
-- `aggregate_by_property` (Attributes) Function to calculate the aggregate by property value of the target entities, such as sum, min, max, median (see [below for nested schema](#nestedatt--method--aggregate_by_property))
-- `average_by_property` (Attributes) Function to calculate the average by property value of the target entities (see [below for nested schema](#nestedatt--method--average_by_property))
-- `average_entities` (Attributes) Function to average the entities of the target entities (see [below for nested schema](#nestedatt--method--average_entities))
+- `aggregate_by_property` (Attributes) Function to calculate the aggregate by property value of the target entities, such as sum, min, max, median (see [below for nested schema](#nestedatt--properties--method--aggregate_by_property))
+- `average_by_property` (Attributes) Function to calculate the average by property value of the target entities (see [below for nested schema](#nestedatt--properties--method--average_by_property))
+- `average_entities` (Attributes) Function to average the entities of the target entities (see [below for nested schema](#nestedatt--properties--method--average_entities))
- `count_entities` (Boolean) Function to count the entities of the target entities
-
-### Nested Schema for `method.aggregate_by_property`
+
+### Nested Schema for `properties.method.aggregate_by_property`
Required:
@@ -481,8 +628,8 @@ Required:
- `property` (String) The property of the aggregate by property
-
-### Nested Schema for `method.average_by_property`
+
+### Nested Schema for `properties.method.average_by_property`
Required:
@@ -491,8 +638,8 @@ Required:
- `property` (String) The property name on which to calculate the average by
-
-### Nested Schema for `method.average_entities`
+
+### Nested Schema for `properties.method.average_entities`
Optional:
diff --git a/port/aggregation-property/model.go b/port/aggregation-properties/model.go
similarity index 80%
rename from port/aggregation-property/model.go
rename to port/aggregation-properties/model.go
index 601a3653..451a1667 100644
--- a/port/aggregation-property/model.go
+++ b/port/aggregation-properties/model.go
@@ -1,11 +1,14 @@
-package aggregation_property
+package aggregation_properties
import "github.com/hashicorp/terraform-plugin-framework/types"
+type AggregationPropertiesModel struct {
+ ID types.String `tfsdk:"id"`
+ BlueprintIdentifier types.String `tfsdk:"blueprint_identifier"`
+ Properties map[string]*AggregationPropertyModel `tfsdk:"properties"`
+}
+
type AggregationPropertyModel struct {
- ID types.String `tfsdk:"id"`
- AggregationIdentifier types.String `tfsdk:"aggregation_identifier"`
- BlueprintIdentifier types.String `tfsdk:"blueprint_identifier"`
Title types.String `tfsdk:"title"`
Icon types.String `tfsdk:"icon"`
Description types.String `tfsdk:"description"`
diff --git a/port/aggregation-properties/readStateToPortBody.go b/port/aggregation-properties/readStateToPortBody.go
new file mode 100644
index 00000000..b6445291
--- /dev/null
+++ b/port/aggregation-properties/readStateToPortBody.go
@@ -0,0 +1,81 @@
+package aggregation_properties
+
+import (
+ "encoding/json"
+ "github.com/port-labs/terraform-provider-port-labs/internal/cli"
+)
+
+func aggregationPropertiesToBody(state *AggregationPropertiesModel) (*map[string]cli.BlueprintAggregationProperty, error) {
+ if state == nil {
+ return nil, nil
+ }
+
+ aggregationProperties := make(map[string]cli.BlueprintAggregationProperty)
+
+ for aggregationPropertyIdentifier, aggregationProperty := range state.Properties {
+
+ newAggregationProperty := cli.BlueprintAggregationProperty{
+ Title: aggregationProperty.Title.ValueStringPointer(),
+ Icon: aggregationProperty.Icon.ValueStringPointer(),
+ Description: aggregationProperty.Description.ValueStringPointer(),
+ Target: aggregationProperty.TargetBlueprintIdentifier.ValueString(),
+ }
+
+ if !aggregationProperty.Method.CountEntities.IsNull() {
+ newAggregationProperty.CalculationSpec = map[string]string{
+ "func": "count",
+ "calculationBy": "entities",
+ }
+ } else if aggregationProperty.Method.AverageEntities != nil {
+ newAggregationProperty.CalculationSpec = map[string]string{
+ "func": "average",
+ "calculationBy": "entities",
+ "averageOf": aggregationProperty.Method.AverageEntities.AverageOf.ValueString(),
+ "measureTimeBy": aggregationProperty.Method.AverageEntities.MeasureTimeBy.ValueString(),
+ }
+ } else if aggregationProperty.Method.AverageByProperty != nil {
+ newAggregationProperty.CalculationSpec = map[string]string{
+ "func": "average",
+ "calculationBy": "property",
+ "property": aggregationProperty.Method.AverageByProperty.Property.ValueString(),
+ "averageOf": aggregationProperty.Method.AverageByProperty.AverageOf.ValueString(),
+ "measureTimeBy": aggregationProperty.Method.AverageByProperty.MeasureTimeBy.ValueString(),
+ }
+ } else if aggregationProperty.Method.AggregateByProperty != nil {
+ newAggregationProperty.CalculationSpec = map[string]string{
+ "func": aggregationProperty.Method.AggregateByProperty.Func.ValueString(),
+ "calculationBy": "property",
+ "property": aggregationProperty.Method.AggregateByProperty.Property.ValueString(),
+ }
+ }
+
+ query, err := queryToPortBody(aggregationProperty.Query.ValueStringPointer())
+
+ if err != nil {
+ return nil, err
+ }
+
+ // don't set query, if it wasn't set in the state, as the backend only supports setting to an object with
+ // the search format, and not empty map or nil
+ if query != nil {
+ newAggregationProperty.Query = *query
+ }
+
+ aggregationProperties[aggregationPropertyIdentifier] = newAggregationProperty
+ }
+
+ return &aggregationProperties, nil
+}
+
+func queryToPortBody(query *string) (*map[string]any, error) {
+ if query == nil || *query == "" {
+ return nil, nil
+ }
+
+ queryMap := make(map[string]any)
+ if err := json.Unmarshal([]byte(*query), &queryMap); err != nil {
+ return nil, err
+ }
+
+ return &queryMap, nil
+}
diff --git a/port/aggregation-properties/refreshAggregationPropertyToState.go b/port/aggregation-properties/refreshAggregationPropertyToState.go
new file mode 100644
index 00000000..4f2094e3
--- /dev/null
+++ b/port/aggregation-properties/refreshAggregationPropertyToState.go
@@ -0,0 +1,72 @@
+package aggregation_properties
+
+import (
+ "github.com/hashicorp/terraform-plugin-framework/types"
+ "github.com/port-labs/terraform-provider-port-labs/internal/cli"
+ "github.com/port-labs/terraform-provider-port-labs/internal/utils"
+)
+
+func refreshAggregationPropertiesState(state *AggregationPropertiesModel, aggregationProperties map[string]cli.BlueprintAggregationProperty) error {
+ state.ID = state.BlueprintIdentifier
+
+ state.Properties = map[string]*AggregationPropertyModel{}
+
+ for aggregationPropertyIdentifier, aggregationProperty := range aggregationProperties {
+
+ state.Properties[aggregationPropertyIdentifier] = &AggregationPropertyModel{
+ Title: types.StringPointerValue(aggregationProperty.Title),
+ Icon: types.StringPointerValue(aggregationProperty.Icon),
+ Description: types.StringPointerValue(aggregationProperty.Description),
+ TargetBlueprintIdentifier: types.StringValue(aggregationProperty.Target),
+ Method: nil,
+ Query: types.StringPointerValue(nil),
+ }
+
+ query, err := utils.GoObjectToTerraformString(aggregationProperty.Query)
+ if err != nil {
+ return err
+ }
+ state.Properties[aggregationPropertyIdentifier].Query = query
+
+ if aggregationProperty.CalculationSpec != nil {
+ if calculationBy, ok := aggregationProperty.CalculationSpec["calculationBy"]; ok {
+ if calculationBy == "entities" {
+ if entitiesFunc, ok := aggregationProperty.CalculationSpec["func"]; ok {
+ if entitiesFunc == "count" {
+ state.Properties[aggregationPropertyIdentifier].Method = &AggregationMethodsModel{
+ CountEntities: types.BoolValue(true),
+ }
+ } else if entitiesFunc == "average" {
+ state.Properties[aggregationPropertyIdentifier].Method = &AggregationMethodsModel{
+ AverageEntities: &AverageEntitiesModel{
+ AverageOf: types.StringValue(aggregationProperty.CalculationSpec["averageOf"]),
+ MeasureTimeBy: types.StringValue(aggregationProperty.CalculationSpec["measureTimeBy"]),
+ },
+ }
+ }
+ }
+ } else if calculationBy == "property" {
+ if propertyFunc, ok := aggregationProperty.CalculationSpec["func"]; ok {
+ if propertyFunc == "average" {
+ state.Properties[aggregationPropertyIdentifier].Method = &AggregationMethodsModel{
+ AverageByProperty: &AverageByProperty{
+ MeasureTimeBy: types.StringValue(aggregationProperty.CalculationSpec["measureTimeBy"]),
+ AverageOf: types.StringValue(aggregationProperty.CalculationSpec["averageOf"]),
+ Property: types.StringValue(aggregationProperty.CalculationSpec["property"]),
+ },
+ }
+ } else {
+ state.Properties[aggregationPropertyIdentifier].Method = &AggregationMethodsModel{
+ AggregateByProperty: &AggregateByPropertyModel{
+ Func: types.StringValue(aggregationProperty.CalculationSpec["func"]),
+ Property: types.StringValue(aggregationProperty.CalculationSpec["property"]),
+ },
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ return nil
+}
diff --git a/port/aggregation-properties/resource.go b/port/aggregation-properties/resource.go
new file mode 100644
index 00000000..8c8711b6
--- /dev/null
+++ b/port/aggregation-properties/resource.go
@@ -0,0 +1,194 @@
+package aggregation_properties
+
+import (
+ "context"
+ "github.com/hashicorp/terraform-plugin-framework/path"
+ "github.com/hashicorp/terraform-plugin-framework/resource"
+ "github.com/port-labs/terraform-provider-port-labs/internal/cli"
+)
+
+var _ resource.Resource = &AggregationPropertiesResource{}
+var _ resource.ResourceWithImportState = &AggregationPropertiesResource{}
+
+func NewAggregationPropertiesResource() resource.Resource {
+ return &AggregationPropertiesResource{}
+}
+
+type AggregationPropertiesResource struct {
+ portClient *cli.PortClient
+}
+
+func (r *AggregationPropertiesResource) Metadata(ctx context.Context, req resource.MetadataRequest, resp *resource.MetadataResponse) {
+ resp.TypeName = req.ProviderTypeName + "_aggregation_properties"
+}
+
+func (r *AggregationPropertiesResource) Configure(ctx context.Context, req resource.ConfigureRequest, resp *resource.ConfigureResponse) {
+ if req.ProviderData == nil {
+ return
+ }
+
+ r.portClient = req.ProviderData.(*cli.PortClient)
+}
+
+func (r *AggregationPropertiesResource) ImportState(ctx context.Context, req resource.ImportStateRequest, resp *resource.ImportStateResponse) {
+ resp.Diagnostics.Append(resp.State.SetAttribute(
+ ctx, path.Root("blueprint_identifier"), req.ID,
+ )...)
+
+ resp.Diagnostics.Append(resp.State.SetAttribute(
+ ctx, path.Root("id"), req.ID,
+ )...)
+}
+
+func (r *AggregationPropertiesResource) Read(ctx context.Context, req resource.ReadRequest, resp *resource.ReadResponse) {
+ var state *AggregationPropertiesModel
+
+ resp.Diagnostics.Append(req.State.Get(ctx, &state)...)
+
+ if resp.Diagnostics.HasError() {
+ return
+ }
+
+ b, statusCode, err := r.portClient.ReadBlueprint(ctx, state.BlueprintIdentifier.ValueString())
+
+ if err != nil {
+ if statusCode == 404 {
+ resp.State.RemoveResource(ctx)
+ return
+ }
+ resp.Diagnostics.AddError("failed reading blueprint", err.Error())
+ return
+ }
+
+ err = refreshAggregationPropertiesState(state, b.AggregationProperties)
+ if err != nil {
+ resp.Diagnostics.AddError("failed writing aggregation property fields to resource", err.Error())
+ return
+ }
+ resp.Diagnostics.Append(resp.State.Set(ctx, &state)...)
+}
+
+func (r *AggregationPropertiesResource) Create(ctx context.Context, req resource.CreateRequest, resp *resource.CreateResponse) {
+ var state *AggregationPropertiesModel
+
+ resp.Diagnostics.Append(req.Plan.Get(ctx, &state)...)
+
+ if resp.Diagnostics.HasError() {
+ return
+ }
+
+ aggregationProperties, err := aggregationPropertiesToBody(state)
+
+ if err != nil {
+ resp.Diagnostics.AddError("failed to convert aggregation property to port valid request", err.Error())
+ return
+ }
+
+ b, statusCode, err := r.portClient.ReadBlueprint(ctx, state.BlueprintIdentifier.ValueString())
+
+ if err != nil {
+ if statusCode == 404 {
+ resp.Diagnostics.AddError("Blueprint doesn't exists, it is required to create aggregation properties", err.Error())
+ return
+ }
+ resp.Diagnostics.AddError("failed reading blueprint", err.Error())
+ }
+
+ // check if the aggregation properties already exists
+ if b.AggregationProperties != nil {
+ for aggregationPropertyIdentifier := range *aggregationProperties {
+ if _, ok := b.AggregationProperties[aggregationPropertyIdentifier]; ok {
+ resp.Diagnostics.AddError("aggregation property already exists", aggregationPropertyIdentifier)
+ return
+ }
+ }
+ }
+
+ b.AggregationProperties = *aggregationProperties
+
+ _, err = r.portClient.UpdateBlueprint(ctx, b, state.BlueprintIdentifier.ValueString())
+
+ if err != nil {
+ resp.Diagnostics.AddError("failed to create aggregation properties", err.Error())
+ return
+ }
+
+ // set the ID to the blueprint identifier
+ state.ID = state.BlueprintIdentifier
+
+ resp.Diagnostics.Append(resp.State.Set(ctx, &state)...)
+}
+
+func (r *AggregationPropertiesResource) Update(ctx context.Context, req resource.UpdateRequest, resp *resource.UpdateResponse) {
+ var state *AggregationPropertiesModel
+ var previousState *AggregationPropertiesModel
+
+ resp.Diagnostics.Append(req.Plan.Get(ctx, &state)...)
+ resp.Diagnostics.Append(req.State.Get(ctx, &previousState)...)
+
+ if resp.Diagnostics.HasError() {
+ return
+ }
+
+ aggregationProperties, err := aggregationPropertiesToBody(state)
+
+ if err != nil {
+ resp.Diagnostics.AddError("failed to convert aggregation property to port valid request", err.Error())
+ return
+ }
+
+ b, statusCode, err := r.portClient.ReadBlueprint(ctx, state.BlueprintIdentifier.ValueString())
+
+ if err != nil {
+ if statusCode == 404 {
+ resp.Diagnostics.AddError("Blueprint doesn't exists, it is required to update the aggregation property", err.Error())
+ return
+ }
+ resp.Diagnostics.AddError("failed reading blueprint", err.Error())
+ }
+
+ b.AggregationProperties = *aggregationProperties
+
+ _, err = r.portClient.UpdateBlueprint(ctx, b, state.BlueprintIdentifier.ValueString())
+
+ if err != nil {
+ resp.Diagnostics.AddError("failed to update aggregation property", err.Error())
+ return
+ }
+
+ // set the ID to the blueprint identifier
+ state.ID = state.BlueprintIdentifier
+
+ resp.Diagnostics.Append(resp.State.Set(ctx, &state)...)
+}
+
+func (r *AggregationPropertiesResource) Delete(ctx context.Context, req resource.DeleteRequest, resp *resource.DeleteResponse) {
+ var state *AggregationPropertiesModel
+
+ resp.Diagnostics.Append(req.State.Get(ctx, &state)...)
+
+ if resp.Diagnostics.HasError() {
+ return
+ }
+
+ b, statusCode, err := r.portClient.ReadBlueprint(ctx, state.BlueprintIdentifier.ValueString())
+
+ if err != nil {
+ if statusCode == 404 {
+ resp.State.RemoveResource(ctx)
+ return
+ }
+ resp.Diagnostics.AddError("failed reading blueprint", err.Error())
+ }
+
+ b.AggregationProperties = make(map[string]cli.BlueprintAggregationProperty)
+
+ _, err = r.portClient.UpdateBlueprint(ctx, b, state.BlueprintIdentifier.ValueString())
+
+ if err != nil {
+ resp.Diagnostics.AddError("failed to delete aggregation property", err.Error())
+ return
+ }
+
+ resp.State.RemoveResource(ctx)
+}
diff --git a/port/aggregation-properties/resource_test.go b/port/aggregation-properties/resource_test.go
new file mode 100644
index 00000000..3cb865ef
--- /dev/null
+++ b/port/aggregation-properties/resource_test.go
@@ -0,0 +1,519 @@
+package aggregation_properties_test
+
+import (
+ "fmt"
+ "testing"
+
+ "github.com/hashicorp/terraform-plugin-testing/helper/resource"
+ "github.com/port-labs/terraform-provider-port-labs/internal/acctest"
+ "github.com/port-labs/terraform-provider-port-labs/internal/utils"
+)
+
+func baseBlueprintsTemplate(parentBlueprintIdentifier string, childBlueprintIdentifier string) string {
+ return fmt.Sprintf(`
+ resource "port_blueprint" "parent_blueprint" {
+ title = "Parent Blueprint"
+ icon = "Terraform"
+ identifier = "%s"
+ description = ""
+ properties = {
+ number_props = {
+ "age" = {
+ title = "Age"
+ }
+ }
+ }
+ }
+
+ resource "port_blueprint" "child_blueprint" {
+ title = "Child Blueprint"
+ icon = "Terraform"
+ identifier = "%s"
+ description = ""
+ relations = {
+ "parent" = {
+ title = "Parent"
+ target = port_blueprint.parent_blueprint.identifier
+ }
+ }
+ }
+`, parentBlueprintIdentifier, childBlueprintIdentifier)
+}
+
+func TestAccPortAggregationPropertyWithCycleRelation(t *testing.T) {
+ // Test checks that a cycle aggregation property works.
+ // The cycle is created by creating a parent blueprint and a child blueprint.
+ // The child blueprint has a relation to the parent blueprint.
+ // The parent blueprint has an aggregation property that counts the children of the parent.
+ // The aggregation property is created with a cycle relation to the child blueprint, which is allowed.
+ parentBlueprintIdentifier := utils.GenID()
+ childBlueprintIdentifier := utils.GenID()
+ var testAccActionConfigCreate = baseBlueprintsTemplate(parentBlueprintIdentifier, childBlueprintIdentifier) + `
+ resource "port_aggregation_properties" "child_aggregation_properties" {
+ blueprint_identifier = port_blueprint.parent_blueprint.identifier
+ properties = {
+ "count_entities" = {
+ target_blueprint_identifier = port_blueprint.child_blueprint.identifier
+ title = "Count Childrens"
+ icon = "Terraform"
+ description = "Count Childrens"
+ method = {
+ count_entities = true
+ }
+ }
+ }
+ }
+`
+
+ resource.Test(t, resource.TestCase{
+ PreCheck: func() { acctest.TestAccPreCheck(t) },
+ ProtoV6ProviderFactories: acctest.TestAccProtoV6ProviderFactories,
+ Steps: []resource.TestStep{
+ {
+ Config: acctest.ProviderConfig + testAccActionConfigCreate,
+ Check: resource.ComposeTestCheckFunc(
+ resource.TestCheckResourceAttr("port_aggregation_properties.child_aggregation_properties", "blueprint_identifier", parentBlueprintIdentifier),
+ resource.TestCheckResourceAttr("port_aggregation_properties.child_aggregation_properties", "properties.count_entities.title", "Count Childrens"),
+ resource.TestCheckResourceAttr("port_aggregation_properties.child_aggregation_properties", "properties.count_entities.icon", "Terraform"),
+ resource.TestCheckResourceAttr("port_aggregation_properties.child_aggregation_properties", "properties.count_entities.description", "Count Childrens"),
+ resource.TestCheckResourceAttr("port_aggregation_properties.child_aggregation_properties", "properties.count_entities.target_blueprint_identifier", childBlueprintIdentifier),
+ resource.TestCheckResourceAttr("port_aggregation_properties.child_aggregation_properties", "properties.count_entities.method.count_entities", "true"),
+ ),
+ },
+ },
+ })
+}
+
+func TestAccCreateAggregationPropertyAverageEntities(t *testing.T) {
+ parentBlueprintIdentifier := utils.GenID()
+ childBlueprintIdentifier := utils.GenID()
+ var testAccActionConfigCreate = baseBlueprintsTemplate(parentBlueprintIdentifier, childBlueprintIdentifier) + `
+ resource "port_aggregation_properties" "parent_aggregation_properties" {
+ blueprint_identifier = port_blueprint.parent_blueprint.identifier
+ properties = {
+ "count_entities" = {
+ target_blueprint_identifier = port_blueprint.child_blueprint.identifier
+ title = "Count Childrens"
+ icon = "Terraform"
+ description = "Count Childrens"
+ method = {
+ average_entities = {
+ "average_of" = "month"
+ "measure_time_by" = "$updatedAt"
+ }
+ }
+ }
+ }
+ }
+`
+
+ var testAccActionConfigUpdate = baseBlueprintsTemplate(parentBlueprintIdentifier, childBlueprintIdentifier) + `
+ resource "port_aggregation_properties" "parent_aggregation_properties" {
+ blueprint_identifier = port_blueprint.parent_blueprint.identifier
+ properties = {
+ "count_entities" = {
+ target_blueprint_identifier = port_blueprint.child_blueprint.identifier
+ title = "Count Childrens"
+ icon = "Terraform"
+ description = "Count Childrens"
+ method = {
+ average_entities = {}
+ }
+ }
+ }
+ }
+`
+
+ resource.Test(t, resource.TestCase{
+ PreCheck: func() { acctest.TestAccPreCheck(t) },
+ ProtoV6ProviderFactories: acctest.TestAccProtoV6ProviderFactories,
+ Steps: []resource.TestStep{
+ {
+ Config: acctest.ProviderConfig + testAccActionConfigCreate,
+ Check: resource.ComposeTestCheckFunc(
+ resource.TestCheckResourceAttr("port_aggregation_properties.parent_aggregation_properties", "blueprint_identifier", parentBlueprintIdentifier),
+ resource.TestCheckResourceAttr("port_aggregation_properties.parent_aggregation_properties", "properties.count_entities.title", "Count Childrens"),
+ resource.TestCheckResourceAttr("port_aggregation_properties.parent_aggregation_properties", "properties.count_entities.icon", "Terraform"),
+ resource.TestCheckResourceAttr("port_aggregation_properties.parent_aggregation_properties", "properties.count_entities.description", "Count Childrens"),
+ resource.TestCheckResourceAttr("port_aggregation_properties.parent_aggregation_properties", "properties.count_entities.target_blueprint_identifier", childBlueprintIdentifier),
+ resource.TestCheckResourceAttr("port_aggregation_properties.parent_aggregation_properties", "properties.count_entities.method.average_entities.average_of", "month"),
+ resource.TestCheckResourceAttr("port_aggregation_properties.parent_aggregation_properties", "properties.count_entities.method.average_entities.measure_time_by", "$updatedAt"),
+ ),
+ },
+ {
+ Config: acctest.ProviderConfig + testAccActionConfigUpdate,
+ Check: resource.ComposeTestCheckFunc(
+ resource.TestCheckResourceAttr("port_aggregation_properties.parent_aggregation_properties", "blueprint_identifier", parentBlueprintIdentifier),
+ resource.TestCheckResourceAttr("port_aggregation_properties.parent_aggregation_properties", "properties.count_entities.title", "Count Childrens"),
+ resource.TestCheckResourceAttr("port_aggregation_properties.parent_aggregation_properties", "properties.count_entities.icon", "Terraform"),
+ resource.TestCheckResourceAttr("port_aggregation_properties.parent_aggregation_properties", "properties.count_entities.description", "Count Childrens"),
+ resource.TestCheckResourceAttr("port_aggregation_properties.parent_aggregation_properties", "properties.count_entities.target_blueprint_identifier", childBlueprintIdentifier),
+ resource.TestCheckResourceAttr("port_aggregation_properties.parent_aggregation_properties", "properties.count_entities.method.average_entities.average_of", "day"),
+ resource.TestCheckResourceAttr("port_aggregation_properties.parent_aggregation_properties", "properties.count_entities.method.average_entities.measure_time_by", "$createdAt"),
+ ),
+ },
+ },
+ })
+}
+
+func TestAccPortCreateAggregationAverageProperties(t *testing.T) {
+ parentBlueprintIdentifier := utils.GenID()
+ childBlueprintIdentifier := utils.GenID()
+ var testAccActionConfigCreate = baseBlueprintsTemplate(parentBlueprintIdentifier, childBlueprintIdentifier) + `
+ resource "port_aggregation_properties" "child_aggregation_properties" {
+ blueprint_identifier = port_blueprint.child_blueprint.identifier
+ properties = {
+ "average_age" = {
+ target_blueprint_identifier = port_blueprint.parent_blueprint.identifier
+ title = "Average Age"
+ icon = "Terraform"
+ description = "Average Age"
+ method = {
+ average_by_property = {
+ "average_of" = "month"
+ "measure_time_by" = "$updatedAt"
+ "property" = "age"
+ }
+ }
+ }
+ }
+ }
+`
+
+ var testAccActionConfigUpdate = baseBlueprintsTemplate(parentBlueprintIdentifier, childBlueprintIdentifier) + `
+ resource "port_aggregation_properties" "child_aggregation_properties" {
+ blueprint_identifier = port_blueprint.child_blueprint.identifier
+ properties = {
+ "average_age" = {
+ target_blueprint_identifier = port_blueprint.parent_blueprint.identifier
+ title = "Average Age"
+ icon = "Terraform"
+ description = "Average Age"
+ method = {
+ average_by_property = {
+ "average_of" = "day"
+ "measure_time_by" = "$createdAt"
+ "property" = "age"
+ }
+ }
+ }
+ }
+ }
+`
+
+ resource.Test(t, resource.TestCase{
+ PreCheck: func() { acctest.TestAccPreCheck(t) },
+ ProtoV6ProviderFactories: acctest.TestAccProtoV6ProviderFactories,
+ Steps: []resource.TestStep{
+ {
+ Config: acctest.ProviderConfig + testAccActionConfigCreate,
+ Check: resource.ComposeTestCheckFunc(
+ resource.TestCheckResourceAttr("port_aggregation_properties.child_aggregation_properties", "blueprint_identifier", childBlueprintIdentifier),
+ resource.TestCheckResourceAttr("port_aggregation_properties.child_aggregation_properties", "properties.average_age.title", "Average Age"),
+ resource.TestCheckResourceAttr("port_aggregation_properties.child_aggregation_properties", "properties.average_age.icon", "Terraform"),
+ resource.TestCheckResourceAttr("port_aggregation_properties.child_aggregation_properties", "properties.average_age.description", "Average Age"),
+ resource.TestCheckResourceAttr("port_aggregation_properties.child_aggregation_properties", "properties.average_age.target_blueprint_identifier", parentBlueprintIdentifier),
+ resource.TestCheckResourceAttr("port_aggregation_properties.child_aggregation_properties", "properties.average_age.method.average_by_property.average_of", "month"),
+ resource.TestCheckResourceAttr("port_aggregation_properties.child_aggregation_properties", "properties.average_age.method.average_by_property.measure_time_by", "$updatedAt"),
+ resource.TestCheckResourceAttr("port_aggregation_properties.child_aggregation_properties", "properties.average_age.method.average_by_property.property", "age"),
+ ),
+ },
+ {
+ Config: acctest.ProviderConfig + testAccActionConfigUpdate,
+ Check: resource.ComposeTestCheckFunc(
+ resource.TestCheckResourceAttr("port_aggregation_properties.child_aggregation_properties", "blueprint_identifier", childBlueprintIdentifier),
+ resource.TestCheckResourceAttr("port_aggregation_properties.child_aggregation_properties", "properties.average_age.title", "Average Age"),
+ resource.TestCheckResourceAttr("port_aggregation_properties.child_aggregation_properties", "properties.average_age.icon", "Terraform"),
+ resource.TestCheckResourceAttr("port_aggregation_properties.child_aggregation_properties", "properties.average_age.description", "Average Age"),
+ resource.TestCheckResourceAttr("port_aggregation_properties.child_aggregation_properties", "properties.average_age.target_blueprint_identifier", parentBlueprintIdentifier),
+ resource.TestCheckResourceAttr("port_aggregation_properties.child_aggregation_properties", "properties.average_age.method.average_by_property.average_of", "day"),
+ resource.TestCheckResourceAttr("port_aggregation_properties.child_aggregation_properties", "properties.average_age.method.average_by_property.measure_time_by", "$createdAt"),
+ resource.TestCheckResourceAttr("port_aggregation_properties.child_aggregation_properties", "properties.average_age.method.average_by_property.property", "age"),
+ ),
+ },
+ },
+ })
+}
+
+func TestAccPortCreateAggregationPropertyAggregateByProperty(t *testing.T) {
+ parentBlueprintIdentifier := utils.GenID()
+ childBlueprintIdentifier := utils.GenID()
+ var testAccActionConfigCreateAggrByPropMin = baseBlueprintsTemplate(parentBlueprintIdentifier, childBlueprintIdentifier) + `
+ resource "port_aggregation_properties" "child_aggregation_properties" {
+ blueprint_identifier = port_blueprint.child_blueprint.identifier
+ properties = {
+ "aggr" = {
+ target_blueprint_identifier = port_blueprint.parent_blueprint.identifier
+ title = "Min Age"
+ icon = "Terraform"
+ description = "Min Age"
+ method = {
+ aggregate_by_property = {
+ "func" = "min"
+ "property" = "age"
+ }
+ }
+ }
+ }
+ }
+`
+
+ var testAccAggregatePropertyUpdateMax = baseBlueprintsTemplate(parentBlueprintIdentifier, childBlueprintIdentifier) + `
+ resource "port_aggregation_properties" "child_aggregation_properties" {
+ blueprint_identifier = port_blueprint.child_blueprint.identifier
+ properties = {
+ "aggr" = {
+ target_blueprint_identifier = port_blueprint.parent_blueprint.identifier
+ title = "Max Age"
+ icon = "Terraform"
+ description = "Max Age"
+ method = {
+ aggregate_by_property = {
+ "func" = "max"
+ "property" = "age"
+ }
+ }
+ }
+ }
+ }
+`
+
+ var testAccAggregatePropertyUpdateSum = baseBlueprintsTemplate(parentBlueprintIdentifier, childBlueprintIdentifier) + `
+ resource "port_aggregation_properties" "child_aggregation_properties" {
+ blueprint_identifier = port_blueprint.child_blueprint.identifier
+ properties = {
+ "aggr" = {
+ target_blueprint_identifier = port_blueprint.parent_blueprint.identifier
+ title = "Sum Age"
+ icon = "Terraform"
+ description = "Sum Age"
+ method = {
+ aggregate_by_property = {
+ "func" = "sum"
+ "property" = "age"
+ }
+ }
+ }
+ }
+ }
+`
+
+ var testAccAggregatePropertyUpdateMedian = baseBlueprintsTemplate(parentBlueprintIdentifier, childBlueprintIdentifier) + `
+ resource "port_aggregation_properties" "child_aggregation_properties" {
+ blueprint_identifier = port_blueprint.child_blueprint.identifier
+ properties = {
+ "aggr" = {
+ target_blueprint_identifier = port_blueprint.parent_blueprint.identifier
+ title = "Median Age"
+ icon = "Terraform"
+ description = "Median Age"
+ method = {
+ aggregate_by_property = {
+ "func" = "median"
+ "property" = "age"
+ }
+ }
+ }
+ }
+ }
+`
+
+ resource.Test(t, resource.TestCase{
+ PreCheck: func() { acctest.TestAccPreCheck(t) },
+ ProtoV6ProviderFactories: acctest.TestAccProtoV6ProviderFactories,
+ Steps: []resource.TestStep{
+ {
+ Config: acctest.ProviderConfig + testAccActionConfigCreateAggrByPropMin,
+ Check: resource.ComposeTestCheckFunc(
+ resource.TestCheckResourceAttr("port_aggregation_properties.child_aggregation_properties", "blueprint_identifier", childBlueprintIdentifier),
+ resource.TestCheckResourceAttr("port_aggregation_properties.child_aggregation_properties", "properties.aggr.title", "Min Age"),
+ resource.TestCheckResourceAttr("port_aggregation_properties.child_aggregation_properties", "properties.aggr.icon", "Terraform"),
+ resource.TestCheckResourceAttr("port_aggregation_properties.child_aggregation_properties", "properties.aggr.description", "Min Age"),
+ resource.TestCheckResourceAttr("port_aggregation_properties.child_aggregation_properties", "properties.aggr.target_blueprint_identifier", parentBlueprintIdentifier),
+ resource.TestCheckResourceAttr("port_aggregation_properties.child_aggregation_properties", "properties.aggr.method.aggregate_by_property.func", "min"),
+ resource.TestCheckResourceAttr("port_aggregation_properties.child_aggregation_properties", "properties.aggr.method.aggregate_by_property.property", "age"),
+ ),
+ },
+ {
+ Config: acctest.ProviderConfig + testAccAggregatePropertyUpdateMax,
+ Check: resource.ComposeTestCheckFunc(
+ resource.TestCheckResourceAttr("port_aggregation_properties.child_aggregation_properties", "blueprint_identifier", childBlueprintIdentifier),
+ resource.TestCheckResourceAttr("port_aggregation_properties.child_aggregation_properties", "properties.aggr.title", "Max Age"),
+ resource.TestCheckResourceAttr("port_aggregation_properties.child_aggregation_properties", "properties.aggr.icon", "Terraform"),
+ resource.TestCheckResourceAttr("port_aggregation_properties.child_aggregation_properties", "properties.aggr.description", "Max Age"),
+ resource.TestCheckResourceAttr("port_aggregation_properties.child_aggregation_properties", "properties.aggr.target_blueprint_identifier", parentBlueprintIdentifier),
+ resource.TestCheckResourceAttr("port_aggregation_properties.child_aggregation_properties", "properties.aggr.method.aggregate_by_property.func", "max"),
+ resource.TestCheckResourceAttr("port_aggregation_properties.child_aggregation_properties", "properties.aggr.method.aggregate_by_property.property", "age"),
+ ),
+ },
+ {
+ Config: acctest.ProviderConfig + testAccAggregatePropertyUpdateSum,
+ Check: resource.ComposeTestCheckFunc(
+ resource.TestCheckResourceAttr("port_aggregation_properties.child_aggregation_properties", "blueprint_identifier", childBlueprintIdentifier),
+ resource.TestCheckResourceAttr("port_aggregation_properties.child_aggregation_properties", "properties.aggr.title", "Sum Age"),
+ resource.TestCheckResourceAttr("port_aggregation_properties.child_aggregation_properties", "properties.aggr.icon", "Terraform"),
+ resource.TestCheckResourceAttr("port_aggregation_properties.child_aggregation_properties", "properties.aggr.description", "Sum Age"),
+ resource.TestCheckResourceAttr("port_aggregation_properties.child_aggregation_properties", "properties.aggr.target_blueprint_identifier", parentBlueprintIdentifier),
+ resource.TestCheckResourceAttr("port_aggregation_properties.child_aggregation_properties", "properties.aggr.method.aggregate_by_property.func", "sum"),
+ resource.TestCheckResourceAttr("port_aggregation_properties.child_aggregation_properties", "properties.aggr.method.aggregate_by_property.property", "age"),
+ ),
+ },
+ {
+ Config: acctest.ProviderConfig + testAccAggregatePropertyUpdateMedian,
+ Check: resource.ComposeTestCheckFunc(
+ resource.TestCheckResourceAttr("port_aggregation_properties.child_aggregation_properties", "blueprint_identifier", childBlueprintIdentifier),
+ resource.TestCheckResourceAttr("port_aggregation_properties.child_aggregation_properties", "properties.aggr.title", "Median Age"),
+ resource.TestCheckResourceAttr("port_aggregation_properties.child_aggregation_properties", "properties.aggr.icon", "Terraform"),
+ resource.TestCheckResourceAttr("port_aggregation_properties.child_aggregation_properties", "properties.aggr.description", "Median Age"),
+ resource.TestCheckResourceAttr("port_aggregation_properties.child_aggregation_properties", "properties.aggr.target_blueprint_identifier", parentBlueprintIdentifier),
+ resource.TestCheckResourceAttr("port_aggregation_properties.child_aggregation_properties", "properties.aggr.method.aggregate_by_property.func", "median"),
+ resource.TestCheckResourceAttr("port_aggregation_properties.child_aggregation_properties", "properties.aggr.method.aggregate_by_property.property", "age"),
+ ),
+ },
+ },
+ })
+}
+
+func TestAccPortCreateBlueprintWithAggregationByPropertyWithFilter(t *testing.T) {
+ parentBlueprintIdentifier := utils.GenID()
+ childBlueprintIdentifier := utils.GenID()
+ var testAccActionConfigCreate = baseBlueprintsTemplate(parentBlueprintIdentifier, childBlueprintIdentifier) + `
+
+ resource "port_aggregation_properties" "child_aggregation_properties" {
+ blueprint_identifier = port_blueprint.child_blueprint.identifier
+ properties = {
+ "aggr" = {
+ target_blueprint_identifier = port_blueprint.parent_blueprint.identifier
+ title = "Min Age"
+ icon = "Terraform"
+ description = "Min Age"
+ method = {
+ aggregate_by_property = {
+ "func" = "min"
+ "property" = "age"
+ }
+ }
+ query = jsonencode(
+ {
+ "combinator" : "and",
+ "rules" : [
+ {
+ "property" : "age",
+ "operator" : "=",
+ "value" : 10
+ }
+ ]
+ }
+ )
+ }
+ }
+ }
+`
+
+ resource.Test(t, resource.TestCase{
+ PreCheck: func() { acctest.TestAccPreCheck(t) },
+ ProtoV6ProviderFactories: acctest.TestAccProtoV6ProviderFactories,
+ Steps: []resource.TestStep{
+ {
+ Config: acctest.ProviderConfig + testAccActionConfigCreate,
+ Check: resource.ComposeTestCheckFunc(
+ resource.TestCheckResourceAttr("port_aggregation_properties.child_aggregation_properties", "blueprint_identifier", childBlueprintIdentifier),
+ resource.TestCheckResourceAttr("port_aggregation_properties.child_aggregation_properties", "properties.aggr.title", "Min Age"),
+ resource.TestCheckResourceAttr("port_aggregation_properties.child_aggregation_properties", "properties.aggr.icon", "Terraform"),
+ resource.TestCheckResourceAttr("port_aggregation_properties.child_aggregation_properties", "properties.aggr.description", "Min Age"),
+ resource.TestCheckResourceAttr("port_aggregation_properties.child_aggregation_properties", "properties.aggr.target_blueprint_identifier", parentBlueprintIdentifier),
+ resource.TestCheckResourceAttr("port_aggregation_properties.child_aggregation_properties", "properties.aggr.method.aggregate_by_property.func", "min"),
+ resource.TestCheckResourceAttr("port_aggregation_properties.child_aggregation_properties", "properties.aggr.method.aggregate_by_property.property", "age"),
+ resource.TestCheckResourceAttr("port_aggregation_properties.child_aggregation_properties", "properties.aggr.query", "{\"combinator\":\"and\",\"rules\":[{\"operator\":\"=\",\"property\":\"age\",\"value\":10}]}"),
+ ),
+ },
+ },
+ })
+}
+
+func TestAccMultipleAggregationPropertiesForBlueprintCreate(t *testing.T) {
+ parentBlueprintIdentifier := utils.GenID()
+ childBlueprintIdentifier := utils.GenID()
+ var testAccActionConfigCreate = baseBlueprintsTemplate(parentBlueprintIdentifier, childBlueprintIdentifier) + `
+ resource "port_aggregation_properties" "child_aggregation_properties" {
+ blueprint_identifier = port_blueprint.child_blueprint.identifier
+ properties = {
+ "aggr" = {
+ target_blueprint_identifier = port_blueprint.parent_blueprint.identifier
+ title = "Min Age"
+ icon = "Terraform"
+ description = "Min Age"
+ method = {
+ aggregate_by_property = {
+ "func" = "min"
+ "property" = "age"
+ }
+ }
+ query = jsonencode(
+ {
+ "combinator" : "and",
+ "rules" : [
+ {
+ "property" : "age",
+ "operator" : "=",
+ "value" : 10
+ }
+ ]
+ }
+ )
+ }
+ "aggr2" = {
+ target_blueprint_identifier = port_blueprint.parent_blueprint.identifier
+ title = "Max age"
+ icon = "Terraform"
+ description = "Max age"
+ method = {
+ aggregate_by_property = {
+ "func" = "max"
+ "property" = "age"
+ }
+ }
+ query = jsonencode(
+ {
+ "combinator" : "and",
+ "rules" : [
+ {
+ "property" : "age",
+ "operator" : "=",
+ "value" : 10
+ }
+ ]
+ }
+ )
+ }
+ }
+ }
+`
+
+ resource.Test(t, resource.TestCase{
+ PreCheck: func() { acctest.TestAccPreCheck(t) },
+ ProtoV6ProviderFactories: acctest.TestAccProtoV6ProviderFactories,
+ Steps: []resource.TestStep{
+ {
+ Config: acctest.ProviderConfig + testAccActionConfigCreate,
+ Check: resource.ComposeTestCheckFunc(
+ resource.TestCheckResourceAttr("port_aggregation_properties.child_aggregation_properties", "blueprint_identifier", childBlueprintIdentifier),
+ resource.TestCheckResourceAttr("port_aggregation_properties.child_aggregation_properties", "properties.aggr.title", "Min Age"),
+ resource.TestCheckResourceAttr("port_aggregation_properties.child_aggregation_properties", "properties.aggr.icon", "Terraform"),
+ resource.TestCheckResourceAttr("port_aggregation_properties.child_aggregation_properties", "properties.aggr.description", "Min Age"),
+ resource.TestCheckResourceAttr("port_aggregation_properties.child_aggregation_properties", "properties.aggr.target_blueprint_identifier", parentBlueprintIdentifier),
+ resource.TestCheckResourceAttr("port_aggregation_properties.child_aggregation_properties", "properties.aggr.method.aggregate_by_property.func", "min"),
+ resource.TestCheckResourceAttr("port_aggregation_properties.child_aggregation_properties", "properties.aggr.method.aggregate_by_property.property", "age"),
+ resource.TestCheckResourceAttr("port_aggregation_properties.child_aggregation_properties", "properties.aggr.query", "{\"combinator\":\"and\",\"rules\":[{\"operator\":\"=\",\"property\":\"age\",\"value\":10}]}"),
+ resource.TestCheckResourceAttr("port_aggregation_properties.child_aggregation_properties", "properties.aggr2.title", "Max age"),
+ resource.TestCheckResourceAttr("port_aggregation_properties.child_aggregation_properties", "properties.aggr2.icon", "Terraform"),
+ resource.TestCheckResourceAttr("port_aggregation_properties.child_aggregation_properties", "properties.aggr2.description", "Max age"),
+ resource.TestCheckResourceAttr("port_aggregation_properties.child_aggregation_properties", "properties.aggr2.target_blueprint_identifier", parentBlueprintIdentifier),
+ resource.TestCheckResourceAttr("port_aggregation_properties.child_aggregation_properties", "properties.aggr2.method.aggregate_by_property.func", "max"),
+ resource.TestCheckResourceAttr("port_aggregation_properties.child_aggregation_properties", "properties.aggr2.method.aggregate_by_property.property", "age"),
+ resource.TestCheckResourceAttr("port_aggregation_properties.child_aggregation_properties", "properties.aggr2.query", "{\"combinator\":\"and\",\"rules\":[{\"operator\":\"=\",\"property\":\"age\",\"value\":10}]}"),
+ ),
+ },
+ },
+ })
+}
diff --git a/port/aggregation-properties/schema.go b/port/aggregation-properties/schema.go
new file mode 100644
index 00000000..45b0ee46
--- /dev/null
+++ b/port/aggregation-properties/schema.go
@@ -0,0 +1,450 @@
+package aggregation_properties
+
+import (
+ "context"
+ "github.com/hashicorp/terraform-plugin-framework-validators/boolvalidator"
+ "github.com/hashicorp/terraform-plugin-framework-validators/stringvalidator"
+ "github.com/hashicorp/terraform-plugin-framework/path"
+ "github.com/hashicorp/terraform-plugin-framework/resource"
+ "github.com/hashicorp/terraform-plugin-framework/resource/schema"
+ "github.com/hashicorp/terraform-plugin-framework/resource/schema/stringdefault"
+ "github.com/hashicorp/terraform-plugin-framework/schema/validator"
+)
+
+func AggregationPropertySchema() schema.Attribute {
+ return schema.MapNestedAttribute{
+ MarkdownDescription: "The aggregation property of the blueprint",
+ Required: true,
+ NestedObject: schema.NestedAttributeObject{
+ Attributes: map[string]schema.Attribute{
+ "target_blueprint_identifier": schema.StringAttribute{
+ MarkdownDescription: "The identifier of the blueprint to perform the aggregation on",
+ Required: true,
+ },
+ "title": schema.StringAttribute{
+ MarkdownDescription: "The title of the aggregation property",
+ Optional: true,
+ },
+ "icon": schema.StringAttribute{
+ MarkdownDescription: "The icon of the aggregation property",
+ Optional: true,
+ },
+ "description": schema.StringAttribute{
+ MarkdownDescription: "The description of the aggregation property",
+ Optional: true,
+ },
+ "method": schema.SingleNestedAttribute{
+ MarkdownDescription: "The aggregation method to perform on the target blueprint, one of count_entities, average_entities, average_by_property, aggregate_by_property",
+ Required: true,
+ Attributes: map[string]schema.Attribute{
+ "count_entities": schema.BoolAttribute{
+ MarkdownDescription: "Function to count the entities of the target entities",
+ Optional: true,
+ Validators: []validator.Bool{
+ boolvalidator.ExactlyOneOf(
+ path.MatchRelative().AtParent().AtName("count_entities"),
+ path.MatchRelative().AtParent().AtName("average_entities"),
+ path.MatchRelative().AtParent().AtName("average_by_property"),
+ path.MatchRelative().AtParent().AtName("aggregate_by_property"),
+ ),
+ },
+ },
+ "average_entities": schema.SingleNestedAttribute{
+ MarkdownDescription: "Function to average the entities of the target entities",
+ Optional: true,
+ Attributes: map[string]schema.Attribute{
+ "average_of": schema.StringAttribute{
+ MarkdownDescription: "The time periods to calculate the average of, e.g. hour, day, week, month",
+ Optional: true,
+ Computed: true,
+ Default: stringdefault.StaticString("day"),
+ Validators: []validator.String{
+ stringvalidator.OneOf("hour", "day", "week", "month"),
+ },
+ },
+ "measure_time_by": schema.StringAttribute{
+ MarkdownDescription: "The property name on which to calculate the the time periods, e.g. $createdAt, $updated_at or any other date property",
+ Optional: true,
+ Computed: true,
+ Default: stringdefault.StaticString("$createdAt"),
+ },
+ },
+ },
+ "average_by_property": schema.SingleNestedAttribute{
+ MarkdownDescription: "Function to calculate the average by property value of the target entities",
+ Optional: true,
+ Attributes: map[string]schema.Attribute{
+ "average_of": schema.StringAttribute{
+ MarkdownDescription: "The time periods to calculate the average by, e.g. hour, day, week, month",
+ Required: true,
+ Validators: []validator.String{
+ stringvalidator.OneOf("hour", "day", "week", "month", "total"),
+ },
+ },
+ "measure_time_by": schema.StringAttribute{
+ MarkdownDescription: "The property name on which to calculate the the time periods, e.g. $createdAt, $updated_at or any other date property",
+ Required: true,
+ },
+ "property": schema.StringAttribute{
+ MarkdownDescription: "The property name on which to calculate the average by",
+ Required: true,
+ },
+ },
+ },
+ "aggregate_by_property": schema.SingleNestedAttribute{
+ MarkdownDescription: "Function to calculate the aggregate by property value of the target entities, such as sum, min, max, median",
+ Optional: true,
+ Attributes: map[string]schema.Attribute{
+ "func": schema.StringAttribute{
+ MarkdownDescription: "The func of the aggregate by property",
+ Required: true,
+ Validators: []validator.String{
+ stringvalidator.OneOf("sum", "min", "max", "median"),
+ },
+ },
+ "property": schema.StringAttribute{
+ MarkdownDescription: "The property of the aggregate by property",
+ Required: true,
+ },
+ },
+ },
+ },
+ },
+ "query": schema.StringAttribute{
+ MarkdownDescription: "Query to filter the target entities",
+ Optional: true,
+ },
+ },
+ },
+ }
+}
+
+func AggregationPropertiesSchema() map[string]schema.Attribute {
+ return map[string]schema.Attribute{
+ "id": schema.StringAttribute{
+ Computed: true,
+ },
+ "blueprint_identifier": schema.StringAttribute{
+ Description: "The identifier of the blueprint the aggregation property will be added to",
+ Required: true,
+ },
+ "properties": AggregationPropertySchema(),
+ }
+}
+
+func (r *AggregationPropertiesResource) Schema(ctx context.Context, req resource.SchemaRequest, resp *resource.SchemaResponse) {
+ resp.Schema = schema.Schema{
+ MarkdownDescription: AggregationPropertyResourceMarkdownDescription,
+ Attributes: AggregationPropertiesSchema(),
+ }
+}
+
+var AggregationPropertyResourceMarkdownDescription = `
+
+# Aggregation Property
+
+This resource allows you to manage an aggregation property.
+
+See the [Port documentation](https://docs.getport.io/build-your-software-catalog/define-your-data-model/setup-blueprint/properties/aggregation-properties/) for more information about aggregation properties.
+
+
+Supported Methods:
+
+- count_entities - Count the entities of the target blueprint
+- average_entities - Average the entities of the target blueprint by time periods
+- average_by_property - Calculate the average by property value of the target entities
+- aggregate_by_property - Calculate the aggregate by property value of the target entities, such as sum, min, max, median
+
+## Example Usage
+
+Create a parent blueprint with a child blueprint and an aggregation property to count the parent kids:
+
+` + "```hcl" + `
+
+resource "port_blueprint" "parent_blueprint" {
+ title = "Parent Blueprint"
+ icon = "Terraform"
+ identifier = "parent"
+ description = ""
+ properties = {
+ number_props = {
+ "age" = {
+ title = "Age"
+ }
+ }
+ }
+}
+
+resource "port_blueprint" "child_blueprint" {
+ title = "Child Blueprint"
+ icon = "Terraform"
+ identifier = "child"
+ description = ""
+ properties = {
+ number_props = {
+ "age" = {
+ title = "Age"
+ }
+ }
+ }
+ relations = {
+ "parent" = {
+ title = "Parent"
+ target = port_blueprint.parent_blueprint.identifier
+ }
+ }
+}
+
+resource "port_aggregation_properties" "parent_aggregation_properties" {
+ blueprint_identifier = port_blueprint.parent_blueprint.identifier
+ properties = {
+ "count_kids" = {
+ target_blueprint_identifier = port_blueprint.child_blueprint.identifier
+ title = "Count Kids"
+ icon = "Terraform"
+ description = "Count Kids"
+ method = {
+ count_entities = true
+ }
+ }
+ }
+}
+
+` + "```" + `
+
+Create a parent blueprint with a child blueprint and an aggregation property to calculate the average avg of the parent kids age:
+
+` + "```hcl" + `
+
+resource "port_blueprint" "parent_blueprint" {
+ title = "Parent Blueprint"
+ icon = "Terraform"
+ identifier = "parent"
+ description = ""
+ properties = {
+ number_props = {
+ "age" = {
+ title = "Age"
+ }
+ }
+ }
+}
+
+resource "port_blueprint" "child_blueprint" {
+ title = "Child Blueprint"
+ icon = "Terraform"
+ identifier = "child"
+ description = ""
+ properties = {
+ number_props = {
+ "age" = {
+ title = "Age"
+ }
+ }
+ }
+ relations = {
+ "parent" = {
+ title = "Parent"
+ target = port_blueprint.parent_blueprint.identifier
+ }
+ }
+}
+
+resource "port_aggregation_properties" "parent_aggregation_properties" {
+ blueprint_identifier = port_blueprint.parent_blueprint.identifier
+ properties = {
+ average_kids_age = {
+ target_blueprint_identifier = port_blueprint.child_blueprint.identifier
+ title = "Average Kids Age"
+ icon = "Terraform"
+ description = "Average Kids Age"
+ method = {
+ average_by_property = {
+ average_of = "total"
+ measure_time_by = "$createdAt"
+ property = "age"
+ }
+ }
+ }
+ }
+}
+
+
+` + "```" + `
+
+Create a repository blueprint and a pull request blueprint and an aggregation property to calculate the average of pull requests created per day:
+
+` + "```hcl" + `
+
+resource "port_blueprint" "repository_blueprint" {
+ title = "Repository Blueprint"
+ icon = "Terraform"
+ identifier = "repository"
+ description = ""
+}
+
+resource "port_blueprint" "pull_request_blueprint" {
+ title = "Pull Request Blueprint"
+ icon = "Terraform"
+ identifier = "pull_request"
+ description = ""
+ properties = {
+ string_props = {
+ "status" = {
+ title = "Status"
+ }
+ }
+ }
+ relations = {
+ "repository" = {
+ title = "Repository"
+ target = port_blueprint.repository_blueprint.identifier
+ }
+ }
+}
+
+resource "port_aggregation_properties" "repository_aggregation_properties" {
+ blueprint_identifier = port_blueprint.repository_blueprint.identifier
+ properties = {
+ "pull_requests_per_day" = {
+ target_blueprint_identifier = port_blueprint.pull_request_blueprint.identifier
+ title = "Pull Requests Per Day"
+ icon = "Terraform"
+ description = "Pull Requests Per Day"
+ method = {
+ average_entities = {
+ average_of = "day"
+ measure_time_by = "$createdAt"
+ }
+ }
+ }
+ }
+}
+
+` + "```" + `
+
+Create a repository blueprint and a pull request blueprint and an aggregation property to calculate the average of fix pull request per month:
+
+To do that we will add a query to the aggregation property to filter only pull requests with fixed title:
+
+` + "```hcl" + `
+
+resource "port_blueprint" "repository_blueprint" {
+ title = "Repository Blueprint"
+ icon = "Terraform"
+ identifier = "repository"
+ description = ""
+}
+
+resource "port_blueprint" "pull_request_blueprint" {
+ title = "Pull Request Blueprint"
+ icon = "Terraform"
+ identifier = "pull_request"
+ description = ""
+ properties = {
+ string_props = {
+ "status" = {
+ title = "Status"
+ }
+ }
+ }
+ relations = {
+ "repository" = {
+ title = "Repository"
+ target = port_blueprint.repository_blueprint.identifier
+ }
+ }
+}
+
+resource "port_aggregation_properties" "repository_aggregation_properties" {
+ blueprint_identifier = port_blueprint.repository_blueprint.identifier
+ properties = {
+ "fix_pull_requests_count" = {
+ target_blueprint_identifier = port_blueprint.pull_request_blueprint.identifier
+ title = "Pull Requests Per Day"
+ icon = "Terraform"
+ description = "Pull Requests Per Day"
+ method = {
+ average_entities = {
+ average_of = "month"
+ measure_time_by = "$createdAt"
+ }
+ }
+ query = jsonencode(
+ {
+ "combinator" : "and",
+ "rules" : [
+ {
+ "property" : "$title",
+ "operator" : "ContainsAny",
+ "value" : ["fix", "fixed", "fixing", "Fix"]
+ }
+ ]
+ }
+ )
+ }
+ }
+}
+
+` + "```" + `
+
+
+Create multiple aggregation properties in one resource:
+
+` + "```hcl" + `
+
+resource "port_blueprint" "repository_blueprint" {
+ title = "Repository Blueprint"
+ icon = "Terraform"
+ identifier = "repository"
+ description = ""
+}
+
+resource "port_blueprint" "pull_request_blueprint" {
+ title = "Pull Request Blueprint"
+ icon = "Terraform"
+ identifier = "pull_request"
+ description = ""
+ properties = {
+ string_props = {
+ "status" = {
+ title = "Status"
+ }
+ }
+ }
+ relations = {
+ "repository" = {
+ title = "Repository"
+ target = port_blueprint.repository_blueprint.identifier
+ }
+ }
+}
+
+resource "port_aggregation_properties" "repository_aggregation_properties" {
+ blueprint_identifier = port_blueprint.repository_blueprint.identifier
+ properties = {
+ "pull_requests_per_day" = {
+ target_blueprint_identifier = port_blueprint.pull_request_blueprint.identifier
+ title = "Pull Requests Per Day"
+ icon = "Terraform"
+ description = "Pull Requests Per Day"
+ method = {
+ average_entities = {
+ average_of = "day"
+ measure_time_by = "$createdAt"
+ }
+ }
+ }
+ "overall_pull_requests_count" = {
+ target_blueprint_identifier = port_blueprint.pull_request_blueprint.identifier
+ title = "Overall Pull Requests Count"
+ icon = "Terraform"
+ description = "Overall Pull Requests Count"
+ method = {
+ count_entities = true
+ }
+ }
+ }
+}
+
+` + "```" + ``
diff --git a/port/aggregation-property/readStateToPortBody.go b/port/aggregation-property/readStateToPortBody.go
deleted file mode 100644
index b1322d42..00000000
--- a/port/aggregation-property/readStateToPortBody.go
+++ /dev/null
@@ -1,74 +0,0 @@
-package aggregation_property
-
-import (
- "encoding/json"
- "github.com/port-labs/terraform-provider-port-labs/internal/cli"
-)
-
-func aggregationPropertyToBody(state *AggregationPropertyModel) (*cli.BlueprintAggregationProperty, error) {
- if state == nil {
- return nil, nil
- }
-
- aggregationProperty := cli.BlueprintAggregationProperty{
- Title: state.Title.ValueStringPointer(),
- Icon: state.Icon.ValueStringPointer(),
- Description: state.Description.ValueStringPointer(),
- Target: state.TargetBlueprintIdentifier.ValueString(),
- }
-
- if !state.Method.CountEntities.IsNull() {
- aggregationProperty.CalculationSpec = map[string]string{
- "func": "count",
- "calculationBy": "entities",
- }
- } else if state.Method.AverageEntities != nil {
- aggregationProperty.CalculationSpec = map[string]string{
- "func": "average",
- "calculationBy": "entities",
- "averageOf": state.Method.AverageEntities.AverageOf.ValueString(),
- "measureTimeBy": state.Method.AverageEntities.MeasureTimeBy.ValueString(),
- }
- } else if state.Method.AverageByProperty != nil {
- aggregationProperty.CalculationSpec = map[string]string{
- "func": "average",
- "calculationBy": "property",
- "property": state.Method.AverageByProperty.Property.ValueString(),
- "averageOf": state.Method.AverageByProperty.AverageOf.ValueString(),
- "measureTimeBy": state.Method.AverageByProperty.MeasureTimeBy.ValueString(),
- }
- } else if state.Method.AggregateByProperty != nil {
- aggregationProperty.CalculationSpec = map[string]string{
- "func": state.Method.AggregateByProperty.Func.ValueString(),
- "calculationBy": "property",
- "property": state.Method.AggregateByProperty.Property.ValueString(),
- }
- }
-
- query, err := queryToPortBody(state.Query.ValueStringPointer())
-
- if err != nil {
- return nil, err
- }
-
- // don't set query, if it wasn't set in the state, as the backend only supports setting to an object with
- // the search format, and not empty map or nil
- if query != nil {
- aggregationProperty.Query = *query
- }
-
- return &aggregationProperty, nil
-}
-
-func queryToPortBody(query *string) (*map[string]any, error) {
- if query == nil || *query == "" {
- return nil, nil
- }
-
- queryMap := make(map[string]any)
- if err := json.Unmarshal([]byte(*query), &queryMap); err != nil {
- return nil, err
- }
-
- return &queryMap, nil
-}
diff --git a/port/aggregation-property/refreshAggregationPropertyToState.go b/port/aggregation-property/refreshAggregationPropertyToState.go
deleted file mode 100644
index 32b3cd85..00000000
--- a/port/aggregation-property/refreshAggregationPropertyToState.go
+++ /dev/null
@@ -1,67 +0,0 @@
-package aggregation_property
-
-import (
- "encoding/json"
- "fmt"
- "github.com/hashicorp/terraform-plugin-framework/types"
- "github.com/port-labs/terraform-provider-port-labs/internal/cli"
-)
-
-func refreshAggregationPropertyState(state *AggregationPropertyModel, aggregationProperty cli.BlueprintAggregationProperty, blueprintIdentifier string, aggregationIdentifier string) error {
- state.ID = types.StringValue(fmt.Sprintf("%s:%s", blueprintIdentifier, aggregationIdentifier))
- state.BlueprintIdentifier = types.StringValue(blueprintIdentifier)
- state.AggregationIdentifier = types.StringValue(aggregationIdentifier)
- state.TargetBlueprintIdentifier = types.StringValue(aggregationProperty.Target)
- state.Icon = types.StringPointerValue(aggregationProperty.Icon)
- state.Title = types.StringPointerValue(aggregationProperty.Title)
- state.Description = types.StringPointerValue(aggregationProperty.Description)
-
- if aggregationProperty.Query != nil {
- query, err := json.Marshal(aggregationProperty.Query)
- if err != nil {
- return err
- }
- state.Query = types.StringValue(string(query))
- }
-
- if aggregationProperty.CalculationSpec != nil {
- if calculationBy, ok := aggregationProperty.CalculationSpec["calculationBy"]; ok {
- if calculationBy == "entities" {
- if entitiesFunc, ok := aggregationProperty.CalculationSpec["func"]; ok {
- if entitiesFunc == "count" {
- state.Method = &AggregationMethodsModel{
- CountEntities: types.BoolValue(true),
- }
- } else if entitiesFunc == "average" {
- state.Method = &AggregationMethodsModel{
- AverageEntities: &AverageEntitiesModel{
- AverageOf: types.StringValue(aggregationProperty.CalculationSpec["averageOf"]),
- MeasureTimeBy: types.StringValue(aggregationProperty.CalculationSpec["measureTimeBy"]),
- },
- }
- }
- }
- } else if calculationBy == "property" {
- if propertyFunc, ok := aggregationProperty.CalculationSpec["func"]; ok {
- if propertyFunc == "average" {
- state.Method = &AggregationMethodsModel{
- AverageByProperty: &AverageByProperty{
- MeasureTimeBy: types.StringValue(aggregationProperty.CalculationSpec["measureTimeBy"]),
- AverageOf: types.StringValue(aggregationProperty.CalculationSpec["averageOf"]),
- Property: types.StringValue(aggregationProperty.CalculationSpec["property"]),
- },
- }
- } else {
- state.Method = &AggregationMethodsModel{
- AggregateByProperty: &AggregateByPropertyModel{
- Func: types.StringValue(aggregationProperty.CalculationSpec["func"]),
- Property: types.StringValue(aggregationProperty.CalculationSpec["property"]),
- },
- }
- }
- }
- }
- }
- }
- return nil
-}
diff --git a/port/aggregation-property/resource.go b/port/aggregation-property/resource.go
deleted file mode 100644
index 73090f16..00000000
--- a/port/aggregation-property/resource.go
+++ /dev/null
@@ -1,227 +0,0 @@
-package aggregation_property
-
-import (
- "context"
- "github.com/hashicorp/terraform-plugin-framework/path"
- "github.com/hashicorp/terraform-plugin-framework/resource"
- "github.com/port-labs/terraform-provider-port-labs/internal/cli"
- "strings"
-)
-
-var _ resource.Resource = &AggregationPropertyResource{}
-var _ resource.ResourceWithImportState = &AggregationPropertyResource{}
-
-func NewAggregationPropertyResource() resource.Resource {
- return &AggregationPropertyResource{}
-}
-
-type AggregationPropertyResource struct {
- portClient *cli.PortClient
-}
-
-func (r *AggregationPropertyResource) Metadata(ctx context.Context, req resource.MetadataRequest, resp *resource.MetadataResponse) {
- resp.TypeName = req.ProviderTypeName + "_aggregation_property"
-}
-
-func (r *AggregationPropertyResource) Configure(ctx context.Context, req resource.ConfigureRequest, resp *resource.ConfigureResponse) {
- if req.ProviderData == nil {
- return
- }
-
- r.portClient = req.ProviderData.(*cli.PortClient)
-}
-
-func (r *AggregationPropertyResource) ImportState(ctx context.Context, req resource.ImportStateRequest, resp *resource.ImportStateResponse) {
- idParts := strings.Split(req.ID, ":")
- if len(idParts) != 2 || idParts[0] == "" || idParts[1] == "" {
- resp.Diagnostics.AddError("invalid import ID", "import ID must be in the format :")
- return
- }
-
- resp.Diagnostics.Append(resp.State.SetAttribute(ctx, path.Root("blueprint_identifier"), idParts[0])...)
- resp.Diagnostics.Append(resp.State.SetAttribute(ctx, path.Root("identifier"), idParts[1])...)
-
-}
-
-func (r *AggregationPropertyResource) Read(ctx context.Context, req resource.ReadRequest, resp *resource.ReadResponse) {
- var state *AggregationPropertyModel
-
- resp.Diagnostics.Append(req.State.Get(ctx, &state)...)
-
- if resp.Diagnostics.HasError() {
- return
- }
-
- blueprintIdentifier := state.BlueprintIdentifier.ValueString()
- aggregationPropertyIdentifier := state.AggregationIdentifier.ValueString()
-
- b, statusCode, err := r.portClient.ReadBlueprint(ctx, blueprintIdentifier)
-
- if err != nil {
- if statusCode == 404 {
- resp.State.RemoveResource(ctx)
- return
- }
- resp.Diagnostics.AddError("failed reading blueprint", err.Error())
- return
- }
-
- aggregationProperty, ok := b.AggregationProperties[aggregationPropertyIdentifier]
- // another way to check if aggregationProperty exists
- if !ok {
- resp.State.RemoveResource(ctx)
- return
- }
-
- err = refreshAggregationPropertyState(state, aggregationProperty, blueprintIdentifier, aggregationPropertyIdentifier)
- if err != nil {
- resp.Diagnostics.AddError("failed writing aggregation property fields to resource", err.Error())
- return
- }
- resp.Diagnostics.Append(resp.State.Set(ctx, &state)...)
-}
-
-func (r *AggregationPropertyResource) Create(ctx context.Context, req resource.CreateRequest, resp *resource.CreateResponse) {
- var state *AggregationPropertyModel
-
- resp.Diagnostics.Append(req.Plan.Get(ctx, &state)...)
-
- if resp.Diagnostics.HasError() {
- return
- }
-
- aggr, err := aggregationPropertyToBody(state)
-
- if err != nil {
- resp.Diagnostics.AddError("failed to convert aggregation property to port valid request", err.Error())
- return
- }
-
- b, statusCode, err := r.portClient.ReadBlueprint(ctx, state.BlueprintIdentifier.ValueString())
-
- if err != nil {
- if statusCode == 404 {
- resp.Diagnostics.AddError("Blueprint doesn't exists, it is required to create aggregation property", err.Error())
- return
- }
- resp.Diagnostics.AddError("failed reading blueprint", err.Error())
- }
-
- _, ok := b.AggregationProperties[state.AggregationIdentifier.ValueString()]
- if ok {
- resp.Diagnostics.AddError("Aggregation property already exists", err.Error())
- return
- }
-
- b.AggregationProperties[state.AggregationIdentifier.ValueString()] = *aggr
-
- bp, err := r.portClient.UpdateBlueprint(ctx, b, state.BlueprintIdentifier.ValueString())
-
- if err != nil {
- resp.Diagnostics.AddError("failed to create aggregation property", err.Error())
- return
- }
-
- aggregationProperty, ok := bp.AggregationProperties[state.AggregationIdentifier.ValueString()]
- if !ok {
- resp.Diagnostics.AddError("failed to create aggregation property", err.Error())
- return
- }
-
- err = refreshAggregationPropertyState(state, aggregationProperty, state.BlueprintIdentifier.ValueString(), state.AggregationIdentifier.ValueString())
- if err != nil {
- resp.Diagnostics.AddError("failed writing aggregation property fields to resource", err.Error())
- return
- }
-
- resp.Diagnostics.Append(resp.State.Set(ctx, &state)...)
-}
-
-func (r *AggregationPropertyResource) Update(ctx context.Context, req resource.UpdateRequest, resp *resource.UpdateResponse) {
- var state *AggregationPropertyModel
- var previousState *AggregationPropertyModel
-
- resp.Diagnostics.Append(req.Plan.Get(ctx, &state)...)
- resp.Diagnostics.Append(req.State.Get(ctx, &previousState)...)
-
- if resp.Diagnostics.HasError() {
- return
- }
-
- aggr, err := aggregationPropertyToBody(state)
-
- if err != nil {
- resp.Diagnostics.AddError("failed to convert aggregation property to port valid request", err.Error())
- return
- }
-
- b, statusCode, err := r.portClient.ReadBlueprint(ctx, state.BlueprintIdentifier.ValueString())
-
- if err != nil {
- if statusCode == 404 {
- resp.Diagnostics.AddError("Blueprint doesn't exists, it is required to update the aggregation property", err.Error())
- return
- }
- resp.Diagnostics.AddError("failed reading blueprint", err.Error())
- }
-
- b.AggregationProperties[state.AggregationIdentifier.ValueString()] = *aggr
-
- bp, err := r.portClient.UpdateBlueprint(ctx, b, state.BlueprintIdentifier.ValueString())
-
- if err != nil {
- resp.Diagnostics.AddError("failed to update aggregation property", err.Error())
- return
- }
-
- aggregationProperty, ok := bp.AggregationProperties[state.AggregationIdentifier.ValueString()]
- if !ok {
- resp.Diagnostics.AddError("failed to update aggregation property", err.Error())
- return
- }
-
- err = refreshAggregationPropertyState(state, aggregationProperty, state.BlueprintIdentifier.ValueString(), state.AggregationIdentifier.ValueString())
- if err != nil {
- resp.Diagnostics.AddError("failed writing aggregation property fields to resource", err.Error())
- return
- }
-
- resp.Diagnostics.Append(resp.State.Set(ctx, &state)...)
-}
-
-func (r *AggregationPropertyResource) Delete(ctx context.Context, req resource.DeleteRequest, resp *resource.DeleteResponse) {
- var state *AggregationPropertyModel
-
- resp.Diagnostics.Append(req.State.Get(ctx, &state)...)
-
- if resp.Diagnostics.HasError() {
- return
- }
-
- b, statusCode, err := r.portClient.ReadBlueprint(ctx, state.BlueprintIdentifier.ValueString())
-
- if err != nil {
- if statusCode == 404 {
- resp.State.RemoveResource(ctx)
- return
- }
- resp.Diagnostics.AddError("failed reading blueprint", err.Error())
- }
-
- delete(b.AggregationProperties, state.AggregationIdentifier.ValueString())
-
- bp, err := r.portClient.UpdateBlueprint(ctx, b, state.BlueprintIdentifier.ValueString())
-
- if err != nil {
- resp.Diagnostics.AddError("failed to delete aggregation property", err.Error())
- return
- }
-
- _, ok := bp.AggregationProperties[state.AggregationIdentifier.ValueString()]
- if ok {
- resp.Diagnostics.AddError("failed to delete aggregation property", err.Error())
- return
- }
-
- resp.State.RemoveResource(ctx)
-}
diff --git a/port/aggregation-property/resource_test.go b/port/aggregation-property/resource_test.go
deleted file mode 100644
index 5ae1bcd9..00000000
--- a/port/aggregation-property/resource_test.go
+++ /dev/null
@@ -1,655 +0,0 @@
-package aggregation_property_test
-
-import (
- "fmt"
- "testing"
-
- "github.com/hashicorp/terraform-plugin-testing/helper/resource"
- "github.com/port-labs/terraform-provider-port-labs/internal/acctest"
- "github.com/port-labs/terraform-provider-port-labs/internal/utils"
-)
-
-func TestAccPortAggregationPropertyWithCycleRelation(t *testing.T) {
- // Test checks that a cycle aggregation property works.
- // The cycle is created by creating a parent blueprint and a child blueprint.
- // The child blueprint has a relation to the parent blueprint.
- // The parent blueprint has an aggregation property that counts the children of the parent.
- // The aggregation property is created with a cycle relation to the child blueprint, which is allowed.
- parentBlueprintIdentifier := utils.GenID()
- childBlueprintIdentifier := utils.GenID()
- aggregationPropIdentifier := utils.GenID()
- var testAccActionConfigCreate = fmt.Sprintf(`
- resource "port_blueprint" "parent_blueprint" {
- title = "Parent Blueprint"
- icon = "Terraform"
- identifier = "%s"
- description = ""
- properties = {
- number_props = {
- "age" = {
- title = "Age"
- }
- }
- }
- }
-
- resource "port_blueprint" "child_blueprint" {
- title = "Child Blueprint"
- icon = "Terraform"
- identifier = "%s"
- description = ""
- relations = {
- "parent" = {
- title = "Parent"
- target = port_blueprint.parent_blueprint.identifier
- }
- }
- }
-
- resource "port_aggregation_property" "count_entities" {
- aggregation_identifier = "%s"
- blueprint_identifier = port_blueprint.parent_blueprint.identifier
- target_blueprint_identifier = port_blueprint.child_blueprint.identifier
- title = "Count Childrens"
- icon = "Terraform"
- description = "Count Childrens"
- method = {
- count_entities = true
- }
- }
-`, parentBlueprintIdentifier, childBlueprintIdentifier, aggregationPropIdentifier)
-
- resource.Test(t, resource.TestCase{
- PreCheck: func() { acctest.TestAccPreCheck(t) },
- ProtoV6ProviderFactories: acctest.TestAccProtoV6ProviderFactories,
- Steps: []resource.TestStep{
- {
- Config: acctest.ProviderConfig + testAccActionConfigCreate,
- Check: resource.ComposeTestCheckFunc(
- resource.TestCheckResourceAttr("port_aggregation_property.count_entities", "title", "Count Childrens"),
- resource.TestCheckResourceAttr("port_aggregation_property.count_entities", "aggregation_identifier", aggregationPropIdentifier),
- resource.TestCheckResourceAttr("port_aggregation_property.count_entities", "icon", "Terraform"),
- resource.TestCheckResourceAttr("port_aggregation_property.count_entities", "description", "Count Childrens"),
- resource.TestCheckResourceAttr("port_aggregation_property.count_entities", "blueprint_identifier", parentBlueprintIdentifier),
- resource.TestCheckResourceAttr("port_aggregation_property.count_entities", "target_blueprint_identifier", childBlueprintIdentifier),
- resource.TestCheckResourceAttr("port_aggregation_property.count_entities", "method.count_entities", "true"),
- ),
- },
- },
- })
-}
-
-func TestAccCreateAggregationPropertyAverageEntities(t *testing.T) {
- parentBlueprintIdentifier := utils.GenID()
- childBlueprintIdentifier := utils.GenID()
- aggregationPropIdentifier := utils.GenID()
- var testAccActionConfigCreate = fmt.Sprintf(`
- resource "port_blueprint" "parent_blueprint" {
- title = "Parent Blueprint"
- icon = "Terraform"
- identifier = "%s"
- description = ""
- properties = {
- number_props = {
- "age" = {
- title = "Age"
- }
- }
- }
- }
-
- resource "port_blueprint" "child_blueprint" {
- title = "Child Blueprint"
- icon = "Terraform"
- identifier = "%s"
- description = ""
- relations = {
- "parent" = {
- title = "Parent"
- target = port_blueprint.parent_blueprint.identifier
- }
- }
- }
-
- resource "port_aggregation_property" "count_entities" {
- aggregation_identifier = "%s"
- blueprint_identifier = port_blueprint.parent_blueprint.identifier
- target_blueprint_identifier = port_blueprint.child_blueprint.identifier
- title = "Count Childrens"
- icon = "Terraform"
- description = "Count Childrens"
- method = {
- average_entities = {
- "average_of" = "month"
- "measure_time_by" = "$updatedAt"
- }
- }
- }
-`, parentBlueprintIdentifier, childBlueprintIdentifier, aggregationPropIdentifier)
-
- var testAccActionConfigUpdate = fmt.Sprintf(`
- resource "port_blueprint" "parent_blueprint" {
- title = "Parent Blueprint"
- icon = "Terraform"
- identifier = "%s"
- description = ""
- properties = {
- number_props = {
- "age" = {
- title = "Age"
- }
- }
- }
- }
-
- resource "port_blueprint" "child_blueprint" {
- title = "Child Blueprint"
- icon = "Terraform"
- identifier = "%s"
- description = ""
- relations = {
- "parent" = {
- title = "Parent"
- target = port_blueprint.parent_blueprint.identifier
- }
- }
- }
-
- resource "port_aggregation_property" "count_entities" {
- aggregation_identifier = "%s"
- blueprint_identifier = port_blueprint.parent_blueprint.identifier
- target_blueprint_identifier = port_blueprint.child_blueprint.identifier
- title = "Count Childrens"
- icon = "Terraform"
- description = "Count Childrens"
- method = {
- average_entities = {}
- }
- }
-`, parentBlueprintIdentifier, childBlueprintIdentifier, aggregationPropIdentifier)
-
- resource.Test(t, resource.TestCase{
- PreCheck: func() { acctest.TestAccPreCheck(t) },
- ProtoV6ProviderFactories: acctest.TestAccProtoV6ProviderFactories,
- Steps: []resource.TestStep{
- {
- Config: acctest.ProviderConfig + testAccActionConfigCreate,
- Check: resource.ComposeTestCheckFunc(
- resource.TestCheckResourceAttr("port_aggregation_property.count_entities", "title", "Count Childrens"),
- resource.TestCheckResourceAttr("port_aggregation_property.count_entities", "aggregation_identifier", aggregationPropIdentifier),
- resource.TestCheckResourceAttr("port_aggregation_property.count_entities", "icon", "Terraform"),
- resource.TestCheckResourceAttr("port_aggregation_property.count_entities", "description", "Count Childrens"),
- resource.TestCheckResourceAttr("port_aggregation_property.count_entities", "blueprint_identifier", parentBlueprintIdentifier),
- resource.TestCheckResourceAttr("port_aggregation_property.count_entities", "target_blueprint_identifier", childBlueprintIdentifier),
- resource.TestCheckResourceAttr("port_aggregation_property.count_entities", "method.average_entities.average_of", "month"),
- resource.TestCheckResourceAttr("port_aggregation_property.count_entities", "method.average_entities.measure_time_by", "$updatedAt"),
- ),
- },
- {
- Config: acctest.ProviderConfig + testAccActionConfigUpdate,
- Check: resource.ComposeTestCheckFunc(
- resource.TestCheckResourceAttr("port_aggregation_property.count_entities", "title", "Count Childrens"),
- resource.TestCheckResourceAttr("port_aggregation_property.count_entities", "aggregation_identifier", aggregationPropIdentifier),
- resource.TestCheckResourceAttr("port_aggregation_property.count_entities", "icon", "Terraform"),
- resource.TestCheckResourceAttr("port_aggregation_property.count_entities", "description", "Count Childrens"),
- resource.TestCheckResourceAttr("port_aggregation_property.count_entities", "blueprint_identifier", parentBlueprintIdentifier),
- resource.TestCheckResourceAttr("port_aggregation_property.count_entities", "target_blueprint_identifier", childBlueprintIdentifier),
- resource.TestCheckResourceAttr("port_aggregation_property.count_entities", "method.average_entities.average_of", "day"),
- resource.TestCheckResourceAttr("port_aggregation_property.count_entities", "method.average_entities.measure_time_by", "$createdAt"),
- ),
- },
- },
- })
-}
-
-func TestAccPortCreateAggregationAverageProperties(t *testing.T) {
- parentBlueprintIdentifier := utils.GenID()
- childBlueprintIdentifier := utils.GenID()
- aggregationPropIdentifier := utils.GenID()
- var testAccActionConfigCreate = fmt.Sprintf(`
- resource "port_blueprint" "parent_blueprint" {
- title = "Parent Blueprint"
- icon = "Terraform"
- identifier = "%s"
- description = ""
- properties = {
- number_props = {
- "age" = {
- title = "Age"
- }
- }
- }
- }
-
- resource "port_blueprint" "child_blueprint" {
- title = "Child Blueprint"
- icon = "Terraform"
- identifier = "%s"
- description = ""
- relations = {
- "parent" = {
- title = "Parent"
- target = port_blueprint.parent_blueprint.identifier
- }
- }
- }
-
- resource "port_aggregation_property" "average_age" {
- aggregation_identifier = "%s"
- blueprint_identifier = port_blueprint.child_blueprint.identifier
- target_blueprint_identifier = port_blueprint.parent_blueprint.identifier
- title = "Average Age"
- icon = "Terraform"
- description = "Average Age"
- method = {
- average_by_property = {
- "average_of" = "month"
- "measure_time_by" = "$updatedAt"
- "property" = "age"
- }
- }
- }
-`, parentBlueprintIdentifier, childBlueprintIdentifier, aggregationPropIdentifier)
-
- var testAccActionConfigUpdate = fmt.Sprintf(`
- resource "port_blueprint" "parent_blueprint" {
- title = "Parent Blueprint"
- icon = "Terraform"
- identifier = "%s"
- description = ""
- properties = {
- number_props = {
- "age" = {
- title = "Age"
- }
- }
- }
- }
-
- resource "port_blueprint" "child_blueprint" {
- title = "Child Blueprint"
- icon = "Terraform"
- identifier = "%s"
- description = ""
- relations = {
- "parent" = {
- title = "Parent"
- target = port_blueprint.parent_blueprint.identifier
- }
- }
- }
-
- resource "port_aggregation_property" "average_age" {
- aggregation_identifier = "%s"
- blueprint_identifier = port_blueprint.child_blueprint.identifier
- target_blueprint_identifier = port_blueprint.parent_blueprint.identifier
- title = "Average Age"
- icon = "Terraform"
- description = "Average Age"
- method = {
- average_by_property = {
- "average_of" = "day"
- "measure_time_by" = "$createdAt"
- "property" = "age"
- }
- }
- }
-`, parentBlueprintIdentifier, childBlueprintIdentifier, aggregationPropIdentifier)
-
- resource.Test(t, resource.TestCase{
- PreCheck: func() { acctest.TestAccPreCheck(t) },
- ProtoV6ProviderFactories: acctest.TestAccProtoV6ProviderFactories,
- Steps: []resource.TestStep{
- {
- Config: acctest.ProviderConfig + testAccActionConfigCreate,
- Check: resource.ComposeTestCheckFunc(
- resource.TestCheckResourceAttr("port_aggregation_property.average_age", "title", "Average Age"),
- resource.TestCheckResourceAttr("port_aggregation_property.average_age", "aggregation_identifier", aggregationPropIdentifier),
- resource.TestCheckResourceAttr("port_aggregation_property.average_age", "icon", "Terraform"),
- resource.TestCheckResourceAttr("port_aggregation_property.average_age", "description", "Average Age"),
- resource.TestCheckResourceAttr("port_aggregation_property.average_age", "blueprint_identifier", childBlueprintIdentifier),
- resource.TestCheckResourceAttr("port_aggregation_property.average_age", "target_blueprint_identifier", parentBlueprintIdentifier),
- resource.TestCheckResourceAttr("port_aggregation_property.average_age", "method.average_by_property.average_of", "month"),
- resource.TestCheckResourceAttr("port_aggregation_property.average_age", "method.average_by_property.measure_time_by", "$updatedAt"),
- resource.TestCheckResourceAttr("port_aggregation_property.average_age", "method.average_by_property.property", "age"),
- ),
- },
- {
- Config: acctest.ProviderConfig + testAccActionConfigUpdate,
- Check: resource.ComposeTestCheckFunc(
- resource.TestCheckResourceAttr("port_aggregation_property.average_age", "title", "Average Age"),
- resource.TestCheckResourceAttr("port_aggregation_property.average_age", "aggregation_identifier", aggregationPropIdentifier),
- resource.TestCheckResourceAttr("port_aggregation_property.average_age", "icon", "Terraform"),
- resource.TestCheckResourceAttr("port_aggregation_property.average_age", "description", "Average Age"),
- resource.TestCheckResourceAttr("port_aggregation_property.average_age", "blueprint_identifier", childBlueprintIdentifier),
- resource.TestCheckResourceAttr("port_aggregation_property.average_age", "target_blueprint_identifier", parentBlueprintIdentifier),
- resource.TestCheckResourceAttr("port_aggregation_property.average_age", "method.average_by_property.average_of", "day"),
- resource.TestCheckResourceAttr("port_aggregation_property.average_age", "method.average_by_property.measure_time_by", "$createdAt"),
- resource.TestCheckResourceAttr("port_aggregation_property.average_age", "method.average_by_property.property", "age"),
- ),
- },
- },
- })
-}
-
-func TestAccPortCreateAggregationPropertyAggregateByProperty(t *testing.T) {
- parentBlueprintIdentifier := utils.GenID()
- childBlueprintIdentifier := utils.GenID()
- aggregationPropIdentifier := utils.GenID()
- var testAccActionConfigCreateAggrByPropMin = fmt.Sprintf(`
- resource "port_blueprint" "parent_blueprint" {
- title = "Parent Blueprint"
- icon = "Terraform"
- identifier = "%s"
- description = ""
- properties = {
- number_props = {
- "age" = {
- title = "Age"
- }
- }
- }
- }
-
- resource "port_blueprint" "child_blueprint" {
- title = "Child Blueprint"
- icon = "Terraform"
- identifier = "%s"
- description = ""
- relations = {
- "parent" = {
- title = "Parent"
- target = port_blueprint.parent_blueprint.identifier
- }
- }
- }
-
- resource "port_aggregation_property" "aggr" {
- aggregation_identifier = "%s"
- blueprint_identifier = port_blueprint.child_blueprint.identifier
- target_blueprint_identifier = port_blueprint.parent_blueprint.identifier
- title = "Min Age"
- icon = "Terraform"
- description = "Min Age"
- method = {
- aggregate_by_property = {
- "func" = "min"
- "property" = "age"
- }
- }
- }
-`, parentBlueprintIdentifier, childBlueprintIdentifier, aggregationPropIdentifier)
-
- var testAccAggregatePropertyUpdateMax = fmt.Sprintf(`
- resource "port_blueprint" "parent_blueprint" {
- title = "Parent Blueprint"
- icon = "Terraform"
- identifier = "%s"
- description = ""
- properties = {
- number_props = {
- "age" = {
- title = "Age"
- }
- }
- }
- }
-
- resource "port_blueprint" "child_blueprint" {
- title = "Child Blueprint"
- icon = "Terraform"
- identifier = "%s"
- description = ""
- relations = {
- "parent" = {
- title = "Parent"
- target = port_blueprint.parent_blueprint.identifier
- }
- }
- }
-
- resource "port_aggregation_property" "aggr" {
- aggregation_identifier = "%s"
- blueprint_identifier = port_blueprint.child_blueprint.identifier
- target_blueprint_identifier = port_blueprint.parent_blueprint.identifier
- title = "Max Age"
- icon = "Terraform"
- description = "Max Age"
- method = {
- aggregate_by_property = {
- "func" = "max"
- "property" = "age"
- }
- }
- }
-`, parentBlueprintIdentifier, childBlueprintIdentifier, aggregationPropIdentifier)
-
- var testAccAggregatePropertyUpdateSum = fmt.Sprintf(`
- resource "port_blueprint" "parent_blueprint" {
- title = "Parent Blueprint"
- icon = "Terraform"
- identifier = "%s"
- description = ""
- properties = {
- number_props = {
- "age" = {
- title = "Age"
- }
- }
- }
- }
-
- resource "port_blueprint" "child_blueprint" {
- title = "Child Blueprint"
- icon = "Terraform"
- identifier = "%s"
- description = ""
- relations = {
- "parent" = {
- title = "Parent"
- target = port_blueprint.parent_blueprint.identifier
- }
- }
- }
-
- resource "port_aggregation_property" "aggr" {
- aggregation_identifier = "%s"
- blueprint_identifier = port_blueprint.child_blueprint.identifier
- target_blueprint_identifier = port_blueprint.parent_blueprint.identifier
- title = "Sum Age"
- icon = "Terraform"
- description = "Sum Age"
- method = {
- aggregate_by_property = {
- "func" = "sum"
- "property" = "age"
- }
- }
- }
-`, parentBlueprintIdentifier, childBlueprintIdentifier, aggregationPropIdentifier)
-
- var testAccAggregatePropertyUpdateMedian = fmt.Sprintf(`
- resource "port_blueprint" "parent_blueprint" {
- title = "Parent Blueprint"
- icon = "Terraform"
- identifier = "%s"
- description = ""
- properties = {
- number_props = {
- "age" = {
- title = "Age"
- }
- }
- }
- }
-
- resource "port_blueprint" "child_blueprint" {
- title = "Child Blueprint"
- icon = "Terraform"
- identifier = "%s"
- description = ""
- relations = {
- "parent" = {
- title = "Parent"
- target = port_blueprint.parent_blueprint.identifier
- }
- }
- }
-
- resource "port_aggregation_property" "aggr" {
- aggregation_identifier = "%s"
- blueprint_identifier = port_blueprint.child_blueprint.identifier
- target_blueprint_identifier = port_blueprint.parent_blueprint.identifier
- title = "Median Age"
- icon = "Terraform"
- description = "Median Age"
- method = {
- aggregate_by_property = {
- "func" = "median"
- "property" = "age"
- }
- }
- }
-`, parentBlueprintIdentifier, childBlueprintIdentifier, aggregationPropIdentifier)
-
- resource.Test(t, resource.TestCase{
- PreCheck: func() { acctest.TestAccPreCheck(t) },
- ProtoV6ProviderFactories: acctest.TestAccProtoV6ProviderFactories,
- Steps: []resource.TestStep{
- {
- Config: acctest.ProviderConfig + testAccActionConfigCreateAggrByPropMin,
- Check: resource.ComposeTestCheckFunc(
- resource.TestCheckResourceAttr("port_aggregation_property.aggr", "title", "Min Age"),
- resource.TestCheckResourceAttr("port_aggregation_property.aggr", "aggregation_identifier", aggregationPropIdentifier),
- resource.TestCheckResourceAttr("port_aggregation_property.aggr", "icon", "Terraform"),
- resource.TestCheckResourceAttr("port_aggregation_property.aggr", "description", "Min Age"),
- resource.TestCheckResourceAttr("port_aggregation_property.aggr", "blueprint_identifier", childBlueprintIdentifier),
- resource.TestCheckResourceAttr("port_aggregation_property.aggr", "target_blueprint_identifier", parentBlueprintIdentifier),
- resource.TestCheckResourceAttr("port_aggregation_property.aggr", "method.aggregate_by_property.func", "min"),
- resource.TestCheckResourceAttr("port_aggregation_property.aggr", "method.aggregate_by_property.property", "age"),
- ),
- },
- {
- Config: acctest.ProviderConfig + testAccAggregatePropertyUpdateMax,
- Check: resource.ComposeTestCheckFunc(
- resource.TestCheckResourceAttr("port_aggregation_property.aggr", "title", "Max Age"),
- resource.TestCheckResourceAttr("port_aggregation_property.aggr", "aggregation_identifier", aggregationPropIdentifier),
- resource.TestCheckResourceAttr("port_aggregation_property.aggr", "icon", "Terraform"),
- resource.TestCheckResourceAttr("port_aggregation_property.aggr", "description", "Max Age"),
- resource.TestCheckResourceAttr("port_aggregation_property.aggr", "blueprint_identifier", childBlueprintIdentifier),
- resource.TestCheckResourceAttr("port_aggregation_property.aggr", "target_blueprint_identifier", parentBlueprintIdentifier),
- resource.TestCheckResourceAttr("port_aggregation_property.aggr", "method.aggregate_by_property.func", "max"),
- resource.TestCheckResourceAttr("port_aggregation_property.aggr", "method.aggregate_by_property.property", "age"),
- ),
- },
- {
- Config: acctest.ProviderConfig + testAccAggregatePropertyUpdateSum,
- Check: resource.ComposeTestCheckFunc(
- resource.TestCheckResourceAttr("port_aggregation_property.aggr", "title", "Sum Age"),
- resource.TestCheckResourceAttr("port_aggregation_property.aggr", "aggregation_identifier", aggregationPropIdentifier),
- resource.TestCheckResourceAttr("port_aggregation_property.aggr", "icon", "Terraform"),
- resource.TestCheckResourceAttr("port_aggregation_property.aggr", "description", "Sum Age"),
- resource.TestCheckResourceAttr("port_aggregation_property.aggr", "blueprint_identifier", childBlueprintIdentifier),
- resource.TestCheckResourceAttr("port_aggregation_property.aggr", "target_blueprint_identifier", parentBlueprintIdentifier),
- resource.TestCheckResourceAttr("port_aggregation_property.aggr", "method.aggregate_by_property.func", "sum"),
- resource.TestCheckResourceAttr("port_aggregation_property.aggr", "method.aggregate_by_property.property", "age"),
- ),
- },
- {
- Config: acctest.ProviderConfig + testAccAggregatePropertyUpdateMedian,
- Check: resource.ComposeTestCheckFunc(
- resource.TestCheckResourceAttr("port_aggregation_property.aggr", "title", "Median Age"),
- resource.TestCheckResourceAttr("port_aggregation_property.aggr", "aggregation_identifier", aggregationPropIdentifier),
- resource.TestCheckResourceAttr("port_aggregation_property.aggr", "icon", "Terraform"),
- resource.TestCheckResourceAttr("port_aggregation_property.aggr", "description", "Median Age"),
- resource.TestCheckResourceAttr("port_aggregation_property.aggr", "blueprint_identifier", childBlueprintIdentifier),
- resource.TestCheckResourceAttr("port_aggregation_property.aggr", "target_blueprint_identifier", parentBlueprintIdentifier),
- resource.TestCheckResourceAttr("port_aggregation_property.aggr", "method.aggregate_by_property.func", "median"),
- resource.TestCheckResourceAttr("port_aggregation_property.aggr", "method.aggregate_by_property.property", "age"),
- ),
- },
- },
- })
-}
-
-func TestAccPortCreateBlueprintWithAggregationByPropertyWithFilter(t *testing.T) {
- parentBlueprintIdentifier := utils.GenID()
- childBlueprintIdentifier := utils.GenID()
- aggregationPropIdentifier := utils.GenID()
- var testAccActionConfigCreate = fmt.Sprintf(`
- resource "port_blueprint" "parent_blueprint" {
- title = "Parent Blueprint"
- icon = "Terraform"
- identifier = "%s"
- description = ""
- properties = {
- number_props = {
- "age" = {
- title = "Age"
- }
- }
- }
- }
-
- resource "port_blueprint" "child_blueprint" {
- title = "Child Blueprint"
- icon = "Terraform"
- identifier = "%s"
- description = ""
- relations = {
- "parent" = {
- title = "Parent"
- target = port_blueprint.parent_blueprint.identifier
- }
- }
- }
-
- resource "port_aggregation_property" "aggr" {
- aggregation_identifier = "%s"
- blueprint_identifier = port_blueprint.child_blueprint.identifier
- target_blueprint_identifier = port_blueprint.parent_blueprint.identifier
- title = "Min Age"
- icon = "Terraform"
- description = "Min Age"
- method = {
- aggregate_by_property = {
- "func" = "min"
- "property" = "age"
- }
- }
- query = jsonencode(
- {
- "combinator": "and",
- "rules": [
- {
- "property": "age",
- "operator": "=",
- "value": 10
- }
- ]
- }
- )
- }
-`, parentBlueprintIdentifier, childBlueprintIdentifier, aggregationPropIdentifier)
-
- resource.Test(t, resource.TestCase{
- PreCheck: func() { acctest.TestAccPreCheck(t) },
- ProtoV6ProviderFactories: acctest.TestAccProtoV6ProviderFactories,
- Steps: []resource.TestStep{
- {
- Config: acctest.ProviderConfig + testAccActionConfigCreate,
- Check: resource.ComposeTestCheckFunc(
- resource.TestCheckResourceAttr("port_aggregation_property.aggr", "title", "Min Age"),
- resource.TestCheckResourceAttr("port_aggregation_property.aggr", "aggregation_identifier", aggregationPropIdentifier),
- resource.TestCheckResourceAttr("port_aggregation_property.aggr", "icon", "Terraform"),
- resource.TestCheckResourceAttr("port_aggregation_property.aggr", "description", "Min Age"),
- resource.TestCheckResourceAttr("port_aggregation_property.aggr", "blueprint_identifier", childBlueprintIdentifier),
- resource.TestCheckResourceAttr("port_aggregation_property.aggr", "target_blueprint_identifier", parentBlueprintIdentifier),
- resource.TestCheckResourceAttr("port_aggregation_property.aggr", "method.aggregate_by_property.func", "min"),
- resource.TestCheckResourceAttr("port_aggregation_property.aggr", "method.aggregate_by_property.property", "age"),
- resource.TestCheckResourceAttr("port_aggregation_property.aggr", "query", "{\"combinator\":\"and\",\"rules\":[{\"operator\":\"=\",\"property\":\"age\",\"value\":10}]}"),
- ),
- },
- },
- })
-}
diff --git a/port/aggregation-property/schema.go b/port/aggregation-property/schema.go
deleted file mode 100644
index 42665556..00000000
--- a/port/aggregation-property/schema.go
+++ /dev/null
@@ -1,386 +0,0 @@
-package aggregation_property
-
-import (
- "context"
- "github.com/hashicorp/terraform-plugin-framework-validators/boolvalidator"
- "github.com/hashicorp/terraform-plugin-framework-validators/objectvalidator"
- "github.com/hashicorp/terraform-plugin-framework-validators/stringvalidator"
- "github.com/hashicorp/terraform-plugin-framework/path"
- "github.com/hashicorp/terraform-plugin-framework/resource"
- "github.com/hashicorp/terraform-plugin-framework/resource/schema"
- "github.com/hashicorp/terraform-plugin-framework/resource/schema/stringdefault"
- "github.com/hashicorp/terraform-plugin-framework/schema/validator"
-)
-
-func AggregationPropertySchema() map[string]schema.Attribute {
- return map[string]schema.Attribute{
- "id": schema.StringAttribute{
- Computed: true,
- },
- "aggregation_identifier": schema.StringAttribute{
- Description: "The identifier of the aggregation property in the blueprint",
- Required: true,
- },
- "blueprint_identifier": schema.StringAttribute{
- Description: "The identifier of the blueprint the aggregation property will be added to",
- Required: true,
- },
- "target_blueprint_identifier": schema.StringAttribute{
- MarkdownDescription: "The identifier of the blueprint to perform the aggregation on",
- Required: true,
- },
- "title": schema.StringAttribute{
- MarkdownDescription: "The title of the aggregation property",
- Optional: true,
- },
- "icon": schema.StringAttribute{
- MarkdownDescription: "The icon of the aggregation property",
- Optional: true,
- },
- "description": schema.StringAttribute{
- MarkdownDescription: "The description of the aggregation property",
- Optional: true,
- },
- "method": schema.SingleNestedAttribute{
- MarkdownDescription: "The aggregation method to perform on the target blueprint, one of count_entities, average_entities, average_by_property, aggregate_by_property",
- Required: true,
- Attributes: map[string]schema.Attribute{
- "count_entities": schema.BoolAttribute{
- MarkdownDescription: "Function to count the entities of the target entities",
- Optional: true,
- Validators: []validator.Bool{
- boolvalidator.ConflictsWith(path.MatchRelative().AtParent().AtName("average_entities")),
- boolvalidator.ConflictsWith(path.MatchRelative().AtParent().AtName("average_by_property")),
- boolvalidator.ConflictsWith(path.MatchRelative().AtParent().AtName("aggregate_by_property")),
- },
- },
- "average_entities": schema.SingleNestedAttribute{
- MarkdownDescription: "Function to average the entities of the target entities",
- Optional: true,
- Attributes: map[string]schema.Attribute{
- "average_of": schema.StringAttribute{
- MarkdownDescription: "The time periods to calculate the average of, e.g. hour, day, week, month",
- Optional: true,
- Computed: true,
- Default: stringdefault.StaticString("day"),
- Validators: []validator.String{
- stringvalidator.OneOf("hour", "day", "week", "month"),
- },
- },
- "measure_time_by": schema.StringAttribute{
- MarkdownDescription: "The property name on which to calculate the the time periods, e.g. $createdAt, $updated_at or any other date property",
- Optional: true,
- Computed: true,
- Default: stringdefault.StaticString("$createdAt"),
- },
- },
- Validators: []validator.Object{
- objectvalidator.ConflictsWith(
- path.MatchRelative().AtParent().AtName("count_entities"),
- path.MatchRelative().AtParent().AtName("average_by_property"),
- path.MatchRelative().AtParent().AtName("aggregate_by_property"),
- ),
- },
- },
- "average_by_property": schema.SingleNestedAttribute{
- MarkdownDescription: "Function to calculate the average by property value of the target entities",
- Optional: true,
- Attributes: map[string]schema.Attribute{
- "average_of": schema.StringAttribute{
- MarkdownDescription: "The time periods to calculate the average by, e.g. hour, day, week, month",
- Required: true,
- Validators: []validator.String{
- stringvalidator.OneOf("hour", "day", "week", "month", "total"),
- },
- },
- "measure_time_by": schema.StringAttribute{
- MarkdownDescription: "The property name on which to calculate the the time periods, e.g. $createdAt, $updated_at or any other date property",
- Required: true,
- },
- "property": schema.StringAttribute{
- MarkdownDescription: "The property name on which to calculate the average by",
- Required: true,
- },
- },
- Validators: []validator.Object{
- objectvalidator.ConflictsWith(
- path.MatchRelative().AtParent().AtName("count_entities"),
- path.MatchRelative().AtParent().AtName("average_entities"),
- path.MatchRelative().AtParent().AtName("aggregate_by_property"),
- ),
- },
- },
- "aggregate_by_property": schema.SingleNestedAttribute{
- MarkdownDescription: "Function to calculate the aggregate by property value of the target entities, such as sum, min, max, median",
- Optional: true,
- Attributes: map[string]schema.Attribute{
- "func": schema.StringAttribute{
- MarkdownDescription: "The func of the aggregate by property",
- Required: true,
- Validators: []validator.String{
- stringvalidator.OneOf("sum", "min", "max", "median"),
- },
- },
- "property": schema.StringAttribute{
- MarkdownDescription: "The property of the aggregate by property",
- Required: true,
- },
- },
- Validators: []validator.Object{
- objectvalidator.ConflictsWith(
- path.MatchRelative().AtParent().AtName("count_entities"),
- path.MatchRelative().AtParent().AtName("average_entities"),
- path.MatchRelative().AtParent().AtName("average_by_property"),
- ),
- },
- },
- },
- },
- "query": schema.StringAttribute{
- MarkdownDescription: "Query to filter the target entities",
- Optional: true,
- },
- }
-}
-
-func (r *AggregationPropertyResource) Schema(ctx context.Context, req resource.SchemaRequest, resp *resource.SchemaResponse) {
- resp.Schema = schema.Schema{
- MarkdownDescription: AggregationPropertyResourceMarkdownDescription,
- Attributes: AggregationPropertySchema(),
- }
-}
-
-var AggregationPropertyResourceMarkdownDescription = `
-
-# Aggregation Property
-
-This resource allows you to manage an aggregation property.
-
-See the [Port documentation](https://docs.getport.io/build-your-software-catalog/define-your-data-model/setup-blueprint/properties/aggregation-property/) for more information about aggregation properties.
-
-
-Supported Methods:
-
-- count_entities - Count the entities of the target blueprint
-- average_entities - Average the entities of the target blueprint by time periods
-- average_by_property - Calculate the average by property value of the target entities
-- aggregate_by_property - Calculate the aggregate by property value of the target entities, such as sum, min, max, median
-
-## Example Usage
-
-Create a parent blueprint with a child blueprint and an aggregation property to count the parent kids:
-
-` + "```hcl" + `
-
-resource "port_blueprint" "parent_blueprint" {
- title = "Parent Blueprint"
- icon = "Terraform"
- identifier = "parent"
- description = ""
- properties = {
- number_props = {
- "age" = {
- title = "Age"
- }
- }
- }
-}
-
-resource "port_blueprint" "child_blueprint" {
- title = "Child Blueprint"
- icon = "Terraform"
- identifier = "child"
- description = ""
- properties = {
- number_props = {
- "age" = {
- title = "Age"
- }
- }
- }
- relations = {
- "parent" = {
- title = "Parent"
- target = port_blueprint.parent_blueprint.identifier
- }
- }
-}
-
-resource "port_aggregation_property" "count_kids" {
- aggregation_identifier = "count_kids"
- blueprint_identifier = port_blueprint.parent_blueprint.identifier
- target_blueprint_identifier = port_blueprint.child_blueprint.identifier
- title = "Count Kids"
- icon = "Terraform"
- description = "Count Kids"
- method = {
- count_entities = true
- }
-}
-` + "```" + `
-
-Create a parent blueprint with a child blueprint and an aggregation property to calculate the average avg of the parent kids age:
-
-` + "```hcl" + `
-
-resource "port_blueprint" "parent_blueprint" {
- title = "Parent Blueprint"
- icon = "Terraform"
- identifier = "parent"
- description = ""
- properties = {
- number_props = {
- "age" = {
- title = "Age"
- }
- }
- }
-}
-
-resource "port_blueprint" "child_blueprint" {
- title = "Child Blueprint"
- icon = "Terraform"
- identifier = "child"
- description = ""
- properties = {
- number_props = {
- "age" = {
- title = "Age"
- }
- }
- }
- relations = {
- "parent" = {
- title = "Parent"
- target = port_blueprint.parent_blueprint.identifier
- }
- }
-}
-
-resource "port_aggregation_property" "average_kids_age" {
- aggregation_identifier = "average_kids_age"
- blueprint_identifier = port_blueprint.parent_blueprint.identifier
- target_blueprint_identifier = port_blueprint.child_blueprint.identifier
- title = "Average Kids Age"
- icon = "Terraform"
- description = "Average Kids Age"
- method = {
- average_by_property = {
- average_of = "total"
- measure_time_by = "$createdAt"
- property = "age"
- }
- }
-}
-
-` + "```" + `
-
-Create a repository blueprint and a pull request blueprint and an aggregation property to calculate the average of pull requests created per day:
-
-` + "```hcl" + `
-
-resource "port_blueprint" "repository_blueprint" {
- title = "Repository Blueprint"
- icon = "Terraform"
- identifier = "repository"
- description = ""
-}
-
-resource "port_blueprint" "pull_request_blueprint" {
- title = "Pull Request Blueprint"
- icon = "Terraform"
- identifier = "pull_request"
- description = ""
- properties = {
- string_props = {
- "status" = {
- title = "Status"
- }
- }
- }
- relations = {
- "repository" = {
- title = "Repository"
- target = port_blueprint.repository_blueprint.identifier
- }
- }
-}
-
-resource "port_aggregation_property" "pull_requests_per_day" {
- aggregation_identifier = "pull_requests_per_day"
- blueprint_identifier = port_blueprint.repository_blueprint.identifier
- target_blueprint_identifier = port_blueprint.pull_request_blueprint.identifier
- title = "Pull Requests Per Day"
- icon = "Terraform"
- description = "Pull Requests Per Day"
- method = {
- average_entities = {
- average_of = "day"
- measure_time_by = "$createdAt"
- }
- }
-}
-
-` + "```" + `
-
-Create a repository blueprint and a pull request blueprint and an aggregation property to calculate the average of fix pull request per month:
-
-To do that we will add a query to the aggregation property to filter only pull requests with fixed title:
-
-` + "```hcl" + `
-
-resource "port_blueprint" "repository_blueprint" {
- title = "Repository Blueprint"
- icon = "Terraform"
- identifier = "repository"
- description = ""
-}
-
-resource "port_blueprint" "pull_request_blueprint" {
- title = "Pull Request Blueprint"
- icon = "Terraform"
- identifier = "pull_request"
- description = ""
- properties = {
- string_props = {
- "status" = {
- title = "Status"
- }
- }
- }
- relations = {
- "repository" = {
- title = "Repository"
- target = port_blueprint.repository_blueprint.identifier
- }
- }
-}
-
-resource "port_aggregation_property" "fix_pull_requests_per_day" {
- aggregation_identifier = "fix_pull_requests_count"
- blueprint_identifier = port_blueprint.repository_blueprint.identifier
- target_blueprint_identifier = port_blueprint.pull_request_blueprint.identifier
- title = "Pull Requests Per Day"
- icon = "Terraform"
- description = "Pull Requests Per Day"
- method = {
- average_entities = {
- average_of = "month"
- measure_time_by = "$createdAt"
- }
- }
- query = jsonencode(
- {
- "combinator" : "and",
- "rules" : [
- {
- "property" : "$title",
- "operator" : "ContainsAny",
- "value" : ["fix", "fixed", "fixing", "Fix"]
- }
- ]
- }
- )
-}
-
-` + "```" + ``
diff --git a/provider/provider.go b/provider/provider.go
index 0b54967b..099c3135 100644
--- a/provider/provider.go
+++ b/provider/provider.go
@@ -12,7 +12,7 @@ import (
"github.com/port-labs/terraform-provider-port-labs/internal/consts"
"github.com/port-labs/terraform-provider-port-labs/port/action"
"github.com/port-labs/terraform-provider-port-labs/port/action-permissions"
- "github.com/port-labs/terraform-provider-port-labs/port/aggregation-property"
+ "github.com/port-labs/terraform-provider-port-labs/port/aggregation-properties"
"github.com/port-labs/terraform-provider-port-labs/port/blueprint"
"github.com/port-labs/terraform-provider-port-labs/port/entity"
"github.com/port-labs/terraform-provider-port-labs/port/scorecard"
@@ -127,7 +127,7 @@ func (p *PortLabsProvider) Configure(ctx context.Context, req provider.Configure
func (p *PortLabsProvider) Resources(ctx context.Context) []func() resource.Resource {
return []func() resource.Resource{
blueprint.NewBlueprintResource,
- aggregation_property.NewAggregationPropertyResource,
+ aggregation_properties.NewAggregationPropertiesResource,
entity.NewEntityResource,
action.NewActionResource,
action_permissions.NewActionPermissionsResource,