Skip to content

Commit 9199dde

Browse files
committed
Policy group support in policy resource
1 parent c86e617 commit 9199dde

File tree

19 files changed

+1635
-374
lines changed

19 files changed

+1635
-374
lines changed

docs/resources/policy.md

Lines changed: 12 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -14,15 +14,15 @@ Resource to configure policies on a switch
1414

1515
```terraform
1616
resource "ndfc_policy" "test_resource_policy_1" {
17-
is_policy_group = false
18-
deploy = true
19-
entity_name = "Switch"
20-
entity_type = "SWITCH"
21-
description = "Policy for switch"
22-
template_name = "TelemetryDst_EF"
23-
source = "CLI"
24-
priority = 500
25-
device_serial_number = "FDO245206N5"
17+
is_policy_group = false
18+
deploy = true
19+
entity_name = "Switch"
20+
entity_type = "SWITCH"
21+
description = "Policy for switch"
22+
template_name = "TelemetryDst_EF"
23+
source = "CLI"
24+
priority = 500
25+
serial_numbers = ["FDO245206N5", "FDO245206N6"]
2626
policy_parameters = {
2727
DSTGRP = "501"
2828
IPADDR = "5.5.5.6"
@@ -37,9 +37,9 @@ resource "ndfc_policy" "test_resource_policy_1" {
3737

3838
### Required
3939

40-
- `device_serial_number` (String) Serial number of the device
4140
- `entity_name` (String) Policy Name
4241
- `entity_type` (String) Type of the entity
42+
- `serial_numbers` (Set of String) Serial numbers of the device. Use only one device for policy. Multiple devices can be in the list if this is a policygroup
4343
- `template_name` (String) Name of the template
4444

4545
### Optional
@@ -54,6 +54,8 @@ resource "ndfc_policy" "test_resource_policy_1" {
5454
### Read-Only
5555

5656
- `auto_generated` (Boolean) Auto generated policy
57+
- `computed_parameters` (Map of String) List of name value pairs not set in config, but returned by NDFC
58+
- `generated_config` (String) Generated configuration
5759
- `id` (Number) ID of the policy
5860
- `policy_id` (String) Policy ID
5961

examples/resources/ndfc_policy/resource.tf

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,14 @@
11

22
resource "ndfc_policy" "test_resource_policy_1" {
3-
is_policy_group = false
4-
deploy = true
5-
entity_name = "Switch"
6-
entity_type = "SWITCH"
7-
description = "Policy for switch"
8-
template_name = "TelemetryDst_EF"
9-
source = "CLI"
10-
priority = 500
11-
device_serial_number = "FDO245206N5"
3+
is_policy_group = false
4+
deploy = true
5+
entity_name = "Switch"
6+
entity_type = "SWITCH"
7+
description = "Policy for switch"
8+
template_name = "TelemetryDst_EF"
9+
source = "CLI"
10+
priority = 500
11+
serial_numbers = ["FDO245206N5", "FDO245206N6"]
1212
policy_parameters = {
1313
DSTGRP = "501"
1414
IPADDR = "5.5.5.6"

generator/defs/policy.yaml

Lines changed: 22 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -66,19 +66,23 @@ resource:
6666
type: String
6767
description: "Source of the policy"
6868
example: "CLI"
69+
include_empty: true
6970
- model_name: priority
7071
tf_name: priority
7172
type: Int64
7273
description: "Priority of the policy"
7374
default_value: 500
7475
example: 500
7576
- model_name: serialNumber
76-
tf_name: device_serial_number
77-
type: String
78-
description: "Serial number of the device"
77+
tf_name: serial_numbers
78+
type: List:String
7979
mandatory: true
80-
tf_requires_replace: true
81-
example: FDO245206N5
80+
description: "Serial numbers of the device. Use only one device for policy. Multiple devices can be in the list if this is a policygroup"
81+
example: "[\"FDO245206N5\", \"FDO245206N6\"]"
82+
tf_requires_replace_if_key: is_policy_group
83+
tf_requires_replace_if_value: false
84+
tf_requires_replace_if_type: bool
85+
ndfc_type: csv
8286
- model_name: nvPairs
8387
tf_name: policy_parameters
8488
type: "Map:String"
@@ -99,5 +103,18 @@ resource:
99103
ndfc_type: bool
100104
description: "Deleted policy"
101105
tf_hide: true
106+
107+
- model_name: generatedConfig
108+
tf_name: generated_config
109+
type: String
110+
description: "Generated configuration"
111+
computed: true
112+
113+
- model_name: computed_parameters
114+
tf_name: computed_parameters
115+
type: "Map:String"
116+
description: "List of name value pairs not set in config, but returned by NDFC"
117+
computed: true
118+
102119

103120

go.mod

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -63,13 +63,13 @@ require (
6363
github.com/vmihailenco/msgpack v4.0.4+incompatible // indirect
6464
github.com/vmihailenco/msgpack/v5 v5.4.1 // indirect
6565
github.com/vmihailenco/tagparser/v2 v2.0.0 // indirect
66-
golang.org/x/crypto v0.37.0 // indirect
67-
golang.org/x/mod v0.24.0 // indirect
68-
golang.org/x/net v0.39.0 // indirect
69-
golang.org/x/sync v0.13.0 // indirect
70-
golang.org/x/sys v0.32.0 // indirect
71-
golang.org/x/text v0.24.0 // indirect
72-
golang.org/x/tools v0.32.0 // indirect
66+
golang.org/x/crypto v0.39.0 // indirect
67+
golang.org/x/mod v0.25.0 // indirect
68+
golang.org/x/net v0.41.0 // indirect
69+
golang.org/x/sync v0.15.0 // indirect
70+
golang.org/x/sys v0.33.0 // indirect
71+
golang.org/x/text v0.26.0 // indirect
72+
golang.org/x/tools v0.34.0 // indirect
7373
google.golang.org/appengine v1.6.8 // indirect
7474
google.golang.org/genproto/googleapis/rpc v0.0.0-20250409194420-de1ac958c67a // indirect
7575
google.golang.org/grpc v1.71.1 // indirect

go.sum

Lines changed: 14 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -193,22 +193,22 @@ go.opentelemetry.io/otel/trace v1.34.0 h1:+ouXS2V8Rd4hp4580a8q23bg0azF2nI8cqLYnC
193193
go.opentelemetry.io/otel/trace v1.34.0/go.mod h1:Svm7lSjQD7kG7KJ/MUHPVXSDGz2OX4h0M2jHBhmSfRE=
194194
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
195195
golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
196-
golang.org/x/crypto v0.37.0 h1:kJNSjF/Xp7kU0iB2Z+9viTPMW4EqqsrywMXLJOOsXSE=
197-
golang.org/x/crypto v0.37.0/go.mod h1:vg+k43peMZ0pUMhYmVAWysMK35e6ioLh3wB8ZCAfbVc=
196+
golang.org/x/crypto v0.39.0 h1:SHs+kF4LP+f+p14esP5jAoDpHU8Gu/v9lFRK6IT5imM=
197+
golang.org/x/crypto v0.39.0/go.mod h1:L+Xg3Wf6HoL4Bn4238Z6ft6KfEpN0tJGo53AAPC632U=
198198
golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4=
199-
golang.org/x/mod v0.24.0 h1:ZfthKaKaT4NrhGVZHO1/WDTwGES4De8KtWO0SIbNJMU=
200-
golang.org/x/mod v0.24.0/go.mod h1:IXM97Txy2VM4PJ3gI61r1YEk/gAj6zAHN3AdZt6S9Ww=
199+
golang.org/x/mod v0.25.0 h1:n7a+ZbQKQA/Ysbyb0/6IbB1H/X41mKgbhfv7AfG/44w=
200+
golang.org/x/mod v0.25.0/go.mod h1:IXM97Txy2VM4PJ3gI61r1YEk/gAj6zAHN3AdZt6S9Ww=
201201
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
202202
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
203203
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
204204
golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
205-
golang.org/x/net v0.39.0 h1:ZCu7HMWDxpXpaiKdhzIfaltL9Lp31x/3fCP11bc6/fY=
206-
golang.org/x/net v0.39.0/go.mod h1:X7NRbYVEA+ewNkCNyJ513WmMdQ3BineSwVtN2zD/d+E=
205+
golang.org/x/net v0.41.0 h1:vBTly1HeNPEn3wtREYfy4GZ/NECgw2Cnl+nK6Nz3uvw=
206+
golang.org/x/net v0.41.0/go.mod h1:B/K4NNqkfmg07DQYrbwvSluqCJOOXwUjeb/5lOisjbA=
207207
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
208208
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
209209
golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
210-
golang.org/x/sync v0.13.0 h1:AauUjRAJ9OSnvULf/ARrrVywoJDy0YS2AwQ98I37610=
211-
golang.org/x/sync v0.13.0/go.mod h1:1dzgHSNfp02xaA81J2MS99Qcpr2w7fw1gpm99rleRqA=
210+
golang.org/x/sync v0.15.0 h1:KWH3jNZsfyT6xfAfKiz6MRNmd46ByHDYaZ7KSkCtdW8=
211+
golang.org/x/sync v0.15.0/go.mod h1:1dzgHSNfp02xaA81J2MS99Qcpr2w7fw1gpm99rleRqA=
212212
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
213213
golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
214214
golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
@@ -220,21 +220,21 @@ golang.org/x/sys v0.0.0-20220503163025-988cb79eb6c6/go.mod h1:oPkhp1MJrh7nUepCBc
220220
golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
221221
golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
222222
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
223-
golang.org/x/sys v0.32.0 h1:s77OFDvIQeibCmezSnk/q6iAfkdiQaJi4VzroCFrN20=
224-
golang.org/x/sys v0.32.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k=
223+
golang.org/x/sys v0.33.0 h1:q3i8TbbEz+JRD9ywIRlyRAQbM0qF7hu24q3teo2hbuw=
224+
golang.org/x/sys v0.33.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k=
225225
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
226226
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
227227
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
228228
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
229229
golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
230230
golang.org/x/text v0.3.8/go.mod h1:E6s5w1FMmriuDzIBO73fBruAKo1PCIq6d2Q6DHfQ8WQ=
231-
golang.org/x/text v0.24.0 h1:dd5Bzh4yt5KYA8f9CJHCP4FB4D51c2c6JvN37xJJkJ0=
232-
golang.org/x/text v0.24.0/go.mod h1:L8rBsPeo2pSS+xqN0d5u2ikmjtmoJbDBT1b7nHvFCdU=
231+
golang.org/x/text v0.26.0 h1:P42AVeLghgTYr4+xUnTRKDMqpar+PtX7KWuNQL21L8M=
232+
golang.org/x/text v0.26.0/go.mod h1:QK15LZJUUQVJxhz7wXgxSy/CJaTFjd0G+YLonydOVQA=
233233
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
234234
golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
235235
golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc=
236-
golang.org/x/tools v0.32.0 h1:Q7N1vhpkQv7ybVzLFtTjvQya2ewbwNDZzUgfXGqtMWU=
237-
golang.org/x/tools v0.32.0/go.mod h1:ZxrU41P/wAbZD8EDa6dDCa6XfpkhJ7HFMjHJXfBDu8s=
236+
golang.org/x/tools v0.34.0 h1:qIpSLOxeCYGg9TrcJokLBG4KFA6d795g0xkBkiESGlo=
237+
golang.org/x/tools v0.34.0/go.mod h1:pAP9OwEaY1CAW3HOmg3hLZC5Z0CCmzjAF2UQMSqNARg=
238238
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
239239
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
240240
google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM=

internal/provider/ndfc/api/api.go

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ import (
1313
"log"
1414
"strings"
1515
"sync"
16+
"time"
1617

1718
"github.com/netascode/go-nd"
1819

@@ -33,6 +34,8 @@ type NDFCAPI interface {
3334
type NDFCAPICommon struct {
3435
NDFCAPI
3536
LockedForDeploy bool
37+
DeployStartTime time.Time
38+
DeployEndTime time.Time
3639
client *nd.Client
3740
}
3841

@@ -136,6 +139,8 @@ func (c NDFCAPICommon) Delete() (gjson.Result, error) {
136139
c.NDFCAPI.GetLock().Lock()
137140
defer c.NDFCAPI.GetLock().Unlock()
138141
qp := c.NDFCAPI.GetDeleteQP()
142+
log.Printf("Delete URL: %s\n", c.NDFCAPI.DeleteUrl())
143+
log.Printf("Delete Query Parameters: %v\n", qp)
139144
var res nd.Res
140145
var err error
141146
if qp != nil {
@@ -183,7 +188,6 @@ func (c NDFCAPICommon) DeployPost(payload []byte) (gjson.Result, error) {
183188
} else {
184189
log.Printf("Deploy write lock is already acquired for %s", c.NDFCAPI.RscName())
185190
}
186-
187191
log.Printf("Deploy Post URL: %s\n", c.NDFCAPI.PostUrl())
188192
lock := c.NDFCAPI.GetLock()
189193
lock.Lock()

internal/provider/ndfc/api/config_deploy_api.go

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ type ConfigDeploymentAPI struct {
2222
SerialNumbers []string
2323
Deploy bool
2424
Preview bool
25+
History bool
2526
FabricName string
2627
}
2728

@@ -34,6 +35,8 @@ const UrlGetFabricErrors = "/lan-fabric/rest/control/fabrics/%s/errors"
3435
const UrlGetGlobalConfigPreview = "/lan-fabric/rest/control/fabrics/%s/config-preview/%s"
3536
const UrlGetConfigPreview = "/lan-fabric/rest/control/fabrics/%s/config-preview"
3637

38+
const UrlGetDeploymentHistory = "/lan-fabric/rest/config/delivery/deployerHistoryByFabric/%s?serialNumber=%s&sort=%s"
39+
3740
func (c *ConfigDeploymentAPI) GetLock() *sync.Mutex {
3841
return c.mutex
3942
}
@@ -44,6 +47,8 @@ func (c *ConfigDeploymentAPI) GetUrl() string {
4447
return fmt.Sprintf(UrlGetGlobalConfigPreview, c.FabricName, strings.Join(c.SerialNumbers, ","))
4548
}
4649
return fmt.Sprintf(UrlGetConfigPreview, c.FabricName)
50+
} else if c.History {
51+
return fmt.Sprintf(UrlGetDeploymentHistory, c.FabricName, strings.Join(c.SerialNumbers, ","), "completedTime%3ADES")
4752
} else {
4853
return fmt.Sprintf(UrlGetFabricErrors, c.FabricName)
4954
}

internal/provider/ndfc/api/policy_api.go

Lines changed: 38 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ package api
1010

1111
import (
1212
"fmt"
13+
"strings"
1314
"sync"
1415

1516
"github.com/netascode/go-nd"
@@ -21,7 +22,9 @@ const UrlPolicy = "/lan-fabric/rest/control/policies/%s"
2122
const UrlPolicyDeploy = "/lan-fabric/rest/control/policies/deploy"
2223

2324
const UrlPolicyGroup = "/lan-fabric/rest/control/policies/policygroup/%s"
24-
const UrlPolicyGroupCreate = "lan-fabric/rest/control/policies/policygroup/create"
25+
const UrlPolicyGroupCreate = "/lan-fabric/rest/control/policies/policygroup/create?serialNumbers=%s"
26+
const UrlPolicyGroupUpdate = "/lan-fabric/rest/control/policies/policygroup/%s?serialNumbers=%s&mark-delete-and-update=true"
27+
const UrlPolicyGroupDelete = "/lan-fabric/rest/control/policies/policygroup/policyIds"
2528

2629
type PolicyAPI struct {
2730
NDFCAPICommon
@@ -37,25 +40,59 @@ func (c *PolicyAPI) GetLock() *sync.Mutex {
3740
}
3841

3942
func (c *PolicyAPI) GetUrl() string {
43+
if c.PolicyGroup {
44+
return fmt.Sprintf(UrlPolicyGroup, c.PolicyID)
45+
}
4046
return fmt.Sprintf(UrlPolicy, c.PolicyID)
4147
}
4248

4349
func (c *PolicyAPI) PostUrl() string {
4450
if c.Deploy {
51+
if c.PolicyGroup {
52+
if len(c.DeploySwitches) != 0 {
53+
return fmt.Sprintf("%s?serialNumber=%s", UrlPolicyDeploy, strings.Join(c.DeploySwitches, ","))
54+
} else {
55+
panic("Switches cannot be empty")
56+
}
57+
}
4558
return UrlPolicyDeploy
4659
}
60+
if c.PolicyGroup {
61+
if len(c.DeploySwitches) != 0 {
62+
return fmt.Sprintf(UrlPolicyGroupCreate, strings.Join(c.DeploySwitches, ","))
63+
} else {
64+
panic("Switches cannot be empty")
65+
}
66+
}
4767
return UrlPolicyCreate
4868
}
4969

5070
func (c *PolicyAPI) PutUrl() string {
71+
if c.PolicyGroup {
72+
if len(c.DeploySwitches) != 0 {
73+
return fmt.Sprintf(UrlPolicyGroupUpdate, c.PolicyID, strings.Join(c.DeploySwitches, ","))
74+
} else {
75+
panic("Switches cannot be empty")
76+
}
77+
}
5178
return fmt.Sprintf(UrlPolicy, c.PolicyID)
5279
}
5380

5481
func (c *PolicyAPI) DeleteUrl() string {
82+
if c.PolicyGroup {
83+
return UrlPolicyGroupDelete
84+
}
5585
return fmt.Sprintf(UrlPolicy, c.PolicyID)
5686
}
5787

5888
func (c *PolicyAPI) GetDeleteQP() []string {
89+
if c.PolicyGroup {
90+
if len(c.DeploySwitches) != 0 {
91+
return []string{"policyIds=" + c.PolicyID, "serialNumbers=" + strings.Join(c.DeploySwitches, ",")}
92+
} else {
93+
panic("Switches cannot be empty")
94+
}
95+
}
5996
return nil
6097
}
6198

0 commit comments

Comments
 (0)