From 49f8df4fe5ebdf28bce0b839860352a88af20332 Mon Sep 17 00:00:00 2001 From: Chris Marget Date: Tue, 16 Jan 2024 15:38:13 -0500 Subject: [PATCH] ensure `rule.TcpStateQualifier` is used only with 4.1.2 and later --- apstra/compatibility.go | 7 ++++++ apstra/two_stage_l3_clos_client.go | 37 ++++++++++++++++++++++++++++++ 2 files changed, 44 insertions(+) diff --git a/apstra/compatibility.go b/apstra/compatibility.go index b9eda352..3028270c 100644 --- a/apstra/compatibility.go +++ b/apstra/compatibility.go @@ -12,6 +12,9 @@ const ( integerPoolForbiddenVersions = "4.1.0, 4.1.1" + policyRuleTcpStateQualifierForbidenVersions = "4.1.0, 4.1.1" + policyRuleTcpStateQualifierForbidenError = "tcp_state_qualifier permitted only with Apstra 4.1.2 and later" + securityZoneJunosEvpnIrbModeRequiredVersions = "4.2.0" securityZoneJunosEvpnIrbModeRequiredError = "junos_evpn_irb_mode is required by Apstra 4.2 and later" @@ -54,6 +57,10 @@ func integerPoolForbidden() StringSliceWithIncludes { return parseVersionList(integerPoolForbiddenVersions) } +func policyRuleTcpStateQualifierForbidden() StringSliceWithIncludes { + return parseVersionList(policyRuleTcpStateQualifierForbidenVersions) +} + func securityZoneJunosEvpnIrbModeRequired() StringSliceWithIncludes { return parseVersionList(securityZoneJunosEvpnIrbModeRequiredVersions) } diff --git a/apstra/two_stage_l3_clos_client.go b/apstra/two_stage_l3_clos_client.go index dfb55d9e..d3eec629 100644 --- a/apstra/two_stage_l3_clos_client.go +++ b/apstra/two_stage_l3_clos_client.go @@ -304,6 +304,21 @@ func (o *TwoStageL3ClosClient) GetPolicyByLabel(ctx context.Context, label strin // CreatePolicy creates a policy within the DC blueprint, returns its ID func (o *TwoStageL3ClosClient) CreatePolicy(ctx context.Context, data *PolicyData) (ObjectId, error) { + var tcpStateQualifier bool + for _, rule := range data.Rules { + if rule.Data.TcpStateQualifier != nil { + tcpStateQualifier = true + break + } + } + + if tcpStateQualifier && policyRuleTcpStateQualifierForbidden().Includes(o.client.apiVersion) { + return "", ClientErr{ + errType: ErrCompatibility, + err: errors.New(policyRuleTcpStateQualifierForbidenError), + } + } + return o.createPolicy(ctx, data.request()) } @@ -314,6 +329,21 @@ func (o *TwoStageL3ClosClient) DeletePolicy(ctx context.Context, id ObjectId) er // UpdatePolicy calls PUT to replace the configuration of policy 'id' within the DC blueprint func (o *TwoStageL3ClosClient) UpdatePolicy(ctx context.Context, id ObjectId, data *PolicyData) error { + var tcpStateQualifier bool + for _, rule := range data.Rules { + if rule.Data.TcpStateQualifier != nil { + tcpStateQualifier = true + break + } + } + + if tcpStateQualifier && policyRuleTcpStateQualifierForbidden().Includes(o.client.apiVersion) { + return ClientErr{ + errType: ErrCompatibility, + err: errors.New(policyRuleTcpStateQualifierForbidenError), + } + } + return o.updatePolicy(ctx, id, data.request()) } @@ -322,6 +352,13 @@ func (o *TwoStageL3ClosClient) UpdatePolicy(ctx context.Context, id ObjectId, da // on the list, etc... Use -1 for last on the list. The returned ObjectId // represents the new rule func (o *TwoStageL3ClosClient) AddPolicyRule(ctx context.Context, rule *PolicyRuleData, position int, policyId ObjectId) (ObjectId, error) { + if rule.TcpStateQualifier != nil && policyRuleTcpStateQualifierForbidden().Includes(o.client.apiVersion) { + return "", ClientErr{ + errType: ErrCompatibility, + err: errors.New(policyRuleTcpStateQualifierForbidenError), + } + } + return o.addPolicyRule(ctx, rule.raw(), position, policyId) }