diff --git a/docs/resources/user_group.md b/docs/resources/user_group.md
index 7dcf1e307..77abb57ef 100644
--- a/docs/resources/user_group.md
+++ b/docs/resources/user_group.md
@@ -73,6 +73,10 @@ resource "harness_user_group" "example" {
actions = ["UPDATE", "DELETE"]
}
+ template {
+ actions = ["CREATE", "READ", "UPDATE", "DELETE"]
+ }
+
workflow {
actions = ["UPDATE", "DELETE"]
filters = ["NON_PRODUCTION_WORKFLOWS", ]
@@ -151,6 +155,7 @@ Optional:
- **pipeline** (Block Set) Permission configuration to perform actions against pipelines. (see [below for nested schema](#nestedblock--permissions--app_permissions--pipeline))
- **provisioner** (Block Set) Permission configuration to perform actions against provisioners. (see [below for nested schema](#nestedblock--permissions--app_permissions--provisioner))
- **service** (Block Set) Permission configuration to perform actions against services. (see [below for nested schema](#nestedblock--permissions--app_permissions--service))
+- **template** (Block Set) Permission configuration to perform actions against templates. (see [below for nested schema](#nestedblock--permissions--app_permissions--template))
- **workflow** (Block Set) Permission configuration to perform actions against workflows. (see [below for nested schema](#nestedblock--permissions--app_permissions--workflow))
@@ -233,6 +238,19 @@ Optional:
- **service_ids** (Set of String) The service IDs to which the permission applies. Leave empty to apply to all services.
+
+### Nested Schema for `permissions.app_permissions.template`
+
+Required:
+
+- **actions** (Set of String) The actions allowed to be performed. Valid options are CREATE, READ, UPDATE, DELETE
+
+Optional:
+
+- **app_ids** (Set of String) The application IDs to which the permission applies. Leave empty to apply to all applications.
+- **template_ids** (Set of String) The template IDs to which the permission applies. Leave empty to apply to all environments.
+
+
### Nested Schema for `permissions.app_permissions.workflow`
diff --git a/examples/resources/harness_user_group/resource.tf b/examples/resources/harness_user_group/resource.tf
index 524c327d9..cd28d6046 100644
--- a/examples/resources/harness_user_group/resource.tf
+++ b/examples/resources/harness_user_group/resource.tf
@@ -58,6 +58,10 @@ resource "harness_user_group" "example" {
actions = ["UPDATE", "DELETE"]
}
+ template {
+ actions = ["CREATE", "READ", "UPDATE", "DELETE"]
+ }
+
workflow {
actions = ["UPDATE", "DELETE"]
filters = ["NON_PRODUCTION_WORKFLOWS", ]
diff --git a/internal/provider/resource_cloudprovider_tanzu.go b/internal/provider/resource_cloudprovider_tanzu.go
index 8a7da5430..76d46eaf6 100644
--- a/internal/provider/resource_cloudprovider_tanzu.go
+++ b/internal/provider/resource_cloudprovider_tanzu.go
@@ -138,30 +138,3 @@ func resourceCloudProviderTanzuCreateOrUpdate(ctx context.Context, d *schema.Res
return readCloudProviderTanzu(c, d, cp)
}
-
-func resourceCloudProviderTanzuUpdate(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics {
- c := meta.(*api.Client)
-
- cp := cac.NewEntity(cac.ObjectTypes.AzureCloudProvider).(*cac.PcfCloudProvider)
- cp.Name = d.Get("name").(string)
- cp.EndpointUrl = d.Get("endpoint").(string)
- cp.SkipValidation = d.Get("skip_validation").(bool)
- cp.Username = d.Get("username").(string)
-
- if attr := d.Get("username_secret_name").(string); attr != "" {
- cp.UsernameSecretId = &cac.SecretRef{
- Name: attr,
- }
- }
-
- cp.Password = &cac.SecretRef{
- Name: d.Get("password_secret_name").(string),
- }
-
- _, err := c.ConfigAsCode().UpsertPcfCloudProvider(cp)
- if err != nil {
- return diag.FromErr(err)
- }
-
- return nil
-}
diff --git a/internal/provider/resource_git_connector_test.go b/internal/provider/resource_git_connector_test.go
index 88c267d5f..254215a43 100644
--- a/internal/provider/resource_git_connector_test.go
+++ b/internal/provider/resource_git_connector_test.go
@@ -249,29 +249,6 @@ func testAccResourceGitConnector(name string, generateWebhook bool, withCommitDe
`, name, generateWebhook, commitDetails, delegateSelectors)
}
-func testAccResourceGitConnector_invalid_urltype(name string) string {
- return fmt.Sprintf(`
- data "harness_secret_manager" "test" {
- default = true
- }
-
- resource "harness_encrypted_text" "test" {
- name = "%[1]s"
- value = "foo"
- secret_manager_id = data.harness_secret_manager.test.id
- }
-
- resource "harness_git_connector" "test" {
- name = "%[1]s"
- url = "https://github.com/micahlmartin/harness-demo"
- branch = "master"
- password_secret_id = harness_encrypted_text.test.id
- url_type = "badvalue"
- username = "someuser"
- }
-`, name)
-}
-
// func testAccResourceEncryptedText_UsageScopes(name string) string {
// // nonprod :=
// return fmt.Sprintf(`
diff --git a/internal/provider/resource_infrastructure_definition_test.go b/internal/provider/resource_infrastructure_definition_test.go
index 981813285..2c81974bd 100644
--- a/internal/provider/resource_infrastructure_definition_test.go
+++ b/internal/provider/resource_infrastructure_definition_test.go
@@ -357,26 +357,6 @@ func testAccInfraDefK8s(name string) string {
`, name)
}
-func testAccInfraDefAws(name string) string {
- return fmt.Sprintf(`
- resource "harness_cloudprovider_aws" "test" {
- name = "%[1]s"
- // delegate_selector = "aws"
-
- }
-
- resource "harness_application" "test" {
- name = "%[1]s"
- }
-
- resource "harness_environment" "test" {
- name = "%[1]s"
- app_id = harness_application.test.id
- type = "NON_PROD"
- }
-`, name)
-}
-
func testAccResourceInfraDefEnvironment(name string) string {
return fmt.Sprintf(`
resource "harness_application" "test" {
diff --git a/internal/provider/resource_service_aws_codedeploy.go b/internal/provider/resource_service_aws_codedeploy.go
index 4daa25e03..5db677647 100644
--- a/internal/provider/resource_service_aws_codedeploy.go
+++ b/internal/provider/resource_service_aws_codedeploy.go
@@ -93,30 +93,3 @@ func resourceAWSCodeDeployServiceCreateOrUpdate(ctx context.Context, d *schema.R
return readServiceCodeDeploy(d, newSvc)
}
-
-func resourceAWSCodeDeployServiceUpdate(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics {
- c := meta.(*api.Client)
-
- // Setup the object to create
- svcInput := &cac.Service{
- Name: d.Get("name").(string),
- ArtifactType: cac.ArtifactTypes.AWSCodeDeploy,
- DeploymentType: cac.DeploymentTypes.AWSCodeDeploy,
- ApplicationId: d.Get("app_id").(string),
- Description: d.Get("description").(string),
- }
-
- if vars := d.Get("variable"); vars != nil {
- svcInput.ConfigVariables = expandServiceVariables(vars.(*schema.Set).List())
- }
-
- // Create Service
- newSvc, err := c.ConfigAsCode().UpsertService(svcInput)
- if err != nil {
- return diag.FromErr(err)
- }
-
- d.SetId(newSvc.Id)
-
- return nil
-}
diff --git a/internal/provider/resource_service_aws_lambda.go b/internal/provider/resource_service_aws_lambda.go
index 42aaf7739..00257f432 100644
--- a/internal/provider/resource_service_aws_lambda.go
+++ b/internal/provider/resource_service_aws_lambda.go
@@ -93,30 +93,3 @@ func resourceAWSLambdaServiceCreateOrUpdate(ctx context.Context, d *schema.Resou
return readServiceAwsLambda(d, newSvc)
}
-
-func resourceAWSLambdaServiceUpdate(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics {
- c := meta.(*api.Client)
-
- // Setup the object to create
- svcInput := &cac.Service{
- Name: d.Get("name").(string),
- ArtifactType: cac.ArtifactTypes.AWSLambda,
- DeploymentType: cac.DeploymentTypes.AWSLambda,
- ApplicationId: d.Get("app_id").(string),
- Description: d.Get("description").(string),
- }
-
- if vars := d.Get("variable"); vars != nil {
- svcInput.ConfigVariables = expandServiceVariables(vars.(*schema.Set).List())
- }
-
- // Create Service
- newSvc, err := c.ConfigAsCode().UpsertService(svcInput)
- if err != nil {
- return diag.FromErr(err)
- }
-
- d.SetId(newSvc.Id)
-
- return nil
-}
diff --git a/internal/provider/resource_service_winrm.go b/internal/provider/resource_service_winrm.go
index b4019c2b5..cc06d4ffc 100644
--- a/internal/provider/resource_service_winrm.go
+++ b/internal/provider/resource_service_winrm.go
@@ -105,30 +105,3 @@ func resourceWinRMServiceCreateOrUpdate(ctx context.Context, d *schema.ResourceD
return readServiceWinRM(d, newSvc)
}
-
-func resourceWinRMServiceUpdate(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics {
- c := meta.(*api.Client)
-
- // Setup the object to create
- svcInput := &cac.Service{
- Name: d.Get("name").(string),
- ArtifactType: cac.ArtifactType(d.Get("artifact_type").(string)),
- DeploymentType: cac.DeploymentTypes.WinRM,
- ApplicationId: d.Get("app_id").(string),
- Description: d.Get("description").(string),
- }
-
- if vars := d.Get("variable"); vars != nil {
- svcInput.ConfigVariables = expandServiceVariables(vars.(*schema.Set).List())
- }
-
- // Create Service
- newSvc, err := c.ConfigAsCode().UpsertService(svcInput)
- if err != nil {
- return diag.FromErr(err)
- }
-
- d.SetId(newSvc.Id)
-
- return nil
-}
diff --git a/internal/provider/resource_user_group.go b/internal/provider/resource_user_group.go
index a355bf847..a518816d6 100644
--- a/internal/provider/resource_user_group.go
+++ b/internal/provider/resource_user_group.go
@@ -326,6 +326,34 @@ func resourceUserGroup() *schema.Resource {
},
},
},
+ "template": {
+ Description: "Permission configuration to perform actions against templates.",
+ Type: schema.TypeSet,
+ Optional: true,
+ Elem: &schema.Resource{
+ Schema: map[string]*schema.Schema{
+ "app_ids": {
+ Description: "The application IDs to which the permission applies. Leave empty to apply to all applications.",
+ Type: schema.TypeSet,
+ Optional: true,
+ Elem: &schema.Schema{Type: schema.TypeString},
+ },
+ "template_ids": {
+ Description: "The template IDs to which the permission applies. Leave empty to apply to all environments.",
+ Type: schema.TypeSet,
+ Optional: true,
+ Elem: &schema.Schema{Type: schema.TypeString},
+ },
+ "actions": {
+ Description: fmt.Sprintf("The actions allowed to be performed. Valid options are %s", strings.Join(standardActions, ", ")),
+ Type: schema.TypeSet,
+ Required: true,
+ MinItems: 1,
+ Elem: &schema.Schema{Type: schema.TypeString},
+ },
+ },
+ },
+ },
},
},
},
@@ -507,6 +535,53 @@ func expandAccountPermissions(d []interface{}, input *graphql.UserGroupPermissio
}
}
+func expandTemplateAppPermissions(d []interface{}, input *graphql.UserGroupPermissions) {
+ if len(d) == 0 {
+ return
+ }
+
+ for _, v := range d {
+ permission := &graphql.AppPermission{
+ PermissionType: graphql.AppPermissionTypes.Template,
+ Applications: &graphql.AppFilter{},
+ Actions: []graphql.Action{},
+ Templates: &graphql.TemplatePermissionFilter{},
+ }
+
+ permissionConfig := v.(map[string]interface{})
+ if attr := permissionConfig["app_ids"]; attr != nil {
+ for _, appId := range attr.(*schema.Set).List() {
+ permission.Applications.AppIds = append(permission.Applications.AppIds, appId.(string))
+ }
+ }
+
+ if len(permission.Applications.AppIds) == 0 {
+ permission.Applications.FilterType = graphql.FilterTypes.All
+ }
+
+ if attr := permissionConfig["actions"]; attr != nil {
+ for _, action := range attr.(*schema.Set).List() {
+ permission.Actions = append(permission.Actions, graphql.Action(action.(string)))
+ }
+ }
+
+ if attr := permissionConfig["template_ids"]; attr != nil {
+ templateIds := attr.(*schema.Set).List()
+ if len(templateIds) > 0 {
+ tmplIds := []string{}
+ for _, templateId := range templateIds {
+ tmplIds = append(tmplIds, templateId.(string))
+ }
+ permission.Templates.TemplateIds = tmplIds
+ } else {
+ permission.Templates.FilterType = graphql.FilterTypes.All
+ }
+ }
+
+ input.AppPermissions = append(input.AppPermissions, permission)
+ }
+}
+
func expandWorkflowAppPermissions(d []interface{}, input *graphql.UserGroupPermissions) {
if len(d) == 0 {
return
@@ -862,6 +937,7 @@ func expandAppPermissions(d []interface{}, input *graphql.UserGroupPermissions)
expandPipelineAppPermissions(appPermissionsConfig["pipeline"].(*schema.Set).List(), input)
expandProvisionerAppPermissions(appPermissionsConfig["provisioner"].(*schema.Set).List(), input)
expandServiceAppPermissions(appPermissionsConfig["service"].(*schema.Set).List(), input)
+ expandTemplateAppPermissions(appPermissionsConfig["template"].(*schema.Set).List(), input)
expandWorkflowAppPermissions(appPermissionsConfig["workflow"].(*schema.Set).List(), input)
}
@@ -1093,6 +1169,26 @@ func flattenAppPermissionService(appPermissions *graphql.AppPermission) map[stri
return results
}
+func flattenAppPermissionTemplate(appPermissions *graphql.AppPermission) map[string]interface{} {
+ results := map[string]interface{}{}
+
+ if len(appPermissions.Applications.AppIds) > 0 {
+ results["app_ids"] = appPermissions.Applications.AppIds
+ }
+
+ if len(appPermissions.Actions) > 0 {
+ results["actions"] = appPermissions.Actions
+ }
+
+ if appPermissions.Templates != nil {
+ if len(appPermissions.Templates.TemplateIds) > 0 {
+ results["template_ids"] = appPermissions.Templates.TemplateIds
+ }
+ }
+
+ return results
+}
+
func flattenAppPermissionWorkflow(appPermissions *graphql.AppPermission) map[string]interface{} {
results := map[string]interface{}{}
@@ -1130,6 +1226,7 @@ func flattenAppPermissions(permissions *graphql.UserGroupPermissions) []interfac
pipelines := []interface{}{}
provisioners := []interface{}{}
services := []interface{}{}
+ templates := []interface{}{}
workflows := []interface{}{}
for _, appPermission := range permissions.AppPermissions {
@@ -1146,6 +1243,8 @@ func flattenAppPermissions(permissions *graphql.UserGroupPermissions) []interfac
provisioners = append(provisioners, flattenAppPermissionProvisioner(appPermission))
case graphql.AppPermissionTypes.Service:
services = append(services, flattenAppPermissionService(appPermission))
+ case graphql.AppPermissionTypes.Template:
+ templates = append(templates, flattenAppPermissionTemplate(appPermission))
case graphql.AppPermissionTypes.Workflow:
workflows = append(workflows, flattenAppPermissionWorkflow(appPermission))
default:
@@ -1160,6 +1259,7 @@ func flattenAppPermissions(permissions *graphql.UserGroupPermissions) []interfac
"pipeline": pipelines,
"provisioner": provisioners,
"service": services,
+ "template": templates,
"workflow": workflows,
})
}
diff --git a/internal/provider/resource_user_group_test.go b/internal/provider/resource_user_group_test.go
index 89dd39778..79e5d85f9 100644
--- a/internal/provider/resource_user_group_test.go
+++ b/internal/provider/resource_user_group_test.go
@@ -64,6 +64,11 @@ func TestAccResourceUserGroup_SAML(t *testing.T) {
testAccUserGroupCreation(t, resourceName, expectedName),
),
},
+ {
+ ResourceName: resourceName,
+ ImportState: true,
+ ImportStateVerify: true,
+ },
},
})
}
@@ -85,6 +90,11 @@ func TestAccResourceUserGroup_NotificationsSettings(t *testing.T) {
testAccUserGroupCreation(t, resourceName, expectedName),
),
},
+ {
+ ResourceName: resourceName,
+ ImportState: true,
+ ImportStateVerify: true,
+ },
},
})
}
@@ -106,6 +116,11 @@ func TestAccResourceUserGroup_AccountPermissions(t *testing.T) {
testAccUserGroupCreation(t, resourceName, expectedName),
),
},
+ {
+ ResourceName: resourceName,
+ ImportState: true,
+ ImportStateVerify: true,
+ },
},
})
}
@@ -162,6 +177,11 @@ func TestAccResourceUserGroup_AppPermissions(t *testing.T) {
testAccUserGroupCreation(t, resourceName, expectedName),
),
},
+ {
+ ResourceName: resourceName,
+ ImportState: true,
+ ImportStateVerify: true,
+ },
},
})
}
@@ -255,6 +275,10 @@ func testAccResourceUserGroupAppPermissions(name string) string {
service {
actions = ["UPDATE", "DELETE"]
}
+
+ template {
+ actions = ["CREATE", "READ", "UPDATE", "DELETE"]
+ }
workflow {
actions = ["UPDATE", "DELETE"]