diff --git a/docs/index.md b/docs/index.md index ff6637f8..5c7229e2 100644 --- a/docs/index.md +++ b/docs/index.md @@ -12,7 +12,6 @@ description: |- - ## Schema diff --git a/docs/resources/action.md b/docs/resources/action.md index 1655fa64..23cc10c7 100644 --- a/docs/resources/action.md +++ b/docs/resources/action.md @@ -19,7 +19,7 @@ Port action - `blueprint_identifier` (String) The identifier of the blueprint - `identifier` (String) The identifier of the action -- `invocation_method` (Block List, Min: 1, Max: 1) The methods the action is dispatched in, Supports WEBHOOK and KAFKA (see [below for nested schema](#nestedblock--invocation_method)) +- `invocation_method` (Block List, Min: 1, Max: 1) The methods the action is dispatched in, Supports WEBHOOK, KAFKA and GITHUB (see [below for nested schema](#nestedblock--invocation_method)) - `title` (String) The display name of the action - `trigger` (String) The type of the action, one of CREATE, DAY-2, DELETE @@ -42,7 +42,14 @@ Required: Optional: +- `agent` (Boolean) Relevant only when selecting type WEBHOOK. The flag that controls if the port execution agent will handle the action +- `omit_payload` (Boolean) Relevant only when selecting type GITHUB. The flag that controls if to omit Port's payload from workflow's dispatch input +- `omit_user_inputs` (Boolean) Relevant only when selecting type GITHUB. The flag that controls if to omit user inputs from workflow's dispatch input +- `org` (String) Required when selecting type GITHUB. The GitHub org that the workflow belongs to +- `repo` (String) Required when selecting type GITHUB. The GitHub repository that the workflow belongs to +- `report_workflow_status` (Boolean) Relevant only when selecting type GITHUB. The flag that controls if to report the action status when the workflow completes - `url` (String) Required when selecting type WEBHOOK. The URL to which the action is dispatched +- `workflow` (String) Required when selecting type GITHUB. The GitHub workflow id or the workflow file name @@ -57,8 +64,8 @@ Required: Optional: - `blueprint` (String) When selecting format 'entity', the identifier of the target blueprint -- `default_items` (List of String) The list of default items, in case the type of this property is a list - `default` (String) A default value for this property in case an entity is created without explicitly providing a value. +- `default_items` (List of String) The list of items, in case the type of default property is a list - `description` (String) A description of the property. This value is visible to users when hovering on the info icon in the UI. It provides detailed information about the use of a specific property. - `enum` (List of String) A list of allowed values for the property - `format` (String) A specific data format to pair with some of the available types diff --git a/docs/resources/blueprint.md b/docs/resources/blueprint.md index 20340185..1b63ca8b 100644 --- a/docs/resources/blueprint.md +++ b/docs/resources/blueprint.md @@ -49,8 +49,8 @@ Required: Optional: -- `default_items` (List of String) The list of default items, in case the type of this property is a list - `default` (String) The default value of the property +- `default_items` (List of String) The list of items, in case the type of default property is a list - `description` (String) The description of the property - `enum` (List of String) A list of allowed values for the property - `enum_colors` (Map of String) A map of colors for the enum values @@ -70,6 +70,7 @@ Optional: - `url` (String) Required when selecting type WEBHOOK. The URL to which the changelog is dispatched + ### Nested Schema for `mirror_properties` diff --git a/port/cli/models.go b/port/cli/models.go index d6f17372..e3be8cf3 100644 --- a/port/cli/models.go +++ b/port/cli/models.go @@ -54,8 +54,15 @@ type ( } InvocationMethod struct { - Type string `json:"type,omitempty"` - Url string `json:"url,omitempty"` + Type string `json:"type,omitempty"` + Url string `json:"url,omitempty"` + Agent bool `json:"agent,omitempty"` + Org string `json:"org,omitempty"` + Repo string `json:"repo,omitempty"` + Workflow string `json:"workflow,omitempty"` + OmitPayload bool `json:"omitPayload,omitempty"` + OmitUserInputs bool `json:"omitUserInputs,omitempty"` + ReportWorkflowStatus bool `json:"reportWorkflowStatus,omitempty"` } ChangelogDestination struct { diff --git a/port/resource_port_action.go b/port/resource_port_action.go index 9157bd7b..ba208369 100644 --- a/port/resource_port_action.go +++ b/port/resource_port_action.go @@ -12,6 +12,9 @@ import ( "github.com/samber/lo" ) +var requiredGithubArguments = []string{"invocation_method.0.org", "invocation_method.0.repo", "invocation_method.0.workflow"} +var requiredWebhookArguments = []string{"invocation_method.0.url"} + func newActionResource() *schema.Resource { return &schema.Resource{ Description: "Port action", @@ -120,19 +123,63 @@ func newActionResource() *schema.Resource { Type: schema.TypeList, MinItems: 1, MaxItems: 1, - Description: "The methods the action is dispatched in, Supports WEBHOOK and KAFKA", + Description: "The methods the action is dispatched in, Supports WEBHOOK, KAFKA and GITHUB", Elem: &schema.Resource{ Schema: map[string]*schema.Schema{ "type": { Type: schema.TypeString, Required: true, Description: "How to invoke the action using WEBHOOK or KAFKA", - ValidateFunc: validation.StringInSlice([]string{"WEBHOOK", "KAFKA"}, false), + ValidateFunc: validation.StringInSlice([]string{"WEBHOOK", "KAFKA", "GITHUB"}, false), }, "url": { - Type: schema.TypeString, - Optional: true, - Description: "Required when selecting type WEBHOOK. The URL to which the action is dispatched", + Type: schema.TypeString, + Optional: true, + Description: "Required when selecting type WEBHOOK. The URL to which the action is dispatched", + ConflictsWith: []string{"invocation_method.0.org"}, + }, + "agent": { + Type: schema.TypeBool, + Optional: true, + Description: "Relevant only when selecting type WEBHOOK. The flag that controls if the port execution agent will handle the action", + RequiredWith: requiredWebhookArguments, + }, + "org": { + Type: schema.TypeString, + Optional: true, + Description: "Required when selecting type GITHUB. The GitHub org that the workflow belongs to", + RequiredWith: requiredGithubArguments, + ConflictsWith: []string{"invocation_method.0.url"}, + }, + "repo": { + Type: schema.TypeString, + Optional: true, + Description: "Required when selecting type GITHUB. The GitHub repository that the workflow belongs to", + RequiredWith: requiredGithubArguments, + }, + "workflow": { + Type: schema.TypeString, + Optional: true, + Description: "Required when selecting type GITHUB. The GitHub workflow id or the workflow file name", + RequiredWith: requiredGithubArguments, + }, + "omit_payload": { + Type: schema.TypeBool, + Optional: true, + Description: "Relevant only when selecting type GITHUB. The flag that controls if to omit Port's payload from workflow's dispatch input", + RequiredWith: requiredGithubArguments, + }, + "omit_user_inputs": { + Type: schema.TypeBool, + Optional: true, + Description: "Relevant only when selecting type GITHUB. The flag that controls if to omit user inputs from workflow's dispatch input", + RequiredWith: requiredGithubArguments, + }, + "report_workflow_status": { + Type: schema.TypeBool, + Optional: true, + Description: "Relevant only when selecting type GITHUB. The flag that controls if to report the action status when the workflow completes", + RequiredWith: requiredGithubArguments, }, }, }, @@ -165,8 +212,15 @@ func writeActionFieldsToResource(d *schema.ResourceData, action *cli.Action) { d.Set("icon", action.Icon) d.Set("description", action.Description) d.Set("invocation_method", []any{map[string]any{ - "type": action.InvocationMethod.Type, - "url": action.InvocationMethod.Url, + "type": action.InvocationMethod.Type, + "url": action.InvocationMethod.Url, + "agent": action.InvocationMethod.Agent, + "org": action.InvocationMethod.Org, + "repo": action.InvocationMethod.Repo, + "workflow": action.InvocationMethod.Workflow, + "omit_payload": action.InvocationMethod.OmitPayload, + "omit_user_inputs": action.InvocationMethod.OmitUserInputs, + "report_workflow_status": action.InvocationMethod.ReportWorkflowStatus, }}) d.Set("trigger", action.Trigger) @@ -231,6 +285,13 @@ func actionResourceToBody(d *schema.ResourceData) (*cli.Action, error) { action.InvocationMethod.Type = invocationMethod.([]any)[0].(map[string]interface{})["type"].(string) action.InvocationMethod.Url = invocationMethod.([]any)[0].(map[string]interface{})["url"].(string) + action.InvocationMethod.Agent = invocationMethod.([]any)[0].(map[string]interface{})["agent"].(bool) + action.InvocationMethod.Org = invocationMethod.([]any)[0].(map[string]interface{})["org"].(string) + action.InvocationMethod.Repo = invocationMethod.([]any)[0].(map[string]interface{})["repo"].(string) + action.InvocationMethod.Workflow = invocationMethod.([]any)[0].(map[string]interface{})["workflow"].(string) + action.InvocationMethod.OmitPayload = invocationMethod.([]any)[0].(map[string]interface{})["omit_payload"].(bool) + action.InvocationMethod.OmitUserInputs = invocationMethod.([]any)[0].(map[string]interface{})["omit_user_inputs"].(bool) + action.InvocationMethod.ReportWorkflowStatus = invocationMethod.([]any)[0].(map[string]interface{})["report_workflow_status"].(bool) } action.Trigger = d.Get("trigger").(string) diff --git a/port/resource_port_action_test.go b/port/resource_port_action_test.go index fdb86a92..a52db4f7 100644 --- a/port/resource_port_action_test.go +++ b/port/resource_port_action_test.go @@ -211,7 +211,7 @@ func TestAccPortActionPropMeta(t *testing.T) { }) } -func TestAccPortActionWebhookInvocation(t *testing.T) { +func TestAccPortActionEntityMultiselect(t *testing.T) { identifier := genID() actionIdentifier := genID() var testAccActionConfigCreate = fmt.Sprintf(` @@ -261,7 +261,7 @@ func TestAccPortActionWebhookInvocation(t *testing.T) { }) } -func TestAccPortActionEntityMultiselect(t *testing.T) { +func TestAccPortActionWebhookInvocation(t *testing.T) { identifier := genID() actionIdentifier := genID() var testAccActionConfigCreate = fmt.Sprintf(` @@ -284,6 +284,7 @@ func TestAccPortActionEntityMultiselect(t *testing.T) { invocation_method { type = "WEBHOOK" url = "https://google.com" + agent = true } } `, identifier, actionIdentifier) @@ -303,6 +304,65 @@ func TestAccPortActionEntityMultiselect(t *testing.T) { resource.TestCheckResourceAttr("port-labs_action.restart_microservice", "trigger", "DAY-2"), resource.TestCheckResourceAttr("port-labs_action.restart_microservice", "invocation_method.0.type", "WEBHOOK"), resource.TestCheckResourceAttr("port-labs_action.restart_microservice", "invocation_method.0.url", "https://google.com"), + resource.TestCheckResourceAttr("port-labs_action.restart_microservice", "invocation_method.0.agent", "true"), + ), + }, + }, + }) +} + +func TestAccPortActionGithubInvocation(t *testing.T) { + identifier := genID() + actionIdentifier := genID() + var testAccActionConfigCreate = fmt.Sprintf(` + resource "port-labs_blueprint" "microservice" { + title = "TF test microservice" + icon = "Terraform" + identifier = "%s" + properties { + identifier = "text" + type = "string" + title = "text" + } + } + resource "port-labs_action" "restart_microservice" { + title = "Restart service" + icon = "Terraform" + identifier = "%s" + blueprint_identifier = port-labs_blueprint.microservice.identifier + trigger = "DAY-2" + invocation_method { + type = "GITHUB" + org = "port-labs" + repo = "Port" + workflow = "deploy.yml" + omit_payload = false + omit_user_inputs = false + report_workflow_status = true + } + } +`, identifier, actionIdentifier) + resource.Test(t, resource.TestCase{ + Providers: map[string]*schema.Provider{ + "port-labs": Provider(), + }, + Steps: []resource.TestStep{ + { + Config: testAccActionConfigCreate, + Destroy: false, + Check: resource.ComposeTestCheckFunc( + resource.TestCheckResourceAttr("port-labs_action.restart_microservice", "title", "Restart service"), + resource.TestCheckResourceAttr("port-labs_action.restart_microservice", "icon", "Terraform"), + resource.TestCheckResourceAttr("port-labs_action.restart_microservice", "identifier", actionIdentifier), + resource.TestCheckResourceAttr("port-labs_action.restart_microservice", "blueprint_identifier", identifier), + resource.TestCheckResourceAttr("port-labs_action.restart_microservice", "trigger", "DAY-2"), + resource.TestCheckResourceAttr("port-labs_action.restart_microservice", "invocation_method.0.type", "GITHUB"), + resource.TestCheckResourceAttr("port-labs_action.restart_microservice", "invocation_method.0.org", "port-labs"), + resource.TestCheckResourceAttr("port-labs_action.restart_microservice", "invocation_method.0.repo", "Port"), + resource.TestCheckResourceAttr("port-labs_action.restart_microservice", "invocation_method.0.workflow", "deploy.yml"), + resource.TestCheckResourceAttr("port-labs_action.restart_microservice", "invocation_method.0.omit_payload", "false"), + resource.TestCheckResourceAttr("port-labs_action.restart_microservice", "invocation_method.0.omit_user_inputs", "false"), + resource.TestCheckResourceAttr("port-labs_action.restart_microservice", "invocation_method.0.report_workflow_status", "true"), ), }, },