diff --git a/docs/data-sources/channels.md b/docs/data-sources/channels.md
index bf1546f4f..0e75679a9 100644
--- a/docs/data-sources/channels.md
+++ b/docs/data-sources/channels.md
@@ -43,6 +43,8 @@ data "octopusdeploy_channels" "example" {
Read-Only:
- `description` (String) The description of this channel.
+- `git_reference_rules` (List of String) List of rules to restrict which Git references can be used with this channel when creating releases for version controlled projects. References must be fully qualified e.g. `refs/heads/main`. Supports glob patten syntax.
+- `git_resource_rules` (List of Object) List of rules to restrict which Git resources can be used with this channel when creating releases with external Git resources. Resources must be fully qualified e.g. `refs/heads/main`. Supports glob patten syntax. (see [below for nested schema](#nestedatt--channels--git_resource_rules))
- `id` (String) The unique ID for this resource.
- `is_default` (Boolean) Indicates if this is the default channel for the associated project.
- `lifecycle_id` (String) The lifecycle ID associated with this channel.
@@ -52,6 +54,25 @@ Read-Only:
- `space_id` (String) The space ID associated with this resource.
- `tenant_tags` (List of String) A list of tenant tags associated with this resource.
+
+### Nested Schema for `channels.git_resource_rules`
+
+Read-Only:
+
+- `git_dependency_actions` (List of Object) (see [below for nested schema](#nestedobjatt--channels--git_resource_rules--git_dependency_actions))
+- `id` (String)
+- `rules` (List of String)
+
+
+### Nested Schema for `channels.git_resource_rules.git_dependency_actions`
+
+Read-Only:
+
+- `deployment_action_slug` (String)
+- `git_dependency_name` (String)
+
+
+
### Nested Schema for `channels.rule`
diff --git a/docs/resources/azure_subscription_account.md b/docs/resources/azure_subscription_account.md
index a7025e91a..7f11a8822 100644
--- a/docs/resources/azure_subscription_account.md
+++ b/docs/resources/azure_subscription_account.md
@@ -22,9 +22,7 @@ resource "octopusdeploy_azure_subscription_account" "example" {
### Required
-- `management_endpoint` (String)
- `name` (String) The name of this resource.
-- `storage_endpoint_suffix` (String) The storage endpoint suffix associated with this Azure subscription account.
- `subscription_id` (String) The subscription ID of this resource.
### Optional
@@ -34,7 +32,9 @@ resource "octopusdeploy_azure_subscription_account" "example" {
- `certificate_thumbprint` (String, Sensitive)
- `description` (String) The description of this Azure subscription account.
- `environments` (List of String) A list of environment IDs associated with this resource.
+- `management_endpoint` (String)
- `space_id` (String) The space ID associated with this resource.
+- `storage_endpoint_suffix` (String) The storage endpoint suffix associated with this Azure subscription account.
- `tenant_tags` (List of String) A list of tenant tags associated with this resource.
- `tenanted_deployment_participation` (String) The tenanted deployment mode of the resource. Valid account types are `Untenanted`, `TenantedOrUntenanted`, or `Tenanted`.
- `tenants` (List of String) A list of tenant IDs associated with this resource.
diff --git a/docs/resources/channel.md b/docs/resources/channel.md
index ca879b8d9..1fa5be29b 100644
--- a/docs/resources/channel.md
+++ b/docs/resources/channel.md
@@ -30,6 +30,8 @@ resource "octopusdeploy_channel" "example" {
### Optional
- `description` (String) The description of this channel.
+- `git_reference_rules` (List of String) List of rules to restrict which Git references can be used with this channel when creating releases for version controlled projects. References must be fully qualified e.g. `refs/heads/main`. Supports glob patten syntax.
+- `git_resource_rules` (Block List) List of rules to restrict which Git resources can be used with this channel when creating releases with external Git resources. Resources must be fully qualified e.g. `refs/heads/main`. Supports glob patten syntax. (see [below for nested schema](#nestedblock--git_resource_rules))
- `id` (String) The unique ID for this resource.
- `is_default` (Boolean) Indicates if this is the default channel for the associated project.
- `lifecycle_id` (String) The lifecycle ID associated with this channel.
@@ -37,6 +39,28 @@ resource "octopusdeploy_channel" "example" {
- `space_id` (String) The space ID associated with this resource.
- `tenant_tags` (List of String) A list of tenant tags associated with this resource.
+
+### Nested Schema for `git_resource_rules`
+
+Required:
+
+- `git_dependency_actions` (Block List, Min: 1) (see [below for nested schema](#nestedblock--git_resource_rules--git_dependency_actions))
+
+Optional:
+
+- `id` (String) The unique ID for this resource.
+- `rules` (List of String)
+
+
+### Nested Schema for `git_resource_rules.git_dependency_actions`
+
+Optional:
+
+- `deployment_action_slug` (String)
+- `git_dependency_name` (String)
+
+
+
### Nested Schema for `rule`
diff --git a/go.mod b/go.mod
index f9bdcfde4..4c75feed5 100644
--- a/go.mod
+++ b/go.mod
@@ -3,7 +3,7 @@ module github.com/OctopusDeploy/terraform-provider-octopusdeploy
go 1.21
require (
- github.com/OctopusDeploy/go-octopusdeploy/v2 v2.43.0
+ github.com/OctopusDeploy/go-octopusdeploy/v2 v2.44.1
github.com/OctopusSolutionsEngineering/OctopusTerraformTestFramework v0.0.0-20240725054341-2848f54d101e
github.com/google/uuid v1.6.0
github.com/gruntwork-io/terratest v0.41.11
diff --git a/go.sum b/go.sum
index d50b01763..b8bdbf8a1 100644
--- a/go.sum
+++ b/go.sum
@@ -40,6 +40,8 @@ github.com/Microsoft/hcsshim v0.11.5 h1:haEcLNpj9Ka1gd3B3tAEs9CpE0c+1IhoL59w/exY
github.com/Microsoft/hcsshim v0.11.5/go.mod h1:MV8xMfmECjl5HdO7U/3/hFVnkmSBjAjmA09d4bExKcU=
github.com/OctopusDeploy/go-octopusdeploy/v2 v2.43.0 h1:fYwGBqG88xy3qHp5j1ySCztdqfw2NLfg2yp0N3XcBYg=
github.com/OctopusDeploy/go-octopusdeploy/v2 v2.43.0/go.mod h1:GZmFu6LmN8Yg0tEoZx3ytk9FnaH+84cWm7u5TdWZC6E=
+github.com/OctopusDeploy/go-octopusdeploy/v2 v2.44.1 h1:e8aGPNAXEBr/PRSTghyE1FgKERJXYvCPh/12C11kmbE=
+github.com/OctopusDeploy/go-octopusdeploy/v2 v2.44.1/go.mod h1:GZmFu6LmN8Yg0tEoZx3ytk9FnaH+84cWm7u5TdWZC6E=
github.com/OctopusSolutionsEngineering/OctopusTerraformTestFramework v0.0.0-20240725054341-2848f54d101e h1:FIvWa8wNg8IBG5uVhqkKvcBhaxx4TgN7T8/5Ed4VQUE=
github.com/OctopusSolutionsEngineering/OctopusTerraformTestFramework v0.0.0-20240725054341-2848f54d101e/go.mod h1:Oq9KbiRNDBB5jFmrwnrgLX0urIqR/1ptY18TzkqXm7M=
github.com/ProtonMail/go-crypto v1.1.0-alpha.2 h1:bkyFVUP+ROOARdgCiJzNQo2V2kiB97LyUpzH9P6Hrlg=
diff --git a/octopusdeploy/schema_channel.go b/octopusdeploy/schema_channel.go
index 88aa0bda9..13f0ecbeb 100644
--- a/octopusdeploy/schema_channel.go
+++ b/octopusdeploy/schema_channel.go
@@ -43,6 +43,18 @@ func expandChannel(d *schema.ResourceData) *channels.Channel {
}
}
+ if v, ok := d.GetOk("git_reference_rules"); ok {
+ channel.GitReferenceRules = expandArray(v.([]interface{}))
+ }
+
+ if v, ok := d.GetOk("git_resource_rules"); ok {
+ channelGitResourceRules := v.([]interface{})
+ for _, channelGitResourceRule := range channelGitResourceRules {
+ rule := expandChannelGitResourceRules(channelGitResourceRule.(map[string]interface{}))
+ channel.GitResourceRules = append(channel.GitResourceRules, rule)
+ }
+ }
+
return channel
}
@@ -52,15 +64,17 @@ func flattenChannel(channel *channels.Channel) map[string]interface{} {
}
return map[string]interface{}{
- "description": channel.Description,
- "id": channel.GetID(),
- "is_default": channel.IsDefault,
- "lifecycle_id": channel.LifecycleID,
- "name": channel.Name,
- "project_id": channel.ProjectID,
- "rule": flattenChannelRules(channel.Rules),
- "space_id": channel.SpaceID,
- "tenant_tags": channel.TenantTags,
+ "description": channel.Description,
+ "id": channel.GetID(),
+ "is_default": channel.IsDefault,
+ "lifecycle_id": channel.LifecycleID,
+ "name": channel.Name,
+ "project_id": channel.ProjectID,
+ "rule": flattenChannelRules(channel.Rules),
+ "space_id": channel.SpaceID,
+ "tenant_tags": channel.TenantTags,
+ "git_reference_rules": flattenArray(channel.GitReferenceRules),
+ "git_resource_rules": flattenChannelGitResourceRules(channel.GitResourceRules),
}
}
@@ -112,6 +126,18 @@ func getChannelSchema() map[string]*schema.Schema {
},
"space_id": getSpaceIDSchema(),
"tenant_tags": getTenantTagsSchema(),
+ "git_reference_rules": {
+ Description: "List of rules to restrict which Git references can be used with this channel when creating releases for version controlled projects. References must be fully qualified e.g. `refs/heads/main`. Supports glob patten syntax.",
+ Optional: true,
+ Type: schema.TypeList,
+ Elem: &schema.Schema{Type: schema.TypeString},
+ },
+ "git_resource_rules": {
+ Description: "List of rules to restrict which Git resources can be used with this channel when creating releases with external Git resources. Resources must be fully qualified e.g. `refs/heads/main`. Supports glob patten syntax.",
+ Optional: true,
+ Type: schema.TypeList,
+ Elem: &schema.Resource{Schema: getChannelGitResourceRuleSchema()},
+ },
}
}
@@ -131,5 +157,13 @@ func setChannel(ctx context.Context, d *schema.ResourceData, channel *channels.C
return fmt.Errorf("error setting tenant_tags: %s", err)
}
+ if err := d.Set("git_reference_rules", channel.GitReferenceRules); err != nil {
+ return fmt.Errorf("error setting git_reference_rules: %s", err)
+ }
+
+ if err := d.Set("git_resource_rules", flattenChannelGitResourceRules(channel.GitResourceRules)); err != nil {
+ return fmt.Errorf("error setting git_resource_rules: %s", err)
+ }
+
return nil
}
diff --git a/octopusdeploy/schema_channel_git_resource_rule.go b/octopusdeploy/schema_channel_git_resource_rule.go
new file mode 100644
index 000000000..e27d3283e
--- /dev/null
+++ b/octopusdeploy/schema_channel_git_resource_rule.go
@@ -0,0 +1,51 @@
+package octopusdeploy
+
+import (
+ "github.com/OctopusDeploy/go-octopusdeploy/v2/pkg/channels"
+ "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
+)
+
+func expandChannelGitResourceRules(ChannelGitResourceRule map[string]interface{}) channels.ChannelGitResourceRule {
+ if len(ChannelGitResourceRule) == 0 {
+ return channels.ChannelGitResourceRule{}
+ }
+
+ return channels.ChannelGitResourceRule{
+ Id: ChannelGitResourceRule["id"].(string),
+ GitDependencyActions: expandDeploymentActionGitDependencies(ChannelGitResourceRule["git_dependency_actions"]),
+ Rules: ChannelGitResourceRule["rules"].([]string),
+ }
+}
+
+func flattenChannelGitResourceRules(ChannelGitResourceRules []channels.ChannelGitResourceRule) []map[string]interface{} {
+ if len(ChannelGitResourceRules) == 0 {
+ return []map[string]interface{}{}
+ }
+
+ var flattenedRules = make([]map[string]interface{}, len(ChannelGitResourceRules))
+ for key, ChannelGitResourceRule := range ChannelGitResourceRules {
+ flattenedRules[key] = map[string]interface{}{
+ "id": ChannelGitResourceRule.Id,
+ "git_dependency_actions": flattenDeploymentActionGitDependencies(ChannelGitResourceRule.GitDependencyActions),
+ "rules": ChannelGitResourceRule.Rules,
+ }
+ }
+
+ return flattenedRules
+}
+
+func getChannelGitResourceRuleSchema() map[string]*schema.Schema {
+ return map[string]*schema.Schema{
+ "id": getIDSchema(),
+ "git_dependency_actions": {
+ Elem: &schema.Resource{Schema: getDeploymentActionGitDependencySchema()},
+ Required: true,
+ Type: schema.TypeList,
+ },
+ "rules": {
+ Elem: &schema.Schema{Type: schema.TypeString},
+ Optional: true,
+ Type: schema.TypeList,
+ },
+ }
+}
diff --git a/octopusdeploy/schema_deployment_action_git_dependency.go b/octopusdeploy/schema_deployment_action_git_dependency.go
new file mode 100644
index 000000000..a66811eb7
--- /dev/null
+++ b/octopusdeploy/schema_deployment_action_git_dependency.go
@@ -0,0 +1,51 @@
+package octopusdeploy
+
+import (
+ "github.com/OctopusDeploy/go-octopusdeploy/v2/pkg/gitdependencies"
+ "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
+)
+
+func flattenDeploymentActionGitDependencies(deploymentActionGitDependencies []gitdependencies.DeploymentActionGitDependency) []interface{} {
+ if len(deploymentActionGitDependencies) == 0 {
+ return nil
+ }
+
+ var flattenedDeploymentActionPackages []interface{}
+ for _, v := range deploymentActionGitDependencies {
+ flattenedDeploymentActionPackage := map[string]interface{}{
+ "deployment_action_slug": v.DeploymentActionSlug,
+ "git_dependency_name": v.GitDependencyName,
+ }
+ flattenedDeploymentActionPackages = append(flattenedDeploymentActionPackages, flattenedDeploymentActionPackage)
+ }
+ return flattenedDeploymentActionPackages
+}
+
+func expandDeploymentActionGitDependencies(values interface{}) []gitdependencies.DeploymentActionGitDependency {
+ if values == nil {
+ return nil
+ }
+
+ var gitDependencies []gitdependencies.DeploymentActionGitDependency
+ for _, v := range values.([]interface{}) {
+ flattenedMap := v.(map[string]interface{})
+ gitDependencies = append(gitDependencies, gitdependencies.DeploymentActionGitDependency{
+ DeploymentActionSlug: flattenedMap["deployment_action_slug"].(string),
+ GitDependencyName: flattenedMap["git_dependency_name"].(string),
+ })
+ }
+ return gitDependencies
+}
+
+func getDeploymentActionGitDependencySchema() map[string]*schema.Schema {
+ return map[string]*schema.Schema{
+ "deployment_action_slug": {
+ Optional: true,
+ Type: schema.TypeString,
+ },
+ "git_dependency_name": {
+ Optional: true,
+ Type: schema.TypeString,
+ },
+ }
+}
diff --git a/octopusdeploy/schema_deployment_action_git_resource_test.go b/octopusdeploy/schema_deployment_action_git_resource_test.go
new file mode 100644
index 000000000..7b9e38cd7
--- /dev/null
+++ b/octopusdeploy/schema_deployment_action_git_resource_test.go
@@ -0,0 +1,96 @@
+package octopusdeploy
+
+import (
+ "github.com/OctopusDeploy/go-octopusdeploy/v2/pkg/channels"
+ "github.com/OctopusDeploy/go-octopusdeploy/v2/pkg/gitdependencies"
+ "reflect"
+ "testing"
+)
+
+func TestExpandChannelGitResourceRules_WithValidData_ReturnsExpectedResult(t *testing.T) {
+ input := map[string]interface{}{
+ "id": "rule-1",
+ "git_dependency_actions": []interface{}{
+ map[string]interface{}{
+ "deployment_action_slug": "deploy-action-1",
+ "git_dependency_name": "",
+ },
+ },
+ "rules": []string{"rule1", "rule2"},
+ }
+
+ expected := channels.ChannelGitResourceRule{
+ Id: "rule-1",
+ GitDependencyActions: []gitdependencies.DeploymentActionGitDependency{
+ {
+ DeploymentActionSlug: "deploy-action-1",
+ GitDependencyName: "",
+ },
+ },
+ Rules: []string{"rule1", "rule2"},
+ }
+
+ actual := expandChannelGitResourceRules(input)
+
+ if !reflect.DeepEqual(actual, expected) {
+ t.Errorf("Expected %+v, got %+v", expected, actual)
+ }
+}
+
+func TestExpandChannelGitResourceRules_WithEmptyData_ReturnsEmptyStruct(t *testing.T) {
+ input := map[string]interface{}{}
+
+ expected := channels.ChannelGitResourceRule{}
+
+ actual := expandChannelGitResourceRules(input)
+
+ if !reflect.DeepEqual(actual, expected) {
+ t.Errorf("Expected %+v, got %+v", expected, actual)
+ }
+}
+
+func TestFlattenChannelGitResourceRules_WithValidData_ReturnsExpectedMap(t *testing.T) {
+ input := []channels.ChannelGitResourceRule{
+ {
+ Id: "rule-1",
+ GitDependencyActions: []gitdependencies.DeploymentActionGitDependency{
+ {
+ DeploymentActionSlug: "deploy-action-1",
+ GitDependencyName: "ref-1",
+ },
+ },
+ Rules: []string{"rule1", "rule2"},
+ },
+ }
+
+ expected := []map[string]interface{}{
+ {
+ "id": "rule-1",
+ "git_dependency_actions": []interface{}{
+ map[string]interface{}{
+ "deployment_action_slug": "deploy-action-1",
+ "git_dependency_name": "ref-1",
+ },
+ },
+ "rules": []string{"rule1", "rule2"},
+ },
+ }
+
+ actual := flattenChannelGitResourceRules(input)
+
+ if !reflect.DeepEqual(actual, expected) {
+ t.Errorf("Expected %+v, got %+v", expected, actual)
+ }
+}
+
+func TestFlattenChannelGitResourceRules_WithEmptyData_ReturnsEmptySlice(t *testing.T) {
+ input := []channels.ChannelGitResourceRule{}
+
+ expected := []map[string]interface{}{}
+
+ actual := flattenChannelGitResourceRules(input)
+
+ if !reflect.DeepEqual(actual, expected) {
+ t.Errorf("Expected %+v, got %+v", expected, actual)
+ }
+}