Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

PORT-4796-Terraform-provider-Add-support-of-permissions-in-action-resource #86

Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 20 additions & 0 deletions internal/cli/models.go
Original file line number Diff line number Diff line change
Expand Up @@ -189,6 +189,26 @@ type (
RequiredApproval *bool `json:"requiredApproval,omitempty"`
InvocationMethod *InvocationMethod `json:"invocationMethod,omitempty"`
ApprovalNotification *ApprovalNotification `json:"approvalNotification,omitempty"`
Permissions *ActionPermissions `json:"actionPermissions,omitempty"`
}

ActionExecutePermissions struct {
Users []string `json:"users"`
Roles []string `json:"roles"`
Teams []string `json:"teams"`
OwnedByTeam *bool `json:"ownedByTeam"`
}

ActionApprovePermissions struct {
Users []string `json:"users"`
Roles []string `json:"roles"`
Teams []string `json:"teams"`
}

ActionPermissions struct {
Action string `json:"action"`
Execute ActionExecutePermissions `json:"execute"`
Approve ActionApprovePermissions `json:"approve"`
}

Relation struct {
Expand Down
12 changes: 9 additions & 3 deletions internal/flex/string.go
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
package flex

import (
"context"

"github.com/hashicorp/terraform-plugin-framework/attr"
"github.com/hashicorp/terraform-plugin-framework/types"
"github.com/hashicorp/terraform-plugin-framework/types/basetypes"
Expand All @@ -16,7 +14,7 @@ func GoStringToFramework(v *string) types.String {
return types.StringValue(*v)
}

func GoArrayStringToTerraformList(ctx context.Context, array []string) types.List {
func GoArrayStringToTerraformList(array []string) types.List {
if array == nil {
return types.ListNull(types.StringType)
}
Expand All @@ -27,3 +25,11 @@ func GoArrayStringToTerraformList(ctx context.Context, array []string) types.Lis
list, _ := types.ListValue(types.StringType, attrs)
return list
}

func TerraformStringListToGoArray(list []types.String) []string {
arr := make([]string, len(list))
for i, t := range list {
arr[i] = t.ValueString()
}
return arr
}
137 changes: 49 additions & 88 deletions port/action/actionStateToPortBody.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import (

"github.com/port-labs/terraform-provider-port-labs/internal/cli"
"github.com/port-labs/terraform-provider-port-labs/internal/consts"
"github.com/port-labs/terraform-provider-port-labs/internal/flex"
"github.com/port-labs/terraform-provider-port-labs/internal/utils"
)

Expand Down Expand Up @@ -37,24 +38,13 @@ func actionDataSetToPortBody(dataSet *DatasetModel) *cli.Dataset {

func actionStateToPortBody(ctx context.Context, data *ActionModel, bp *cli.Blueprint) (*cli.Action, error) {
action := &cli.Action{
Identifier: data.Identifier.ValueString(),
Title: data.Title.ValueString(),
Trigger: data.Trigger.ValueString(),
}

if !data.Icon.IsNull() {
icon := data.Icon.ValueString()
action.Icon = &icon
}

if !data.Description.IsNull() {
description := data.Description.ValueString()
action.Description = &description
}

if !data.RequiredApproval.IsNull() {
requiredApproval := data.RequiredApproval.ValueBool()
action.RequiredApproval = &requiredApproval
Identifier: data.Identifier.ValueString(),
Title: data.Title.ValueString(),
Trigger: data.Trigger.ValueString(),
Icon: data.Icon.ValueStringPointer(),
Description: data.Description.ValueStringPointer(),
RequiredApproval: data.RequiredApproval.ValueBoolPointer(),
Permissions: actionPermissionsToPortBody(data.Permissions),
}

if !data.ApprovalEmailNotification.IsNull() {
Expand Down Expand Up @@ -140,31 +130,15 @@ func invocationMethodToBody(data *ActionModel) *cli.InvocationMethod {
}

if data.GithubMethod != nil {
org := data.GithubMethod.Org.ValueString()
repo := data.GithubMethod.Repo.ValueString()
workflow := data.GithubMethod.Workflow.ValueString()
githubInvocation := &cli.InvocationMethod{
Type: consts.Github,
Org: &org,
Repo: &repo,
Workflow: &workflow,
}

if !data.GithubMethod.OmitPayload.IsNull() {
omitPayload := data.GithubMethod.OmitPayload.ValueBool()
githubInvocation.OmitPayload = &omitPayload
}

if !data.GithubMethod.OmitUserInputs.IsNull() {
omitUserInputs := data.GithubMethod.OmitUserInputs.ValueBool()
githubInvocation.OmitUserInputs = &omitUserInputs
}

if !data.GithubMethod.ReportWorkflowStatus.IsNull() {
reportWorkflowStatus := data.GithubMethod.ReportWorkflowStatus.ValueBool()
githubInvocation.ReportWorkflowStatus = &reportWorkflowStatus
return &cli.InvocationMethod{
Type: consts.Github,
Org: data.GithubMethod.Org.ValueStringPointer(),
Repo: data.GithubMethod.Repo.ValueStringPointer(),
Workflow: data.GithubMethod.Workflow.ValueStringPointer(),
OmitPayload: data.GithubMethod.OmitPayload.ValueBoolPointer(),
OmitUserInputs: data.GithubMethod.OmitUserInputs.ValueBoolPointer(),
ReportWorkflowStatus: data.GithubMethod.ReportWorkflowStatus.ValueBoolPointer(),
}
return githubInvocation
}

if !data.KafkaMethod.IsNull() {
Expand All @@ -174,58 +148,45 @@ func invocationMethodToBody(data *ActionModel) *cli.InvocationMethod {
}

if data.WebhookMethod != nil {
url := data.WebhookMethod.Url.ValueString()
webhookInvocation := &cli.InvocationMethod{
Type: consts.Webhook,
Url: &url,
}
if !data.WebhookMethod.Agent.IsNull() {
agent := data.WebhookMethod.Agent.ValueBool()
webhookInvocation.Agent = &agent
}
if !data.WebhookMethod.Synchronized.IsNull() {
synchronized := data.WebhookMethod.Synchronized.ValueBool()
webhookInvocation.Synchronized = &synchronized
}
if !data.WebhookMethod.Method.IsNull() {
method := data.WebhookMethod.Method.ValueString()
webhookInvocation.Method = &method
return &cli.InvocationMethod{
Type: consts.Webhook,
Url: data.WebhookMethod.Url.ValueStringPointer(),
Agent: data.WebhookMethod.Agent.ValueBoolPointer(),
Synchronized: data.WebhookMethod.Synchronized.ValueBoolPointer(),
Method: data.WebhookMethod.Method.ValueStringPointer(),
}

return webhookInvocation
}

if data.GitlabMethod != nil {
projectName := data.GitlabMethod.ProjectName.ValueString()
groupName := data.GitlabMethod.GroupName.ValueString()
gitlabInvocation := &cli.InvocationMethod{
Type: consts.Gitlab,
ProjectName: &projectName,
GroupName: &groupName,
}

if !data.GitlabMethod.OmitPayload.IsNull() {
omitPayload := data.GitlabMethod.OmitPayload.ValueBool()
gitlabInvocation.OmitPayload = &omitPayload
}

if !data.GitlabMethod.OmitUserInputs.IsNull() {
omitUserInputs := data.GitlabMethod.OmitUserInputs.ValueBool()
gitlabInvocation.OmitUserInputs = &omitUserInputs
}

if !data.GitlabMethod.DefaultRef.IsNull() {
defaultRef := data.GitlabMethod.DefaultRef.ValueString()
gitlabInvocation.DefaultRef = &defaultRef
}

if !data.GitlabMethod.Agent.IsNull() {
agent := data.GitlabMethod.Agent.ValueBool()
gitlabInvocation.Agent = &agent
return &cli.InvocationMethod{
Type: consts.Gitlab,
ProjectName: data.GitlabMethod.ProjectName.ValueStringPointer(),
GroupName: data.GitlabMethod.GroupName.ValueStringPointer(),
OmitPayload: data.GitlabMethod.OmitPayload.ValueBoolPointer(),
OmitUserInputs: data.GitlabMethod.OmitUserInputs.ValueBoolPointer(),
DefaultRef: data.GitlabMethod.DefaultRef.ValueStringPointer(),
Agent: data.GitlabMethod.Agent.ValueBoolPointer(),
}

return gitlabInvocation
}

return nil
}
func actionPermissionsToPortBody(state *PermissionsModel) *cli.ActionPermissions {
if state == nil {
return nil
}

return &cli.ActionPermissions{
Execute: cli.ActionExecutePermissions{
Users: flex.TerraformStringListToGoArray(state.Execute.Users),
Roles: flex.TerraformStringListToGoArray(state.Execute.Roles),
Teams: flex.TerraformStringListToGoArray(state.Execute.Teams),
OwnedByTeam: state.Execute.OwnedByTeam.ValueBoolPointer(),
},
Approve: cli.ActionApprovePermissions{
Users: flex.TerraformStringListToGoArray(state.Approve.Users),
Roles: flex.TerraformStringListToGoArray(state.Approve.Roles),
Teams: flex.TerraformStringListToGoArray(state.Approve.Teams),
},
}
}
19 changes: 19 additions & 0 deletions port/action/model.go
Original file line number Diff line number Diff line change
Expand Up @@ -156,6 +156,24 @@ type ApprovalWebhookNotificationModel struct {
Format types.String `tfsdk:"format"`
}

type ExecuteModel struct {
Users []types.String `tfsdk:"users"`
Roles []types.String `tfsdk:"roles"`
Teams []types.String `tfsdk:"teams"`
OwnedByTeam types.Bool `tfsdk:"ownedByTeam"`
}

type ApproveModel struct {
Users []types.String `tfsdk:"users"`
Roles []types.String `tfsdk:"roles"`
Teams []types.String `tfsdk:"teams"`
}

type PermissionsModel struct {
Execute *ExecuteModel `tfsdk:"execute"`
Approve *ApproveModel `tfsdk:"approve"`
}

type ActionModel struct {
ID types.String `tfsdk:"id"`
Identifier types.String `tfsdk:"identifier"`
Expand All @@ -173,5 +191,6 @@ type ActionModel struct {
UserProperties *UserPropertiesModel `tfsdk:"user_properties"`
ApprovalWebhookNotification *ApprovalWebhookNotificationModel `tfsdk:"approval_webhook_notification"`
ApprovalEmailNotification types.Object `tfsdk:"approval_email_notification"`
Permissions *PermissionsModel `tfsdk:"permissions"`
OrderProperties types.List `tfsdk:"order_properties"`
}
12 changes: 6 additions & 6 deletions port/action/refreshActionState.go
Original file line number Diff line number Diff line change
Expand Up @@ -193,7 +193,7 @@ func writeInputsToResource(ctx context.Context, a *cli.Action, state *ActionMode
}
state.UserProperties = properties
if len(a.UserInputs.Order) > 0 {
state.OrderProperties = flex.GoArrayStringToTerraformList(ctx, a.UserInputs.Order)
state.OrderProperties = flex.GoArrayStringToTerraformList(a.UserInputs.Order)
}
}
return nil
Expand Down Expand Up @@ -336,15 +336,15 @@ func setCommonProperties(ctx context.Context, v cli.ActionProperty, prop interfa
case "DependsOn":
switch p := prop.(type) {
case *StringPropModel:
p.DependsOn = flex.GoArrayStringToTerraformList(ctx, v.DependsOn)
p.DependsOn = flex.GoArrayStringToTerraformList(v.DependsOn)
case *NumberPropModel:
p.DependsOn = flex.GoArrayStringToTerraformList(ctx, v.DependsOn)
p.DependsOn = flex.GoArrayStringToTerraformList(v.DependsOn)
case *BooleanPropModel:
p.DependsOn = flex.GoArrayStringToTerraformList(ctx, v.DependsOn)
p.DependsOn = flex.GoArrayStringToTerraformList(v.DependsOn)
case *ArrayPropModel:
p.DependsOn = flex.GoArrayStringToTerraformList(ctx, v.DependsOn)
p.DependsOn = flex.GoArrayStringToTerraformList(v.DependsOn)
case *ObjectPropModel:
p.DependsOn = flex.GoArrayStringToTerraformList(ctx, v.DependsOn)
p.DependsOn = flex.GoArrayStringToTerraformList(v.DependsOn)
}

case "Dataset":
Expand Down
52 changes: 52 additions & 0 deletions port/action/schema.go
Original file line number Diff line number Diff line change
Expand Up @@ -128,6 +128,58 @@ func ActionSchema() map[string]schema.Attribute {
Optional: true,
AttributeTypes: map[string]attr.Type{},
},
"permissions": schema.SingleNestedAttribute{
MarkdownDescription: "The permissions for the action",
Optional: true,
Attributes: map[string]schema.Attribute{
"execute": schema.SingleNestedAttribute{
MarkdownDescription: "The permission to execute the action",
Optional: true,
Attributes: map[string]schema.Attribute{
"users": schema.ListAttribute{
MarkdownDescription: "The users with execution permission",
Optional: true,
ElementType: types.StringType,
},
"roles": schema.ListAttribute{
MarkdownDescription: "The roles with execution permission",
Optional: true,
ElementType: types.StringType,
},
"teams": schema.ListAttribute{
MarkdownDescription: "The teams with execution permission",
Optional: true,
ElementType: types.StringType,
},
"owned_by_team": schema.BoolAttribute{
MarkdownDescription: "Give execution permission to the teams who own the entity",
Optional: true,
},
},
},
"approve": schema.SingleNestedAttribute{
MarkdownDescription: "The permission to approve the action's runs",
Optional: true,
Attributes: map[string]schema.Attribute{
"users": schema.ListAttribute{
MarkdownDescription: "The users with approval permission",
Optional: true,
ElementType: types.StringType,
},
"roles": schema.ListAttribute{
MarkdownDescription: "The roles with approval permission",
Optional: true,
ElementType: types.StringType,
},
"teams": schema.ListAttribute{
MarkdownDescription: "The teams with approval permission",
Optional: true,
ElementType: types.StringType,
},
},
},
},
},
"trigger": schema.StringAttribute{
MarkdownDescription: "The trigger type of the action",
Required: true,
Expand Down
6 changes: 2 additions & 4 deletions port/entity/entityResourceToPortBody.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import (

"github.com/hashicorp/terraform-plugin-framework/types/basetypes"
"github.com/port-labs/terraform-provider-port-labs/internal/cli"
"github.com/port-labs/terraform-provider-port-labs/internal/flex"
"github.com/port-labs/terraform-provider-port-labs/internal/utils"
)

Expand Down Expand Up @@ -84,10 +85,7 @@ func entityResourceToBody(ctx context.Context, state *EntityModel, bp *cli.Bluep
}

if state.Teams != nil {
e.Team = make([]string, len(state.Teams))
for i, t := range state.Teams {
e.Team[i] = t.ValueString()
}
e.Team = flex.TerraformStringListToGoArray(state.Teams)
}

properties := make(map[string]interface{})
Expand Down
6 changes: 2 additions & 4 deletions port/team/teamResourceToPortBody.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import (
"context"

"github.com/port-labs/terraform-provider-port-labs/internal/cli"
"github.com/port-labs/terraform-provider-port-labs/internal/flex"
)

func TeamResourceToPortBody(ctx context.Context, state *TeamModel) (*cli.Team, error) {
Expand All @@ -12,10 +13,7 @@ func TeamResourceToPortBody(ctx context.Context, state *TeamModel) (*cli.Team, e
Description: state.Description.ValueString(),
}
if state.Users != nil {
tp.Users = make([]string, len(state.Users))
for i, t := range state.Users {
tp.Users[i] = t.ValueString()
}
tp.Users = flex.TerraformStringListToGoArray(state.Users)
}

return tp, nil
Expand Down