Skip to content

Commit

Permalink
adding support for unidir contracts including feedback
Browse files Browse the repository at this point in the history
  • Loading branch information
robvand committed Jul 17, 2024
1 parent 732c6a4 commit f1b2b3f
Show file tree
Hide file tree
Showing 5 changed files with 251 additions and 19 deletions.
33 changes: 27 additions & 6 deletions aci_tenants.tf
Original file line number Diff line number Diff line change
Expand Up @@ -1730,19 +1730,40 @@ locals {
qos_class = try(contract.qos_class, local.defaults.apic.tenants.contracts.qos_class)
target_dscp = try(contract.target_dscp, local.defaults.apic.tenants.contracts.target_dscp)
subjects = [for subject in try(contract.subjects, []) : {
name = "${subject.name}${local.defaults.apic.tenants.contracts.subjects.name_suffix}"
alias = try(subject.alias, "")
description = try(subject.description, "")
service_graph = try("${subject.service_graph}${local.defaults.apic.tenants.services.service_graph_templates.name_suffix}", null)
qos_class = try(subject.qos_class, local.defaults.apic.tenants.contracts.subjects.qos_class)
target_dscp = try(subject.target_dscp, local.defaults.apic.tenants.contracts.subjects.target_dscp)
name = "${subject.name}${local.defaults.apic.tenants.contracts.subjects.name_suffix}"
alias = try(subject.alias, "")
description = try(subject.description, "")
reverse_filter_ports = try(subject.reverse_filter_ports, local.defaults.apic.tenants.contracts.subjects.reverse_filter_ports)
service_graph = try("${subject.service_graph}${local.defaults.apic.tenants.services.service_graph_templates.name_suffix}", null)
qos_class = try(subject.qos_class, local.defaults.apic.tenants.contracts.subjects.qos_class)
target_dscp = try(subject.target_dscp, local.defaults.apic.tenants.contracts.subjects.target_dscp)
filters = [for filter in try(subject.filters, []) : {
filter = "${filter.filter}${local.defaults.apic.tenants.filters.name_suffix}"
action = try(filter.action, local.defaults.apic.tenants.contracts.subjects.filters.action)
priority = try(filter.priority, local.defaults.apic.tenants.contracts.subjects.filters.priority)
log = try(filter.log, local.defaults.apic.tenants.contracts.subjects.filters.log)
no_stats = try(filter.no_stats, local.defaults.apic.tenants.contracts.subjects.filters.no_stats)
}]
consumer_to_provider_service_graph = try("${subject.consumer_to_provider.service_graph}${local.defaults.apic.tenants.services.service_graph_templates.name_suffix}", null)
consumer_to_provider_qos_class = try(subject.consumer_to_provider.qos_class, local.defaults.apic.tenants.contracts.subjects.qos_class)
consumer_to_provider_target_dscp = try(subject.consumer_to_provider.target_dscp, local.defaults.apic.tenants.contracts.subjects.target_dscp)
consumer_to_provider_filters = [for filter in try(subject.consumer_to_provider.filters, []) : {
filter = "${filter.filter}${local.defaults.apic.tenants.filters.name_suffix}"
action = try(filter.action, local.defaults.apic.tenants.contracts.subjects.filters.action)
priority = try(filter.priority, local.defaults.apic.tenants.contracts.subjects.filters.priority)
log = try(filter.log, local.defaults.apic.tenants.contracts.subjects.filters.log)
no_stats = try(filter.no_stats, local.defaults.apic.tenants.contracts.subjects.filters.no_stats)
}]
provider_to_consumer_service_graph = try("${subject.provider_to_consumer.service_graph}${local.defaults.apic.tenants.services.service_graph_templates.name_suffix}", null)
provider_to_consumer_qos_class = try(subject.provider_to_consumer.qos_class, local.defaults.apic.tenants.contracts.subjects.qos_class)
provider_to_consumer_target_dscp = try(subject.provider_to_consumer.target_dscp, local.defaults.apic.tenants.contracts.subjects.target_dscp)
provider_to_consumer_filters = [for filter in try(subject.provider_to_consumer.filters, []) : {
filter = "${filter.filter}${local.defaults.apic.tenants.filters.name_suffix}"
action = try(filter.action, local.defaults.apic.tenants.contracts.subjects.filters.action)
priority = try(filter.priority, local.defaults.apic.tenants.contracts.subjects.filters.priority)
log = try(filter.log, local.defaults.apic.tenants.contracts.subjects.filters.log)
no_stats = try(filter.no_stats, local.defaults.apic.tenants.contracts.subjects.filters.no_stats)
}]
}]
}
]
Expand Down
1 change: 1 addition & 0 deletions defaults/defaults.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -1107,6 +1107,7 @@ defaults:
name_suffix: ""
qos_class: unspecified
target_dscp: unspecified
reverse_filter_ports: true
filters:
action: permit
priority: default
Expand Down
8 changes: 7 additions & 1 deletion modules/terraform-aci-contract/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ module "aci_contract" {
| <a name="input_scope"></a> [scope](#input\_scope) | Contract scope. Choices: `application-profile`, `tenant`, `context`, `global`. | `string` | `"context"` | no |
| <a name="input_qos_class"></a> [qos\_class](#input\_qos\_class) | Contract QoS Class. Choices: `unspecified`, `level1`, `level2`, `level3`, `level4`, `level5`, `level6`. | `string` | `"unspecified"` | no |
| <a name="input_target_dscp"></a> [target\_dscp](#input\_target\_dscp) | Contract Target DSCP. Valid values are `unspecified`, `CS0`, `CS1`, `AF11`, `AF12`, `AF13`, `CS2`, `AF21`, `AF22`, `AF23`, `CS4`, `AF41`, `AF42`, `AF43`, `CS5`, `VA`, `EF`, `CS6`, `CS7` or a number between 0 and 63. | `string` | `"unspecified"` | no |
| <a name="input_subjects"></a> [subjects](#input\_subjects) | List of contract subjects. Choices `action`: `permit`, `deny`. Default value `action`: `permit`. Choices `priority`: `default`, `level1`, `level2`, `level3`. Default value `priority`: `default`. Default value `log`: `false`. Default value `no_stats`: `false`. Choices `qos_class`: `unspecified`, `level1`, `level2`, `level3`, `level4`, `level5` or`level6`. Default value `qos_class`: `unspecified`. Choices `dscp_target` : `unspecified`, `CS0`, `CS1`, `AF11`, `AF12`, `AF13`, `CS2`, `AF21`, `AF22`, `AF23`, `CS4`, `AF41`, `AF42`, `AF43`, `CS5`, `VA`, `EF`, `CS6` `CS7` or a number between 0 and 63. Default value `dscp_target`: `unspecified` | <pre>list(object({<br> name = string<br> alias = optional(string, "")<br> description = optional(string, "")<br> service_graph = optional(string)<br> qos_class = optional(string, "unspecified")<br> target_dscp = optional(string, "unspecified")<br> filters = optional(list(object({<br> filter = string<br> action = optional(string, "permit")<br> priority = optional(string, "default")<br> log = optional(bool, false)<br> no_stats = optional(bool, false)<br> })), [])<br> }))</pre> | `[]` | no |
| <a name="input_subjects"></a> [subjects](#input\_subjects) | List of contract subjects. Choices `action`: `permit`, `deny`. Default value `action`: `permit`. Choices `priority`: `default`, `level1`, `level2`, `level3`. Default value `priority`: `default`. Default value `log`: `false`. Default value `no_stats`: `false`. Choices `qos_class`: `unspecified`, `level1`, `level2`, `level3`, `level4`, `level5` or`level6`. Default value `qos_class`: `unspecified`. Choices `dscp_target` : `unspecified`, `CS0`, `CS1`, `AF11`, `AF12`, `AF13`, `CS2`, `AF21`, `AF22`, `AF23`, `CS4`, `AF41`, `AF42`, `AF43`, `CS5`, `VA`, `EF`, `CS6` `CS7` or a number between 0 and 63. Default value `dscp_target`: `unspecified` | <pre>list(object({<br> name = string<br> alias = optional(string, "")<br> description = optional(string, "")<br> reverse_filter_ports = optional(bool, true)<br> service_graph = optional(string)<br> qos_class = optional(string, "unspecified")<br> target_dscp = optional(string, "unspecified")<br> filters = optional(list(object({<br> filter = string<br> action = optional(string, "permit")<br> priority = optional(string, "default")<br> log = optional(bool, false)<br> no_stats = optional(bool, false)<br> })), [])<br> consumer_to_provider_service_graph = optional(string)<br> consumer_to_provider_qos_class = optional(string, "unspecified")<br> consumer_to_provider_target_dscp = optional(string, "unspecified")<br> consumer_to_provider_filters = optional(list(object({<br> filter = string<br> action = optional(string, "permit")<br> priority = optional(string, "default")<br> log = optional(bool, false)<br> no_stats = optional(bool, false)<br> })), [])<br> provider_to_consumer_service_graph = optional(string)<br> provider_to_consumer_qos_class = optional(string, "unspecified")<br> provider_to_consumer_target_dscp = optional(string, "unspecified")<br> provider_to_consumer_filters = optional(list(object({<br> filter = string<br> action = optional(string, "permit")<br> priority = optional(string, "default")<br> log = optional(bool, false)<br> no_stats = optional(bool, false)<br> })), [])<br> }))</pre> | `[]` | no |

## Outputs

Expand All @@ -76,6 +76,12 @@ module "aci_contract" {
| Name | Type |
|------|------|
| [aci_rest_managed.vzBrCP](https://registry.terraform.io/providers/CiscoDevNet/aci/latest/docs/resources/rest_managed) | resource |
| [aci_rest_managed.vzInTerm](https://registry.terraform.io/providers/CiscoDevNet/aci/latest/docs/resources/rest_managed) | resource |
| [aci_rest_managed.vzOutTerm](https://registry.terraform.io/providers/CiscoDevNet/aci/latest/docs/resources/rest_managed) | resource |
| [aci_rest_managed.vzRsFiltAtt_ctp](https://registry.terraform.io/providers/CiscoDevNet/aci/latest/docs/resources/rest_managed) | resource |
| [aci_rest_managed.vzRsFiltAtt_ptc](https://registry.terraform.io/providers/CiscoDevNet/aci/latest/docs/resources/rest_managed) | resource |
| [aci_rest_managed.vzRsInTermGraphAtt](https://registry.terraform.io/providers/CiscoDevNet/aci/latest/docs/resources/rest_managed) | resource |
| [aci_rest_managed.vzRsOutTermGraphAtt](https://registry.terraform.io/providers/CiscoDevNet/aci/latest/docs/resources/rest_managed) | resource |
| [aci_rest_managed.vzRsSubjFiltAtt](https://registry.terraform.io/providers/CiscoDevNet/aci/latest/docs/resources/rest_managed) | resource |
| [aci_rest_managed.vzRsSubjGraphAtt](https://registry.terraform.io/providers/CiscoDevNet/aci/latest/docs/resources/rest_managed) | resource |
| [aci_rest_managed.vzSubj](https://registry.terraform.io/providers/CiscoDevNet/aci/latest/docs/resources/rest_managed) | resource |
Expand Down
97 changes: 94 additions & 3 deletions modules/terraform-aci-contract/main.tf
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@

locals {
subj_filter_list = flatten([
for subj in var.subjects : [
Expand All @@ -14,6 +13,36 @@ locals {
])
}

locals {
subj_filter_list_ctp = flatten([
for subj in var.subjects : [
for flt in coalesce(subj.consumer_to_provider_filters, []) : {
id = "${subj.name}-${flt.filter}"
subj = subj.name
filter = flt.filter
action = flt.action
directives = join(",", concat(flt.log == true ? ["log"] : [], flt.no_stats == true ? ["no_stats"] : []))
priority = flt.priority
}
]
])
}

locals {
subj_filter_list_ptc = flatten([
for subj in var.subjects : [
for flt in coalesce(subj.provider_to_consumer_filters, []) : {
id = "${subj.name}-${flt.filter}"
subj = subj.name
filter = flt.filter
action = flt.action
directives = join(",", concat(flt.log == true ? ["log"] : [], flt.no_stats == true ? ["no_stats"] : []))
priority = flt.priority
}
]
])
}

resource "aci_rest_managed" "vzBrCP" {
dn = "uni/tn-${var.tenant}/brc-${var.name}"
class_name = "vzBrCP"
Expand All @@ -35,7 +64,7 @@ resource "aci_rest_managed" "vzSubj" {
name = each.value.name
nameAlias = each.value.alias
descr = each.value.description
revFltPorts = "yes"
revFltPorts = length(each.value.filters) != 0 ? (each.value.reverse_filter_ports ? "yes" : "no") : "no"
prio = each.value.qos_class
targetDscp = each.value.target_dscp
}
Expand All @@ -54,10 +83,72 @@ resource "aci_rest_managed" "vzRsSubjFiltAtt" {
}

resource "aci_rest_managed" "vzRsSubjGraphAtt" {
for_each = { for subj in var.subjects : subj.name => subj if subj.service_graph != null }
for_each = { for subj in var.subjects : subj.name => subj if subj.service_graph != null && length(subj.filters) != 0 }
dn = "${aci_rest_managed.vzSubj[each.key].dn}/rsSubjGraphAtt"
class_name = "vzRsSubjGraphAtt"
content = {
tnVnsAbsGraphName = each.value.service_graph
}
}

resource "aci_rest_managed" "vzInTerm" {
for_each = { for subj in var.subjects : subj.name => subj if length(subj.filters) == 0 }
dn = "${aci_rest_managed.vzSubj[each.key].dn}/intmnl"
class_name = "vzInTerm"
content = {
prio = each.value.consumer_to_provider_qos_class
targetDscp = each.value.consumer_to_provider_target_dscp
}
}

resource "aci_rest_managed" "vzOutTerm" {
for_each = { for subj in var.subjects : subj.name => subj if length(subj.filters) == 0 }
dn = "${aci_rest_managed.vzSubj[each.key].dn}/outtmnl"
class_name = "vzOutTerm"
content = {
prio = each.value.provider_to_consumer_qos_class
targetDscp = each.value.provider_to_consumer_target_dscp
}
}

resource "aci_rest_managed" "vzRsFiltAtt_ctp" {
for_each = { for filter in local.subj_filter_list_ctp : filter.id => filter }
dn = "${aci_rest_managed.vzInTerm[each.value.subj].dn}/rsfiltAtt-${each.value.filter}"
class_name = "vzRsFiltAtt"
content = {
action = each.value.action
tnVzFilterName = each.value.filter
directives = each.value.directives
priorityOverride = each.value.priority
}
}

resource "aci_rest_managed" "vzRsFiltAtt_ptc" {
for_each = { for filter in local.subj_filter_list_ptc : filter.id => filter }
dn = "${aci_rest_managed.vzOutTerm[each.value.subj].dn}/rsfiltAtt-${each.value.filter}"
class_name = "vzRsFiltAtt"
content = {
action = each.value.action
tnVzFilterName = each.value.filter
directives = each.value.directives
priorityOverride = each.value.priority
}
}

resource "aci_rest_managed" "vzRsInTermGraphAtt" {
for_each = { for subj in var.subjects : subj.name => subj if subj.consumer_to_provider_service_graph != null && length(subj.filters) == 0 }
dn = "${aci_rest_managed.vzInTerm[each.key].dn}/rsInTermGraphAtt"
class_name = "vzRsInTermGraphAtt"
content = {
tnVnsAbsGraphName = each.value.consumer_to_provider_service_graph
}
}

resource "aci_rest_managed" "vzRsOutTermGraphAtt" {
for_each = { for subj in var.subjects : subj.name => subj if subj.provider_to_consumer_service_graph != null && length(subj.filters) == 0 }
dn = "${aci_rest_managed.vzOutTerm[each.key].dn}/rsOutTermGraphAtt"
class_name = "vzRsOutTermGraphAtt"
content = {
tnVnsAbsGraphName = each.value.provider_to_consumer_service_graph
}
}
Loading

0 comments on commit f1b2b3f

Please sign in to comment.