diff --git a/gen/templates/data_source.go b/gen/templates/data_source.go index ab940816..ef58e915 100644 --- a/gen/templates/data_source.go +++ b/gen/templates/data_source.go @@ -157,11 +157,11 @@ func (d *{{camelCase .Name}}DataSource) Read(ctx context.Context, req datasource if device.Managed { getResp, err := d.data.Client.Get(ctx, config.Device.ValueString(), config.getPath()) if err != nil { - resp.Diagnostics.AddError("Unable to apply gNMI Get operation", err.Error()) + resp.Diagnostics.AddError("Unable to apply Get operation", err.Error()) return } - config.fromBody(ctx, getResp.Notification[0].Update[0].Val.GetJsonIetfVal()) + config.fromBody(ctx, getResp) } config.Id = types.StringValue(config.getPath()) diff --git a/gen/templates/provider.go b/gen/templates/provider.go index 792246c5..ffe9e104 100644 --- a/gen/templates/provider.go +++ b/gen/templates/provider.go @@ -22,6 +22,7 @@ package provider import ( "context" + "fmt" "os" "slices" "strconv" @@ -49,20 +50,25 @@ type providerData struct { Username types.String `tfsdk:"username"` Password types.String `tfsdk:"password"` Host types.String `tfsdk:"host"` + Protocol types.String `tfsdk:"protocol"` + Port types.Int64 `tfsdk:"port"` VerifyCertificate types.Bool `tfsdk:"verify_certificate"` Tls types.Bool `tfsdk:"tls"` Certificate types.String `tfsdk:"certificate"` Key types.String `tfsdk:"key"` CaCertificate types.String `tfsdk:"ca_certificate"` ReuseConnection types.Bool `tfsdk:"reuse_connection"` + MaxRetries types.Int64 `tfsdk:"max_retries"` SelectedDevices types.List `tfsdk:"selected_devices"` Devices []providerDataDevice `tfsdk:"devices"` } type providerDataDevice struct { - Name types.String `tfsdk:"name"` - Host types.String `tfsdk:"host"` - Managed types.Bool `tfsdk:"managed"` + Name types.String `tfsdk:"name"` + Host types.String `tfsdk:"host"` + Protocol types.String `tfsdk:"protocol"` + Port types.Int64 `tfsdk:"port"` + Managed types.Bool `tfsdk:"managed"` } type IosxrProviderData struct { @@ -71,7 +77,8 @@ type IosxrProviderData struct { } type IosxrProviderDataDevice struct { - Managed bool + Managed bool + Protocol string } // Metadata returns the provider type name. @@ -95,6 +102,14 @@ func (p *iosxrProvider) Schema(ctx context.Context, req provider.SchemaRequest, MarkdownDescription: "IP or name of the Cisco IOS-XR device. Optionally a port can be added with `:12345`. The default port is `57400`. This can also be set as the IOSXR_HOST environment variable. If no `host` is provided, the `host` of the first device from the `devices` list is being used.", Optional: true, }, + "protocol": schema.StringAttribute{ + MarkdownDescription: "Protocol to use for device communication. Valid values are `gnmi` and `netconf`. Defaults to `gnmi`. This can also be set as the IOSXR_PROTOCOL environment variable.", + Optional: true, + }, + "port": schema.Int64Attribute{ + MarkdownDescription: "Port to connect to on the Cisco IOS-XR device. Defaults to `57400` for gNMI and `830` for NETCONF. This can also be set as the IOSXR_PORT environment variable.", + Optional: true, + }, "verify_certificate": schema.BoolAttribute{ MarkdownDescription: "Verify target certificate. This can also be set as the IOSXR_VERIFY_CERTIFICATE environment variable. Defaults to `false`.", Optional: true, @@ -119,6 +134,10 @@ func (p *iosxrProvider) Schema(ctx context.Context, req provider.SchemaRequest, MarkdownDescription: "Reuse gNMI connection. This can also be set as the IOSXR_REUSE_CONNECTION environment variable. Defaults to `true`.", Optional: true, }, + "max_retries": schema.Int64Attribute{ + MarkdownDescription: "Maximum number of retries for device operations. This can also be set as the IOSXR_MAX_RETRIES environment variable. Defaults to `3`.", + Optional: true, + }, "selected_devices": schema.ListAttribute{ MarkdownDescription: "This can be used to select a list of devices to manage from the `devices` list. Selected devices will be managed while other devices will be skipped and their state will be frozen. This can be used to deploy changes to a subset of devices. Defaults to all devices.", Optional: true, @@ -137,6 +156,14 @@ func (p *iosxrProvider) Schema(ctx context.Context, req provider.SchemaRequest, MarkdownDescription: "IP of the Cisco IOS-XR device.", Required: true, }, + "protocol": schema.StringAttribute{ + MarkdownDescription: "Protocol to use for this device. Valid values are `gnmi` and `netconf`. If not specified, uses the provider-level protocol setting.", + Optional: true, + }, + "port": schema.Int64Attribute{ + MarkdownDescription: "Port to connect to on this device. If not specified, uses the provider-level port setting or protocol defaults.", + Optional: true, + }, "managed": schema.BoolAttribute{ MarkdownDescription: "Enable or disable device management. This can be used to temporarily skip a device due to maintenance for example. Defaults to `true`.", Optional: true, @@ -238,6 +265,68 @@ func (p *iosxrProvider) Configure(ctx context.Context, req provider.ConfigureReq return } + var protocol string + if config.Protocol.IsUnknown() { + // Cannot connect to client with an unknown value + resp.Diagnostics.AddWarning( + "Unable to create client", + "Cannot use unknown value as protocol", + ) + return + } + + if config.Protocol.IsNull() { + protocol = os.Getenv("IOSXR_PROTOCOL") + if protocol == "" { + protocol = "gnmi" // Default to gNMI + } + } else { + protocol = config.Protocol.ValueString() + } + + // Validate protocol + if protocol != "gnmi" && protocol != "netconf" { + resp.Diagnostics.AddError( + "Invalid protocol", + "Protocol must be either 'gnmi' or 'netconf', got: "+protocol, + ) + return + } + + var port int64 + if config.Port.IsUnknown() { + // Cannot connect to client with an unknown value + resp.Diagnostics.AddWarning( + "Unable to create client", + "Cannot use unknown value as port", + ) + return + } + + if config.Port.IsNull() { + portStr := os.Getenv("IOSXR_PORT") + if portStr == "" { + // Set default port based on protocol + if protocol == "netconf" { + port = 830 + } else { + port = 57400 // gNMI default + } + } else { + var err error + port, err = strconv.ParseInt(portStr, 10, 64) + if err != nil { + resp.Diagnostics.AddError( + "Invalid port value", + "IOSXR_PORT must be a valid integer, got: "+portStr, + ) + return + } + } + } else { + port = config.Port.ValueInt64() + } + var verifyCertificate bool if config.VerifyCertificate.IsUnknown() { // Cannot connect to client with an unknown value @@ -373,6 +462,35 @@ func (p *iosxrProvider) Configure(ctx context.Context, req provider.ConfigureReq reuseConnection = config.ReuseConnection.ValueBool() } + var maxRetries int64 + if config.MaxRetries.IsUnknown() { + // Cannot connect to client with an unknown value + resp.Diagnostics.AddWarning( + "Unable to create client", + "Cannot use unknown value as max_retries", + ) + return + } + + if config.MaxRetries.IsNull() { + maxRetriesStr := os.Getenv("IOSXR_MAX_RETRIES") + if maxRetriesStr == "" { + maxRetries = 3 // Default to 3 retries + } else { + var err error + maxRetries, err = strconv.ParseInt(maxRetriesStr, 10, 64) + if err != nil { + resp.Diagnostics.AddError( + "Invalid max_retries value", + "IOSXR_MAX_RETRIES must be a valid integer, got: "+maxRetriesStr, + ) + return + } + } + } else { + maxRetries = config.MaxRetries.ValueInt64() + } + var selectedDevices []string if config.SelectedDevices.IsUnknown() { // Cannot connect to client with an unknown value @@ -424,21 +542,33 @@ func (p *iosxrProvider) Configure(ctx context.Context, req provider.ConfigureReq } } - client := client.NewClient(reuseConnection) + // Create unified client based on protocol + clientInstance := client.NewClient(client.ProtocolType(protocol), reuseConnection, int(maxRetries)) + + // Add target for default device + var err error + hostWithPort := host + if !strings.Contains(host, ":") { + hostWithPort = fmt.Sprintf("%s:%d", host, port) + } + err = clientInstance.AddTarget(ctx, "", hostWithPort, username, password, int(port), certificate, key, caCertificate, verifyCertificate, tls) - err := client.AddTarget(ctx, "", host, username, password, certificate, key, caCertificate, verifyCertificate, tls) if err != nil { resp.Diagnostics.AddError("Unable to add target", err.Error()) + return } // Build provider data structure with device management information providerData := &IosxrProviderData{ - Client: &client, + Client: clientInstance, Devices: make(map[string]*IosxrProviderDataDevice), } // Add default device (empty string) - providerData.Devices[""] = &IosxrProviderDataDevice{Managed: true} + providerData.Devices[""] = &IosxrProviderDataDevice{ + Managed: true, + Protocol: protocol, + } // Add all devices with their managed status for _, device := range config.Devices { @@ -449,12 +579,54 @@ func (p *iosxrProvider) Configure(ctx context.Context, req provider.ConfigureReq } else { managed = device.Managed.IsNull() || device.Managed.IsUnknown() || device.Managed.ValueBool() } - providerData.Devices[deviceName] = &IosxrProviderDataDevice{Managed: managed} if managed { - err := client.AddTarget(ctx, deviceName, device.Host.ValueString(), username, password, certificate, key, caCertificate, verifyCertificate, tls) + // Get device-specific protocol and port if specified, otherwise use defaults + deviceProtocol := protocol + devicePort := port + + if !device.Protocol.IsNull() && !device.Protocol.IsUnknown() { + deviceProtocol = device.Protocol.ValueString() + // Validate device protocol + if deviceProtocol != "gnmi" && deviceProtocol != "netconf" { + resp.Diagnostics.AddError( + "Invalid device protocol", + fmt.Sprintf("Device '%s' protocol must be either 'gnmi' or 'netconf', got: %s", deviceName, deviceProtocol), + ) + return + } + } + + if !device.Port.IsNull() && !device.Port.IsUnknown() { + devicePort = device.Port.ValueInt64() + } + + // Store device info with protocol + providerData.Devices[deviceName] = &IosxrProviderDataDevice{ + Managed: managed, + Protocol: deviceProtocol, + } + + // Add device target + deviceHostWithPort := device.Host.ValueString() + if !strings.Contains(deviceHostWithPort, ":") { + deviceHostWithPort = fmt.Sprintf("%s:%d", deviceHostWithPort, devicePort) + } + err = clientInstance.AddTarget(ctx, deviceName, deviceHostWithPort, username, password, int(devicePort), certificate, key, caCertificate, verifyCertificate, tls) + if err != nil { - resp.Diagnostics.AddError("Unable to add target", err.Error()) + resp.Diagnostics.AddError("Unable to add device target", fmt.Sprintf("Device '%s': %s", deviceName, err.Error())) + return + } + } else { + // For unmanaged devices, still store the protocol info + deviceProtocol := protocol + if !device.Protocol.IsNull() && !device.Protocol.IsUnknown() { + deviceProtocol = device.Protocol.ValueString() + } + providerData.Devices[deviceName] = &IosxrProviderDataDevice{ + Managed: managed, + Protocol: deviceProtocol, } } } diff --git a/gen/templates/resource.go b/gen/templates/resource.go index f5cc0fa0..32ed4bfc 100644 --- a/gen/templates/resource.go +++ b/gen/templates/resource.go @@ -356,7 +356,7 @@ func (r *{{camelCase .Name}}Resource) Read(ctx context.Context, req resource.Rea resp.State.RemoveResource(ctx) return } else { - resp.Diagnostics.AddError("Unable to apply gNMI Get operation", err.Error()) + resp.Diagnostics.AddError("Unable to apply Get operation", err.Error()) return } } @@ -367,7 +367,7 @@ func (r *{{camelCase .Name}}Resource) Read(ctx context.Context, req resource.Rea } // After `terraform import` we switch to a full read. - respBody := getResp.Notification[0].Update[0].Val.GetJsonIetfVal() + respBody := getResp if imp { state.fromBody(ctx, respBody) } else { diff --git a/go.mod b/go.mod index a6ad85f4..1ae892d3 100644 --- a/go.mod +++ b/go.mod @@ -12,6 +12,7 @@ require ( github.com/openconfig/gnmi v0.14.1 github.com/openconfig/gnmic/pkg/api v0.1.9 github.com/openconfig/goyang v1.6.3 + github.com/scrapli/scrapligo v1.3.3 github.com/tidwall/gjson v1.18.0 github.com/tidwall/sjson v1.2.5 golang.org/x/tools v0.37.0 @@ -35,6 +36,7 @@ require ( github.com/bmatcuk/doublestar/v4 v4.9.1 // indirect github.com/bufbuild/protocompile v0.14.1 // indirect github.com/cloudflare/circl v1.6.1 // indirect + github.com/creack/pty v1.1.23 // indirect github.com/fatih/color v1.18.0 // indirect github.com/go-test/deep v1.1.0 // indirect github.com/golang/protobuf v1.5.4 // indirect @@ -76,6 +78,7 @@ require ( github.com/posener/complete v1.2.3 // indirect github.com/rivo/uniseg v0.4.4 // indirect github.com/shopspring/decimal v1.3.1 // indirect + github.com/sirikothe/gotextfsm v1.0.1-0.20200816110946-6aa2cfd355e4 // indirect github.com/spf13/cast v1.6.0 // indirect github.com/tidwall/match v1.2.0 // indirect github.com/tidwall/pretty v1.2.1 // indirect diff --git a/go.sum b/go.sum index baceb840..ef567bf4 100644 --- a/go.sum +++ b/go.sum @@ -33,6 +33,8 @@ github.com/bufbuild/protocompile v0.14.1 h1:iA73zAf/fyljNjQKwYzUHD6AD4R8KMasmwa/ github.com/bufbuild/protocompile v0.14.1/go.mod h1:ppVdAIhbr2H8asPk6k4pY7t9zB1OU5DoEw9xY/FUi1c= github.com/cloudflare/circl v1.6.1 h1:zqIqSPIndyBh1bjLVVDHMPpVKqp8Su/V+6MeDzzQBQ0= github.com/cloudflare/circl v1.6.1/go.mod h1:uddAzsPgqdMAYatqJ0lsjX1oECcQLIlRpzZh3pJrofs= +github.com/creack/pty v1.1.23 h1:4M6+isWdcStXEf15G/RbrMPOQj1dZ7HPZCGwE4kOeP0= +github.com/creack/pty v1.1.23/go.mod h1:08sCNb52WyoAwi2QDyzUCTgcvVFhUzewun7wtTfvcwE= github.com/cyphar/filepath-securejoin v0.4.1 h1:JyxxyPEaktOD+GAnqIqTf9A8tHyAG22rowi7HkoSU1s= github.com/cyphar/filepath-securejoin v0.4.1/go.mod h1:Sdj7gXlvMcPZsbhwhQ33GguGLDGQL7h7bg04C/+u9jI= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= @@ -194,11 +196,15 @@ github.com/rivo/uniseg v0.4.4 h1:8TfxU8dW6PdqD27gjM8MVNuicgxIjxpm4K7x4jp8sis= github.com/rivo/uniseg v0.4.4/go.mod h1:FN3SvrM+Zdj16jyLfmOkMNblXMcoc8DfTHruCPUcx88= github.com/rogpeppe/go-internal v1.14.1 h1:UQB4HGPB6osV0SQTLymcB4TgvyWu6ZyliaW0tI/otEQ= github.com/rogpeppe/go-internal v1.14.1/go.mod h1:MaRKkUm5W0goXpeCfT7UZI6fk/L7L7so1lCWt35ZSgc= +github.com/scrapli/scrapligo v1.3.3 h1:D9zj1QrOYNYAQ30YT7wfQBINvPGxvs5L5Lz+2LnL7V4= +github.com/scrapli/scrapligo v1.3.3/go.mod h1:pOWxVyPsQRrWTrkoSSDg05tjOqtWfLffAZtAsCc0w3M= github.com/sergi/go-diff v1.3.2-0.20230802210424-5b0b94c5c0d3 h1:n661drycOFuPLCN3Uc8sB6B/s6Z4t2xvBgU1htSHuq8= github.com/sergi/go-diff v1.3.2-0.20230802210424-5b0b94c5c0d3/go.mod h1:A0bzQcvG0E7Rwjx0REVgAGH58e96+X0MeOfepqsbeW4= github.com/shopspring/decimal v1.2.0/go.mod h1:DKyhrW/HYNuLGql+MJL6WCR6knT2jwCFRcu2hWCYk4o= github.com/shopspring/decimal v1.3.1 h1:2Usl1nmF/WZucqkFZhnfFYxxxu8LG21F6nPQBE5gKV8= github.com/shopspring/decimal v1.3.1/go.mod h1:DKyhrW/HYNuLGql+MJL6WCR6knT2jwCFRcu2hWCYk4o= +github.com/sirikothe/gotextfsm v1.0.1-0.20200816110946-6aa2cfd355e4 h1:FHUL2HofYJuslFOQdy/JjjP36zxqIpd/dcoiwLMIs7k= +github.com/sirikothe/gotextfsm v1.0.1-0.20200816110946-6aa2cfd355e4/go.mod h1:CJYqpTg9u5VPCoD0VEl9E68prCIiWQD8m457k098DdQ= github.com/skeema/knownhosts v1.3.1 h1:X2osQ+RAjK76shCbvhHHHVl3ZlgDm8apHEHFqRjnBY8= github.com/skeema/knownhosts v1.3.1/go.mod h1:r7KTdC8l4uxWRyK2TpQZ/1o5HaSzh06ePQNxPwTcfiY= github.com/spf13/cast v1.3.1/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE= @@ -297,6 +303,8 @@ golang.org/x/telemetry v0.0.0-20250908211612-aef8a434d053/go.mod h1:+nZKN+XVh4LC golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/term v0.2.0/go.mod h1:TVmDHMZPmdnySmBfhjOoOdhjzdE1h4u1VwSiw2l1Nuc= +golang.org/x/term v0.35.0 h1:bZBVKBudEyhRcajGcNc3jIfWPqV4y/Kt2XcoigOWtDQ= +golang.org/x/term v0.35.0/go.mod h1:TPGtkTLesOwf2DE8CgVYiZinHAOuy5AYUYT1lENIZnA= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= diff --git a/internal/provider/client/client.go b/internal/provider/client/client.go index 1791a938..2ecbc3b5 100644 --- a/internal/provider/client/client.go +++ b/internal/provider/client/client.go @@ -22,14 +22,9 @@ import ( "fmt" "math" "math/rand" - "strings" - "sync" "time" "github.com/hashicorp/terraform-plugin-log/tflog" - "github.com/openconfig/gnmi/proto/gnmi" - "github.com/openconfig/gnmic/pkg/api" - target "github.com/openconfig/gnmic/pkg/api/target" ) const ( @@ -37,10 +32,10 @@ const ( DefaultBackoffMinDelay int = 4 DefaultBackoffMaxDelay int = 60 DefaultBackoffDelayFactor float64 = 3 - GnmiTimeout = 15 * time.Second ) type SetOperationType string +type ProtocolType string const ( Update SetOperationType = "update" @@ -48,8 +43,22 @@ const ( Delete SetOperationType = "delete" ) -type Client struct { - Devices map[string]*Device +const ( + ProtocolGNMI ProtocolType = "gnmi" + ProtocolNETCONF ProtocolType = "netconf" +) + +// Client is the interface that both NETCONF and gNMI clients implement +type Client interface { + AddTarget(ctx context.Context, device, host, username, password string, port int, certificate, key, caCertificate string, verifyCertificate, useTls bool) error + Set(ctx context.Context, device string, operations ...SetOperation) (bool, error) + Get(ctx context.Context, device, path string) ([]byte, error) + GetProtocol() ProtocolType + Close(ctx context.Context) +} + +// BaseClient holds common configuration for protocol clients +type BaseClient struct { // Reuse connection ReuseConnection bool // Maximum number of retries @@ -62,187 +71,49 @@ type Client struct { BackoffDelayFactor float64 } -type Device struct { - SetMutex *sync.Mutex - Target *target.Target -} - type SetOperation struct { Path string Body string Operation SetOperationType } -func NewClient(reuseConnection bool) Client { - devices := make(map[string]*Device) - return Client{ - Devices: devices, +// NewClient creates a new client based on protocol type +func NewClient(protocol ProtocolType, reuseConnection bool, maxRetries int) Client { + baseConfig := BaseClient{ ReuseConnection: reuseConnection, - MaxRetries: DefaultMaxRetries, + MaxRetries: maxRetries, BackoffMinDelay: DefaultBackoffMinDelay, BackoffMaxDelay: DefaultBackoffMaxDelay, BackoffDelayFactor: DefaultBackoffDelayFactor, } -} - -func (c *Client) AddTarget(ctx context.Context, device, host, username, password, certificate, key, caCertificate string, verifyCertificate, Tls bool) error { - if !strings.Contains(host, ":") { - host = host + ":57400" - } - - t, err := api.NewTarget( - api.Name(device), - api.Address(host), - api.Username(username), - api.Password(password), - api.TLSCert(certificate), - api.TLSKey(key), - api.TLSCA(caCertificate), - api.SkipVerify(!verifyCertificate), - api.Insecure(!Tls), - ) - if err != nil { - return fmt.Errorf("Unable to create target: %w", err) - } - - if c.ReuseConnection { - err = t.CreateGNMIClient(ctx) - if err != nil { - return fmt.Errorf("Unable to create gNMI client: %w", err) - } - } - - c.Devices[device] = &Device{} - c.Devices[device].Target = t - c.Devices[device].SetMutex = &sync.Mutex{} - - return nil -} - -func (c *Client) Set(ctx context.Context, device string, operations ...SetOperation) (*gnmi.SetResponse, error) { - if _, ok := c.Devices[device]; !ok { - return nil, fmt.Errorf("Device '%s' does not exist in provider configuration.", device) - } - - target := c.Devices[device].Target - - var ops []api.GNMIOption - for _, op := range operations { - if op.Operation == Update { - ops = append(ops, api.Update(api.Path(op.Path), api.Value(op.Body, "json_ietf"))) - } else if op.Operation == Replace { - ops = append(ops, api.Replace(api.Path(op.Path), api.Value(op.Body, "json_ietf"))) - } else if op.Operation == Delete { - ops = append(ops, api.Delete(op.Path)) - } - } - setReq, err := api.NewSetRequest(ops...) - if err != nil { - return nil, fmt.Errorf("Failed to create set request, got error: %w", err) + switch protocol { + case ProtocolNETCONF: + return NewNetconfClient(baseConfig) + case ProtocolGNMI: + return NewGNMIClient(baseConfig) + default: + return NewGNMIClient(baseConfig) } - - var setResp *gnmi.SetResponse - for attempts := 0; ; attempts++ { - c.Devices[device].SetMutex.Lock() - if !c.ReuseConnection { - err = target.CreateGNMIClient(ctx) - if err != nil { - if ok := c.Backoff(ctx, attempts); !ok { - return nil, fmt.Errorf("Unable to create gNMI client: %w", err) - } else { - tflog.Error(ctx, fmt.Sprintf("Unable to create gNMI client: %s, retries: %v", err.Error(), attempts)) - continue - } - } - } - tCtx, cancel := context.WithTimeout(ctx, GnmiTimeout) - defer cancel() - tflog.Debug(ctx, fmt.Sprintf("gNMI set request: %s", setReq.String())) - setResp, err = target.Set(tCtx, setReq) - tflog.Debug(ctx, fmt.Sprintf("gNMI set response: %s", setResp.String())) - c.Devices[device].SetMutex.Unlock() - if !c.ReuseConnection { - target.Close() - } - if err != nil { - if ok := c.Backoff(ctx, attempts); !ok { - return nil, fmt.Errorf("Set request failed, got error: %w", err) - } else { - tflog.Error(ctx, fmt.Sprintf("gNMI set request failed: %s, retries: %v", err, attempts)) - continue - } - } - break - } - - return setResp, nil -} - -func (c *Client) Get(ctx context.Context, device, path string) (*gnmi.GetResponse, error) { - if _, ok := c.Devices[device]; !ok { - return nil, fmt.Errorf("Device '%s' does not exist in provider configuration.", device) - } - - target := c.Devices[device].Target - - getReq, err := api.NewGetRequest(api.Path(path), api.Encoding("json_ietf")) - if err != nil { - return nil, fmt.Errorf("Failed to create get request, got error: %w", err) - } - - var getResp *gnmi.GetResponse - for attempts := 0; ; attempts++ { - tflog.Debug(ctx, fmt.Sprintf("gNMI get request: %s", getReq.String())) - if !c.ReuseConnection { - err = target.CreateGNMIClient(ctx) - if err != nil { - if ok := c.Backoff(ctx, attempts); !ok { - return nil, fmt.Errorf("Unable to create gNMI client: %w", err) - } else { - tflog.Error(ctx, fmt.Sprintf("Unable to create gNMI client: %s, retries: %v", err.Error(), attempts)) - continue - } - } - } - tCtx, cancel := context.WithTimeout(ctx, GnmiTimeout) - defer cancel() - getResp, err = target.Get(tCtx, getReq) - if !c.ReuseConnection { - target.Close() - } - tflog.Debug(ctx, fmt.Sprintf("gNMI get response: %s", getResp.String())) - if err != nil { - if ok := c.Backoff(ctx, attempts); !ok { - return nil, fmt.Errorf(("Get request failed, got error: %w"), err) - } else { - tflog.Error(ctx, fmt.Sprintf("gNMI get request failed: %s, retries: %v", err, attempts)) - continue - } - } - break - } - - return getResp, nil } // Backoff waits following an exponential backoff algorithm -func (c *Client) Backoff(ctx context.Context, attempts int) bool { - tflog.Debug(ctx, fmt.Sprintf("Begining backoff method: attempts %v on %v", attempts, c.MaxRetries)) - if attempts >= c.MaxRetries { +func (b *BaseClient) Backoff(ctx context.Context, attempts int) bool { + tflog.Debug(ctx, fmt.Sprintf("Begining backoff method: attempts %v on %v", attempts, b.MaxRetries)) + if attempts >= b.MaxRetries { tflog.Debug(ctx, "Exit from backoff method with return value false") return false } - minDelay := time.Duration(c.BackoffMinDelay) * time.Second - maxDelay := time.Duration(c.BackoffMaxDelay) * time.Second + minDelay := time.Duration(b.BackoffMinDelay) * time.Second + maxDelay := time.Duration(b.BackoffMaxDelay) * time.Second - min := float64(minDelay) - backoff := min * math.Pow(c.BackoffDelayFactor, float64(attempts)) + minDelayFloat := float64(minDelay) + backoff := minDelayFloat * math.Pow(b.BackoffDelayFactor, float64(attempts)) if backoff > float64(maxDelay) { backoff = float64(maxDelay) } - backoff = (rand.Float64()/2+0.5)*(backoff-min) + min + backoff = (rand.Float64()/2+0.5)*(backoff-minDelayFloat) + minDelayFloat backoffDuration := time.Duration(backoff) tflog.Debug(ctx, fmt.Sprintf("Starting sleeping for %v", backoffDuration.Round(time.Second))) time.Sleep(backoffDuration) diff --git a/internal/provider/client/gnmi_client.go b/internal/provider/client/gnmi_client.go new file mode 100644 index 00000000..9e0938a4 --- /dev/null +++ b/internal/provider/client/gnmi_client.go @@ -0,0 +1,240 @@ +// Copyright © 2023 Cisco Systems, Inc. and its affiliates. +// All rights reserved. +// +// Licensed under the Mozilla Public License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// https://mozilla.org/MPL/2.0/ +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +// SPDX-License-Identifier: MPL-2.0 + +package client + +import ( + "context" + "fmt" + "strings" + "sync" + "time" + + "github.com/hashicorp/terraform-plugin-log/tflog" + "github.com/openconfig/gnmi/proto/gnmi" + "github.com/openconfig/gnmic/pkg/api" + target "github.com/openconfig/gnmic/pkg/api/target" +) + +const ( + DefaultGNMIPort = 57400 + DefaultGNMITimeout = 15 * time.Second +) + +// GNMIClient implements the Client interface for gNMI protocol +type GNMIClient struct { + BaseClient + Devices map[string]*GNMIDevice + // gNMI operation timeout + GnmiTimeout time.Duration +} + +type GNMIDevice struct { + SetMutex *sync.Mutex + Target *target.Target +} + +func NewGNMIClient(base BaseClient) *GNMIClient { + devices := make(map[string]*GNMIDevice) + + return &GNMIClient{ + BaseClient: base, + Devices: devices, + GnmiTimeout: DefaultGNMITimeout, + } +} + +func (gc *GNMIClient) AddTarget(ctx context.Context, device, host, username, password string, port int, certificate, key, caCertificate string, verifyCertificate, useTls bool) error { + if port == 0 { + port = DefaultGNMIPort + } + + if !strings.Contains(host, ":") { + host = fmt.Sprintf("%s:%d", host, port) + } + + t, err := api.NewTarget( + api.Name(device), + api.Address(host), + api.Username(username), + api.Password(password), + api.TLSCert(certificate), + api.TLSKey(key), + api.TLSCA(caCertificate), + api.SkipVerify(!verifyCertificate), + api.Insecure(!useTls), + ) + if err != nil { + return fmt.Errorf("Unable to create gNMI target: %w", err) + } + + if gc.ReuseConnection { + err = t.CreateGNMIClient(ctx) + if err != nil { + return fmt.Errorf("Unable to create gNMI client: %w", err) + } + } + + gc.Devices[device] = &GNMIDevice{ + Target: t, + SetMutex: &sync.Mutex{}, + } + + return nil +} + +func (gc *GNMIClient) Close(ctx context.Context) { + for device, dev := range gc.Devices { + if dev.Target != nil { + tflog.Debug(ctx, fmt.Sprintf("Closing gNMI connection for device: %s", device)) + dev.Target.Close() + } + } +} + +// SetWithOperations performs gNMI Set operations (Update, Replace, Delete) +func (gc *GNMIClient) SetWithOperations(ctx context.Context, device string, operations ...SetOperation) (*gnmi.SetResponse, error) { + dev, exists := gc.Devices[device] + if !exists { + return nil, fmt.Errorf("Device '%s' does not exist in gNMI client configuration", device) + } + + var ops []api.GNMIOption + for _, op := range operations { + switch op.Operation { + case Update: + ops = append(ops, api.Update(api.Path(op.Path), api.Value(op.Body, "json_ietf"))) + case Replace: + ops = append(ops, api.Replace(api.Path(op.Path), api.Value(op.Body, "json_ietf"))) + case Delete: + ops = append(ops, api.Delete(op.Path)) + } + } + + setReq, err := api.NewSetRequest(ops...) + if err != nil { + return nil, fmt.Errorf("Failed to create gNMI set request: %w", err) + } + + var setResp *gnmi.SetResponse + for attempts := 0; ; attempts++ { + dev.SetMutex.Lock() + + if !gc.ReuseConnection { + err = dev.Target.CreateGNMIClient(ctx) + if err != nil { + dev.SetMutex.Unlock() + if ok := gc.Backoff(ctx, attempts); !ok { + return nil, fmt.Errorf("Unable to create gNMI client: %w", err) + } else { + tflog.Error(ctx, fmt.Sprintf("Unable to create gNMI client: %s, retries: %v", err.Error(), attempts)) + continue + } + } + } + + tCtx, cancel := context.WithTimeout(ctx, gc.GnmiTimeout) + tflog.Debug(ctx, fmt.Sprintf("gNMI set request: %s", setReq.String())) + setResp, err = dev.Target.Set(tCtx, setReq) + cancel() + + dev.SetMutex.Unlock() + + if !gc.ReuseConnection { + dev.Target.Close() + } + + if err != nil { + if ok := gc.Backoff(ctx, attempts); !ok { + return nil, fmt.Errorf("gNMI Set request failed: %w", err) + } else { + tflog.Error(ctx, fmt.Sprintf("gNMI set request failed: %s, retries: %v", err, attempts)) + continue + } + } + + tflog.Debug(ctx, fmt.Sprintf("gNMI set response: %s", setResp)) + break + } + + return setResp, nil +} + +// Get performs gNMI Get operations +func (gc *GNMIClient) Get(ctx context.Context, device, path string) ([]byte, error) { + dev, exists := gc.Devices[device] + if !exists { + return nil, fmt.Errorf("Device '%s' does not exist in gNMI client configuration", device) + } + + getReq, err := api.NewGetRequest(api.Path(path), api.Encoding("json_ietf")) + if err != nil { + return nil, fmt.Errorf("Failed to create gNMI get request: %w", err) + } + + var getResp *gnmi.GetResponse + for attempts := 0; ; attempts++ { + tflog.Debug(ctx, fmt.Sprintf("gNMI get request: %s", getReq.String())) + + if !gc.ReuseConnection { + err = dev.Target.CreateGNMIClient(ctx) + if err != nil { + if ok := gc.Backoff(ctx, attempts); !ok { + return nil, fmt.Errorf("Unable to create gNMI client: %w", err) + } else { + tflog.Error(ctx, fmt.Sprintf("Unable to create gNMI client: %s, retries: %v", err.Error(), attempts)) + continue + } + } + } + + tCtx, cancel := context.WithTimeout(ctx, gc.GnmiTimeout) + getResp, err = dev.Target.Get(tCtx, getReq) + cancel() + + if !gc.ReuseConnection { + dev.Target.Close() + } + + if err != nil { + if ok := gc.Backoff(ctx, attempts); !ok { + return nil, fmt.Errorf("gNMI Get request failed: %w", err) + } else { + tflog.Error(ctx, fmt.Sprintf("gNMI get request failed: %s, retries: %v", err, attempts)) + continue + } + } + + tflog.Debug(ctx, fmt.Sprintf("gNMI get response: %s", getResp.Notification[0].Update[0].Val.GetJsonIetfVal())) + break + } + return getResp.Notification[0].Update[0].Val.GetJsonIetfVal(), nil +} + +// Set wraps SetWithOperations for the Client interface +func (gc *GNMIClient) Set(ctx context.Context, device string, operations ...SetOperation) (bool, error) { + _, err := gc.SetWithOperations(ctx, device, operations...) + if err != nil { + return false, err + } + return true, nil +} + +// GetProtocol returns the protocol type for this client +func (gc *GNMIClient) GetProtocol() ProtocolType { + return ProtocolGNMI +} diff --git a/internal/provider/client/netconf_client.go b/internal/provider/client/netconf_client.go new file mode 100644 index 00000000..12d5026b --- /dev/null +++ b/internal/provider/client/netconf_client.go @@ -0,0 +1,608 @@ +// Copyright © 2023 Cisco Systems, Inc. and its affiliates. +// All rights reserved. +// +// Licensed under the Mozilla Public License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// https://mozilla.org/MPL/2.0/ +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +// SPDX-License-Identifier: MPL-2.0 + +package client + +import ( + //"bytes" + "context" + "fmt" + "strings" + "sync" + "time" + + "github.com/CiscoDevNet/terraform-provider-iosxr/internal/provider/helpers" + "github.com/hashicorp/terraform-plugin-log/tflog" + "github.com/scrapli/scrapligo/driver/netconf" + "github.com/scrapli/scrapligo/driver/options" + "github.com/scrapli/scrapligo/response" + "github.com/scrapli/scrapligo/util" +) + +const ( + DefaultNetconfPort = 830 + DefaultNetconfTimeout = 120 * time.Second + DefaultNetconfIdleTimeout = 10 * time.Minute + DefaultNetconfConnectTimeout = 120 * time.Second +) + +type NetconfOperationType string + +const ( + NetconfGet NetconfOperationType = "get" + NetconfGetConfig NetconfOperationType = "get-config" + NetconfEditConfig NetconfOperationType = "edit-config" + NetconfCommit NetconfOperationType = "commit" + NetconfLock NetconfOperationType = "lock" + NetconfUnlock NetconfOperationType = "unlock" +) + +type NetconfClient struct { + BaseClient + Devices map[string]*NetconfDevice + // Connection timeout - configurable by user + ConnectTimeout time.Duration + // NETCONF operation timeout - configurable by user + OperationTimeout time.Duration + // NETCONF operation timeout + NetconfTimeout time.Duration + // Idle timeout for connections + IdleTimeout time.Duration +} + +type NetconfDevice struct { + SessionMutex *sync.Mutex + Driver *netconf.Driver + Host string + Port int + Username string + Password string + UseTLS bool + SkipVerify bool + CandidateLocked bool // Track if candidate is locked + LockMutex *sync.Mutex // Mutex for candidate datastore lock +} + +type NetconfOperation struct { + Type NetconfOperationType + Target string // datastore target (candidate, running, etc.) + Filter string // XML filter for get operations + Config string // XML config for edit-config operations + TestOnly bool // for validate operations +} + +func NewNetconfClient(base BaseClient) *NetconfClient { + devices := make(map[string]*NetconfDevice) + + return &NetconfClient{ + BaseClient: base, + Devices: devices, + ConnectTimeout: DefaultNetconfConnectTimeout, + OperationTimeout: DefaultNetconfTimeout, + NetconfTimeout: DefaultNetconfTimeout, + IdleTimeout: DefaultNetconfIdleTimeout, + } +} + +func (nc *NetconfClient) AddTarget(ctx context.Context, device, host, username, password string, port int, _certificate, _key, _caCertificate string, verifyCertificate, useTls bool) error { + if port == 0 { + port = DefaultNetconfPort + } + + // Strip port from host if it was included (NETCONF driver handles port separately) + if strings.Contains(host, ":") { + hostParts := strings.Split(host, ":") + host = hostParts[0] + } + + nc.Devices[device] = &NetconfDevice{ + SessionMutex: &sync.Mutex{}, + LockMutex: &sync.Mutex{}, + Host: host, + Port: port, + Username: username, + Password: password, + UseTLS: useTls, + SkipVerify: !verifyCertificate, + CandidateLocked: false, + } + + if nc.ReuseConnection { + err := nc.createSession(ctx, device) + if err != nil { + return fmt.Errorf("Unable to create NETCONF session: %w", err) + } + } + + return nil +} + +func (nc *NetconfClient) createSession(ctx context.Context, device string) error { + dev, exists := nc.Devices[device] + if !exists { + return fmt.Errorf("Device '%s' does not exist in provider configuration", device) + } + + tflog.Debug(ctx, fmt.Sprintf("Creating NETCONF session to %s with timeout: %v", dev.Host, nc.ConnectTimeout)) + + // Create NETCONF driver options + driverOptions := []util.Option{ + options.WithAuthUsername(dev.Username), + options.WithAuthPassword(dev.Password), + options.WithPort(dev.Port), + options.WithTimeoutOps(nc.NetconfTimeout), + options.WithTimeoutSocket(nc.ConnectTimeout), + } + + // Add strict key checking option if skipVerify is true + if dev.SkipVerify { + driverOptions = append(driverOptions, options.WithAuthNoStrictKey()) + } + + // Create NETCONF driver + driver, err := netconf.NewDriver(dev.Host, driverOptions...) + if err != nil { + return fmt.Errorf("Failed to create NETCONF driver: %w", err) + } + + // Open the connection + err = driver.Open() + if err != nil { + return fmt.Errorf("Failed to open NETCONF connection: %w", err) + } + + dev.Driver = driver + tflog.Debug(ctx, fmt.Sprintf("Successfully created NETCONF session to %s", dev.Host)) + return nil +} + +func (nc *NetconfClient) ExecuteRPC(ctx context.Context, device string, operation NetconfOperation) (string, error) { + dev, exists := nc.Devices[device] + if !exists { + return "", fmt.Errorf("Device '%s' does not exist in provider configuration", device) + } + + var result string + var err error + + for attempts := 0; ; attempts++ { + dev.SessionMutex.Lock() + + if !nc.ReuseConnection || dev.Driver == nil { + err = nc.createSession(ctx, device) + if err != nil { + dev.SessionMutex.Unlock() + if ok := nc.Backoff(ctx, attempts); !ok { + return "", fmt.Errorf("Unable to create NETCONF session: %w", err) + } else { + tflog.Error(ctx, fmt.Sprintf("Unable to create NETCONF session: %s, retries: %v", err.Error(), attempts)) + continue + } + } + } + + // Create a timeout context for the operation + opCtx, cancel := context.WithTimeout(ctx, nc.NetconfTimeout) + + // Execute the operation with timeout + result, err = nc.executeOperation(opCtx, dev.Driver, operation) + cancel() // Always cancel to release resources + + dev.SessionMutex.Unlock() + + if !nc.ReuseConnection && dev.Driver != nil { + if closeErr := dev.Driver.Close(); closeErr != nil { + tflog.Warn(ctx, fmt.Sprintf("Failed to close NETCONF session: %s", closeErr.Error())) + } + dev.Driver = nil + } + + if err != nil { + // Check if it's an I/O error - likely session died, force reconnect + if strings.Contains(err.Error(), "input/output error") || + strings.Contains(err.Error(), "connection reset") || + strings.Contains(err.Error(), "broken pipe") { + tflog.Warn(ctx, fmt.Sprintf("NETCONF session error detected, closing and will retry: %v", err)) + dev.SessionMutex.Lock() + if dev.Driver != nil { + if closeErr := dev.Driver.Close(); closeErr != nil { + tflog.Warn(ctx, fmt.Sprintf("Failed to close NETCONF driver: %v", closeErr)) + } + dev.Driver = nil + } + dev.SessionMutex.Unlock() + } + + if ok := nc.Backoff(ctx, attempts); !ok { + return "", fmt.Errorf("NETCONF operation failed: %w", err) + } else { + tflog.Error(ctx, fmt.Sprintf("NETCONF operation failed: %s, retries: %v", err, attempts)) + continue + } + } + + // Check if the result contains rpc-error even when err is nil + // This handles cases where the NETCONF driver doesn't return an error + // but the device sends back an error in the XML response + if strings.Contains(result, "") { + // Special case: for delete operations, treat "data-missing" as success + // since the element to delete doesn't exist (idempotent delete) + if operation.Type == NetconfEditConfig && strings.Contains(operation.Config, `nc:operation="delete"`) && + strings.Contains(result, "data-missing") { + tflog.Info(ctx, "NETCONF delete operation: element already missing, treating as success") + break + } + + // Special case: for lock operations, if lock-denied, provide helpful error message + if operation.Type == NetconfLock && strings.Contains(result, "lock-denied") { + // Extract session-id if present + sessionID := "unknown" + if strings.Contains(result, "") { + start := strings.Index(result, "") + len("") + end := strings.Index(result[start:], "") + if end > 0 { + sessionID = result[start : start+end] + } + } + tflog.Error(ctx, fmt.Sprintf("NETCONF candidate datastore is locked by session: %s. You may need to unlock it manually or wait for the lock to be released.", sessionID)) + return "", fmt.Errorf("NETCONF candidate datastore is locked by another session (session-id: %s). Please unlock the candidate datastore manually using 'unlock candidate' or wait for the lock to expire", sessionID) + } + + tflog.Error(ctx, fmt.Sprintf("NETCONF operation returned rpc-error: %s", result)) + err = fmt.Errorf("NETCONF operation failed with rpc-error: %s", result) + if ok := nc.Backoff(ctx, attempts); !ok { + return "", err + } else { + tflog.Error(ctx, fmt.Sprintf("NETCONF rpc-error detected, retries: %v", attempts)) + continue + } + } + + break + } + + return result, nil +} + +func (nc *NetconfClient) executeOperation(ctx context.Context, driver *netconf.Driver, operation NetconfOperation) (string, error) { + switch operation.Type { + case NetconfGet: + tflog.Debug(ctx, fmt.Sprintf("NETCONF get request with filter: %s", operation.Filter)) + + reply, err := driver.Get(operation.Filter) + if err != nil { + tflog.Error(ctx, fmt.Sprintf("NETCONF get failed: %v", err)) + return "", err + } + tflog.Debug(ctx, fmt.Sprintf("NETCONF get response: %s", string(reply.Result))) + return string(reply.Result), nil + + case NetconfGetConfig: + tflog.Debug(ctx, fmt.Sprintf("NETCONF get-config request on %s", operation.Target)) + + // If a filter is provided, use Get method with filter; otherwise use GetConfig + var reply *response.NetconfResponse + var err error + + if operation.Filter != "" { + // Use Get method when filter is needed + tflog.Debug(ctx, fmt.Sprintf("NETCONF get with filter: %s", operation.Filter)) + reply, err = driver.Get(operation.Filter) + } else { + // Use GetConfig without filter + reply, err = driver.GetConfig(operation.Target) + } + + if err != nil { + tflog.Error(ctx, fmt.Sprintf("NETCONF get-config failed: %v", err)) + return "", err + } + tflog.Debug(ctx, fmt.Sprintf("NETCONF get-config response: %s", string(reply.Result))) + return string(reply.Result), nil + + case NetconfEditConfig: + tflog.Debug(ctx, fmt.Sprintf("NETCONF edit-config request on %s with config: %s", operation.Target, operation.Config)) + + reply, err := driver.EditConfig(operation.Target, operation.Config) + if err != nil { + tflog.Error(ctx, fmt.Sprintf("NETCONF edit-config failed: %v", err)) + return "", err + } + + tflog.Debug(ctx, fmt.Sprintf("NETCONF edit-config completed successfully, response: %s", string(reply.Result))) + return string(reply.Result), nil + + case NetconfCommit: + tflog.Debug(ctx, "NETCONF commit request") + tflog.Info(ctx, "Executing NETCONF commit operation") + + reply, err := driver.Commit() + if err != nil { + tflog.Error(ctx, fmt.Sprintf("NETCONF commit failed with error: %v", err)) + return "", fmt.Errorf("commit operation failed: %w", err) + } + tflog.Debug(ctx, "NETCONF commit completed successfully") + return string(reply.Result), nil + + case NetconfLock: + tflog.Debug(ctx, fmt.Sprintf("NETCONF lock request on %s", operation.Target)) + + reply, err := driver.Lock(operation.Target) + if err != nil { + return "", err + } + tflog.Debug(ctx, fmt.Sprintf("NETCONF lock on %s completed successfully", operation.Target)) + return string(reply.Result), nil + + case NetconfUnlock: + tflog.Debug(ctx, fmt.Sprintf("NETCONF unlock request on %s", operation.Target)) + + reply, err := driver.Unlock(operation.Target) + if err != nil { + return "", err + } + tflog.Debug(ctx, fmt.Sprintf("NETCONF unlock on %s completed successfully", operation.Target)) + return string(reply.Result), nil + + default: + return "", fmt.Errorf("Unknown NETCONF operation type: %s", operation.Type) + } +} + +// SetWithOperations performs NETCONF operations using candidate datastore with global lock management +func (nc *NetconfClient) SetWithOperations(ctx context.Context, device string, operations ...SetOperation) error { + dev, exists := nc.Devices[device] + if !exists { + return fmt.Errorf("Device '%s' does not exist in provider configuration", device) + } + + // Use the lock mutex to ensure only one goroutine can lock/edit/commit at a time + dev.LockMutex.Lock() + defer dev.LockMutex.Unlock() + + // Check if candidate is already locked by this client + if !dev.CandidateLocked { + tflog.Info(ctx, fmt.Sprintf("Locking candidate datastore for device: %s", device)) + err := nc.Lock(ctx, device, "candidate") + if err != nil { + tflog.Error(ctx, fmt.Sprintf("Failed to lock candidate datastore: %v", err)) + return fmt.Errorf("Failed to lock candidate datastore: %w", err) + } + dev.CandidateLocked = true + tflog.Debug(ctx, fmt.Sprintf("Candidate datastore locked for device: %s", device)) + } else { + tflog.Debug(ctx, fmt.Sprintf("Candidate datastore already locked for device: %s, reusing lock", device)) + } + + // Apply all operations to candidate datastore + for _, op := range operations { + var config string + var err error + + switch op.Operation { + case Update, Replace: + tflog.Debug(ctx, fmt.Sprintf("NETCONF config op.Body: %s", op.Body)) + config, err = helpers.GetNetconfXml(op.Path, "update", op.Body) + if err != nil { + return fmt.Errorf("Failed to convert config to XML: %w", err) + } + case Delete: + // Create delete operation XML with proper namespace + config, err = helpers.GetNetconfXml(op.Path, "delete", "") + if err != nil { + return fmt.Errorf("Failed to convert delete config to XML: %w", err) + } + } + + // Use candidate datastore (traditional NETCONF workflow) + tflog.Info(ctx, fmt.Sprintf("Applying NETCONF edit-config to candidate datastore for device: %s", device)) + + // EditConfig to candidate datastore + tflog.Debug(ctx, fmt.Sprintf("Sending NETCONF edit-config to candidate datastore with XML:\n%s", config)) + err = nc.EditConfig(ctx, device, "candidate", config) + if err != nil { + tflog.Error(ctx, fmt.Sprintf("NETCONF edit-config failed: %v", err)) + // Unlock and clear state on error + if unlockErr := nc.Unlock(ctx, device, "candidate"); unlockErr != nil { + tflog.Warn(ctx, fmt.Sprintf("Failed to unlock candidate datastore after edit-config error: %v", unlockErr)) + } + dev.CandidateLocked = false + return fmt.Errorf("NETCONF edit-config failed: %w", err) + } + } + + // Commit the changes immediately after edit-config + tflog.Info(ctx, fmt.Sprintf("Committing changes for device: %s", device)) + err := nc.Commit(ctx, device) + if err != nil { + tflog.Error(ctx, fmt.Sprintf("NETCONF commit failed: %v", err)) + // Unlock and clear state on error + if unlockErr := nc.Unlock(ctx, device, "candidate"); unlockErr != nil { + tflog.Warn(ctx, fmt.Sprintf("Failed to unlock candidate datastore after commit error: %v", unlockErr)) + } + dev.CandidateLocked = false + return fmt.Errorf("NETCONF commit failed: %w", err) + } + + // After successful commit, unlock the candidate datastore + // This allows the next resource in the Terraform plan to acquire the lock fresh + tflog.Info(ctx, fmt.Sprintf("Unlocking candidate datastore for device: %s after successful commit", device)) + unlockErr := nc.Unlock(ctx, device, "candidate") + if unlockErr != nil { + tflog.Warn(ctx, fmt.Sprintf("Failed to unlock candidate datastore: %v", unlockErr)) + } + dev.CandidateLocked = false + + tflog.Info(ctx, fmt.Sprintf("Successfully applied and committed configuration to device %s", device)) + return nil +} + +// CommitAndUnlock commits all pending changes and unlocks the candidate datastore +func (nc *NetconfClient) CommitAndUnlock(ctx context.Context, device string) error { + dev, exists := nc.Devices[device] + if !exists { + return fmt.Errorf("Device '%s' does not exist in provider configuration", device) + } + + dev.LockMutex.Lock() + defer dev.LockMutex.Unlock() + + if !dev.CandidateLocked { + tflog.Debug(ctx, fmt.Sprintf("Candidate datastore not locked for device: %s, nothing to commit", device)) + return nil + } + + // Commit the changes + tflog.Info(ctx, fmt.Sprintf("Committing all changes for device: %s", device)) + err := nc.Commit(ctx, device) + if err != nil { + tflog.Error(ctx, fmt.Sprintf("NETCONF commit failed: %v", err)) + // Still try to unlock even if commit fails + unlockErr := nc.Unlock(ctx, device, "candidate") + if unlockErr != nil { + tflog.Warn(ctx, fmt.Sprintf("Failed to unlock candidate datastore after commit error: %v", unlockErr)) + } + dev.CandidateLocked = false + return fmt.Errorf("NETCONF commit failed: %w", err) + } + + // Unlock the candidate datastore + tflog.Info(ctx, fmt.Sprintf("Unlocking candidate datastore for device: %s", device)) + unlockErr := nc.Unlock(ctx, device, "candidate") + if unlockErr != nil { + tflog.Warn(ctx, fmt.Sprintf("Failed to unlock candidate datastore: %v", unlockErr)) + } + dev.CandidateLocked = false + + tflog.Info(ctx, fmt.Sprintf("Successfully committed and unlocked configuration for device %s", device)) + return nil +} + +// GetWithPath performs NETCONF get-config with automatic path conversion and XML to JSON conversion +func (nc *NetconfClient) GetWithPath(ctx context.Context, device, path string) ([]byte, error) { + var err error + + tflog.Info(ctx, fmt.Sprintf("NETCONF GetWithPath starting for path: %s", path)) + tflog.Debug(ctx, fmt.Sprintf("netconf filter: %s", path)) + filter, err := helpers.GetNetconfXml(path, "get", "") + if err != nil { + return nil, fmt.Errorf("failed to build filter: %w", err) + } + tflog.Debug(ctx, fmt.Sprintf("netconf filter XML: %s", filter)) + + tflog.Info(ctx, "Executing NETCONF GetConfig operation...") + configData, err := nc.GetConfig(ctx, device, "running", filter) + if err != nil { + tflog.Error(ctx, fmt.Sprintf("NETCONF get-config failed: %v", err)) + return nil, fmt.Errorf("NETCONF get-config failed: %w", err) + } + tflog.Info(ctx, fmt.Sprintf("NETCONF GetConfig completed, received %s ", (configData))) + result, err := helpers.XMLToJSON(configData) + if err != nil { + fmt.Printf("Error: %v\n", err) + return nil, fmt.Errorf("NETCONF get-config failed: %w", err) + } + tflog.Debug(ctx, fmt.Sprintf("netconf filter result: %s", result)) + tflog.Info(ctx, "NETCONF GetWithPath completed successfully") + return []byte(result), nil +} + +// GetConfig retrieves configuration from a datastore +func (nc *NetconfClient) GetConfig(ctx context.Context, device, target, filter string) (string, error) { + operation := NetconfOperation{ + Type: NetconfGetConfig, + Target: target, + Filter: filter, + } + return nc.ExecuteRPC(ctx, device, operation) +} + +// EditConfig modifies configuration in a datastore +func (nc *NetconfClient) EditConfig(ctx context.Context, device, target, config string) error { + operation := NetconfOperation{ + Type: NetconfEditConfig, + Target: target, + Config: config, + } + _, err := nc.ExecuteRPC(ctx, device, operation) + return err +} + +// Commit commits pending changes +func (nc *NetconfClient) Commit(ctx context.Context, device string) error { + operation := NetconfOperation{ + Type: NetconfCommit, + } + _, err := nc.ExecuteRPC(ctx, device, operation) + return err +} + +// Lock locks a datastore +func (nc *NetconfClient) Lock(ctx context.Context, device, target string) error { + operation := NetconfOperation{ + Type: NetconfLock, + Target: target, + } + _, err := nc.ExecuteRPC(ctx, device, operation) + return err +} + +// Unlock unlocks a datastore +func (nc *NetconfClient) Unlock(ctx context.Context, device, target string) error { + operation := NetconfOperation{ + Type: NetconfUnlock, + Target: target, + } + _, err := nc.ExecuteRPC(ctx, device, operation) + return err +} + +// Close closes all NETCONF sessions +func (nc *NetconfClient) Close(ctx context.Context) { + for device, dev := range nc.Devices { + if dev.Driver != nil { + tflog.Debug(ctx, fmt.Sprintf("Closing NETCONF connection for device: %s", device)) + if err := dev.Driver.Close(); err != nil { + tflog.Warn(ctx, fmt.Sprintf("Failed to close NETCONF connection for device %s: %v", device, err)) + } + } + } +} + +// Set implements the Client interface for NETCONF by wrapping SetWithOperations +func (nc *NetconfClient) Set(ctx context.Context, device string, operations ...SetOperation) (bool, error) { + err := nc.SetWithOperations(ctx, device, operations...) + if err != nil { + return false, err + } + return true, nil +} + +// Get implements the Client interface for NETCONF +func (nc *NetconfClient) Get(ctx context.Context, device, path string) ([]byte, error) { + jsonData, err := nc.GetWithPath(ctx, device, path) + if err != nil { + return nil, err + } + + return jsonData, nil +} + +// GetProtocol returns the protocol type for this client +func (nc *NetconfClient) GetProtocol() ProtocolType { + return ProtocolNETCONF +} diff --git a/internal/provider/data_source_iosxr_as_path_set.go b/internal/provider/data_source_iosxr_as_path_set.go index a7ad755c..1262cf39 100644 --- a/internal/provider/data_source_iosxr_as_path_set.go +++ b/internal/provider/data_source_iosxr_as_path_set.go @@ -112,11 +112,11 @@ func (d *ASPathSetDataSource) Read(ctx context.Context, req datasource.ReadReque if device.Managed { getResp, err := d.data.Client.Get(ctx, config.Device.ValueString(), config.getPath()) if err != nil { - resp.Diagnostics.AddError("Unable to apply gNMI Get operation", err.Error()) + resp.Diagnostics.AddError("Unable to apply Get operation", err.Error()) return } - config.fromBody(ctx, getResp.Notification[0].Update[0].Val.GetJsonIetfVal()) + config.fromBody(ctx, getResp) } config.Id = types.StringValue(config.getPath()) diff --git a/internal/provider/data_source_iosxr_banner.go b/internal/provider/data_source_iosxr_banner.go index d0ef0d67..888c0d7e 100644 --- a/internal/provider/data_source_iosxr_banner.go +++ b/internal/provider/data_source_iosxr_banner.go @@ -112,11 +112,11 @@ func (d *BannerDataSource) Read(ctx context.Context, req datasource.ReadRequest, if device.Managed { getResp, err := d.data.Client.Get(ctx, config.Device.ValueString(), config.getPath()) if err != nil { - resp.Diagnostics.AddError("Unable to apply gNMI Get operation", err.Error()) + resp.Diagnostics.AddError("Unable to apply Get operation", err.Error()) return } - config.fromBody(ctx, getResp.Notification[0].Update[0].Val.GetJsonIetfVal()) + config.fromBody(ctx, getResp) } config.Id = types.StringValue(config.getPath()) diff --git a/internal/provider/data_source_iosxr_bfd.go b/internal/provider/data_source_iosxr_bfd.go index f2ed0775..743879e4 100644 --- a/internal/provider/data_source_iosxr_bfd.go +++ b/internal/provider/data_source_iosxr_bfd.go @@ -244,11 +244,11 @@ func (d *BFDDataSource) Read(ctx context.Context, req datasource.ReadRequest, re if device.Managed { getResp, err := d.data.Client.Get(ctx, config.Device.ValueString(), config.getPath()) if err != nil { - resp.Diagnostics.AddError("Unable to apply gNMI Get operation", err.Error()) + resp.Diagnostics.AddError("Unable to apply Get operation", err.Error()) return } - config.fromBody(ctx, getResp.Notification[0].Update[0].Val.GetJsonIetfVal()) + config.fromBody(ctx, getResp) } config.Id = types.StringValue(config.getPath()) diff --git a/internal/provider/data_source_iosxr_bgp_as_format.go b/internal/provider/data_source_iosxr_bgp_as_format.go index 37b2b769..8b8d0177 100644 --- a/internal/provider/data_source_iosxr_bgp_as_format.go +++ b/internal/provider/data_source_iosxr_bgp_as_format.go @@ -108,11 +108,11 @@ func (d *BGPASFormatDataSource) Read(ctx context.Context, req datasource.ReadReq if device.Managed { getResp, err := d.data.Client.Get(ctx, config.Device.ValueString(), config.getPath()) if err != nil { - resp.Diagnostics.AddError("Unable to apply gNMI Get operation", err.Error()) + resp.Diagnostics.AddError("Unable to apply Get operation", err.Error()) return } - config.fromBody(ctx, getResp.Notification[0].Update[0].Val.GetJsonIetfVal()) + config.fromBody(ctx, getResp) } config.Id = types.StringValue(config.getPath()) diff --git a/internal/provider/data_source_iosxr_cdp.go b/internal/provider/data_source_iosxr_cdp.go index 88459686..1c0b0c6c 100644 --- a/internal/provider/data_source_iosxr_cdp.go +++ b/internal/provider/data_source_iosxr_cdp.go @@ -124,11 +124,11 @@ func (d *CDPDataSource) Read(ctx context.Context, req datasource.ReadRequest, re if device.Managed { getResp, err := d.data.Client.Get(ctx, config.Device.ValueString(), config.getPath()) if err != nil { - resp.Diagnostics.AddError("Unable to apply gNMI Get operation", err.Error()) + resp.Diagnostics.AddError("Unable to apply Get operation", err.Error()) return } - config.fromBody(ctx, getResp.Notification[0].Update[0].Val.GetJsonIetfVal()) + config.fromBody(ctx, getResp) } config.Id = types.StringValue(config.getPath()) diff --git a/internal/provider/data_source_iosxr_class_map_qos.go b/internal/provider/data_source_iosxr_class_map_qos.go index fa9d45b5..cf10fd1c 100644 --- a/internal/provider/data_source_iosxr_class_map_qos.go +++ b/internal/provider/data_source_iosxr_class_map_qos.go @@ -136,11 +136,11 @@ func (d *ClassMapQoSDataSource) Read(ctx context.Context, req datasource.ReadReq if device.Managed { getResp, err := d.data.Client.Get(ctx, config.Device.ValueString(), config.getPath()) if err != nil { - resp.Diagnostics.AddError("Unable to apply gNMI Get operation", err.Error()) + resp.Diagnostics.AddError("Unable to apply Get operation", err.Error()) return } - config.fromBody(ctx, getResp.Notification[0].Update[0].Val.GetJsonIetfVal()) + config.fromBody(ctx, getResp) } config.Id = types.StringValue(config.getPath()) diff --git a/internal/provider/data_source_iosxr_community_set.go b/internal/provider/data_source_iosxr_community_set.go index 63419d1e..bec14571 100644 --- a/internal/provider/data_source_iosxr_community_set.go +++ b/internal/provider/data_source_iosxr_community_set.go @@ -112,11 +112,11 @@ func (d *CommunitySetDataSource) Read(ctx context.Context, req datasource.ReadRe if device.Managed { getResp, err := d.data.Client.Get(ctx, config.Device.ValueString(), config.getPath()) if err != nil { - resp.Diagnostics.AddError("Unable to apply gNMI Get operation", err.Error()) + resp.Diagnostics.AddError("Unable to apply Get operation", err.Error()) return } - config.fromBody(ctx, getResp.Notification[0].Update[0].Val.GetJsonIetfVal()) + config.fromBody(ctx, getResp) } config.Id = types.StringValue(config.getPath()) diff --git a/internal/provider/data_source_iosxr_domain.go b/internal/provider/data_source_iosxr_domain.go index 5b28e9a7..483eee9d 100644 --- a/internal/provider/data_source_iosxr_domain.go +++ b/internal/provider/data_source_iosxr_domain.go @@ -190,11 +190,11 @@ func (d *DomainDataSource) Read(ctx context.Context, req datasource.ReadRequest, if device.Managed { getResp, err := d.data.Client.Get(ctx, config.Device.ValueString(), config.getPath()) if err != nil { - resp.Diagnostics.AddError("Unable to apply gNMI Get operation", err.Error()) + resp.Diagnostics.AddError("Unable to apply Get operation", err.Error()) return } - config.fromBody(ctx, getResp.Notification[0].Update[0].Val.GetJsonIetfVal()) + config.fromBody(ctx, getResp) } config.Id = types.StringValue(config.getPath()) diff --git a/internal/provider/data_source_iosxr_domain_test.go b/internal/provider/data_source_iosxr_domain_test.go index c33aa08c..8e120b41 100644 --- a/internal/provider/data_source_iosxr_domain_test.go +++ b/internal/provider/data_source_iosxr_domain_test.go @@ -32,18 +32,18 @@ import ( func TestAccDataSourceIosxrDomain(t *testing.T) { var checks []resource.TestCheckFunc - checks = append(checks, resource.TestCheckResourceAttr("data.iosxr_domain.test", "domains.0.domain_name", "example.com")) + checks = append(checks, resource.TestCheckResourceAttr("data.iosxr_domain.test", "domains.0.domain_name", "DOMAIN1")) checks = append(checks, resource.TestCheckResourceAttr("data.iosxr_domain.test", "domains.0.order", "0")) checks = append(checks, resource.TestCheckResourceAttr("data.iosxr_domain.test", "lookup_disable", "true")) checks = append(checks, resource.TestCheckResourceAttr("data.iosxr_domain.test", "lookup_source_interface", "Loopback214")) - checks = append(checks, resource.TestCheckResourceAttr("data.iosxr_domain.test", "name", "cisco.com")) - checks = append(checks, resource.TestCheckResourceAttr("data.iosxr_domain.test", "ipv4_hosts.0.host_name", "HOST_NAME_IPV4")) - checks = append(checks, resource.TestCheckResourceAttr("data.iosxr_domain.test", "ipv4_hosts.0.ip_address.0", "10.0.0.10")) + checks = append(checks, resource.TestCheckResourceAttr("data.iosxr_domain.test", "name", "DOMAIN")) + checks = append(checks, resource.TestCheckResourceAttr("data.iosxr_domain.test", "ipv4_hosts.0.host_name", "HOST_NAME")) + checks = append(checks, resource.TestCheckResourceAttr("data.iosxr_domain.test", "ipv4_hosts.0.ip_address.0", "10.0.0.0")) checks = append(checks, resource.TestCheckResourceAttr("data.iosxr_domain.test", "name_servers.0.address", "10.0.0.1")) checks = append(checks, resource.TestCheckResourceAttr("data.iosxr_domain.test", "name_servers.0.order", "345")) checks = append(checks, resource.TestCheckResourceAttr("data.iosxr_domain.test", "ipv6_hosts.0.host_name", "HOST_NAME_IPV6")) checks = append(checks, resource.TestCheckResourceAttr("data.iosxr_domain.test", "ipv6_hosts.0.ipv6_address.0", "10::10")) - checks = append(checks, resource.TestCheckResourceAttr("data.iosxr_domain.test", "multicast", "multicast.cisco.com")) + checks = append(checks, resource.TestCheckResourceAttr("data.iosxr_domain.test", "multicast", "DOMAIN1_ACC")) checks = append(checks, resource.TestCheckResourceAttr("data.iosxr_domain.test", "default_flows_disable", "true")) resource.Test(t, resource.TestCase{ PreCheck: func() { testAccPreCheck(t) }, @@ -69,15 +69,15 @@ func testAccDataSourceIosxrDomainConfig() string { config := `resource "iosxr_domain" "test" {` + "\n" config += ` delete_mode = "attributes"` + "\n" config += ` domains = [{` + "\n" - config += ` domain_name = "example.com"` + "\n" + config += ` domain_name = "DOMAIN1"` + "\n" config += ` order = 0` + "\n" config += ` }]` + "\n" config += ` lookup_disable = true` + "\n" config += ` lookup_source_interface = "Loopback214"` + "\n" - config += ` name = "cisco.com"` + "\n" + config += ` name = "DOMAIN"` + "\n" config += ` ipv4_hosts = [{` + "\n" - config += ` host_name = "HOST_NAME_IPV4"` + "\n" - config += ` ip_address = ["10.0.0.10"]` + "\n" + config += ` host_name = "HOST_NAME"` + "\n" + config += ` ip_address = ["10.0.0.0"]` + "\n" config += ` }]` + "\n" config += ` name_servers = [{` + "\n" config += ` address = "10.0.0.1"` + "\n" @@ -87,7 +87,7 @@ func testAccDataSourceIosxrDomainConfig() string { config += ` host_name = "HOST_NAME_IPV6"` + "\n" config += ` ipv6_address = ["10::10"]` + "\n" config += ` }]` + "\n" - config += ` multicast = "multicast.cisco.com"` + "\n" + config += ` multicast = "DOMAIN1_ACC"` + "\n" config += ` default_flows_disable = true` + "\n" config += `}` + "\n" diff --git a/internal/provider/data_source_iosxr_domain_vrf.go b/internal/provider/data_source_iosxr_domain_vrf.go index e42f4cd8..204b90d7 100644 --- a/internal/provider/data_source_iosxr_domain_vrf.go +++ b/internal/provider/data_source_iosxr_domain_vrf.go @@ -190,11 +190,11 @@ func (d *DomainVRFDataSource) Read(ctx context.Context, req datasource.ReadReque if device.Managed { getResp, err := d.data.Client.Get(ctx, config.Device.ValueString(), config.getPath()) if err != nil { - resp.Diagnostics.AddError("Unable to apply gNMI Get operation", err.Error()) + resp.Diagnostics.AddError("Unable to apply Get operation", err.Error()) return } - config.fromBody(ctx, getResp.Notification[0].Update[0].Val.GetJsonIetfVal()) + config.fromBody(ctx, getResp) } config.Id = types.StringValue(config.getPath()) diff --git a/internal/provider/data_source_iosxr_error_disable_recovery.go b/internal/provider/data_source_iosxr_error_disable_recovery.go index 532c9a21..20e7cda7 100644 --- a/internal/provider/data_source_iosxr_error_disable_recovery.go +++ b/internal/provider/data_source_iosxr_error_disable_recovery.go @@ -184,11 +184,11 @@ func (d *ErrorDisableRecoveryDataSource) Read(ctx context.Context, req datasourc if device.Managed { getResp, err := d.data.Client.Get(ctx, config.Device.ValueString(), config.getPath()) if err != nil { - resp.Diagnostics.AddError("Unable to apply gNMI Get operation", err.Error()) + resp.Diagnostics.AddError("Unable to apply Get operation", err.Error()) return } - config.fromBody(ctx, getResp.Notification[0].Update[0].Val.GetJsonIetfVal()) + config.fromBody(ctx, getResp) } config.Id = types.StringValue(config.getPath()) diff --git a/internal/provider/data_source_iosxr_esi_set.go b/internal/provider/data_source_iosxr_esi_set.go index bd65c592..79ed7ee4 100644 --- a/internal/provider/data_source_iosxr_esi_set.go +++ b/internal/provider/data_source_iosxr_esi_set.go @@ -112,11 +112,11 @@ func (d *ESISetDataSource) Read(ctx context.Context, req datasource.ReadRequest, if device.Managed { getResp, err := d.data.Client.Get(ctx, config.Device.ValueString(), config.getPath()) if err != nil { - resp.Diagnostics.AddError("Unable to apply gNMI Get operation", err.Error()) + resp.Diagnostics.AddError("Unable to apply Get operation", err.Error()) return } - config.fromBody(ctx, getResp.Notification[0].Update[0].Val.GetJsonIetfVal()) + config.fromBody(ctx, getResp) } config.Id = types.StringValue(config.getPath()) diff --git a/internal/provider/data_source_iosxr_evpn.go b/internal/provider/data_source_iosxr_evpn.go index ee14c839..e4630d22 100644 --- a/internal/provider/data_source_iosxr_evpn.go +++ b/internal/provider/data_source_iosxr_evpn.go @@ -152,11 +152,11 @@ func (d *EVPNDataSource) Read(ctx context.Context, req datasource.ReadRequest, r if device.Managed { getResp, err := d.data.Client.Get(ctx, config.Device.ValueString(), config.getPath()) if err != nil { - resp.Diagnostics.AddError("Unable to apply gNMI Get operation", err.Error()) + resp.Diagnostics.AddError("Unable to apply Get operation", err.Error()) return } - config.fromBody(ctx, getResp.Notification[0].Update[0].Val.GetJsonIetfVal()) + config.fromBody(ctx, getResp) } config.Id = types.StringValue(config.getPath()) diff --git a/internal/provider/data_source_iosxr_evpn_evi.go b/internal/provider/data_source_iosxr_evpn_evi.go index d78f51af..afff158c 100644 --- a/internal/provider/data_source_iosxr_evpn_evi.go +++ b/internal/provider/data_source_iosxr_evpn_evi.go @@ -272,11 +272,11 @@ func (d *EVPNEVIDataSource) Read(ctx context.Context, req datasource.ReadRequest if device.Managed { getResp, err := d.data.Client.Get(ctx, config.Device.ValueString(), config.getPath()) if err != nil { - resp.Diagnostics.AddError("Unable to apply gNMI Get operation", err.Error()) + resp.Diagnostics.AddError("Unable to apply Get operation", err.Error()) return } - config.fromBody(ctx, getResp.Notification[0].Update[0].Val.GetJsonIetfVal()) + config.fromBody(ctx, getResp) } config.Id = types.StringValue(config.getPath()) diff --git a/internal/provider/data_source_iosxr_evpn_group.go b/internal/provider/data_source_iosxr_evpn_group.go index e90fc9bc..c07cf3f2 100644 --- a/internal/provider/data_source_iosxr_evpn_group.go +++ b/internal/provider/data_source_iosxr_evpn_group.go @@ -120,11 +120,11 @@ func (d *EVPNGroupDataSource) Read(ctx context.Context, req datasource.ReadReque if device.Managed { getResp, err := d.data.Client.Get(ctx, config.Device.ValueString(), config.getPath()) if err != nil { - resp.Diagnostics.AddError("Unable to apply gNMI Get operation", err.Error()) + resp.Diagnostics.AddError("Unable to apply Get operation", err.Error()) return } - config.fromBody(ctx, getResp.Notification[0].Update[0].Val.GetJsonIetfVal()) + config.fromBody(ctx, getResp) } config.Id = types.StringValue(config.getPath()) diff --git a/internal/provider/data_source_iosxr_evpn_interface.go b/internal/provider/data_source_iosxr_evpn_interface.go index 94907a54..89062467 100644 --- a/internal/provider/data_source_iosxr_evpn_interface.go +++ b/internal/provider/data_source_iosxr_evpn_interface.go @@ -132,11 +132,11 @@ func (d *EVPNInterfaceDataSource) Read(ctx context.Context, req datasource.ReadR if device.Managed { getResp, err := d.data.Client.Get(ctx, config.Device.ValueString(), config.getPath()) if err != nil { - resp.Diagnostics.AddError("Unable to apply gNMI Get operation", err.Error()) + resp.Diagnostics.AddError("Unable to apply Get operation", err.Error()) return } - config.fromBody(ctx, getResp.Notification[0].Update[0].Val.GetJsonIetfVal()) + config.fromBody(ctx, getResp) } config.Id = types.StringValue(config.getPath()) diff --git a/internal/provider/data_source_iosxr_evpn_segment_routing_srv6_evi.go b/internal/provider/data_source_iosxr_evpn_segment_routing_srv6_evi.go index 898a1b5f..48883677 100644 --- a/internal/provider/data_source_iosxr_evpn_segment_routing_srv6_evi.go +++ b/internal/provider/data_source_iosxr_evpn_segment_routing_srv6_evi.go @@ -228,11 +228,11 @@ func (d *EVPNSegmentRoutingSRv6EVIDataSource) Read(ctx context.Context, req data if device.Managed { getResp, err := d.data.Client.Get(ctx, config.Device.ValueString(), config.getPath()) if err != nil { - resp.Diagnostics.AddError("Unable to apply gNMI Get operation", err.Error()) + resp.Diagnostics.AddError("Unable to apply Get operation", err.Error()) return } - config.fromBody(ctx, getResp.Notification[0].Update[0].Val.GetJsonIetfVal()) + config.fromBody(ctx, getResp) } config.Id = types.StringValue(config.getPath()) diff --git a/internal/provider/data_source_iosxr_extcommunity_cost_set.go b/internal/provider/data_source_iosxr_extcommunity_cost_set.go index 0194a408..9ebb82ec 100644 --- a/internal/provider/data_source_iosxr_extcommunity_cost_set.go +++ b/internal/provider/data_source_iosxr_extcommunity_cost_set.go @@ -112,11 +112,11 @@ func (d *ExtcommunityCostSetDataSource) Read(ctx context.Context, req datasource if device.Managed { getResp, err := d.data.Client.Get(ctx, config.Device.ValueString(), config.getPath()) if err != nil { - resp.Diagnostics.AddError("Unable to apply gNMI Get operation", err.Error()) + resp.Diagnostics.AddError("Unable to apply Get operation", err.Error()) return } - config.fromBody(ctx, getResp.Notification[0].Update[0].Val.GetJsonIetfVal()) + config.fromBody(ctx, getResp) } config.Id = types.StringValue(config.getPath()) diff --git a/internal/provider/data_source_iosxr_extcommunity_opaque_set.go b/internal/provider/data_source_iosxr_extcommunity_opaque_set.go index e12bb397..e16b490a 100644 --- a/internal/provider/data_source_iosxr_extcommunity_opaque_set.go +++ b/internal/provider/data_source_iosxr_extcommunity_opaque_set.go @@ -112,11 +112,11 @@ func (d *ExtcommunityOpaqueSetDataSource) Read(ctx context.Context, req datasour if device.Managed { getResp, err := d.data.Client.Get(ctx, config.Device.ValueString(), config.getPath()) if err != nil { - resp.Diagnostics.AddError("Unable to apply gNMI Get operation", err.Error()) + resp.Diagnostics.AddError("Unable to apply Get operation", err.Error()) return } - config.fromBody(ctx, getResp.Notification[0].Update[0].Val.GetJsonIetfVal()) + config.fromBody(ctx, getResp) } config.Id = types.StringValue(config.getPath()) diff --git a/internal/provider/data_source_iosxr_extcommunity_rt_set.go b/internal/provider/data_source_iosxr_extcommunity_rt_set.go index cc5aa909..f70679c9 100644 --- a/internal/provider/data_source_iosxr_extcommunity_rt_set.go +++ b/internal/provider/data_source_iosxr_extcommunity_rt_set.go @@ -112,11 +112,11 @@ func (d *ExtcommunityRTSetDataSource) Read(ctx context.Context, req datasource.R if device.Managed { getResp, err := d.data.Client.Get(ctx, config.Device.ValueString(), config.getPath()) if err != nil { - resp.Diagnostics.AddError("Unable to apply gNMI Get operation", err.Error()) + resp.Diagnostics.AddError("Unable to apply Get operation", err.Error()) return } - config.fromBody(ctx, getResp.Notification[0].Update[0].Val.GetJsonIetfVal()) + config.fromBody(ctx, getResp) } config.Id = types.StringValue(config.getPath()) diff --git a/internal/provider/data_source_iosxr_extcommunity_soo_set.go b/internal/provider/data_source_iosxr_extcommunity_soo_set.go index 74a0eceb..70dd485f 100644 --- a/internal/provider/data_source_iosxr_extcommunity_soo_set.go +++ b/internal/provider/data_source_iosxr_extcommunity_soo_set.go @@ -112,11 +112,11 @@ func (d *ExtcommunitySOOSetDataSource) Read(ctx context.Context, req datasource. if device.Managed { getResp, err := d.data.Client.Get(ctx, config.Device.ValueString(), config.getPath()) if err != nil { - resp.Diagnostics.AddError("Unable to apply gNMI Get operation", err.Error()) + resp.Diagnostics.AddError("Unable to apply Get operation", err.Error()) return } - config.fromBody(ctx, getResp.Notification[0].Update[0].Val.GetJsonIetfVal()) + config.fromBody(ctx, getResp) } config.Id = types.StringValue(config.getPath()) diff --git a/internal/provider/data_source_iosxr_flow_exporter_map.go b/internal/provider/data_source_iosxr_flow_exporter_map.go index a2121fa0..a6a9ee83 100644 --- a/internal/provider/data_source_iosxr_flow_exporter_map.go +++ b/internal/provider/data_source_iosxr_flow_exporter_map.go @@ -172,11 +172,11 @@ func (d *FlowExporterMapDataSource) Read(ctx context.Context, req datasource.Rea if device.Managed { getResp, err := d.data.Client.Get(ctx, config.Device.ValueString(), config.getPath()) if err != nil { - resp.Diagnostics.AddError("Unable to apply gNMI Get operation", err.Error()) + resp.Diagnostics.AddError("Unable to apply Get operation", err.Error()) return } - config.fromBody(ctx, getResp.Notification[0].Update[0].Val.GetJsonIetfVal()) + config.fromBody(ctx, getResp) } config.Id = types.StringValue(config.getPath()) diff --git a/internal/provider/data_source_iosxr_flow_exporter_map_test.go b/internal/provider/data_source_iosxr_flow_exporter_map_test.go index b68043eb..56e7d6a8 100644 --- a/internal/provider/data_source_iosxr_flow_exporter_map_test.go +++ b/internal/provider/data_source_iosxr_flow_exporter_map_test.go @@ -32,11 +32,12 @@ import ( // Section below is generated&owned by "gen/generator.go". //template:begin testAccDataSource func TestAccDataSourceIosxrFlowExporterMap(t *testing.T) { - if os.Getenv("NCS") == "" { - t.Skip("skipping test, set environment variable NCS") + if os.Getenv("PHYSICAL") == "" { + t.Skip("skipping test, set environment variable PHYSICAL") } var checks []resource.TestCheckFunc - checks = append(checks, resource.TestCheckResourceAttr("data.iosxr_flow_exporter_map.test", "destination_ipv4_address", "192.0.2.1")) + checks = append(checks, resource.TestCheckResourceAttr("data.iosxr_flow_exporter_map.test", "destination_ipv4_address", "10.1.1.1")) + checks = append(checks, resource.TestCheckResourceAttr("data.iosxr_flow_exporter_map.test", "destination_ipv6_address", "1::1")) checks = append(checks, resource.TestCheckResourceAttr("data.iosxr_flow_exporter_map.test", "destination_vrf", "VRF1")) checks = append(checks, resource.TestCheckResourceAttr("data.iosxr_flow_exporter_map.test", "source", "GigabitEthernet0/0/0/1")) checks = append(checks, resource.TestCheckResourceAttr("data.iosxr_flow_exporter_map.test", "dscp", "62")) @@ -56,7 +57,7 @@ func TestAccDataSourceIosxrFlowExporterMap(t *testing.T) { ProtoV6ProviderFactories: testAccProtoV6ProviderFactories, Steps: []resource.TestStep{ { - Config: testAccDataSourceIosxrFlowExporterMapPrerequisitesConfig + testAccDataSourceIosxrFlowExporterMapConfig(), + Config: testAccDataSourceIosxrFlowExporterMapConfig(), Check: resource.ComposeTestCheckFunc(checks...), }, }, @@ -66,15 +67,6 @@ func TestAccDataSourceIosxrFlowExporterMap(t *testing.T) { // End of section. //template:end testAccDataSource // Section below is generated&owned by "gen/generator.go". //template:begin testPrerequisites -const testAccDataSourceIosxrFlowExporterMapPrerequisitesConfig = ` -resource "iosxr_gnmi" "PreReq0" { - path = "Cisco-IOS-XR-um-vrf-cfg:/vrfs/vrf[vrf-name=VRF1]" - attributes = { - "vrf-name" = "VRF1" - } -} - -` // End of section. //template:end testPrerequisites @@ -82,8 +74,9 @@ resource "iosxr_gnmi" "PreReq0" { func testAccDataSourceIosxrFlowExporterMapConfig() string { config := `resource "iosxr_flow_exporter_map" "test" {` + "\n" - config += ` name = "exporter_map1"` + "\n" - config += ` destination_ipv4_address = "192.0.2.1"` + "\n" + config += ` name = "TEST"` + "\n" + config += ` destination_ipv4_address = "10.1.1.1"` + "\n" + config += ` destination_ipv6_address = "1::1"` + "\n" config += ` destination_vrf = "VRF1"` + "\n" config += ` source = "GigabitEthernet0/0/0/1"` + "\n" config += ` dscp = 62` + "\n" @@ -98,12 +91,11 @@ func testAccDataSourceIosxrFlowExporterMapConfig() string { config += ` version_options_sampler_table_timeout = 4096` + "\n" config += ` version_options_class_table_timeout = 255` + "\n" config += ` version_options_vrf_table_timeout = 122` + "\n" - config += ` depends_on = [iosxr_gnmi.PreReq0, ]` + "\n" config += `}` + "\n" config += ` data "iosxr_flow_exporter_map" "test" { - name = "exporter_map1" + name = "TEST" depends_on = [iosxr_flow_exporter_map.test] } ` diff --git a/internal/provider/data_source_iosxr_flow_monitor_map.go b/internal/provider/data_source_iosxr_flow_monitor_map.go index d78deed9..76967120 100644 --- a/internal/provider/data_source_iosxr_flow_monitor_map.go +++ b/internal/provider/data_source_iosxr_flow_monitor_map.go @@ -167,14 +167,6 @@ func (d *FlowMonitorMapDataSource) Schema(ctx context.Context, req datasource.Sc MarkdownDescription: "IPV4 gtp record format", Computed: true, }, - "record_ipv4_l2_l3": schema.BoolAttribute{ - MarkdownDescription: "IPv4 record with Layer2 details", - Computed: true, - }, - "record_ipv4_extended": schema.BoolAttribute{ - MarkdownDescription: "IPv4 record with extended details", - Computed: true, - }, "record_ipv6": schema.BoolAttribute{ MarkdownDescription: "IPv6 raw record format", Computed: true, @@ -191,18 +183,6 @@ func (d *FlowMonitorMapDataSource) Schema(ctx context.Context, req datasource.Sc MarkdownDescription: "IPV6 gtp record format", Computed: true, }, - "record_ipv6_srv6": schema.BoolAttribute{ - MarkdownDescription: "SRv6 record format", - Computed: true, - }, - "record_ipv6_l2_l3": schema.BoolAttribute{ - MarkdownDescription: "IPv6 record with Layer2 details", - Computed: true, - }, - "record_ipv6_extended": schema.BoolAttribute{ - MarkdownDescription: "IPv6 record with extended details", - Computed: true, - }, "record_mpls": schema.BoolAttribute{ MarkdownDescription: "MPLS record format", Computed: true, @@ -348,11 +328,11 @@ func (d *FlowMonitorMapDataSource) Read(ctx context.Context, req datasource.Read if device.Managed { getResp, err := d.data.Client.Get(ctx, config.Device.ValueString(), config.getPath()) if err != nil { - resp.Diagnostics.AddError("Unable to apply gNMI Get operation", err.Error()) + resp.Diagnostics.AddError("Unable to apply Get operation", err.Error()) return } - config.fromBody(ctx, getResp.Notification[0].Update[0].Val.GetJsonIetfVal()) + config.fromBody(ctx, getResp) } config.Id = types.StringValue(config.getPath()) diff --git a/internal/provider/data_source_iosxr_flow_monitor_map_test.go b/internal/provider/data_source_iosxr_flow_monitor_map_test.go index 0fd99c0f..26231da6 100644 --- a/internal/provider/data_source_iosxr_flow_monitor_map_test.go +++ b/internal/provider/data_source_iosxr_flow_monitor_map_test.go @@ -32,21 +32,52 @@ import ( // Section below is generated&owned by "gen/generator.go". //template:begin testAccDataSource func TestAccDataSourceIosxrFlowMonitorMap(t *testing.T) { - if os.Getenv("NCS") == "" { - t.Skip("skipping test, set environment variable NCS") + if os.Getenv("PHYSICAL") == "" { + t.Skip("skipping test, set environment variable PHYSICAL") } var checks []resource.TestCheckFunc - checks = append(checks, resource.TestCheckResourceAttr("data.iosxr_flow_monitor_map.test", "exporters.0.name", "exporter_map1")) + checks = append(checks, resource.TestCheckResourceAttr("data.iosxr_flow_monitor_map.test", "exporters.0.name", "exporter1")) checks = append(checks, resource.TestCheckResourceAttr("data.iosxr_flow_monitor_map.test", "option_outphysint", "true")) checks = append(checks, resource.TestCheckResourceAttr("data.iosxr_flow_monitor_map.test", "option_filtered", "true")) checks = append(checks, resource.TestCheckResourceAttr("data.iosxr_flow_monitor_map.test", "option_bgpattr", "true")) checks = append(checks, resource.TestCheckResourceAttr("data.iosxr_flow_monitor_map.test", "option_outbundlemember", "true")) + checks = append(checks, resource.TestCheckResourceAttr("data.iosxr_flow_monitor_map.test", "record_ipv4", "true")) + checks = append(checks, resource.TestCheckResourceAttr("data.iosxr_flow_monitor_map.test", "record_ipv4_destination", "true")) + checks = append(checks, resource.TestCheckResourceAttr("data.iosxr_flow_monitor_map.test", "record_ipv4_destination_tos", "true")) + checks = append(checks, resource.TestCheckResourceAttr("data.iosxr_flow_monitor_map.test", "record_ipv4_as", "true")) + checks = append(checks, resource.TestCheckResourceAttr("data.iosxr_flow_monitor_map.test", "record_ipv4_protocol_port", "true")) + checks = append(checks, resource.TestCheckResourceAttr("data.iosxr_flow_monitor_map.test", "record_ipv4_prefix", "true")) + checks = append(checks, resource.TestCheckResourceAttr("data.iosxr_flow_monitor_map.test", "record_ipv4_source_prefix", "true")) + checks = append(checks, resource.TestCheckResourceAttr("data.iosxr_flow_monitor_map.test", "record_ipv4_destination_prefix", "true")) + checks = append(checks, resource.TestCheckResourceAttr("data.iosxr_flow_monitor_map.test", "record_ipv4_as_tos", "true")) + checks = append(checks, resource.TestCheckResourceAttr("data.iosxr_flow_monitor_map.test", "record_ipv4_protocol_port_tos", "true")) + checks = append(checks, resource.TestCheckResourceAttr("data.iosxr_flow_monitor_map.test", "record_ipv4_prefix_tos", "true")) + checks = append(checks, resource.TestCheckResourceAttr("data.iosxr_flow_monitor_map.test", "record_ipv4_source_prefix_tos", "true")) + checks = append(checks, resource.TestCheckResourceAttr("data.iosxr_flow_monitor_map.test", "record_ipv4_destination_prefix_tos", "true")) + checks = append(checks, resource.TestCheckResourceAttr("data.iosxr_flow_monitor_map.test", "record_ipv4_prefix_port", "true")) + checks = append(checks, resource.TestCheckResourceAttr("data.iosxr_flow_monitor_map.test", "record_ipv4_bgp_nexthop_tos", "true")) + checks = append(checks, resource.TestCheckResourceAttr("data.iosxr_flow_monitor_map.test", "record_ipv4_peer_as", "true")) + checks = append(checks, resource.TestCheckResourceAttr("data.iosxr_flow_monitor_map.test", "record_ipv4_gtp", "true")) + checks = append(checks, resource.TestCheckResourceAttr("data.iosxr_flow_monitor_map.test", "record_ipv6", "true")) + checks = append(checks, resource.TestCheckResourceAttr("data.iosxr_flow_monitor_map.test", "record_ipv6_destination", "true")) + checks = append(checks, resource.TestCheckResourceAttr("data.iosxr_flow_monitor_map.test", "record_ipv6_peer_as", "true")) + checks = append(checks, resource.TestCheckResourceAttr("data.iosxr_flow_monitor_map.test", "record_ipv6_gtp", "true")) + checks = append(checks, resource.TestCheckResourceAttr("data.iosxr_flow_monitor_map.test", "record_mpls", "true")) + checks = append(checks, resource.TestCheckResourceAttr("data.iosxr_flow_monitor_map.test", "record_mpls_ipv4_fields", "true")) + checks = append(checks, resource.TestCheckResourceAttr("data.iosxr_flow_monitor_map.test", "record_mpls_ipv6_fields", "true")) + checks = append(checks, resource.TestCheckResourceAttr("data.iosxr_flow_monitor_map.test", "record_mpls_ipv4_ipv6_fields", "true")) checks = append(checks, resource.TestCheckResourceAttr("data.iosxr_flow_monitor_map.test", "record_mpls_labels", "2")) + checks = append(checks, resource.TestCheckResourceAttr("data.iosxr_flow_monitor_map.test", "record_map_t", "true")) + checks = append(checks, resource.TestCheckResourceAttr("data.iosxr_flow_monitor_map.test", "record_sflow", "true")) + checks = append(checks, resource.TestCheckResourceAttr("data.iosxr_flow_monitor_map.test", "record_datalink_record", "true")) + checks = append(checks, resource.TestCheckResourceAttr("data.iosxr_flow_monitor_map.test", "record_default_rtp", "true")) + checks = append(checks, resource.TestCheckResourceAttr("data.iosxr_flow_monitor_map.test", "record_default_mdi", "true")) checks = append(checks, resource.TestCheckResourceAttr("data.iosxr_flow_monitor_map.test", "cache_entries", "5000")) checks = append(checks, resource.TestCheckResourceAttr("data.iosxr_flow_monitor_map.test", "cache_timeout_active", "1")) checks = append(checks, resource.TestCheckResourceAttr("data.iosxr_flow_monitor_map.test", "cache_timeout_inactive", "0")) checks = append(checks, resource.TestCheckResourceAttr("data.iosxr_flow_monitor_map.test", "cache_timeout_update", "1")) checks = append(checks, resource.TestCheckResourceAttr("data.iosxr_flow_monitor_map.test", "cache_timeout_rate_limit", "5000")) + checks = append(checks, resource.TestCheckResourceAttr("data.iosxr_flow_monitor_map.test", "cache_permanent", "true")) checks = append(checks, resource.TestCheckResourceAttr("data.iosxr_flow_monitor_map.test", "cache_immediate", "true")) checks = append(checks, resource.TestCheckResourceAttr("data.iosxr_flow_monitor_map.test", "hw_cache_timeout_inactive", "50")) checks = append(checks, resource.TestCheckResourceAttr("data.iosxr_flow_monitor_map.test", "sflow_options", "true")) @@ -63,7 +94,7 @@ func TestAccDataSourceIosxrFlowMonitorMap(t *testing.T) { ProtoV6ProviderFactories: testAccProtoV6ProviderFactories, Steps: []resource.TestStep{ { - Config: testAccDataSourceIosxrFlowMonitorMapPrerequisitesConfig + testAccDataSourceIosxrFlowMonitorMapConfig(), + Config: testAccDataSourceIosxrFlowMonitorMapConfig(), Check: resource.ComposeTestCheckFunc(checks...), }, }, @@ -73,15 +104,6 @@ func TestAccDataSourceIosxrFlowMonitorMap(t *testing.T) { // End of section. //template:end testAccDataSource // Section below is generated&owned by "gen/generator.go". //template:begin testPrerequisites -const testAccDataSourceIosxrFlowMonitorMapPrerequisitesConfig = ` -resource "iosxr_gnmi" "PreReq0" { - path = "Cisco-IOS-XR-um-flow-cfg:/flow/exporter-maps/exporter-map[exporter-map-name=exporter_map1]" - attributes = { - "exporter-map-name" = "exporter_map1" - } -} - -` // End of section. //template:end testPrerequisites @@ -91,18 +113,49 @@ func testAccDataSourceIosxrFlowMonitorMapConfig() string { config := `resource "iosxr_flow_monitor_map" "test" {` + "\n" config += ` name = "monitor_map1"` + "\n" config += ` exporters = [{` + "\n" - config += ` name = "exporter_map1"` + "\n" + config += ` name = "exporter1"` + "\n" config += ` }]` + "\n" config += ` option_outphysint = true` + "\n" config += ` option_filtered = true` + "\n" config += ` option_bgpattr = true` + "\n" config += ` option_outbundlemember = true` + "\n" + config += ` record_ipv4 = true` + "\n" + config += ` record_ipv4_destination = true` + "\n" + config += ` record_ipv4_destination_tos = true` + "\n" + config += ` record_ipv4_as = true` + "\n" + config += ` record_ipv4_protocol_port = true` + "\n" + config += ` record_ipv4_prefix = true` + "\n" + config += ` record_ipv4_source_prefix = true` + "\n" + config += ` record_ipv4_destination_prefix = true` + "\n" + config += ` record_ipv4_as_tos = true` + "\n" + config += ` record_ipv4_protocol_port_tos = true` + "\n" + config += ` record_ipv4_prefix_tos = true` + "\n" + config += ` record_ipv4_source_prefix_tos = true` + "\n" + config += ` record_ipv4_destination_prefix_tos = true` + "\n" + config += ` record_ipv4_prefix_port = true` + "\n" + config += ` record_ipv4_bgp_nexthop_tos = true` + "\n" + config += ` record_ipv4_peer_as = true` + "\n" + config += ` record_ipv4_gtp = true` + "\n" + config += ` record_ipv6 = true` + "\n" + config += ` record_ipv6_destination = true` + "\n" + config += ` record_ipv6_peer_as = true` + "\n" + config += ` record_ipv6_gtp = true` + "\n" + config += ` record_mpls = true` + "\n" + config += ` record_mpls_ipv4_fields = true` + "\n" + config += ` record_mpls_ipv6_fields = true` + "\n" + config += ` record_mpls_ipv4_ipv6_fields = true` + "\n" config += ` record_mpls_labels = 2` + "\n" + config += ` record_map_t = true` + "\n" + config += ` record_sflow = true` + "\n" + config += ` record_datalink_record = true` + "\n" + config += ` record_default_rtp = true` + "\n" + config += ` record_default_mdi = true` + "\n" config += ` cache_entries = 5000` + "\n" config += ` cache_timeout_active = 1` + "\n" config += ` cache_timeout_inactive = 0` + "\n" config += ` cache_timeout_update = 1` + "\n" config += ` cache_timeout_rate_limit = 5000` + "\n" + config += ` cache_permanent = true` + "\n" config += ` cache_immediate = true` + "\n" config += ` hw_cache_timeout_inactive = 50` + "\n" config += ` sflow_options = true` + "\n" @@ -114,7 +167,6 @@ func testAccDataSourceIosxrFlowMonitorMapConfig() string { config += ` sflow_options_sample_header_size = 128` + "\n" config += ` sflow_options_input_ifindex = "physical"` + "\n" config += ` sflow_options_output_ifindex = "physical"` + "\n" - config += ` depends_on = [iosxr_gnmi.PreReq0, ]` + "\n" config += `}` + "\n" config += ` diff --git a/internal/provider/data_source_iosxr_flow_sampler_map.go b/internal/provider/data_source_iosxr_flow_sampler_map.go index ef05e7e9..caefd5f1 100644 --- a/internal/provider/data_source_iosxr_flow_sampler_map.go +++ b/internal/provider/data_source_iosxr_flow_sampler_map.go @@ -116,11 +116,11 @@ func (d *FlowSamplerMapDataSource) Read(ctx context.Context, req datasource.Read if device.Managed { getResp, err := d.data.Client.Get(ctx, config.Device.ValueString(), config.getPath()) if err != nil { - resp.Diagnostics.AddError("Unable to apply gNMI Get operation", err.Error()) + resp.Diagnostics.AddError("Unable to apply Get operation", err.Error()) return } - config.fromBody(ctx, getResp.Notification[0].Update[0].Val.GetJsonIetfVal()) + config.fromBody(ctx, getResp) } config.Id = types.StringValue(config.getPath()) diff --git a/internal/provider/data_source_iosxr_flow_sampler_map_test.go b/internal/provider/data_source_iosxr_flow_sampler_map_test.go index c5434565..abb71244 100644 --- a/internal/provider/data_source_iosxr_flow_sampler_map_test.go +++ b/internal/provider/data_source_iosxr_flow_sampler_map_test.go @@ -32,8 +32,8 @@ import ( // Section below is generated&owned by "gen/generator.go". //template:begin testAccDataSource func TestAccDataSourceIosxrFlowSamplerMap(t *testing.T) { - if os.Getenv("NCS") == "" { - t.Skip("skipping test, set environment variable NCS") + if os.Getenv("PHYSICAL") == "" { + t.Skip("skipping test, set environment variable PHYSICAL") } var checks []resource.TestCheckFunc checks = append(checks, resource.TestCheckResourceAttr("data.iosxr_flow_sampler_map.test", "random", "1")) diff --git a/internal/provider/data_source_iosxr_fpd.go b/internal/provider/data_source_iosxr_fpd.go index 8d8b3b39..39f8212c 100644 --- a/internal/provider/data_source_iosxr_fpd.go +++ b/internal/provider/data_source_iosxr_fpd.go @@ -120,11 +120,11 @@ func (d *FPDDataSource) Read(ctx context.Context, req datasource.ReadRequest, re if device.Managed { getResp, err := d.data.Client.Get(ctx, config.Device.ValueString(), config.getPath()) if err != nil { - resp.Diagnostics.AddError("Unable to apply gNMI Get operation", err.Error()) + resp.Diagnostics.AddError("Unable to apply Get operation", err.Error()) return } - config.fromBody(ctx, getResp.Notification[0].Update[0].Val.GetJsonIetfVal()) + config.fromBody(ctx, getResp) } config.Id = types.StringValue(config.getPath()) diff --git a/internal/provider/data_source_iosxr_fpd_test.go b/internal/provider/data_source_iosxr_fpd_test.go index 1adc5429..ec9c9254 100644 --- a/internal/provider/data_source_iosxr_fpd_test.go +++ b/internal/provider/data_source_iosxr_fpd_test.go @@ -32,11 +32,14 @@ import ( // Section below is generated&owned by "gen/generator.go". //template:begin testAccDataSource func TestAccDataSourceIosxrFPD(t *testing.T) { - if os.Getenv("NCS") == "" { - t.Skip("skipping test, set environment variable NCS") + if os.Getenv("PHYSICAL") == "" { + t.Skip("skipping test, set environment variable PHYSICAL") } var checks []resource.TestCheckFunc - checks = append(checks, resource.TestCheckResourceAttr("data.iosxr_fpd.test", "auto_upgrade_enable", "true")) + checks = append(checks, resource.TestCheckResourceAttr("data.iosxr_fpd.test", "auto_upgrade_enable", "false")) + checks = append(checks, resource.TestCheckResourceAttr("data.iosxr_fpd.test", "auto_upgrade_disable", "false")) + checks = append(checks, resource.TestCheckResourceAttr("data.iosxr_fpd.test", "auto_reload_enable", "false")) + checks = append(checks, resource.TestCheckResourceAttr("data.iosxr_fpd.test", "auto_reload_disable", "false")) resource.Test(t, resource.TestCase{ PreCheck: func() { testAccPreCheck(t) }, ProtoV6ProviderFactories: testAccProtoV6ProviderFactories, @@ -60,7 +63,10 @@ func TestAccDataSourceIosxrFPD(t *testing.T) { func testAccDataSourceIosxrFPDConfig() string { config := `resource "iosxr_fpd" "test" {` + "\n" config += ` delete_mode = "attributes"` + "\n" - config += ` auto_upgrade_enable = true` + "\n" + config += ` auto_upgrade_enable = false` + "\n" + config += ` auto_upgrade_disable = false` + "\n" + config += ` auto_reload_enable = false` + "\n" + config += ` auto_reload_disable = false` + "\n" config += `}` + "\n" config += ` diff --git a/internal/provider/data_source_iosxr_gnmi.go b/internal/provider/data_source_iosxr_gnmi.go index 7426a19e..1697e953 100644 --- a/internal/provider/data_source_iosxr_gnmi.go +++ b/internal/provider/data_source_iosxr_gnmi.go @@ -106,11 +106,11 @@ func (d *GnmiDataSource) Read(ctx context.Context, req datasource.ReadRequest, r if device.Managed { getResp, err := d.data.Client.Get(ctx, config.Device.ValueString(), config.Path.ValueString()) if err != nil { - resp.Diagnostics.AddError("Unable to apply gNMI Get operation", err.Error()) + resp.Diagnostics.AddError("Unable to apply Get operation", err.Error()) return } - for attr, value := range gjson.ParseBytes(getResp.Notification[0].Update[0].Val.GetJsonIetfVal()).Map() { + for attr, value := range gjson.ParseBytes(getResp).Map() { attributes[attr] = types.StringValue(value.String()) } } diff --git a/internal/provider/data_source_iosxr_hostname.go b/internal/provider/data_source_iosxr_hostname.go index a3af60ed..953fb85a 100644 --- a/internal/provider/data_source_iosxr_hostname.go +++ b/internal/provider/data_source_iosxr_hostname.go @@ -108,11 +108,11 @@ func (d *HostnameDataSource) Read(ctx context.Context, req datasource.ReadReques if device.Managed { getResp, err := d.data.Client.Get(ctx, config.Device.ValueString(), config.getPath()) if err != nil { - resp.Diagnostics.AddError("Unable to apply gNMI Get operation", err.Error()) + resp.Diagnostics.AddError("Unable to apply Get operation", err.Error()) return } - config.fromBody(ctx, getResp.Notification[0].Update[0].Val.GetJsonIetfVal()) + config.fromBody(ctx, getResp) } config.Id = types.StringValue(config.getPath()) diff --git a/internal/provider/data_source_iosxr_interface.go b/internal/provider/data_source_iosxr_interface.go index 42c1cdc3..c54d0b94 100644 --- a/internal/provider/data_source_iosxr_interface.go +++ b/internal/provider/data_source_iosxr_interface.go @@ -480,11 +480,11 @@ func (d *InterfaceDataSource) Read(ctx context.Context, req datasource.ReadReque if device.Managed { getResp, err := d.data.Client.Get(ctx, config.Device.ValueString(), config.getPath()) if err != nil { - resp.Diagnostics.AddError("Unable to apply gNMI Get operation", err.Error()) + resp.Diagnostics.AddError("Unable to apply Get operation", err.Error()) return } - config.fromBody(ctx, getResp.Notification[0].Update[0].Val.GetJsonIetfVal()) + config.fromBody(ctx, getResp) } config.Id = types.StringValue(config.getPath()) diff --git a/internal/provider/data_source_iosxr_interface_test.go b/internal/provider/data_source_iosxr_interface_test.go index 5da6d3ee..0820f723 100644 --- a/internal/provider/data_source_iosxr_interface_test.go +++ b/internal/provider/data_source_iosxr_interface_test.go @@ -39,13 +39,9 @@ func TestAccDataSourceIosxrInterface(t *testing.T) { checks = append(checks, resource.TestCheckResourceAttr("data.iosxr_interface.test", "dampening", "true")) checks = append(checks, resource.TestCheckResourceAttr("data.iosxr_interface.test", "dampening_decay_half_life_value", "2")) checks = append(checks, resource.TestCheckResourceAttr("data.iosxr_interface.test", "ipv4_point_to_point", "true")) - if os.Getenv("XRV9K") != "" { - checks = append(checks, resource.TestCheckResourceAttr("data.iosxr_interface.test", "service_policy_input.0.name", "PMAP-IN")) - } - if os.Getenv("XRV9K") != "" { - checks = append(checks, resource.TestCheckResourceAttr("data.iosxr_interface.test", "service_policy_output.0.name", "PMAP-OUT")) - } - checks = append(checks, resource.TestCheckResourceAttr("data.iosxr_interface.test", "shutdown", "false")) + checks = append(checks, resource.TestCheckResourceAttr("data.iosxr_interface.test", "service_policy_input.0.name", "PMAP-IN")) + checks = append(checks, resource.TestCheckResourceAttr("data.iosxr_interface.test", "service_policy_output.0.name", "PMAP-OUT")) + checks = append(checks, resource.TestCheckResourceAttr("data.iosxr_interface.test", "shutdown", "true")) checks = append(checks, resource.TestCheckResourceAttr("data.iosxr_interface.test", "mtu", "9000")) checks = append(checks, resource.TestCheckResourceAttr("data.iosxr_interface.test", "bandwidth", "100000")) checks = append(checks, resource.TestCheckResourceAttr("data.iosxr_interface.test", "description", "My Interface Description")) @@ -63,48 +59,22 @@ func TestAccDataSourceIosxrInterface(t *testing.T) { checks = append(checks, resource.TestCheckResourceAttr("data.iosxr_interface.test", "ipv4_verify_unicast_source_reachable_via_allow_default", "false")) } checks = append(checks, resource.TestCheckResourceAttr("data.iosxr_interface.test", "ipv4_access_group_ingress_acl1", "ACL1")) - if os.Getenv("XRV9K") != "" { - checks = append(checks, resource.TestCheckResourceAttr("data.iosxr_interface.test", "ipv4_access_group_ingress_hardware_count", "true")) - } - if os.Getenv("XRV9K") != "" { - checks = append(checks, resource.TestCheckResourceAttr("data.iosxr_interface.test", "ipv4_access_group_ingress_interface_statistics", "true")) - } - if os.Getenv("NCS") != "" || os.Getenv("XRV9K") != "" { - checks = append(checks, resource.TestCheckResourceAttr("data.iosxr_interface.test", "ipv4_access_group_ingress_compress", "0")) - } + checks = append(checks, resource.TestCheckResourceAttr("data.iosxr_interface.test", "ipv4_access_group_ingress_hardware_count", "true")) + checks = append(checks, resource.TestCheckResourceAttr("data.iosxr_interface.test", "ipv4_access_group_ingress_interface_statistics", "true")) + checks = append(checks, resource.TestCheckResourceAttr("data.iosxr_interface.test", "ipv4_access_group_ingress_compress", "0")) checks = append(checks, resource.TestCheckResourceAttr("data.iosxr_interface.test", "ipv4_access_group_egress_acl", "ACL1")) - if os.Getenv("XRV9K") != "" { - checks = append(checks, resource.TestCheckResourceAttr("data.iosxr_interface.test", "ipv4_access_group_egress_hardware_count", "true")) - } - if os.Getenv("XRV9K") != "" { - checks = append(checks, resource.TestCheckResourceAttr("data.iosxr_interface.test", "ipv4_access_group_egress_interface_statistics", "true")) - } - if os.Getenv("NCS") != "" || os.Getenv("XRV9K") != "" { - checks = append(checks, resource.TestCheckResourceAttr("data.iosxr_interface.test", "ipv4_access_group_egress_compress", "0")) - } - if os.Getenv("XRV9K") != "" { - checks = append(checks, resource.TestCheckResourceAttr("data.iosxr_interface.test", "ipv6_verify_unicast_source_reachable_via_type", "any")) - } - if os.Getenv("XRV9K") != "" { - checks = append(checks, resource.TestCheckResourceAttr("data.iosxr_interface.test", "ipv6_verify_unicast_source_reachable_via_allow_self_ping", "true")) - } - if os.Getenv("XRV9K") != "" { - checks = append(checks, resource.TestCheckResourceAttr("data.iosxr_interface.test", "ipv6_verify_unicast_source_reachable_via_allow_default", "false")) - } + checks = append(checks, resource.TestCheckResourceAttr("data.iosxr_interface.test", "ipv4_access_group_egress_hardware_count", "true")) + checks = append(checks, resource.TestCheckResourceAttr("data.iosxr_interface.test", "ipv4_access_group_egress_interface_statistics", "true")) + checks = append(checks, resource.TestCheckResourceAttr("data.iosxr_interface.test", "ipv4_access_group_egress_compress", "0")) + checks = append(checks, resource.TestCheckResourceAttr("data.iosxr_interface.test", "ipv6_verify_unicast_source_reachable_via_type", "any")) + checks = append(checks, resource.TestCheckResourceAttr("data.iosxr_interface.test", "ipv6_verify_unicast_source_reachable_via_allow_self_ping", "true")) + checks = append(checks, resource.TestCheckResourceAttr("data.iosxr_interface.test", "ipv6_verify_unicast_source_reachable_via_allow_default", "false")) checks = append(checks, resource.TestCheckResourceAttr("data.iosxr_interface.test", "ipv6_access_group_ingress_acl1", "ACL2")) - if os.Getenv("XRV9K") != "" { - checks = append(checks, resource.TestCheckResourceAttr("data.iosxr_interface.test", "ipv6_access_group_ingress_interface_statistics", "true")) - } - if os.Getenv("NCS") != "" || os.Getenv("XRV9K") != "" { - checks = append(checks, resource.TestCheckResourceAttr("data.iosxr_interface.test", "ipv6_access_group_ingress_compress", "0")) - } + checks = append(checks, resource.TestCheckResourceAttr("data.iosxr_interface.test", "ipv6_access_group_ingress_interface_statistics", "true")) + checks = append(checks, resource.TestCheckResourceAttr("data.iosxr_interface.test", "ipv6_access_group_ingress_compress", "0")) checks = append(checks, resource.TestCheckResourceAttr("data.iosxr_interface.test", "ipv6_access_group_egress_acl", "ACL2")) - if os.Getenv("XRV9K") != "" { - checks = append(checks, resource.TestCheckResourceAttr("data.iosxr_interface.test", "ipv6_access_group_egress_interface_statistics", "true")) - } - if os.Getenv("NCS") != "" || os.Getenv("XRV9K") != "" { - checks = append(checks, resource.TestCheckResourceAttr("data.iosxr_interface.test", "ipv6_access_group_egress_compress", "0")) - } + checks = append(checks, resource.TestCheckResourceAttr("data.iosxr_interface.test", "ipv6_access_group_egress_interface_statistics", "true")) + checks = append(checks, resource.TestCheckResourceAttr("data.iosxr_interface.test", "ipv6_access_group_egress_compress", "0")) checks = append(checks, resource.TestCheckResourceAttr("data.iosxr_interface.test", "ipv6_link_local_address", "fe80::1")) checks = append(checks, resource.TestCheckResourceAttr("data.iosxr_interface.test", "ipv6_link_local_zone", "0")) checks = append(checks, resource.TestCheckResourceAttr("data.iosxr_interface.test", "ipv6_autoconfig", "false")) @@ -113,14 +83,34 @@ func TestAccDataSourceIosxrInterface(t *testing.T) { checks = append(checks, resource.TestCheckResourceAttr("data.iosxr_interface.test", "ipv6_addresses.0.prefix_length", "64")) checks = append(checks, resource.TestCheckResourceAttr("data.iosxr_interface.test", "ipv6_addresses.0.zone", "0")) checks = append(checks, resource.TestCheckResourceAttr("data.iosxr_interface.test", "bundle_port_priority", "100")) - if os.Getenv("FLOW") != "" { + if os.Getenv("PHYSICAL") != "" { + checks = append(checks, resource.TestCheckResourceAttr("data.iosxr_interface.test", "flow_ipv4_ingress_monitors.0.monitor_map_name", "MMAP1")) + } + if os.Getenv("PHYSICAL") != "" { checks = append(checks, resource.TestCheckResourceAttr("data.iosxr_interface.test", "flow_ipv4_ingress_monitor_samplers.0.monitor_map_name", "MMAP1")) checks = append(checks, resource.TestCheckResourceAttr("data.iosxr_interface.test", "flow_ipv4_ingress_monitor_samplers.0.sampler_map_name", "SMAP1")) } - if os.Getenv("FLOW") != "" { - checks = append(checks, resource.TestCheckResourceAttr("data.iosxr_interface.test", "flow_ipv6_ingress_monitor_samplers.0.monitor_map_name", "MMAP2")) + if os.Getenv("PHYSICAL") != "" { + checks = append(checks, resource.TestCheckResourceAttr("data.iosxr_interface.test", "flow_ipv4_egress_monitors.0.monitor_map_name", "MMAP1")) + } + if os.Getenv("PHYSICAL") != "" { + checks = append(checks, resource.TestCheckResourceAttr("data.iosxr_interface.test", "flow_ipv4_egress_monitor_samplers.0.monitor_map_name", "MMAP1")) + checks = append(checks, resource.TestCheckResourceAttr("data.iosxr_interface.test", "flow_ipv4_egress_monitor_samplers.0.sampler_map_name", "SMAP1")) + } + if os.Getenv("PHYSICAL") != "" { + checks = append(checks, resource.TestCheckResourceAttr("data.iosxr_interface.test", "flow_ipv6_ingress_monitors.0.monitor_map_name", "MMAP1")) + } + if os.Getenv("PHYSICAL") != "" { + checks = append(checks, resource.TestCheckResourceAttr("data.iosxr_interface.test", "flow_ipv6_ingress_monitor_samplers.0.monitor_map_name", "MMAP1")) checks = append(checks, resource.TestCheckResourceAttr("data.iosxr_interface.test", "flow_ipv6_ingress_monitor_samplers.0.sampler_map_name", "SMAP1")) } + if os.Getenv("PHYSICAL") != "" { + checks = append(checks, resource.TestCheckResourceAttr("data.iosxr_interface.test", "flow_ipv6_egress_monitors.0.monitor_map_name", "MMAP1")) + } + if os.Getenv("PHYSICAL") != "" { + checks = append(checks, resource.TestCheckResourceAttr("data.iosxr_interface.test", "flow_ipv6_egress_monitor_samplers.0.monitor_map_name", "MMAP1")) + checks = append(checks, resource.TestCheckResourceAttr("data.iosxr_interface.test", "flow_ipv6_egress_monitor_samplers.0.sampler_map_name", "SMAP1")) + } resource.Test(t, resource.TestCase{ PreCheck: func() { testAccPreCheck(t) }, ProtoV6ProviderFactories: testAccProtoV6ProviderFactories, @@ -235,17 +225,13 @@ func testAccDataSourceIosxrInterfaceConfig() string { config += ` dampening = true` + "\n" config += ` dampening_decay_half_life_value = 2` + "\n" config += ` ipv4_point_to_point = true` + "\n" - if os.Getenv("XRV9K") != "" { - config += ` service_policy_input = [{` + "\n" - config += ` name = "PMAP-IN"` + "\n" - config += ` }]` + "\n" - } - if os.Getenv("XRV9K") != "" { - config += ` service_policy_output = [{` + "\n" - config += ` name = "PMAP-OUT"` + "\n" - config += ` }]` + "\n" - } - config += ` shutdown = false` + "\n" + config += ` service_policy_input = [{` + "\n" + config += ` name = "PMAP-IN"` + "\n" + config += ` }]` + "\n" + config += ` service_policy_output = [{` + "\n" + config += ` name = "PMAP-OUT"` + "\n" + config += ` }]` + "\n" + config += ` shutdown = true` + "\n" config += ` mtu = 9000` + "\n" config += ` bandwidth = 100000` + "\n" config += ` description = "My Interface Description"` + "\n" @@ -263,48 +249,22 @@ func testAccDataSourceIosxrInterfaceConfig() string { config += ` ipv4_verify_unicast_source_reachable_via_allow_default = false` + "\n" } config += ` ipv4_access_group_ingress_acl1 = "ACL1"` + "\n" - if os.Getenv("XRV9K") != "" { - config += ` ipv4_access_group_ingress_hardware_count = true` + "\n" - } - if os.Getenv("XRV9K") != "" { - config += ` ipv4_access_group_ingress_interface_statistics = true` + "\n" - } - if os.Getenv("NCS") != "" || os.Getenv("XRV9K") != "" { - config += ` ipv4_access_group_ingress_compress = 0` + "\n" - } + config += ` ipv4_access_group_ingress_hardware_count = true` + "\n" + config += ` ipv4_access_group_ingress_interface_statistics = true` + "\n" + config += ` ipv4_access_group_ingress_compress = 0` + "\n" config += ` ipv4_access_group_egress_acl = "ACL1"` + "\n" - if os.Getenv("XRV9K") != "" { - config += ` ipv4_access_group_egress_hardware_count = true` + "\n" - } - if os.Getenv("XRV9K") != "" { - config += ` ipv4_access_group_egress_interface_statistics = true` + "\n" - } - if os.Getenv("NCS") != "" || os.Getenv("XRV9K") != "" { - config += ` ipv4_access_group_egress_compress = 0` + "\n" - } - if os.Getenv("XRV9K") != "" { - config += ` ipv6_verify_unicast_source_reachable_via_type = "any"` + "\n" - } - if os.Getenv("XRV9K") != "" { - config += ` ipv6_verify_unicast_source_reachable_via_allow_self_ping = true` + "\n" - } - if os.Getenv("XRV9K") != "" { - config += ` ipv6_verify_unicast_source_reachable_via_allow_default = false` + "\n" - } + config += ` ipv4_access_group_egress_hardware_count = true` + "\n" + config += ` ipv4_access_group_egress_interface_statistics = true` + "\n" + config += ` ipv4_access_group_egress_compress = 0` + "\n" + config += ` ipv6_verify_unicast_source_reachable_via_type = "any"` + "\n" + config += ` ipv6_verify_unicast_source_reachable_via_allow_self_ping = true` + "\n" + config += ` ipv6_verify_unicast_source_reachable_via_allow_default = false` + "\n" config += ` ipv6_access_group_ingress_acl1 = "ACL2"` + "\n" - if os.Getenv("XRV9K") != "" { - config += ` ipv6_access_group_ingress_interface_statistics = true` + "\n" - } - if os.Getenv("NCS") != "" || os.Getenv("XRV9K") != "" { - config += ` ipv6_access_group_ingress_compress = 0` + "\n" - } + config += ` ipv6_access_group_ingress_interface_statistics = true` + "\n" + config += ` ipv6_access_group_ingress_compress = 0` + "\n" config += ` ipv6_access_group_egress_acl = "ACL2"` + "\n" - if os.Getenv("XRV9K") != "" { - config += ` ipv6_access_group_egress_interface_statistics = true` + "\n" - } - if os.Getenv("NCS") != "" || os.Getenv("XRV9K") != "" { - config += ` ipv6_access_group_egress_compress = 0` + "\n" - } + config += ` ipv6_access_group_egress_interface_statistics = true` + "\n" + config += ` ipv6_access_group_egress_compress = 0` + "\n" config += ` ipv6_link_local_address = "fe80::1"` + "\n" config += ` ipv6_link_local_zone = "0"` + "\n" config += ` ipv6_autoconfig = false` + "\n" @@ -315,15 +275,47 @@ func testAccDataSourceIosxrInterfaceConfig() string { config += ` zone = "0"` + "\n" config += ` }]` + "\n" config += ` bundle_port_priority = 100` + "\n" - if os.Getenv("FLOW") != "" { + if os.Getenv("PHYSICAL") != "" { + config += ` flow_ipv4_ingress_monitors = [{` + "\n" + config += ` monitor_map_name = "MMAP1"` + "\n" + config += ` }]` + "\n" + } + if os.Getenv("PHYSICAL") != "" { config += ` flow_ipv4_ingress_monitor_samplers = [{` + "\n" config += ` monitor_map_name = "MMAP1"` + "\n" config += ` sampler_map_name = "SMAP1"` + "\n" config += ` }]` + "\n" } - if os.Getenv("FLOW") != "" { + if os.Getenv("PHYSICAL") != "" { + config += ` flow_ipv4_egress_monitors = [{` + "\n" + config += ` monitor_map_name = "MMAP1"` + "\n" + config += ` }]` + "\n" + } + if os.Getenv("PHYSICAL") != "" { + config += ` flow_ipv4_egress_monitor_samplers = [{` + "\n" + config += ` monitor_map_name = "MMAP1"` + "\n" + config += ` sampler_map_name = "SMAP1"` + "\n" + config += ` }]` + "\n" + } + if os.Getenv("PHYSICAL") != "" { + config += ` flow_ipv6_ingress_monitors = [{` + "\n" + config += ` monitor_map_name = "MMAP1"` + "\n" + config += ` }]` + "\n" + } + if os.Getenv("PHYSICAL") != "" { config += ` flow_ipv6_ingress_monitor_samplers = [{` + "\n" - config += ` monitor_map_name = "MMAP2"` + "\n" + config += ` monitor_map_name = "MMAP1"` + "\n" + config += ` sampler_map_name = "SMAP1"` + "\n" + config += ` }]` + "\n" + } + if os.Getenv("PHYSICAL") != "" { + config += ` flow_ipv6_egress_monitors = [{` + "\n" + config += ` monitor_map_name = "MMAP1"` + "\n" + config += ` }]` + "\n" + } + if os.Getenv("PHYSICAL") != "" { + config += ` flow_ipv6_egress_monitor_samplers = [{` + "\n" + config += ` monitor_map_name = "MMAP1"` + "\n" config += ` sampler_map_name = "SMAP1"` + "\n" config += ` }]` + "\n" } diff --git a/internal/provider/data_source_iosxr_ipv4_access_list.go b/internal/provider/data_source_iosxr_ipv4_access_list.go index e96aed4f..fa760a01 100644 --- a/internal/provider/data_source_iosxr_ipv4_access_list.go +++ b/internal/provider/data_source_iosxr_ipv4_access_list.go @@ -796,11 +796,11 @@ func (d *IPv4AccessListDataSource) Read(ctx context.Context, req datasource.Read if device.Managed { getResp, err := d.data.Client.Get(ctx, config.Device.ValueString(), config.getPath()) if err != nil { - resp.Diagnostics.AddError("Unable to apply gNMI Get operation", err.Error()) + resp.Diagnostics.AddError("Unable to apply Get operation", err.Error()) return } - config.fromBody(ctx, getResp.Notification[0].Update[0].Val.GetJsonIetfVal()) + config.fromBody(ctx, getResp) } config.Id = types.StringValue(config.getPath()) diff --git a/internal/provider/data_source_iosxr_ipv4_access_list_options.go b/internal/provider/data_source_iosxr_ipv4_access_list_options.go index c11d7a69..045e4cb5 100644 --- a/internal/provider/data_source_iosxr_ipv4_access_list_options.go +++ b/internal/provider/data_source_iosxr_ipv4_access_list_options.go @@ -116,11 +116,11 @@ func (d *IPv4AccessListOptionsDataSource) Read(ctx context.Context, req datasour if device.Managed { getResp, err := d.data.Client.Get(ctx, config.Device.ValueString(), config.getPath()) if err != nil { - resp.Diagnostics.AddError("Unable to apply gNMI Get operation", err.Error()) + resp.Diagnostics.AddError("Unable to apply Get operation", err.Error()) return } - config.fromBody(ctx, getResp.Notification[0].Update[0].Val.GetJsonIetfVal()) + config.fromBody(ctx, getResp) } config.Id = types.StringValue(config.getPath()) diff --git a/internal/provider/data_source_iosxr_ipv4_prefix_list.go b/internal/provider/data_source_iosxr_ipv4_prefix_list.go index 833a7324..ba0bc46c 100644 --- a/internal/provider/data_source_iosxr_ipv4_prefix_list.go +++ b/internal/provider/data_source_iosxr_ipv4_prefix_list.go @@ -148,11 +148,11 @@ func (d *IPv4PrefixListDataSource) Read(ctx context.Context, req datasource.Read if device.Managed { getResp, err := d.data.Client.Get(ctx, config.Device.ValueString(), config.getPath()) if err != nil { - resp.Diagnostics.AddError("Unable to apply gNMI Get operation", err.Error()) + resp.Diagnostics.AddError("Unable to apply Get operation", err.Error()) return } - config.fromBody(ctx, getResp.Notification[0].Update[0].Val.GetJsonIetfVal()) + config.fromBody(ctx, getResp) } config.Id = types.StringValue(config.getPath()) diff --git a/internal/provider/data_source_iosxr_ipv4_prefix_list_test.go b/internal/provider/data_source_iosxr_ipv4_prefix_list_test.go index 04ffcb11..f239031b 100644 --- a/internal/provider/data_source_iosxr_ipv4_prefix_list_test.go +++ b/internal/provider/data_source_iosxr_ipv4_prefix_list_test.go @@ -36,6 +36,7 @@ func TestAccDataSourceIosxrIPv4PrefixList(t *testing.T) { checks = append(checks, resource.TestCheckResourceAttr("data.iosxr_ipv4_prefix_list.test", "sequences.0.permission", "deny")) checks = append(checks, resource.TestCheckResourceAttr("data.iosxr_ipv4_prefix_list.test", "sequences.0.prefix", "10.1.0.0")) checks = append(checks, resource.TestCheckResourceAttr("data.iosxr_ipv4_prefix_list.test", "sequences.0.mask", "255.255.0.0")) + checks = append(checks, resource.TestCheckResourceAttr("data.iosxr_ipv4_prefix_list.test", "sequences.0.match_prefix_length_eq", "12")) checks = append(checks, resource.TestCheckResourceAttr("data.iosxr_ipv4_prefix_list.test", "sequences.0.match_prefix_length_ge", "22")) checks = append(checks, resource.TestCheckResourceAttr("data.iosxr_ipv4_prefix_list.test", "sequences.0.match_prefix_length_le", "32")) resource.Test(t, resource.TestCase{ @@ -66,6 +67,7 @@ func testAccDataSourceIosxrIPv4PrefixListConfig() string { config += ` permission = "deny"` + "\n" config += ` prefix = "10.1.0.0"` + "\n" config += ` mask = "255.255.0.0"` + "\n" + config += ` match_prefix_length_eq = 12` + "\n" config += ` match_prefix_length_ge = 22` + "\n" config += ` match_prefix_length_le = 32` + "\n" config += ` }]` + "\n" diff --git a/internal/provider/data_source_iosxr_ipv6.go b/internal/provider/data_source_iosxr_ipv6.go index c3d66923..142ea34f 100644 --- a/internal/provider/data_source_iosxr_ipv6.go +++ b/internal/provider/data_source_iosxr_ipv6.go @@ -148,11 +148,11 @@ func (d *IPv6DataSource) Read(ctx context.Context, req datasource.ReadRequest, r if device.Managed { getResp, err := d.data.Client.Get(ctx, config.Device.ValueString(), config.getPath()) if err != nil { - resp.Diagnostics.AddError("Unable to apply gNMI Get operation", err.Error()) + resp.Diagnostics.AddError("Unable to apply Get operation", err.Error()) return } - config.fromBody(ctx, getResp.Notification[0].Update[0].Val.GetJsonIetfVal()) + config.fromBody(ctx, getResp) } config.Id = types.StringValue(config.getPath()) diff --git a/internal/provider/data_source_iosxr_ipv6_access_list.go b/internal/provider/data_source_iosxr_ipv6_access_list.go index 00ab81a7..b0875ba7 100644 --- a/internal/provider/data_source_iosxr_ipv6_access_list.go +++ b/internal/provider/data_source_iosxr_ipv6_access_list.go @@ -688,11 +688,11 @@ func (d *IPv6AccessListDataSource) Read(ctx context.Context, req datasource.Read if device.Managed { getResp, err := d.data.Client.Get(ctx, config.Device.ValueString(), config.getPath()) if err != nil { - resp.Diagnostics.AddError("Unable to apply gNMI Get operation", err.Error()) + resp.Diagnostics.AddError("Unable to apply Get operation", err.Error()) return } - config.fromBody(ctx, getResp.Notification[0].Update[0].Val.GetJsonIetfVal()) + config.fromBody(ctx, getResp) } config.Id = types.StringValue(config.getPath()) diff --git a/internal/provider/data_source_iosxr_ipv6_access_list_options.go b/internal/provider/data_source_iosxr_ipv6_access_list_options.go index 37e1704e..a4ca56e9 100644 --- a/internal/provider/data_source_iosxr_ipv6_access_list_options.go +++ b/internal/provider/data_source_iosxr_ipv6_access_list_options.go @@ -116,11 +116,11 @@ func (d *IPv6AccessListOptionsDataSource) Read(ctx context.Context, req datasour if device.Managed { getResp, err := d.data.Client.Get(ctx, config.Device.ValueString(), config.getPath()) if err != nil { - resp.Diagnostics.AddError("Unable to apply gNMI Get operation", err.Error()) + resp.Diagnostics.AddError("Unable to apply Get operation", err.Error()) return } - config.fromBody(ctx, getResp.Notification[0].Update[0].Val.GetJsonIetfVal()) + config.fromBody(ctx, getResp) } config.Id = types.StringValue(config.getPath()) diff --git a/internal/provider/data_source_iosxr_ipv6_prefix_list.go b/internal/provider/data_source_iosxr_ipv6_prefix_list.go index b8d5db12..752cf7a3 100644 --- a/internal/provider/data_source_iosxr_ipv6_prefix_list.go +++ b/internal/provider/data_source_iosxr_ipv6_prefix_list.go @@ -148,11 +148,11 @@ func (d *IPv6PrefixListDataSource) Read(ctx context.Context, req datasource.Read if device.Managed { getResp, err := d.data.Client.Get(ctx, config.Device.ValueString(), config.getPath()) if err != nil { - resp.Diagnostics.AddError("Unable to apply gNMI Get operation", err.Error()) + resp.Diagnostics.AddError("Unable to apply Get operation", err.Error()) return } - config.fromBody(ctx, getResp.Notification[0].Update[0].Val.GetJsonIetfVal()) + config.fromBody(ctx, getResp) } config.Id = types.StringValue(config.getPath()) diff --git a/internal/provider/data_source_iosxr_key_chain.go b/internal/provider/data_source_iosxr_key_chain.go index f6de6c23..6108bc9d 100644 --- a/internal/provider/data_source_iosxr_key_chain.go +++ b/internal/provider/data_source_iosxr_key_chain.go @@ -184,11 +184,11 @@ func (d *KeyChainDataSource) Read(ctx context.Context, req datasource.ReadReques if device.Managed { getResp, err := d.data.Client.Get(ctx, config.Device.ValueString(), config.getPath()) if err != nil { - resp.Diagnostics.AddError("Unable to apply gNMI Get operation", err.Error()) + resp.Diagnostics.AddError("Unable to apply Get operation", err.Error()) return } - config.fromBody(ctx, getResp.Notification[0].Update[0].Val.GetJsonIetfVal()) + config.fromBody(ctx, getResp) } config.Id = types.StringValue(config.getPath()) diff --git a/internal/provider/data_source_iosxr_l2vpn.go b/internal/provider/data_source_iosxr_l2vpn.go index 43fd177a..3542bff7 100644 --- a/internal/provider/data_source_iosxr_l2vpn.go +++ b/internal/provider/data_source_iosxr_l2vpn.go @@ -132,11 +132,11 @@ func (d *L2VPNDataSource) Read(ctx context.Context, req datasource.ReadRequest, if device.Managed { getResp, err := d.data.Client.Get(ctx, config.Device.ValueString(), config.getPath()) if err != nil { - resp.Diagnostics.AddError("Unable to apply gNMI Get operation", err.Error()) + resp.Diagnostics.AddError("Unable to apply Get operation", err.Error()) return } - config.fromBody(ctx, getResp.Notification[0].Update[0].Val.GetJsonIetfVal()) + config.fromBody(ctx, getResp) } config.Id = types.StringValue(config.getPath()) diff --git a/internal/provider/data_source_iosxr_l2vpn_bridge_group.go b/internal/provider/data_source_iosxr_l2vpn_bridge_group.go index d6e501fe..a13a9bf7 100644 --- a/internal/provider/data_source_iosxr_l2vpn_bridge_group.go +++ b/internal/provider/data_source_iosxr_l2vpn_bridge_group.go @@ -108,11 +108,11 @@ func (d *L2VPNBridgeGroupDataSource) Read(ctx context.Context, req datasource.Re if device.Managed { getResp, err := d.data.Client.Get(ctx, config.Device.ValueString(), config.getPath()) if err != nil { - resp.Diagnostics.AddError("Unable to apply gNMI Get operation", err.Error()) + resp.Diagnostics.AddError("Unable to apply Get operation", err.Error()) return } - config.fromBody(ctx, getResp.Notification[0].Update[0].Val.GetJsonIetfVal()) + config.fromBody(ctx, getResp) } config.Id = types.StringValue(config.getPath()) diff --git a/internal/provider/data_source_iosxr_l2vpn_bridge_group_bridge_domain.go b/internal/provider/data_source_iosxr_l2vpn_bridge_group_bridge_domain.go index cbc31520..1659b0c6 100644 --- a/internal/provider/data_source_iosxr_l2vpn_bridge_group_bridge_domain.go +++ b/internal/provider/data_source_iosxr_l2vpn_bridge_group_bridge_domain.go @@ -192,11 +192,11 @@ func (d *L2VPNBridgeGroupBridgeDomainDataSource) Read(ctx context.Context, req d if device.Managed { getResp, err := d.data.Client.Get(ctx, config.Device.ValueString(), config.getPath()) if err != nil { - resp.Diagnostics.AddError("Unable to apply gNMI Get operation", err.Error()) + resp.Diagnostics.AddError("Unable to apply Get operation", err.Error()) return } - config.fromBody(ctx, getResp.Notification[0].Update[0].Val.GetJsonIetfVal()) + config.fromBody(ctx, getResp) } config.Id = types.StringValue(config.getPath()) diff --git a/internal/provider/data_source_iosxr_l2vpn_pw_class.go b/internal/provider/data_source_iosxr_l2vpn_pw_class.go index f4bf98e8..cddf583a 100644 --- a/internal/provider/data_source_iosxr_l2vpn_pw_class.go +++ b/internal/provider/data_source_iosxr_l2vpn_pw_class.go @@ -160,11 +160,11 @@ func (d *L2VPNPWClassDataSource) Read(ctx context.Context, req datasource.ReadRe if device.Managed { getResp, err := d.data.Client.Get(ctx, config.Device.ValueString(), config.getPath()) if err != nil { - resp.Diagnostics.AddError("Unable to apply gNMI Get operation", err.Error()) + resp.Diagnostics.AddError("Unable to apply Get operation", err.Error()) return } - config.fromBody(ctx, getResp.Notification[0].Update[0].Val.GetJsonIetfVal()) + config.fromBody(ctx, getResp) } config.Id = types.StringValue(config.getPath()) diff --git a/internal/provider/data_source_iosxr_l2vpn_pw_class_test.go b/internal/provider/data_source_iosxr_l2vpn_pw_class_test.go index 9729b29e..ffb676d7 100644 --- a/internal/provider/data_source_iosxr_l2vpn_pw_class_test.go +++ b/internal/provider/data_source_iosxr_l2vpn_pw_class_test.go @@ -21,7 +21,6 @@ package provider // Section below is generated&owned by "gen/generator.go". //template:begin imports import ( - "os" "testing" "github.com/hashicorp/terraform-plugin-testing/helper/resource" @@ -37,9 +36,7 @@ func TestAccDataSourceIosxrL2VPNPWClass(t *testing.T) { checks = append(checks, resource.TestCheckResourceAttr("data.iosxr_l2vpn_pw_class.test", "encapsulation_mpls_transport_mode_ethernet", "true")) checks = append(checks, resource.TestCheckResourceAttr("data.iosxr_l2vpn_pw_class.test", "encapsulation_mpls_transport_mode_vlan", "false")) checks = append(checks, resource.TestCheckResourceAttr("data.iosxr_l2vpn_pw_class.test", "encapsulation_mpls_transport_mode_passthrough", "false")) - if os.Getenv("NCS") != "" || os.Getenv("XRV9K") != "" { - checks = append(checks, resource.TestCheckResourceAttr("data.iosxr_l2vpn_pw_class.test", "encapsulation_mpls_load_balancing_pw_label", "true")) - } + checks = append(checks, resource.TestCheckResourceAttr("data.iosxr_l2vpn_pw_class.test", "encapsulation_mpls_load_balancing_pw_label", "true")) checks = append(checks, resource.TestCheckResourceAttr("data.iosxr_l2vpn_pw_class.test", "encapsulation_mpls_load_balancing_flow_label_both", "true")) checks = append(checks, resource.TestCheckResourceAttr("data.iosxr_l2vpn_pw_class.test", "encapsulation_mpls_load_balancing_flow_label_both_static", "true")) checks = append(checks, resource.TestCheckResourceAttr("data.iosxr_l2vpn_pw_class.test", "encapsulation_mpls_load_balancing_flow_label_code_one7", "true")) @@ -80,9 +77,7 @@ func testAccDataSourceIosxrL2VPNPWClassConfig() string { config += ` encapsulation_mpls_transport_mode_ethernet = true` + "\n" config += ` encapsulation_mpls_transport_mode_vlan = false` + "\n" config += ` encapsulation_mpls_transport_mode_passthrough = false` + "\n" - if os.Getenv("NCS") != "" || os.Getenv("XRV9K") != "" { - config += ` encapsulation_mpls_load_balancing_pw_label = true` + "\n" - } + config += ` encapsulation_mpls_load_balancing_pw_label = true` + "\n" config += ` encapsulation_mpls_load_balancing_flow_label_both = true` + "\n" config += ` encapsulation_mpls_load_balancing_flow_label_both_static = true` + "\n" config += ` encapsulation_mpls_load_balancing_flow_label_code_one7 = true` + "\n" diff --git a/internal/provider/data_source_iosxr_l2vpn_xconnect_group_p2p.go b/internal/provider/data_source_iosxr_l2vpn_xconnect_group_p2p.go index 77243757..dc688c78 100644 --- a/internal/provider/data_source_iosxr_l2vpn_xconnect_group_p2p.go +++ b/internal/provider/data_source_iosxr_l2vpn_xconnect_group_p2p.go @@ -232,11 +232,11 @@ func (d *L2VPNXconnectGroupP2PDataSource) Read(ctx context.Context, req datasour if device.Managed { getResp, err := d.data.Client.Get(ctx, config.Device.ValueString(), config.getPath()) if err != nil { - resp.Diagnostics.AddError("Unable to apply gNMI Get operation", err.Error()) + resp.Diagnostics.AddError("Unable to apply Get operation", err.Error()) return } - config.fromBody(ctx, getResp.Notification[0].Update[0].Val.GetJsonIetfVal()) + config.fromBody(ctx, getResp) } config.Id = types.StringValue(config.getPath()) diff --git a/internal/provider/data_source_iosxr_lacp.go b/internal/provider/data_source_iosxr_lacp.go index 1a8d8203..51e000b2 100644 --- a/internal/provider/data_source_iosxr_lacp.go +++ b/internal/provider/data_source_iosxr_lacp.go @@ -112,11 +112,11 @@ func (d *LACPDataSource) Read(ctx context.Context, req datasource.ReadRequest, r if device.Managed { getResp, err := d.data.Client.Get(ctx, config.Device.ValueString(), config.getPath()) if err != nil { - resp.Diagnostics.AddError("Unable to apply gNMI Get operation", err.Error()) + resp.Diagnostics.AddError("Unable to apply Get operation", err.Error()) return } - config.fromBody(ctx, getResp.Notification[0].Update[0].Val.GetJsonIetfVal()) + config.fromBody(ctx, getResp) } config.Id = types.StringValue(config.getPath()) diff --git a/internal/provider/data_source_iosxr_lldp.go b/internal/provider/data_source_iosxr_lldp.go index 1a42c47f..e203c79f 100644 --- a/internal/provider/data_source_iosxr_lldp.go +++ b/internal/provider/data_source_iosxr_lldp.go @@ -152,11 +152,11 @@ func (d *LLDPDataSource) Read(ctx context.Context, req datasource.ReadRequest, r if device.Managed { getResp, err := d.data.Client.Get(ctx, config.Device.ValueString(), config.getPath()) if err != nil { - resp.Diagnostics.AddError("Unable to apply gNMI Get operation", err.Error()) + resp.Diagnostics.AddError("Unable to apply Get operation", err.Error()) return } - config.fromBody(ctx, getResp.Notification[0].Update[0].Val.GetJsonIetfVal()) + config.fromBody(ctx, getResp) } config.Id = types.StringValue(config.getPath()) diff --git a/internal/provider/data_source_iosxr_logging.go b/internal/provider/data_source_iosxr_logging.go index 33f8ac57..730c15d6 100644 --- a/internal/provider/data_source_iosxr_logging.go +++ b/internal/provider/data_source_iosxr_logging.go @@ -148,11 +148,11 @@ func (d *LoggingDataSource) Read(ctx context.Context, req datasource.ReadRequest if device.Managed { getResp, err := d.data.Client.Get(ctx, config.Device.ValueString(), config.getPath()) if err != nil { - resp.Diagnostics.AddError("Unable to apply gNMI Get operation", err.Error()) + resp.Diagnostics.AddError("Unable to apply Get operation", err.Error()) return } - config.fromBody(ctx, getResp.Notification[0].Update[0].Val.GetJsonIetfVal()) + config.fromBody(ctx, getResp) } config.Id = types.StringValue(config.getPath()) diff --git a/internal/provider/data_source_iosxr_logging_source_interface.go b/internal/provider/data_source_iosxr_logging_source_interface.go index 143f3093..f5fffb02 100644 --- a/internal/provider/data_source_iosxr_logging_source_interface.go +++ b/internal/provider/data_source_iosxr_logging_source_interface.go @@ -120,11 +120,11 @@ func (d *LoggingSourceInterfaceDataSource) Read(ctx context.Context, req datasou if device.Managed { getResp, err := d.data.Client.Get(ctx, config.Device.ValueString(), config.getPath()) if err != nil { - resp.Diagnostics.AddError("Unable to apply gNMI Get operation", err.Error()) + resp.Diagnostics.AddError("Unable to apply Get operation", err.Error()) return } - config.fromBody(ctx, getResp.Notification[0].Update[0].Val.GetJsonIetfVal()) + config.fromBody(ctx, getResp) } config.Id = types.StringValue(config.getPath()) diff --git a/internal/provider/data_source_iosxr_logging_vrf.go b/internal/provider/data_source_iosxr_logging_vrf.go index 1e4740c3..c7ee97da 100644 --- a/internal/provider/data_source_iosxr_logging_vrf.go +++ b/internal/provider/data_source_iosxr_logging_vrf.go @@ -156,11 +156,11 @@ func (d *LoggingVRFDataSource) Read(ctx context.Context, req datasource.ReadRequ if device.Managed { getResp, err := d.data.Client.Get(ctx, config.Device.ValueString(), config.getPath()) if err != nil { - resp.Diagnostics.AddError("Unable to apply gNMI Get operation", err.Error()) + resp.Diagnostics.AddError("Unable to apply Get operation", err.Error()) return } - config.fromBody(ctx, getResp.Notification[0].Update[0].Val.GetJsonIetfVal()) + config.fromBody(ctx, getResp) } config.Id = types.StringValue(config.getPath()) diff --git a/internal/provider/data_source_iosxr_mpls_ldp.go b/internal/provider/data_source_iosxr_mpls_ldp.go index f8828428..04ffa410 100644 --- a/internal/provider/data_source_iosxr_mpls_ldp.go +++ b/internal/provider/data_source_iosxr_mpls_ldp.go @@ -103,10 +103,6 @@ func (d *MPLSLDPDataSource) Schema(ctx context.Context, req datasource.SchemaReq }, }, }, - "capabilities_sac": schema.BoolAttribute{ - MarkdownDescription: "State Advertisement Control", - Computed: true, - }, "capabilities_sac_ipv4_disable": schema.BoolAttribute{ MarkdownDescription: "Disable exchanging IPv4 prefix label bindings", Computed: true, @@ -131,10 +127,6 @@ func (d *MPLSLDPDataSource) Schema(ctx context.Context, req datasource.SchemaReq MarkdownDescription: "Global sync up delay to be used after process restart", Computed: true, }, - "mldp": schema.BoolAttribute{ - MarkdownDescription: "Configure mLDP parameters", - Computed: true, - }, "mldp_logging_notifications": schema.BoolAttribute{ MarkdownDescription: "MLDP logging notifications", Computed: true, @@ -208,11 +200,11 @@ func (d *MPLSLDPDataSource) Read(ctx context.Context, req datasource.ReadRequest if device.Managed { getResp, err := d.data.Client.Get(ctx, config.Device.ValueString(), config.getPath()) if err != nil { - resp.Diagnostics.AddError("Unable to apply gNMI Get operation", err.Error()) + resp.Diagnostics.AddError("Unable to apply Get operation", err.Error()) return } - config.fromBody(ctx, getResp.Notification[0].Update[0].Val.GetJsonIetfVal()) + config.fromBody(ctx, getResp) } config.Id = types.StringValue(config.getPath()) diff --git a/internal/provider/data_source_iosxr_mpls_oam.go b/internal/provider/data_source_iosxr_mpls_oam.go index 0ff742fe..40b5c74c 100644 --- a/internal/provider/data_source_iosxr_mpls_oam.go +++ b/internal/provider/data_source_iosxr_mpls_oam.go @@ -124,11 +124,11 @@ func (d *MPLSOAMDataSource) Read(ctx context.Context, req datasource.ReadRequest if device.Managed { getResp, err := d.data.Client.Get(ctx, config.Device.ValueString(), config.getPath()) if err != nil { - resp.Diagnostics.AddError("Unable to apply gNMI Get operation", err.Error()) + resp.Diagnostics.AddError("Unable to apply Get operation", err.Error()) return } - config.fromBody(ctx, getResp.Notification[0].Update[0].Val.GetJsonIetfVal()) + config.fromBody(ctx, getResp) } config.Id = types.StringValue(config.getPath()) diff --git a/internal/provider/data_source_iosxr_mpls_traffic_eng.go b/internal/provider/data_source_iosxr_mpls_traffic_eng.go index ffc34328..ebce5f29 100644 --- a/internal/provider/data_source_iosxr_mpls_traffic_eng.go +++ b/internal/provider/data_source_iosxr_mpls_traffic_eng.go @@ -108,11 +108,11 @@ func (d *MPLSTrafficEngDataSource) Read(ctx context.Context, req datasource.Read if device.Managed { getResp, err := d.data.Client.Get(ctx, config.Device.ValueString(), config.getPath()) if err != nil { - resp.Diagnostics.AddError("Unable to apply gNMI Get operation", err.Error()) + resp.Diagnostics.AddError("Unable to apply Get operation", err.Error()) return } - config.fromBody(ctx, getResp.Notification[0].Update[0].Val.GetJsonIetfVal()) + config.fromBody(ctx, getResp) } config.Id = types.StringValue(config.getPath()) diff --git a/internal/provider/data_source_iosxr_ntp.go b/internal/provider/data_source_iosxr_ntp.go index 95020f4a..32821fd4 100644 --- a/internal/provider/data_source_iosxr_ntp.go +++ b/internal/provider/data_source_iosxr_ntp.go @@ -636,11 +636,11 @@ func (d *NTPDataSource) Read(ctx context.Context, req datasource.ReadRequest, re if device.Managed { getResp, err := d.data.Client.Get(ctx, config.Device.ValueString(), config.getPath()) if err != nil { - resp.Diagnostics.AddError("Unable to apply gNMI Get operation", err.Error()) + resp.Diagnostics.AddError("Unable to apply Get operation", err.Error()) return } - config.fromBody(ctx, getResp.Notification[0].Update[0].Val.GetJsonIetfVal()) + config.fromBody(ctx, getResp) } config.Id = types.StringValue(config.getPath()) diff --git a/internal/provider/data_source_iosxr_pce.go b/internal/provider/data_source_iosxr_pce.go index e9fd897b..27e48635 100644 --- a/internal/provider/data_source_iosxr_pce.go +++ b/internal/provider/data_source_iosxr_pce.go @@ -152,11 +152,11 @@ func (d *PCEDataSource) Read(ctx context.Context, req datasource.ReadRequest, re if device.Managed { getResp, err := d.data.Client.Get(ctx, config.Device.ValueString(), config.getPath()) if err != nil { - resp.Diagnostics.AddError("Unable to apply gNMI Get operation", err.Error()) + resp.Diagnostics.AddError("Unable to apply Get operation", err.Error()) return } - config.fromBody(ctx, getResp.Notification[0].Update[0].Val.GetJsonIetfVal()) + config.fromBody(ctx, getResp) } config.Id = types.StringValue(config.getPath()) diff --git a/internal/provider/data_source_iosxr_policy_map_qos.go b/internal/provider/data_source_iosxr_policy_map_qos.go index 1aa1d7dd..182b5c71 100644 --- a/internal/provider/data_source_iosxr_policy_map_qos.go +++ b/internal/provider/data_source_iosxr_policy_map_qos.go @@ -208,11 +208,11 @@ func (d *PolicyMapQoSDataSource) Read(ctx context.Context, req datasource.ReadRe if device.Managed { getResp, err := d.data.Client.Get(ctx, config.Device.ValueString(), config.getPath()) if err != nil { - resp.Diagnostics.AddError("Unable to apply gNMI Get operation", err.Error()) + resp.Diagnostics.AddError("Unable to apply Get operation", err.Error()) return } - config.fromBody(ctx, getResp.Notification[0].Update[0].Val.GetJsonIetfVal()) + config.fromBody(ctx, getResp) } config.Id = types.StringValue(config.getPath()) diff --git a/internal/provider/data_source_iosxr_prefix_set.go b/internal/provider/data_source_iosxr_prefix_set.go index c2568c7f..03c1d387 100644 --- a/internal/provider/data_source_iosxr_prefix_set.go +++ b/internal/provider/data_source_iosxr_prefix_set.go @@ -112,11 +112,11 @@ func (d *PrefixSetDataSource) Read(ctx context.Context, req datasource.ReadReque if device.Managed { getResp, err := d.data.Client.Get(ctx, config.Device.ValueString(), config.getPath()) if err != nil { - resp.Diagnostics.AddError("Unable to apply gNMI Get operation", err.Error()) + resp.Diagnostics.AddError("Unable to apply Get operation", err.Error()) return } - config.fromBody(ctx, getResp.Notification[0].Update[0].Val.GetJsonIetfVal()) + config.fromBody(ctx, getResp) } config.Id = types.StringValue(config.getPath()) diff --git a/internal/provider/data_source_iosxr_rd_set.go b/internal/provider/data_source_iosxr_rd_set.go index 0d4d197e..aa54b09e 100644 --- a/internal/provider/data_source_iosxr_rd_set.go +++ b/internal/provider/data_source_iosxr_rd_set.go @@ -112,11 +112,11 @@ func (d *RDSetDataSource) Read(ctx context.Context, req datasource.ReadRequest, if device.Managed { getResp, err := d.data.Client.Get(ctx, config.Device.ValueString(), config.getPath()) if err != nil { - resp.Diagnostics.AddError("Unable to apply gNMI Get operation", err.Error()) + resp.Diagnostics.AddError("Unable to apply Get operation", err.Error()) return } - config.fromBody(ctx, getResp.Notification[0].Update[0].Val.GetJsonIetfVal()) + config.fromBody(ctx, getResp) } config.Id = types.StringValue(config.getPath()) diff --git a/internal/provider/data_source_iosxr_route_policy.go b/internal/provider/data_source_iosxr_route_policy.go index 3d6ae346..74676ae5 100644 --- a/internal/provider/data_source_iosxr_route_policy.go +++ b/internal/provider/data_source_iosxr_route_policy.go @@ -112,11 +112,11 @@ func (d *RoutePolicyDataSource) Read(ctx context.Context, req datasource.ReadReq if device.Managed { getResp, err := d.data.Client.Get(ctx, config.Device.ValueString(), config.getPath()) if err != nil { - resp.Diagnostics.AddError("Unable to apply gNMI Get operation", err.Error()) + resp.Diagnostics.AddError("Unable to apply Get operation", err.Error()) return } - config.fromBody(ctx, getResp.Notification[0].Update[0].Val.GetJsonIetfVal()) + config.fromBody(ctx, getResp) } config.Id = types.StringValue(config.getPath()) diff --git a/internal/provider/data_source_iosxr_router_bgp.go b/internal/provider/data_source_iosxr_router_bgp.go index 84556b12..8a37cf3f 100644 --- a/internal/provider/data_source_iosxr_router_bgp.go +++ b/internal/provider/data_source_iosxr_router_bgp.go @@ -79,10 +79,6 @@ func (d *RouterBGPDataSource) Schema(ctx context.Context, req datasource.SchemaR MarkdownDescription: "default redistributed metric", Computed: true, }, - "nsr": schema.BoolAttribute{ - MarkdownDescription: "Enable non-stop-routing support for all neighbors", - Computed: true, - }, "nsr_disable": schema.BoolAttribute{ MarkdownDescription: "Disable non-stop-routing support for all neighbors", Computed: true, @@ -107,10 +103,6 @@ func (d *RouterBGPDataSource) Schema(ctx context.Context, req datasource.SchemaR MarkdownDescription: "Disable keepalives/hold time", Computed: true, }, - "timers_bgp_keepalive_zero_holdtime_zero": schema.BoolAttribute{ - MarkdownDescription: "Disable keepalives/hold time", - Computed: true, - }, "timers_bgp_keepalive_zero_minimum_acceptable_holdtime": schema.Int64Attribute{ MarkdownDescription: "Minimum acceptable holdtime from neighbor", Computed: true, @@ -119,6 +111,10 @@ func (d *RouterBGPDataSource) Schema(ctx context.Context, req datasource.SchemaR MarkdownDescription: "Holdtime", Computed: true, }, + "timers_bgp_holdtime_zero": schema.BoolAttribute{ + MarkdownDescription: "Disable keepalives/hold time", + Computed: true, + }, "timers_bgp_holdtime_minimum_acceptable_holdtime": schema.Int64Attribute{ MarkdownDescription: "Minimum acceptable holdtime from neighbor", Computed: true, @@ -284,18 +280,18 @@ func (d *RouterBGPDataSource) Schema(ctx context.Context, req datasource.SchemaR MarkdownDescription: "Disable keepalives/hold time", Computed: true, }, - "timers_keepalive_zero_holdtime_zero": schema.BoolAttribute{ - MarkdownDescription: "Disable keepalives/hold time", - Computed: true, - }, "timers_keepalive_zero_minimum_acceptable_holdtime": schema.Int64Attribute{ MarkdownDescription: "Minimum acceptable holdtime from neighbor", Computed: true, }, - "timers_holdtime": schema.Int64Attribute{ + "timers_holdtime_number": schema.Int64Attribute{ MarkdownDescription: "Holdtime", Computed: true, }, + "timers_holdtime_zero": schema.BoolAttribute{ + MarkdownDescription: "Disable keepalives/hold time", + Computed: true, + }, "timers_holdtime_minimum_acceptable_holdtime": schema.Int64Attribute{ MarkdownDescription: "Minimum acceptable holdtime from neighbor", Computed: true, @@ -348,11 +344,11 @@ func (d *RouterBGPDataSource) Read(ctx context.Context, req datasource.ReadReque if device.Managed { getResp, err := d.data.Client.Get(ctx, config.Device.ValueString(), config.getPath()) if err != nil { - resp.Diagnostics.AddError("Unable to apply gNMI Get operation", err.Error()) + resp.Diagnostics.AddError("Unable to apply Get operation", err.Error()) return } - config.fromBody(ctx, getResp.Notification[0].Update[0].Val.GetJsonIetfVal()) + config.fromBody(ctx, getResp) } config.Id = types.StringValue(config.getPath()) diff --git a/internal/provider/data_source_iosxr_router_bgp_address_family.go b/internal/provider/data_source_iosxr_router_bgp_address_family.go index 36af34d4..1f4af853 100644 --- a/internal/provider/data_source_iosxr_router_bgp_address_family.go +++ b/internal/provider/data_source_iosxr_router_bgp_address_family.go @@ -127,10 +127,6 @@ func (d *RouterBGPAddressFamilyDataSource) Schema(ctx context.Context, req datas MarkdownDescription: "Number of paths (limit includes backup path)", Computed: true, }, - "maximum_paths_ibgp_unequal_cost": schema.BoolAttribute{ - MarkdownDescription: "Allow multipaths to have different BGP nexthop IGP metrics", - Computed: true, - }, "maximum_paths_ibgp_unequal_cost_deterministic": schema.BoolAttribute{ MarkdownDescription: "Deterministic Multipath selection primarily on IGP metric order", Computed: true, @@ -736,11 +732,11 @@ func (d *RouterBGPAddressFamilyDataSource) Read(ctx context.Context, req datasou if device.Managed { getResp, err := d.data.Client.Get(ctx, config.Device.ValueString(), config.getPath()) if err != nil { - resp.Diagnostics.AddError("Unable to apply gNMI Get operation", err.Error()) + resp.Diagnostics.AddError("Unable to apply Get operation", err.Error()) return } - config.fromBody(ctx, getResp.Notification[0].Update[0].Val.GetJsonIetfVal()) + config.fromBody(ctx, getResp) } config.Id = types.StringValue(config.getPath()) diff --git a/internal/provider/data_source_iosxr_router_bgp_address_family_test.go b/internal/provider/data_source_iosxr_router_bgp_address_family_test.go index e3f83bd1..25c80334 100644 --- a/internal/provider/data_source_iosxr_router_bgp_address_family_test.go +++ b/internal/provider/data_source_iosxr_router_bgp_address_family_test.go @@ -40,12 +40,9 @@ func TestAccDataSourceIosxrRouterBGPAddressFamily(t *testing.T) { checks = append(checks, resource.TestCheckResourceAttr("data.iosxr_router_bgp_address_family.test", "advertise_best_external", "true")) checks = append(checks, resource.TestCheckResourceAttr("data.iosxr_router_bgp_address_family.test", "maximum_paths_ebgp_multipath", "10")) checks = append(checks, resource.TestCheckResourceAttr("data.iosxr_router_bgp_address_family.test", "maximum_paths_ebgp_selective", "true")) - checks = append(checks, resource.TestCheckResourceAttr("data.iosxr_router_bgp_address_family.test", "maximum_paths_ebgp_route_policy", "MULTIPATH_POLICY")) checks = append(checks, resource.TestCheckResourceAttr("data.iosxr_router_bgp_address_family.test", "maximum_paths_ibgp_multipath", "10")) - checks = append(checks, resource.TestCheckResourceAttr("data.iosxr_router_bgp_address_family.test", "maximum_paths_ibgp_unequal_cost", "true")) checks = append(checks, resource.TestCheckResourceAttr("data.iosxr_router_bgp_address_family.test", "maximum_paths_ibgp_unequal_cost_deterministic", "true")) checks = append(checks, resource.TestCheckResourceAttr("data.iosxr_router_bgp_address_family.test", "maximum_paths_ibgp_selective", "true")) - checks = append(checks, resource.TestCheckResourceAttr("data.iosxr_router_bgp_address_family.test", "maximum_paths_ibgp_route_policy", "MULTIPATH_POLICY")) checks = append(checks, resource.TestCheckResourceAttr("data.iosxr_router_bgp_address_family.test", "maximum_paths_unique_nexthop_check_disable", "true")) checks = append(checks, resource.TestCheckResourceAttr("data.iosxr_router_bgp_address_family.test", "nexthop_trigger_delay_critical", "10")) checks = append(checks, resource.TestCheckResourceAttr("data.iosxr_router_bgp_address_family.test", "nexthop_trigger_delay_non_critical", "20")) @@ -65,6 +62,7 @@ func TestAccDataSourceIosxrRouterBGPAddressFamily(t *testing.T) { checks = append(checks, resource.TestCheckResourceAttr("data.iosxr_router_bgp_address_family.test", "redistribute_ospf.0.multipath", "true")) checks = append(checks, resource.TestCheckResourceAttr("data.iosxr_router_bgp_address_family.test", "redistribute_ospf.0.route_policy", "REDISTRIBUTE_POLICY")) checks = append(checks, resource.TestCheckResourceAttr("data.iosxr_router_bgp_address_family.test", "redistribute_eigrp.0.instance_name", "EIGRP1")) + checks = append(checks, resource.TestCheckResourceAttr("data.iosxr_router_bgp_address_family.test", "redistribute_eigrp.0.match_internal", "true")) checks = append(checks, resource.TestCheckResourceAttr("data.iosxr_router_bgp_address_family.test", "redistribute_eigrp.0.match_internal_external", "true")) checks = append(checks, resource.TestCheckResourceAttr("data.iosxr_router_bgp_address_family.test", "redistribute_eigrp.0.metric", "100")) checks = append(checks, resource.TestCheckResourceAttr("data.iosxr_router_bgp_address_family.test", "redistribute_eigrp.0.multipath", "true")) @@ -166,12 +164,9 @@ func testAccDataSourceIosxrRouterBGPAddressFamilyConfig() string { config += ` advertise_best_external = true` + "\n" config += ` maximum_paths_ebgp_multipath = 10` + "\n" config += ` maximum_paths_ebgp_selective = true` + "\n" - config += ` maximum_paths_ebgp_route_policy = "MULTIPATH_POLICY"` + "\n" config += ` maximum_paths_ibgp_multipath = 10` + "\n" - config += ` maximum_paths_ibgp_unequal_cost = true` + "\n" config += ` maximum_paths_ibgp_unequal_cost_deterministic = true` + "\n" config += ` maximum_paths_ibgp_selective = true` + "\n" - config += ` maximum_paths_ibgp_route_policy = "MULTIPATH_POLICY"` + "\n" config += ` maximum_paths_unique_nexthop_check_disable = true` + "\n" config += ` nexthop_trigger_delay_critical = 10` + "\n" config += ` nexthop_trigger_delay_non_critical = 20` + "\n" @@ -198,6 +193,7 @@ func testAccDataSourceIosxrRouterBGPAddressFamilyConfig() string { config += ` }]` + "\n" config += ` redistribute_eigrp = [{` + "\n" config += ` instance_name = "EIGRP1"` + "\n" + config += ` match_internal = true` + "\n" config += ` match_internal_external = true` + "\n" config += ` metric = 100` + "\n" config += ` multipath = true` + "\n" diff --git a/internal/provider/data_source_iosxr_router_bgp_neighbor_address_family.go b/internal/provider/data_source_iosxr_router_bgp_neighbor_address_family.go index c9e85ca3..618ecbbb 100644 --- a/internal/provider/data_source_iosxr_router_bgp_neighbor_address_family.go +++ b/internal/provider/data_source_iosxr_router_bgp_neighbor_address_family.go @@ -103,14 +103,6 @@ func (d *RouterBGPNeighborAddressFamilyDataSource) Schema(ctx context.Context, r MarkdownDescription: "Prevent route-reflector-client from being inherited from the parent", Computed: true, }, - "advertise_vpnv4_unicast": schema.BoolAttribute{ - MarkdownDescription: "Enable advertise vpnv4 unicast", - Computed: true, - }, - "advertise_vpnv4_unicast_re_originated": schema.BoolAttribute{ - MarkdownDescription: "Advertise re-orignated and local routes only", - Computed: true, - }, "advertise_vpnv4_unicast_re_originated_stitching_rt": schema.BoolAttribute{ MarkdownDescription: "Advertise re-originated and local routes with stitching Route-Targets", Computed: true, @@ -135,10 +127,6 @@ func (d *RouterBGPNeighborAddressFamilyDataSource) Schema(ctx context.Context, r MarkdownDescription: "Apply route policy to outbound routes", Computed: true, }, - "soft_reconfiguration_inbound": schema.BoolAttribute{ - MarkdownDescription: "Allow inbound soft reconfiguration for this neighbor", - Computed: true, - }, "soft_reconfiguration_inbound_always": schema.BoolAttribute{ MarkdownDescription: "Always use soft reconfig, even if route refresh is supported", Computed: true, @@ -220,11 +208,11 @@ func (d *RouterBGPNeighborAddressFamilyDataSource) Read(ctx context.Context, req if device.Managed { getResp, err := d.data.Client.Get(ctx, config.Device.ValueString(), config.getPath()) if err != nil { - resp.Diagnostics.AddError("Unable to apply gNMI Get operation", err.Error()) + resp.Diagnostics.AddError("Unable to apply Get operation", err.Error()) return } - config.fromBody(ctx, getResp.Notification[0].Update[0].Val.GetJsonIetfVal()) + config.fromBody(ctx, getResp) } config.Id = types.StringValue(config.getPath()) diff --git a/internal/provider/data_source_iosxr_router_bgp_neighbor_address_family_test.go b/internal/provider/data_source_iosxr_router_bgp_neighbor_address_family_test.go index 5f894c57..86ca39d4 100644 --- a/internal/provider/data_source_iosxr_router_bgp_neighbor_address_family_test.go +++ b/internal/provider/data_source_iosxr_router_bgp_neighbor_address_family_test.go @@ -32,23 +32,20 @@ import ( func TestAccDataSourceIosxrRouterBGPNeighborAddressFamily(t *testing.T) { var checks []resource.TestCheckFunc + checks = append(checks, resource.TestCheckResourceAttr("data.iosxr_router_bgp_neighbor_address_family.test", "import_stitching_rt_re_originate_stitching_rt", "true")) checks = append(checks, resource.TestCheckResourceAttr("data.iosxr_router_bgp_neighbor_address_family.test", "route_reflector_client", "true")) checks = append(checks, resource.TestCheckResourceAttr("data.iosxr_router_bgp_neighbor_address_family.test", "route_reflector_client_inheritance_disable", "true")) - checks = append(checks, resource.TestCheckResourceAttr("data.iosxr_router_bgp_neighbor_address_family.test", "advertise_vpnv4_unicast", "true")) - checks = append(checks, resource.TestCheckResourceAttr("data.iosxr_router_bgp_neighbor_address_family.test", "advertise_vpnv4_unicast_re_originated", "true")) checks = append(checks, resource.TestCheckResourceAttr("data.iosxr_router_bgp_neighbor_address_family.test", "advertise_vpnv4_unicast_re_originated_stitching_rt", "true")) checks = append(checks, resource.TestCheckResourceAttr("data.iosxr_router_bgp_neighbor_address_family.test", "next_hop_self", "true")) checks = append(checks, resource.TestCheckResourceAttr("data.iosxr_router_bgp_neighbor_address_family.test", "next_hop_self_inheritance_disable", "true")) checks = append(checks, resource.TestCheckResourceAttr("data.iosxr_router_bgp_neighbor_address_family.test", "encapsulation_type", "srv6")) checks = append(checks, resource.TestCheckResourceAttr("data.iosxr_router_bgp_neighbor_address_family.test", "route_policy_in", "ROUTE_POLICY_1")) checks = append(checks, resource.TestCheckResourceAttr("data.iosxr_router_bgp_neighbor_address_family.test", "route_policy_out", "ROUTE_POLICY_1")) - checks = append(checks, resource.TestCheckResourceAttr("data.iosxr_router_bgp_neighbor_address_family.test", "soft_reconfiguration_inbound", "true")) checks = append(checks, resource.TestCheckResourceAttr("data.iosxr_router_bgp_neighbor_address_family.test", "soft_reconfiguration_inbound_always", "true")) checks = append(checks, resource.TestCheckResourceAttr("data.iosxr_router_bgp_neighbor_address_family.test", "maximum_prefix_limit", "1248576")) checks = append(checks, resource.TestCheckResourceAttr("data.iosxr_router_bgp_neighbor_address_family.test", "maximum_prefix_threshold", "80")) checks = append(checks, resource.TestCheckResourceAttr("data.iosxr_router_bgp_neighbor_address_family.test", "maximum_prefix_warning_only", "true")) checks = append(checks, resource.TestCheckResourceAttr("data.iosxr_router_bgp_neighbor_address_family.test", "default_originate", "true")) - checks = append(checks, resource.TestCheckResourceAttr("data.iosxr_router_bgp_neighbor_address_family.test", "default_originate_route_policy", "ROUTE_POLICY_1")) resource.Test(t, resource.TestCase{ PreCheck: func() { testAccPreCheck(t) }, ProtoV6ProviderFactories: testAccProtoV6ProviderFactories, @@ -113,23 +110,20 @@ func testAccDataSourceIosxrRouterBGPNeighborAddressFamilyConfig() string { config += ` as_number = "65001"` + "\n" config += ` address = "10.1.1.2"` + "\n" config += ` af_name = "vpnv4-unicast"` + "\n" + config += ` import_stitching_rt_re_originate_stitching_rt = true` + "\n" config += ` route_reflector_client = true` + "\n" config += ` route_reflector_client_inheritance_disable = true` + "\n" - config += ` advertise_vpnv4_unicast = true` + "\n" - config += ` advertise_vpnv4_unicast_re_originated = true` + "\n" config += ` advertise_vpnv4_unicast_re_originated_stitching_rt = true` + "\n" config += ` next_hop_self = true` + "\n" config += ` next_hop_self_inheritance_disable = true` + "\n" config += ` encapsulation_type = "srv6"` + "\n" config += ` route_policy_in = "ROUTE_POLICY_1"` + "\n" config += ` route_policy_out = "ROUTE_POLICY_1"` + "\n" - config += ` soft_reconfiguration_inbound = true` + "\n" config += ` soft_reconfiguration_inbound_always = true` + "\n" config += ` maximum_prefix_limit = 1248576` + "\n" config += ` maximum_prefix_threshold = 80` + "\n" config += ` maximum_prefix_warning_only = true` + "\n" config += ` default_originate = true` + "\n" - config += ` default_originate_route_policy = "ROUTE_POLICY_1"` + "\n" config += ` depends_on = [iosxr_gnmi.PreReq0, iosxr_gnmi.PreReq1, ]` + "\n" config += `}` + "\n" diff --git a/internal/provider/data_source_iosxr_router_bgp_neighbor_group.go b/internal/provider/data_source_iosxr_router_bgp_neighbor_group.go index 18b85792..1cf2f67b 100644 --- a/internal/provider/data_source_iosxr_router_bgp_neighbor_group.go +++ b/internal/provider/data_source_iosxr_router_bgp_neighbor_group.go @@ -167,10 +167,6 @@ func (d *RouterBGPNeighborGroupDataSource) Schema(ctx context.Context, req datas MarkdownDescription: "Disable keepalives/hold time", Computed: true, }, - "timers_keepalive_zero_holdtime_zero": schema.BoolAttribute{ - MarkdownDescription: "Disable keepalives/hold time", - Computed: true, - }, "timers_keepalive_zero_minimum_acceptable_holdtime": schema.Int64Attribute{ MarkdownDescription: "Minimum acceptable holdtime from neighbor", Computed: true, @@ -179,6 +175,10 @@ func (d *RouterBGPNeighborGroupDataSource) Schema(ctx context.Context, req datas MarkdownDescription: "Holdtime", Computed: true, }, + "timers_holdtime_zero": schema.BoolAttribute{ + MarkdownDescription: "Disable keepalives/hold time", + Computed: true, + }, "timers_holdtime_minimum_acceptable_holdtime": schema.Int64Attribute{ MarkdownDescription: "Minimum acceptable holdtime from neighbor", Computed: true, @@ -264,11 +264,11 @@ func (d *RouterBGPNeighborGroupDataSource) Read(ctx context.Context, req datasou if device.Managed { getResp, err := d.data.Client.Get(ctx, config.Device.ValueString(), config.getPath()) if err != nil { - resp.Diagnostics.AddError("Unable to apply gNMI Get operation", err.Error()) + resp.Diagnostics.AddError("Unable to apply Get operation", err.Error()) return } - config.fromBody(ctx, getResp.Notification[0].Update[0].Val.GetJsonIetfVal()) + config.fromBody(ctx, getResp) } config.Id = types.StringValue(config.getPath()) diff --git a/internal/provider/data_source_iosxr_router_bgp_neighbor_group_test.go b/internal/provider/data_source_iosxr_router_bgp_neighbor_group_test.go index c2ef5e2e..d2eedcc8 100644 --- a/internal/provider/data_source_iosxr_router_bgp_neighbor_group_test.go +++ b/internal/provider/data_source_iosxr_router_bgp_neighbor_group_test.go @@ -40,11 +40,11 @@ func TestAccDataSourceIosxrRouterBGPNeighborGroup(t *testing.T) { checks = append(checks, resource.TestCheckResourceAttr("data.iosxr_router_bgp_neighbor_group.test", "bfd_multiplier", "4")) checks = append(checks, resource.TestCheckResourceAttr("data.iosxr_router_bgp_neighbor_group.test", "bfd_fast_detect", "true")) checks = append(checks, resource.TestCheckResourceAttr("data.iosxr_router_bgp_neighbor_group.test", "bfd_fast_detect_strict_mode", "false")) + checks = append(checks, resource.TestCheckResourceAttr("data.iosxr_router_bgp_neighbor_group.test", "bfd_fast_detect_disable", "false")) checks = append(checks, resource.TestCheckResourceAttr("data.iosxr_router_bgp_neighbor_group.test", "password", "12341C2713181F13253920")) checks = append(checks, resource.TestCheckResourceAttr("data.iosxr_router_bgp_neighbor_group.test", "password_inheritance_disable", "false")) checks = append(checks, resource.TestCheckResourceAttr("data.iosxr_router_bgp_neighbor_group.test", "timers_keepalive_interval", "10")) - checks = append(checks, resource.TestCheckResourceAttr("data.iosxr_router_bgp_neighbor_group.test", "timers_holdtime", "30")) - checks = append(checks, resource.TestCheckResourceAttr("data.iosxr_router_bgp_neighbor_group.test", "timers_holdtime_minimum_acceptable_holdtime", "30")) + checks = append(checks, resource.TestCheckResourceAttr("data.iosxr_router_bgp_neighbor_group.test", "timers_holdtime", "20")) checks = append(checks, resource.TestCheckResourceAttr("data.iosxr_router_bgp_neighbor_group.test", "address_families.0.af_name", "ipv4-labeled-unicast")) checks = append(checks, resource.TestCheckResourceAttr("data.iosxr_router_bgp_neighbor_group.test", "address_families.0.soft_reconfiguration_inbound_always", "true")) checks = append(checks, resource.TestCheckResourceAttr("data.iosxr_router_bgp_neighbor_group.test", "address_families.0.next_hop_self", "true")) @@ -103,11 +103,11 @@ func testAccDataSourceIosxrRouterBGPNeighborGroupConfig() string { config += ` bfd_multiplier = 4` + "\n" config += ` bfd_fast_detect = true` + "\n" config += ` bfd_fast_detect_strict_mode = false` + "\n" + config += ` bfd_fast_detect_disable = false` + "\n" config += ` password = "12341C2713181F13253920"` + "\n" config += ` password_inheritance_disable = false` + "\n" config += ` timers_keepalive_interval = 10` + "\n" - config += ` timers_holdtime = 30` + "\n" - config += ` timers_holdtime_minimum_acceptable_holdtime = 30` + "\n" + config += ` timers_holdtime = 20` + "\n" config += ` address_families = [{` + "\n" config += ` af_name = "ipv4-labeled-unicast"` + "\n" config += ` soft_reconfiguration_inbound_always = true` + "\n" diff --git a/internal/provider/data_source_iosxr_router_bgp_test.go b/internal/provider/data_source_iosxr_router_bgp_test.go index 4cb4261d..712a5c0f 100644 --- a/internal/provider/data_source_iosxr_router_bgp_test.go +++ b/internal/provider/data_source_iosxr_router_bgp_test.go @@ -34,14 +34,12 @@ func TestAccDataSourceIosxrRouterBGP(t *testing.T) { var checks []resource.TestCheckFunc checks = append(checks, resource.TestCheckResourceAttr("data.iosxr_router_bgp.test", "default_information_originate", "true")) checks = append(checks, resource.TestCheckResourceAttr("data.iosxr_router_bgp.test", "default_metric", "125")) - checks = append(checks, resource.TestCheckResourceAttr("data.iosxr_router_bgp.test", "nsr", "true")) checks = append(checks, resource.TestCheckResourceAttr("data.iosxr_router_bgp.test", "nsr_disable", "false")) checks = append(checks, resource.TestCheckResourceAttr("data.iosxr_router_bgp.test", "bgp_redistribute_internal", "true")) checks = append(checks, resource.TestCheckResourceAttr("data.iosxr_router_bgp.test", "segment_routing_srv6_locator", "locator11")) checks = append(checks, resource.TestCheckResourceAttr("data.iosxr_router_bgp.test", "segment_routing_srv6_usid_allocation_wide_local_id_block", "true")) - checks = append(checks, resource.TestCheckResourceAttr("data.iosxr_router_bgp.test", "timers_bgp_keepalive_interval", "10")) - checks = append(checks, resource.TestCheckResourceAttr("data.iosxr_router_bgp.test", "timers_bgp_holdtime", "30")) - checks = append(checks, resource.TestCheckResourceAttr("data.iosxr_router_bgp.test", "timers_bgp_holdtime_minimum_acceptable_holdtime", "30")) + checks = append(checks, resource.TestCheckResourceAttr("data.iosxr_router_bgp.test", "timers_bgp_keepalive_interval", "5")) + checks = append(checks, resource.TestCheckResourceAttr("data.iosxr_router_bgp.test", "timers_bgp_holdtime", "20")) checks = append(checks, resource.TestCheckResourceAttr("data.iosxr_router_bgp.test", "bgp_router_id", "22.22.22.22")) checks = append(checks, resource.TestCheckResourceAttr("data.iosxr_router_bgp.test", "bgp_graceful_restart_graceful_reset", "true")) checks = append(checks, resource.TestCheckResourceAttr("data.iosxr_router_bgp.test", "ibgp_policy_out_enforce_modifications", "true")) @@ -49,7 +47,6 @@ func TestAccDataSourceIosxrRouterBGP(t *testing.T) { checks = append(checks, resource.TestCheckResourceAttr("data.iosxr_router_bgp.test", "bfd_minimum_interval", "10")) checks = append(checks, resource.TestCheckResourceAttr("data.iosxr_router_bgp.test", "bfd_multiplier", "4")) checks = append(checks, resource.TestCheckResourceAttr("data.iosxr_router_bgp.test", "nexthop_validation_color_extcomm_sr_policy", "true")) - checks = append(checks, resource.TestCheckResourceAttr("data.iosxr_router_bgp.test", "bgp_bestpath_as_path_ignore", "true")) checks = append(checks, resource.TestCheckResourceAttr("data.iosxr_router_bgp.test", "bgp_bestpath_as_path_multipath_relax", "true")) checks = append(checks, resource.TestCheckResourceAttr("data.iosxr_router_bgp.test", "bgp_bestpath_cost_community_ignore", "true")) checks = append(checks, resource.TestCheckResourceAttr("data.iosxr_router_bgp.test", "bgp_bestpath_compare_routerid", "true")) @@ -70,12 +67,10 @@ func TestAccDataSourceIosxrRouterBGP(t *testing.T) { checks = append(checks, resource.TestCheckResourceAttr("data.iosxr_router_bgp.test", "neighbors.0.bfd_multiplier", "4")) checks = append(checks, resource.TestCheckResourceAttr("data.iosxr_router_bgp.test", "neighbors.0.bfd_fast_detect", "true")) checks = append(checks, resource.TestCheckResourceAttr("data.iosxr_router_bgp.test", "neighbors.0.bfd_fast_detect_strict_mode", "false")) - checks = append(checks, resource.TestCheckResourceAttr("data.iosxr_router_bgp.test", "neighbors.0.bfd_fast_detect_disable", "false")) checks = append(checks, resource.TestCheckResourceAttr("data.iosxr_router_bgp.test", "neighbors.0.password", "12341C2713181F13253920")) checks = append(checks, resource.TestCheckResourceAttr("data.iosxr_router_bgp.test", "neighbors.0.shutdown", "false")) checks = append(checks, resource.TestCheckResourceAttr("data.iosxr_router_bgp.test", "neighbors.0.timers_keepalive_interval", "10")) - checks = append(checks, resource.TestCheckResourceAttr("data.iosxr_router_bgp.test", "neighbors.0.timers_holdtime", "30")) - checks = append(checks, resource.TestCheckResourceAttr("data.iosxr_router_bgp.test", "neighbors.0.timers_holdtime_minimum_acceptable_holdtime", "30")) + checks = append(checks, resource.TestCheckResourceAttr("data.iosxr_router_bgp.test", "neighbors.0.timers_holdtime_number", "20")) checks = append(checks, resource.TestCheckResourceAttr("data.iosxr_router_bgp.test", "neighbors.0.update_source", "GigabitEthernet0/0/0/1")) checks = append(checks, resource.TestCheckResourceAttr("data.iosxr_router_bgp.test", "neighbors.0.ttl_security", "false")) resource.Test(t, resource.TestCase{ @@ -125,14 +120,12 @@ func testAccDataSourceIosxrRouterBGPConfig() string { config += ` as_number = "65001"` + "\n" config += ` default_information_originate = true` + "\n" config += ` default_metric = 125` + "\n" - config += ` nsr = true` + "\n" config += ` nsr_disable = false` + "\n" config += ` bgp_redistribute_internal = true` + "\n" config += ` segment_routing_srv6_locator = "locator11"` + "\n" config += ` segment_routing_srv6_usid_allocation_wide_local_id_block = true` + "\n" - config += ` timers_bgp_keepalive_interval = 10` + "\n" - config += ` timers_bgp_holdtime = 30` + "\n" - config += ` timers_bgp_holdtime_minimum_acceptable_holdtime = 30` + "\n" + config += ` timers_bgp_keepalive_interval = 5` + "\n" + config += ` timers_bgp_holdtime = 20` + "\n" config += ` bgp_router_id = "22.22.22.22"` + "\n" config += ` bgp_graceful_restart_graceful_reset = true` + "\n" config += ` ibgp_policy_out_enforce_modifications = true` + "\n" @@ -140,7 +133,6 @@ func testAccDataSourceIosxrRouterBGPConfig() string { config += ` bfd_minimum_interval = 10` + "\n" config += ` bfd_multiplier = 4` + "\n" config += ` nexthop_validation_color_extcomm_sr_policy = true` + "\n" - config += ` bgp_bestpath_as_path_ignore = true` + "\n" config += ` bgp_bestpath_as_path_multipath_relax = true` + "\n" config += ` bgp_bestpath_cost_community_ignore = true` + "\n" config += ` bgp_bestpath_compare_routerid = true` + "\n" @@ -162,12 +154,10 @@ func testAccDataSourceIosxrRouterBGPConfig() string { config += ` bfd_multiplier = 4` + "\n" config += ` bfd_fast_detect = true` + "\n" config += ` bfd_fast_detect_strict_mode = false` + "\n" - config += ` bfd_fast_detect_disable = false` + "\n" config += ` password = "12341C2713181F13253920"` + "\n" config += ` shutdown = false` + "\n" config += ` timers_keepalive_interval = 10` + "\n" - config += ` timers_holdtime = 30` + "\n" - config += ` timers_holdtime_minimum_acceptable_holdtime = 30` + "\n" + config += ` timers_holdtime_number = 20` + "\n" config += ` update_source = "GigabitEthernet0/0/0/1"` + "\n" config += ` ttl_security = false` + "\n" config += ` }]` + "\n" diff --git a/internal/provider/data_source_iosxr_router_bgp_vrf.go b/internal/provider/data_source_iosxr_router_bgp_vrf.go index 86e3f606..ab5258c9 100644 --- a/internal/provider/data_source_iosxr_router_bgp_vrf.go +++ b/internal/provider/data_source_iosxr_router_bgp_vrf.go @@ -119,10 +119,6 @@ func (d *RouterBGPVRFDataSource) Schema(ctx context.Context, req datasource.Sche MarkdownDescription: "Disable keepalives/hold time", Computed: true, }, - "timers_bgp_keepalive_zero_holdtime_zero": schema.BoolAttribute{ - MarkdownDescription: "Disable keepalives/hold time", - Computed: true, - }, "timers_bgp_keepalive_zero_minimum_acceptable_holdtime": schema.Int64Attribute{ MarkdownDescription: "Minimum acceptable holdtime from neighbor", Computed: true, @@ -131,6 +127,10 @@ func (d *RouterBGPVRFDataSource) Schema(ctx context.Context, req datasource.Sche MarkdownDescription: "Holdtime", Computed: true, }, + "timers_bgp_holdtime_zero": schema.BoolAttribute{ + MarkdownDescription: "Disable keepalives/hold time", + Computed: true, + }, "timers_bgp_holdtime_minimum_acceptable_holdtime": schema.Int64Attribute{ MarkdownDescription: "Minimum acceptable holdtime from neighbor", Computed: true, @@ -216,11 +216,11 @@ func (d *RouterBGPVRFDataSource) Schema(ctx context.Context, req datasource.Sche MarkdownDescription: "Do not prepend local AS to announcements from this neighbor", Computed: true, }, - "local_as_no_prepend_replace_as": schema.BoolAttribute{ + "local_as_replace_as": schema.BoolAttribute{ MarkdownDescription: "Prepend only local AS to announcements to this neighbor", Computed: true, }, - "local_as_no_prepend_replace_as_dual_as": schema.BoolAttribute{ + "local_as_dual_as": schema.BoolAttribute{ MarkdownDescription: "Dual-AS mode", Computed: true, }, @@ -244,10 +244,6 @@ func (d *RouterBGPVRFDataSource) Schema(ctx context.Context, req datasource.Sche MarkdownDescription: "Disable keepalives/hold time", Computed: true, }, - "timers_keepalive_zero_holdtime_zero": schema.BoolAttribute{ - MarkdownDescription: "Disable keepalives/hold time", - Computed: true, - }, "timers_keepalive_zero_minimum_acceptable_holdtime": schema.Int64Attribute{ MarkdownDescription: "Minimum acceptable holdtime from neighbor", Computed: true, @@ -256,6 +252,10 @@ func (d *RouterBGPVRFDataSource) Schema(ctx context.Context, req datasource.Sche MarkdownDescription: "Holdtime", Computed: true, }, + "timers_holdtime_zero": schema.BoolAttribute{ + MarkdownDescription: "Disable keepalives/hold time", + Computed: true, + }, "timers_holdtime_minimum_acceptable_holdtime": schema.Int64Attribute{ MarkdownDescription: "Minimum acceptable holdtime from neighbor", Computed: true, @@ -308,11 +308,11 @@ func (d *RouterBGPVRFDataSource) Read(ctx context.Context, req datasource.ReadRe if device.Managed { getResp, err := d.data.Client.Get(ctx, config.Device.ValueString(), config.getPath()) if err != nil { - resp.Diagnostics.AddError("Unable to apply gNMI Get operation", err.Error()) + resp.Diagnostics.AddError("Unable to apply Get operation", err.Error()) return } - config.fromBody(ctx, getResp.Notification[0].Update[0].Val.GetJsonIetfVal()) + config.fromBody(ctx, getResp) } config.Id = types.StringValue(config.getPath()) diff --git a/internal/provider/data_source_iosxr_router_bgp_vrf_address_family.go b/internal/provider/data_source_iosxr_router_bgp_vrf_address_family.go index 30b92b66..279fe440 100644 --- a/internal/provider/data_source_iosxr_router_bgp_vrf_address_family.go +++ b/internal/provider/data_source_iosxr_router_bgp_vrf_address_family.go @@ -139,10 +139,6 @@ func (d *RouterBGPVRFAddressFamilyDataSource) Schema(ctx context.Context, req da MarkdownDescription: "Number of paths (limit includes backup path)", Computed: true, }, - "maximum_paths_ibgp_unequal_cost": schema.BoolAttribute{ - MarkdownDescription: "Allow multipaths to have different BGP nexthop IGP metrics", - Computed: true, - }, "maximum_paths_ibgp_unequal_cost_deterministic": schema.BoolAttribute{ MarkdownDescription: "Deterministic Multipath selection primarily on IGP metric order", Computed: true, @@ -760,11 +756,11 @@ func (d *RouterBGPVRFAddressFamilyDataSource) Read(ctx context.Context, req data if device.Managed { getResp, err := d.data.Client.Get(ctx, config.Device.ValueString(), config.getPath()) if err != nil { - resp.Diagnostics.AddError("Unable to apply gNMI Get operation", err.Error()) + resp.Diagnostics.AddError("Unable to apply Get operation", err.Error()) return } - config.fromBody(ctx, getResp.Notification[0].Update[0].Val.GetJsonIetfVal()) + config.fromBody(ctx, getResp) } config.Id = types.StringValue(config.getPath()) diff --git a/internal/provider/data_source_iosxr_router_bgp_vrf_neighbor_address_family.go b/internal/provider/data_source_iosxr_router_bgp_vrf_neighbor_address_family.go index 0d6d651a..2c80194e 100644 --- a/internal/provider/data_source_iosxr_router_bgp_vrf_neighbor_address_family.go +++ b/internal/provider/data_source_iosxr_router_bgp_vrf_neighbor_address_family.go @@ -91,10 +91,6 @@ func (d *RouterBGPVRFNeighborAddressFamilyDataSource) Schema(ctx context.Context MarkdownDescription: "Apply route policy to outbound routes", Computed: true, }, - "default_originate": schema.BoolAttribute{ - MarkdownDescription: "Originate default route to this neighbor", - Computed: true, - }, "default_originate_route_policy": schema.StringAttribute{ MarkdownDescription: "Route policy to specify criteria to originate default", Computed: true, @@ -184,11 +180,11 @@ func (d *RouterBGPVRFNeighborAddressFamilyDataSource) Read(ctx context.Context, if device.Managed { getResp, err := d.data.Client.Get(ctx, config.Device.ValueString(), config.getPath()) if err != nil { - resp.Diagnostics.AddError("Unable to apply gNMI Get operation", err.Error()) + resp.Diagnostics.AddError("Unable to apply Get operation", err.Error()) return } - config.fromBody(ctx, getResp.Notification[0].Update[0].Val.GetJsonIetfVal()) + config.fromBody(ctx, getResp) } config.Id = types.StringValue(config.getPath()) diff --git a/internal/provider/data_source_iosxr_router_hsrp_interface.go b/internal/provider/data_source_iosxr_router_hsrp_interface.go index a78b2d0a..870785ea 100644 --- a/internal/provider/data_source_iosxr_router_hsrp_interface.go +++ b/internal/provider/data_source_iosxr_router_hsrp_interface.go @@ -136,11 +136,11 @@ func (d *RouterHSRPInterfaceDataSource) Read(ctx context.Context, req datasource if device.Managed { getResp, err := d.data.Client.Get(ctx, config.Device.ValueString(), config.getPath()) if err != nil { - resp.Diagnostics.AddError("Unable to apply gNMI Get operation", err.Error()) + resp.Diagnostics.AddError("Unable to apply Get operation", err.Error()) return } - config.fromBody(ctx, getResp.Notification[0].Update[0].Val.GetJsonIetfVal()) + config.fromBody(ctx, getResp) } config.Id = types.StringValue(config.getPath()) diff --git a/internal/provider/data_source_iosxr_router_hsrp_interface_ipv4_group_v1.go b/internal/provider/data_source_iosxr_router_hsrp_interface_ipv4_group_v1.go index 5b19ea7b..6f143659 100644 --- a/internal/provider/data_source_iosxr_router_hsrp_interface_ipv4_group_v1.go +++ b/internal/provider/data_source_iosxr_router_hsrp_interface_ipv4_group_v1.go @@ -103,15 +103,15 @@ func (d *RouterHSRPInterfaceIPv4GroupV1DataSource) Schema(ctx context.Context, r MarkdownDescription: "Specify hellotime in milliseconds", Computed: true, }, - "timers_msec_holdtime": schema.Int64Attribute{ + "timers_msec2": schema.Int64Attribute{ MarkdownDescription: "Specify hold time in milliseconds", Computed: true, }, - "timers_seconds": schema.Int64Attribute{ + "timers_hold_time": schema.Int64Attribute{ MarkdownDescription: "Hold time in seconds", Computed: true, }, - "timers_seconds_holdtime": schema.Int64Attribute{ + "timers_hold_time2": schema.Int64Attribute{ MarkdownDescription: "Hold time in seconds", Computed: true, }, @@ -204,11 +204,11 @@ func (d *RouterHSRPInterfaceIPv4GroupV1DataSource) Read(ctx context.Context, req if device.Managed { getResp, err := d.data.Client.Get(ctx, config.Device.ValueString(), config.getPath()) if err != nil { - resp.Diagnostics.AddError("Unable to apply gNMI Get operation", err.Error()) + resp.Diagnostics.AddError("Unable to apply Get operation", err.Error()) return } - config.fromBody(ctx, getResp.Notification[0].Update[0].Val.GetJsonIetfVal()) + config.fromBody(ctx, getResp) } config.Id = types.StringValue(config.getPath()) diff --git a/internal/provider/data_source_iosxr_router_hsrp_interface_ipv4_group_v1_test.go b/internal/provider/data_source_iosxr_router_hsrp_interface_ipv4_group_v1_test.go index 01e67f8f..3dc078b4 100644 --- a/internal/provider/data_source_iosxr_router_hsrp_interface_ipv4_group_v1_test.go +++ b/internal/provider/data_source_iosxr_router_hsrp_interface_ipv4_group_v1_test.go @@ -35,14 +35,10 @@ func TestAccDataSourceIosxrRouterHSRPInterfaceIPv4GroupV1(t *testing.T) { checks = append(checks, resource.TestCheckResourceAttr("data.iosxr_router_hsrp_interface_ipv4_group_v1.test", "address", "22.22.1.1")) checks = append(checks, resource.TestCheckResourceAttr("data.iosxr_router_hsrp_interface_ipv4_group_v1.test", "address_learn", "false")) checks = append(checks, resource.TestCheckResourceAttr("data.iosxr_router_hsrp_interface_ipv4_group_v1.test", "priority", "124")) - checks = append(checks, resource.TestCheckResourceAttr("data.iosxr_router_hsrp_interface_ipv4_group_v1.test", "mac_address", "00:01:00:02:00:02")) checks = append(checks, resource.TestCheckResourceAttr("data.iosxr_router_hsrp_interface_ipv4_group_v1.test", "name", "NAME11")) checks = append(checks, resource.TestCheckResourceAttr("data.iosxr_router_hsrp_interface_ipv4_group_v1.test", "preempt_delay", "3200")) - checks = append(checks, resource.TestCheckResourceAttr("data.iosxr_router_hsrp_interface_ipv4_group_v1.test", "timers_msec", "100")) - checks = append(checks, resource.TestCheckResourceAttr("data.iosxr_router_hsrp_interface_ipv4_group_v1.test", "timers_msec_holdtime", "300")) checks = append(checks, resource.TestCheckResourceAttr("data.iosxr_router_hsrp_interface_ipv4_group_v1.test", "bfd_fast_detect_peer_ipv4", "44.44.4.4")) - checks = append(checks, resource.TestCheckResourceAttr("data.iosxr_router_hsrp_interface_ipv4_group_v1.test", "bfd_fast_detect_peer_interface", "GigabitEthernet0/0/0/1")) - checks = append(checks, resource.TestCheckResourceAttr("data.iosxr_router_hsrp_interface_ipv4_group_v1.test", "secondary_ipv4_addresses.0.address", "2.2.2.2")) + checks = append(checks, resource.TestCheckResourceAttr("data.iosxr_router_hsrp_interface_ipv4_group_v1.test", "bfd_fast_detect_peer_interface", "GigabitEthernet0/0/0/7")) checks = append(checks, resource.TestCheckResourceAttr("data.iosxr_router_hsrp_interface_ipv4_group_v1.test", "track_interfaces.0.track_name", "GigabitEthernet0/0/0/1")) checks = append(checks, resource.TestCheckResourceAttr("data.iosxr_router_hsrp_interface_ipv4_group_v1.test", "track_interfaces.0.priority_decrement", "166")) checks = append(checks, resource.TestCheckResourceAttr("data.iosxr_router_hsrp_interface_ipv4_group_v1.test", "track_objects.0.object_name", "OBJECT1")) @@ -84,16 +80,10 @@ func testAccDataSourceIosxrRouterHSRPInterfaceIPv4GroupV1Config() string { config += ` address = "22.22.1.1"` + "\n" config += ` address_learn = false` + "\n" config += ` priority = 124` + "\n" - config += ` mac_address = "00:01:00:02:00:02"` + "\n" config += ` name = "NAME11"` + "\n" config += ` preempt_delay = 3200` + "\n" - config += ` timers_msec = 100` + "\n" - config += ` timers_msec_holdtime = 300` + "\n" config += ` bfd_fast_detect_peer_ipv4 = "44.44.4.4"` + "\n" - config += ` bfd_fast_detect_peer_interface = "GigabitEthernet0/0/0/1"` + "\n" - config += ` secondary_ipv4_addresses = [{` + "\n" - config += ` address = "2.2.2.2"` + "\n" - config += ` }]` + "\n" + config += ` bfd_fast_detect_peer_interface = "GigabitEthernet0/0/0/7"` + "\n" config += ` track_interfaces = [{` + "\n" config += ` track_name = "GigabitEthernet0/0/0/1"` + "\n" config += ` priority_decrement = 166` + "\n" diff --git a/internal/provider/data_source_iosxr_router_hsrp_interface_ipv4_group_v2.go b/internal/provider/data_source_iosxr_router_hsrp_interface_ipv4_group_v2.go index b27f5b9e..b1c8272f 100644 --- a/internal/provider/data_source_iosxr_router_hsrp_interface_ipv4_group_v2.go +++ b/internal/provider/data_source_iosxr_router_hsrp_interface_ipv4_group_v2.go @@ -103,15 +103,15 @@ func (d *RouterHSRPInterfaceIPv4GroupV2DataSource) Schema(ctx context.Context, r MarkdownDescription: "Specify hellotime in milliseconds", Computed: true, }, - "timers_msec_holdtime": schema.Int64Attribute{ + "timers_msec2": schema.Int64Attribute{ MarkdownDescription: "Specify hold time in milliseconds", Computed: true, }, - "timers_seconds": schema.Int64Attribute{ + "timers_hold_time": schema.Int64Attribute{ MarkdownDescription: "Hold time in seconds", Computed: true, }, - "timers_seconds_holdtime": schema.Int64Attribute{ + "timers_hold_time2": schema.Int64Attribute{ MarkdownDescription: "Hold time in seconds", Computed: true, }, @@ -204,11 +204,11 @@ func (d *RouterHSRPInterfaceIPv4GroupV2DataSource) Read(ctx context.Context, req if device.Managed { getResp, err := d.data.Client.Get(ctx, config.Device.ValueString(), config.getPath()) if err != nil { - resp.Diagnostics.AddError("Unable to apply gNMI Get operation", err.Error()) + resp.Diagnostics.AddError("Unable to apply Get operation", err.Error()) return } - config.fromBody(ctx, getResp.Notification[0].Update[0].Val.GetJsonIetfVal()) + config.fromBody(ctx, getResp) } config.Id = types.StringValue(config.getPath()) diff --git a/internal/provider/data_source_iosxr_router_hsrp_interface_ipv4_group_v2_test.go b/internal/provider/data_source_iosxr_router_hsrp_interface_ipv4_group_v2_test.go index ca901642..c501bc82 100644 --- a/internal/provider/data_source_iosxr_router_hsrp_interface_ipv4_group_v2_test.go +++ b/internal/provider/data_source_iosxr_router_hsrp_interface_ipv4_group_v2_test.go @@ -35,14 +35,9 @@ func TestAccDataSourceIosxrRouterHSRPInterfaceIPv4GroupV2(t *testing.T) { checks = append(checks, resource.TestCheckResourceAttr("data.iosxr_router_hsrp_interface_ipv4_group_v2.test", "address", "33.33.33.3")) checks = append(checks, resource.TestCheckResourceAttr("data.iosxr_router_hsrp_interface_ipv4_group_v2.test", "address_learn", "false")) checks = append(checks, resource.TestCheckResourceAttr("data.iosxr_router_hsrp_interface_ipv4_group_v2.test", "priority", "133")) - checks = append(checks, resource.TestCheckResourceAttr("data.iosxr_router_hsrp_interface_ipv4_group_v2.test", "mac_address", "00:01:00:02:00:02")) checks = append(checks, resource.TestCheckResourceAttr("data.iosxr_router_hsrp_interface_ipv4_group_v2.test", "name", "NAME22")) checks = append(checks, resource.TestCheckResourceAttr("data.iosxr_router_hsrp_interface_ipv4_group_v2.test", "preempt_delay", "3100")) - checks = append(checks, resource.TestCheckResourceAttr("data.iosxr_router_hsrp_interface_ipv4_group_v2.test", "timers_seconds", "10")) - checks = append(checks, resource.TestCheckResourceAttr("data.iosxr_router_hsrp_interface_ipv4_group_v2.test", "timers_seconds_holdtime", "30")) checks = append(checks, resource.TestCheckResourceAttr("data.iosxr_router_hsrp_interface_ipv4_group_v2.test", "bfd_fast_detect_peer_ipv4", "45.45.45.4")) - checks = append(checks, resource.TestCheckResourceAttr("data.iosxr_router_hsrp_interface_ipv4_group_v2.test", "bfd_fast_detect_peer_interface", "GigabitEthernet0/0/0/1")) - checks = append(checks, resource.TestCheckResourceAttr("data.iosxr_router_hsrp_interface_ipv4_group_v2.test", "secondary_ipv4_addresses.0.address", "10.10.1.2")) checks = append(checks, resource.TestCheckResourceAttr("data.iosxr_router_hsrp_interface_ipv4_group_v2.test", "track_interfaces.0.track_name", "GigabitEthernet0/0/0/7")) checks = append(checks, resource.TestCheckResourceAttr("data.iosxr_router_hsrp_interface_ipv4_group_v2.test", "track_interfaces.0.priority_decrement", "66")) checks = append(checks, resource.TestCheckResourceAttr("data.iosxr_router_hsrp_interface_ipv4_group_v2.test", "track_objects.0.object_name", "OBJECT2")) @@ -84,16 +79,9 @@ func testAccDataSourceIosxrRouterHSRPInterfaceIPv4GroupV2Config() string { config += ` address = "33.33.33.3"` + "\n" config += ` address_learn = false` + "\n" config += ` priority = 133` + "\n" - config += ` mac_address = "00:01:00:02:00:02"` + "\n" config += ` name = "NAME22"` + "\n" config += ` preempt_delay = 3100` + "\n" - config += ` timers_seconds = 10` + "\n" - config += ` timers_seconds_holdtime = 30` + "\n" config += ` bfd_fast_detect_peer_ipv4 = "45.45.45.4"` + "\n" - config += ` bfd_fast_detect_peer_interface = "GigabitEthernet0/0/0/1"` + "\n" - config += ` secondary_ipv4_addresses = [{` + "\n" - config += ` address = "10.10.1.2"` + "\n" - config += ` }]` + "\n" config += ` track_interfaces = [{` + "\n" config += ` track_name = "GigabitEthernet0/0/0/7"` + "\n" config += ` priority_decrement = 66` + "\n" diff --git a/internal/provider/data_source_iosxr_router_hsrp_interface_ipv6_group_v2.go b/internal/provider/data_source_iosxr_router_hsrp_interface_ipv6_group_v2.go index 7e6e9a91..382e1f6f 100644 --- a/internal/provider/data_source_iosxr_router_hsrp_interface_ipv6_group_v2.go +++ b/internal/provider/data_source_iosxr_router_hsrp_interface_ipv6_group_v2.go @@ -83,11 +83,11 @@ func (d *RouterHSRPInterfaceIPv6GroupV2DataSource) Schema(ctx context.Context, r MarkdownDescription: "Use specified mac address for the virtual router", Computed: true, }, - "timers_seconds": schema.Int64Attribute{ + "timers_hold_time": schema.Int64Attribute{ MarkdownDescription: "Hold time in seconds", Computed: true, }, - "timers_seconds_holdtime": schema.Int64Attribute{ + "timers_hold_time2": schema.Int64Attribute{ MarkdownDescription: "Hold time in seconds", Computed: true, }, @@ -95,7 +95,7 @@ func (d *RouterHSRPInterfaceIPv6GroupV2DataSource) Schema(ctx context.Context, r MarkdownDescription: "Specify hellotime in milliseconds", Computed: true, }, - "timers_msec_holdtime": schema.Int64Attribute{ + "timers_msec2": schema.Int64Attribute{ MarkdownDescription: "Specify hold time in milliseconds", Computed: true, }, @@ -208,11 +208,11 @@ func (d *RouterHSRPInterfaceIPv6GroupV2DataSource) Read(ctx context.Context, req if device.Managed { getResp, err := d.data.Client.Get(ctx, config.Device.ValueString(), config.getPath()) if err != nil { - resp.Diagnostics.AddError("Unable to apply gNMI Get operation", err.Error()) + resp.Diagnostics.AddError("Unable to apply Get operation", err.Error()) return } - config.fromBody(ctx, getResp.Notification[0].Update[0].Val.GetJsonIetfVal()) + config.fromBody(ctx, getResp) } config.Id = types.StringValue(config.getPath()) diff --git a/internal/provider/data_source_iosxr_router_isis.go b/internal/provider/data_source_iosxr_router_isis.go index 1585ee16..490095ab 100644 --- a/internal/provider/data_source_iosxr_router_isis.go +++ b/internal/provider/data_source_iosxr_router_isis.go @@ -239,10 +239,6 @@ func (d *RouterISISDataSource) Schema(ctx context.Context, req datasource.Schema MarkdownDescription: "Enable purge originator identification", Computed: true, }, - "distribute_link_state": schema.BoolAttribute{ - MarkdownDescription: "Distribute the link-state database to external services", - Computed: true, - }, "distribute_link_state_instance_id": schema.Int64Attribute{ MarkdownDescription: "Set distribution process instance identifier", Computed: true, @@ -384,11 +380,11 @@ func (d *RouterISISDataSource) Read(ctx context.Context, req datasource.ReadRequ if device.Managed { getResp, err := d.data.Client.Get(ctx, config.Device.ValueString(), config.getPath()) if err != nil { - resp.Diagnostics.AddError("Unable to apply gNMI Get operation", err.Error()) + resp.Diagnostics.AddError("Unable to apply Get operation", err.Error()) return } - config.fromBody(ctx, getResp.Notification[0].Update[0].Val.GetJsonIetfVal()) + config.fromBody(ctx, getResp) } config.Id = types.StringValue(config.getPath()) diff --git a/internal/provider/data_source_iosxr_router_isis_address_family.go b/internal/provider/data_source_iosxr_router_isis_address_family.go index cc72c66b..66f7dfcc 100644 --- a/internal/provider/data_source_iosxr_router_isis_address_family.go +++ b/internal/provider/data_source_iosxr_router_isis_address_family.go @@ -644,11 +644,11 @@ func (d *RouterISISAddressFamilyDataSource) Read(ctx context.Context, req dataso if device.Managed { getResp, err := d.data.Client.Get(ctx, config.Device.ValueString(), config.getPath()) if err != nil { - resp.Diagnostics.AddError("Unable to apply gNMI Get operation", err.Error()) + resp.Diagnostics.AddError("Unable to apply Get operation", err.Error()) return } - config.fromBody(ctx, getResp.Notification[0].Update[0].Val.GetJsonIetfVal()) + config.fromBody(ctx, getResp) } config.Id = types.StringValue(config.getPath()) diff --git a/internal/provider/data_source_iosxr_router_isis_interface.go b/internal/provider/data_source_iosxr_router_isis_interface.go index 0c23684c..10c50efd 100644 --- a/internal/provider/data_source_iosxr_router_isis_interface.go +++ b/internal/provider/data_source_iosxr_router_isis_interface.go @@ -163,7 +163,7 @@ func (d *RouterISISInterfaceDataSource) Schema(ctx context.Context, req datasour MarkdownDescription: "Do not require authentication of incoming IIHs", Computed: true, }, - "hello_password_keychain_name": schema.StringAttribute{ + "hello_password_keychain": schema.StringAttribute{ MarkdownDescription: "Specifies a Key Chain name will follow", Computed: true, }, @@ -180,27 +180,27 @@ func (d *RouterISISInterfaceDataSource) Schema(ctx context.Context, req datasour MarkdownDescription: "Set hello-password for one level only", Computed: true, }, - "hello_password_text_encrypted": schema.StringAttribute{ + "text_encrypted": schema.StringAttribute{ MarkdownDescription: "Specifies a password will follow", Computed: true, }, - "hello_password_text_send_only": schema.BoolAttribute{ + "text_send_only": schema.BoolAttribute{ MarkdownDescription: "Do not require authentication of incoming IIHs", Computed: true, }, - "hello_password_hmac_md5_encrypted": schema.StringAttribute{ + "hmac_md5_encrypted": schema.StringAttribute{ MarkdownDescription: "Specifies a password will follow", Computed: true, }, - "hello_password_hmac_md5_send_only": schema.BoolAttribute{ + "hmac_md5_send_only": schema.BoolAttribute{ MarkdownDescription: "Do not require authentication of incoming IIHs", Computed: true, }, - "hello_keychain_name": schema.StringAttribute{ + "keychain_name": schema.StringAttribute{ MarkdownDescription: "Specifies a Key Chain name will follow", Computed: true, }, - "hello_keychain_send_only": schema.BoolAttribute{ + "keychain_send_only": schema.BoolAttribute{ MarkdownDescription: "Do not require authentication of incoming IIHs", Computed: true, }, @@ -260,11 +260,11 @@ func (d *RouterISISInterfaceDataSource) Read(ctx context.Context, req datasource if device.Managed { getResp, err := d.data.Client.Get(ctx, config.Device.ValueString(), config.getPath()) if err != nil { - resp.Diagnostics.AddError("Unable to apply gNMI Get operation", err.Error()) + resp.Diagnostics.AddError("Unable to apply Get operation", err.Error()) return } - config.fromBody(ctx, getResp.Notification[0].Update[0].Val.GetJsonIetfVal()) + config.fromBody(ctx, getResp) } config.Id = types.StringValue(config.getPath()) diff --git a/internal/provider/data_source_iosxr_router_isis_interface_address_family.go b/internal/provider/data_source_iosxr_router_isis_interface_address_family.go index d943ed41..6f646063 100644 --- a/internal/provider/data_source_iosxr_router_isis_interface_address_family.go +++ b/internal/provider/data_source_iosxr_router_isis_interface_address_family.go @@ -232,11 +232,11 @@ func (d *RouterISISInterfaceAddressFamilyDataSource) Read(ctx context.Context, r if device.Managed { getResp, err := d.data.Client.Get(ctx, config.Device.ValueString(), config.getPath()) if err != nil { - resp.Diagnostics.AddError("Unable to apply gNMI Get operation", err.Error()) + resp.Diagnostics.AddError("Unable to apply Get operation", err.Error()) return } - config.fromBody(ctx, getResp.Notification[0].Update[0].Val.GetJsonIetfVal()) + config.fromBody(ctx, getResp) } config.Id = types.StringValue(config.getPath()) diff --git a/internal/provider/data_source_iosxr_router_ospf.go b/internal/provider/data_source_iosxr_router_ospf.go index 40100e38..a7c1372c 100644 --- a/internal/provider/data_source_iosxr_router_ospf.go +++ b/internal/provider/data_source_iosxr_router_ospf.go @@ -304,11 +304,11 @@ func (d *RouterOSPFDataSource) Read(ctx context.Context, req datasource.ReadRequ if device.Managed { getResp, err := d.data.Client.Get(ctx, config.Device.ValueString(), config.getPath()) if err != nil { - resp.Diagnostics.AddError("Unable to apply gNMI Get operation", err.Error()) + resp.Diagnostics.AddError("Unable to apply Get operation", err.Error()) return } - config.fromBody(ctx, getResp.Notification[0].Update[0].Val.GetJsonIetfVal()) + config.fromBody(ctx, getResp) } config.Id = types.StringValue(config.getPath()) diff --git a/internal/provider/data_source_iosxr_router_ospf_area_interface.go b/internal/provider/data_source_iosxr_router_ospf_area_interface.go index b90bf52a..a2c5540e 100644 --- a/internal/provider/data_source_iosxr_router_ospf_area_interface.go +++ b/internal/provider/data_source_iosxr_router_ospf_area_interface.go @@ -200,11 +200,11 @@ func (d *RouterOSPFAreaInterfaceDataSource) Read(ctx context.Context, req dataso if device.Managed { getResp, err := d.data.Client.Get(ctx, config.Device.ValueString(), config.getPath()) if err != nil { - resp.Diagnostics.AddError("Unable to apply gNMI Get operation", err.Error()) + resp.Diagnostics.AddError("Unable to apply Get operation", err.Error()) return } - config.fromBody(ctx, getResp.Notification[0].Update[0].Val.GetJsonIetfVal()) + config.fromBody(ctx, getResp) } config.Id = types.StringValue(config.getPath()) diff --git a/internal/provider/data_source_iosxr_router_ospf_vrf.go b/internal/provider/data_source_iosxr_router_ospf_vrf.go index 24686b3d..d6cc8193 100644 --- a/internal/provider/data_source_iosxr_router_ospf_vrf.go +++ b/internal/provider/data_source_iosxr_router_ospf_vrf.go @@ -300,11 +300,11 @@ func (d *RouterOSPFVRFDataSource) Read(ctx context.Context, req datasource.ReadR if device.Managed { getResp, err := d.data.Client.Get(ctx, config.Device.ValueString(), config.getPath()) if err != nil { - resp.Diagnostics.AddError("Unable to apply gNMI Get operation", err.Error()) + resp.Diagnostics.AddError("Unable to apply Get operation", err.Error()) return } - config.fromBody(ctx, getResp.Notification[0].Update[0].Val.GetJsonIetfVal()) + config.fromBody(ctx, getResp) } config.Id = types.StringValue(config.getPath()) diff --git a/internal/provider/data_source_iosxr_router_ospf_vrf_area_interface.go b/internal/provider/data_source_iosxr_router_ospf_vrf_area_interface.go index 12fe9dcf..0f68ee5a 100644 --- a/internal/provider/data_source_iosxr_router_ospf_vrf_area_interface.go +++ b/internal/provider/data_source_iosxr_router_ospf_vrf_area_interface.go @@ -152,11 +152,11 @@ func (d *RouterOSPFVRFAreaInterfaceDataSource) Read(ctx context.Context, req dat if device.Managed { getResp, err := d.data.Client.Get(ctx, config.Device.ValueString(), config.getPath()) if err != nil { - resp.Diagnostics.AddError("Unable to apply gNMI Get operation", err.Error()) + resp.Diagnostics.AddError("Unable to apply Get operation", err.Error()) return } - config.fromBody(ctx, getResp.Notification[0].Update[0].Val.GetJsonIetfVal()) + config.fromBody(ctx, getResp) } config.Id = types.StringValue(config.getPath()) diff --git a/internal/provider/data_source_iosxr_router_static_ipv4_multicast.go b/internal/provider/data_source_iosxr_router_static_ipv4_multicast.go index deb31b88..a6806d52 100644 --- a/internal/provider/data_source_iosxr_router_static_ipv4_multicast.go +++ b/internal/provider/data_source_iosxr_router_static_ipv4_multicast.go @@ -348,11 +348,11 @@ func (d *RouterStaticIPv4MulticastDataSource) Read(ctx context.Context, req data if device.Managed { getResp, err := d.data.Client.Get(ctx, config.Device.ValueString(), config.getPath()) if err != nil { - resp.Diagnostics.AddError("Unable to apply gNMI Get operation", err.Error()) + resp.Diagnostics.AddError("Unable to apply Get operation", err.Error()) return } - config.fromBody(ctx, getResp.Notification[0].Update[0].Val.GetJsonIetfVal()) + config.fromBody(ctx, getResp) } config.Id = types.StringValue(config.getPath()) diff --git a/internal/provider/data_source_iosxr_router_static_ipv4_unicast.go b/internal/provider/data_source_iosxr_router_static_ipv4_unicast.go index 2cf49102..b74e154b 100644 --- a/internal/provider/data_source_iosxr_router_static_ipv4_unicast.go +++ b/internal/provider/data_source_iosxr_router_static_ipv4_unicast.go @@ -124,14 +124,6 @@ func (d *RouterStaticIPv4UnicastDataSource) Schema(ctx context.Context, req data MarkdownDescription: "Forwarding router's address", Computed: true, }, - "bfd_fast_detect_minimum_interval": schema.Int64Attribute{ - MarkdownDescription: "Hello interval", - Computed: true, - }, - "bfd_fast_detect_multiplier": schema.Int64Attribute{ - MarkdownDescription: "Detect multiplier", - Computed: true, - }, "description": schema.StringAttribute{ MarkdownDescription: "description of the static route", Computed: true, @@ -168,14 +160,6 @@ func (d *RouterStaticIPv4UnicastDataSource) Schema(ctx context.Context, req data MarkdownDescription: "Forwarding router's address", Computed: true, }, - "bfd_fast_detect_minimum_interval": schema.Int64Attribute{ - MarkdownDescription: "Hello interval", - Computed: true, - }, - "bfd_fast_detect_multiplier": schema.Int64Attribute{ - MarkdownDescription: "Detect multiplier", - Computed: true, - }, "description": schema.StringAttribute{ MarkdownDescription: "description of the static route", Computed: true, @@ -261,14 +245,6 @@ func (d *RouterStaticIPv4UnicastDataSource) Schema(ctx context.Context, req data MarkdownDescription: "Forwarding router's address", Computed: true, }, - "bfd_fast_detect_minimum_interval": schema.Int64Attribute{ - MarkdownDescription: "Hello interval", - Computed: true, - }, - "bfd_fast_detect_multiplier": schema.Int64Attribute{ - MarkdownDescription: "Detect multiplier", - Computed: true, - }, "description": schema.StringAttribute{ MarkdownDescription: "description of the static route", Computed: true, @@ -305,14 +281,6 @@ func (d *RouterStaticIPv4UnicastDataSource) Schema(ctx context.Context, req data MarkdownDescription: "Forwarding router's address", Computed: true, }, - "bfd_fast_detect_minimum_interval": schema.Int64Attribute{ - MarkdownDescription: "Hello interval", - Computed: true, - }, - "bfd_fast_detect_multiplier": schema.Int64Attribute{ - MarkdownDescription: "Detect multiplier", - Computed: true, - }, "description": schema.StringAttribute{ MarkdownDescription: "description of the static route", Computed: true, @@ -380,11 +348,11 @@ func (d *RouterStaticIPv4UnicastDataSource) Read(ctx context.Context, req dataso if device.Managed { getResp, err := d.data.Client.Get(ctx, config.Device.ValueString(), config.getPath()) if err != nil { - resp.Diagnostics.AddError("Unable to apply gNMI Get operation", err.Error()) + resp.Diagnostics.AddError("Unable to apply Get operation", err.Error()) return } - config.fromBody(ctx, getResp.Notification[0].Update[0].Val.GetJsonIetfVal()) + config.fromBody(ctx, getResp) } config.Id = types.StringValue(config.getPath()) diff --git a/internal/provider/data_source_iosxr_router_static_ipv6_multicast.go b/internal/provider/data_source_iosxr_router_static_ipv6_multicast.go index 6fba97b3..2993d261 100644 --- a/internal/provider/data_source_iosxr_router_static_ipv6_multicast.go +++ b/internal/provider/data_source_iosxr_router_static_ipv6_multicast.go @@ -348,11 +348,11 @@ func (d *RouterStaticIPv6MulticastDataSource) Read(ctx context.Context, req data if device.Managed { getResp, err := d.data.Client.Get(ctx, config.Device.ValueString(), config.getPath()) if err != nil { - resp.Diagnostics.AddError("Unable to apply gNMI Get operation", err.Error()) + resp.Diagnostics.AddError("Unable to apply Get operation", err.Error()) return } - config.fromBody(ctx, getResp.Notification[0].Update[0].Val.GetJsonIetfVal()) + config.fromBody(ctx, getResp) } config.Id = types.StringValue(config.getPath()) diff --git a/internal/provider/data_source_iosxr_router_static_ipv6_unicast.go b/internal/provider/data_source_iosxr_router_static_ipv6_unicast.go index e27e4e42..40cbc271 100644 --- a/internal/provider/data_source_iosxr_router_static_ipv6_unicast.go +++ b/internal/provider/data_source_iosxr_router_static_ipv6_unicast.go @@ -348,11 +348,11 @@ func (d *RouterStaticIPv6UnicastDataSource) Read(ctx context.Context, req dataso if device.Managed { getResp, err := d.data.Client.Get(ctx, config.Device.ValueString(), config.getPath()) if err != nil { - resp.Diagnostics.AddError("Unable to apply gNMI Get operation", err.Error()) + resp.Diagnostics.AddError("Unable to apply Get operation", err.Error()) return } - config.fromBody(ctx, getResp.Notification[0].Update[0].Val.GetJsonIetfVal()) + config.fromBody(ctx, getResp) } config.Id = types.StringValue(config.getPath()) diff --git a/internal/provider/data_source_iosxr_router_static_vrf_ipv4_multicast.go b/internal/provider/data_source_iosxr_router_static_vrf_ipv4_multicast.go index 078618eb..fceb3c16 100644 --- a/internal/provider/data_source_iosxr_router_static_vrf_ipv4_multicast.go +++ b/internal/provider/data_source_iosxr_router_static_vrf_ipv4_multicast.go @@ -128,14 +128,6 @@ func (d *RouterStaticVRFIPv4MulticastDataSource) Schema(ctx context.Context, req MarkdownDescription: "Forwarding router's address", Computed: true, }, - "bfd_fast_detect_minimum_interval": schema.Int64Attribute{ - MarkdownDescription: "Hello interval", - Computed: true, - }, - "bfd_fast_detect_multiplier": schema.Int64Attribute{ - MarkdownDescription: "Detect multiplier", - Computed: true, - }, "description": schema.StringAttribute{ MarkdownDescription: "description of the static route", Computed: true, @@ -160,6 +152,14 @@ func (d *RouterStaticVRFIPv4MulticastDataSource) Schema(ctx context.Context, req MarkdownDescription: "Set metric for this route", Computed: true, }, + "bfd_fast_detect_minimum_interval": schema.Int64Attribute{ + MarkdownDescription: "Hello interval", + Computed: true, + }, + "bfd_fast_detect_multiplier": schema.Int64Attribute{ + MarkdownDescription: "Detect multiplier", + Computed: true, + }, }, }, }, @@ -172,14 +172,6 @@ func (d *RouterStaticVRFIPv4MulticastDataSource) Schema(ctx context.Context, req MarkdownDescription: "Forwarding router's address", Computed: true, }, - "bfd_fast_detect_minimum_interval": schema.Int64Attribute{ - MarkdownDescription: "Hello interval", - Computed: true, - }, - "bfd_fast_detect_multiplier": schema.Int64Attribute{ - MarkdownDescription: "Detect multiplier", - Computed: true, - }, "description": schema.StringAttribute{ MarkdownDescription: "description of the static route", Computed: true, @@ -265,14 +257,6 @@ func (d *RouterStaticVRFIPv4MulticastDataSource) Schema(ctx context.Context, req MarkdownDescription: "Forwarding router's address", Computed: true, }, - "bfd_fast_detect_minimum_interval": schema.Int64Attribute{ - MarkdownDescription: "Hello interval", - Computed: true, - }, - "bfd_fast_detect_multiplier": schema.Int64Attribute{ - MarkdownDescription: "Detect multiplier", - Computed: true, - }, "description": schema.StringAttribute{ MarkdownDescription: "description of the static route", Computed: true, @@ -309,14 +293,6 @@ func (d *RouterStaticVRFIPv4MulticastDataSource) Schema(ctx context.Context, req MarkdownDescription: "Forwarding router's address", Computed: true, }, - "bfd_fast_detect_minimum_interval": schema.Int64Attribute{ - MarkdownDescription: "Hello interval", - Computed: true, - }, - "bfd_fast_detect_multiplier": schema.Int64Attribute{ - MarkdownDescription: "Detect multiplier", - Computed: true, - }, "description": schema.StringAttribute{ MarkdownDescription: "description of the static route", Computed: true, @@ -384,11 +360,11 @@ func (d *RouterStaticVRFIPv4MulticastDataSource) Read(ctx context.Context, req d if device.Managed { getResp, err := d.data.Client.Get(ctx, config.Device.ValueString(), config.getPath()) if err != nil { - resp.Diagnostics.AddError("Unable to apply gNMI Get operation", err.Error()) + resp.Diagnostics.AddError("Unable to apply Get operation", err.Error()) return } - config.fromBody(ctx, getResp.Notification[0].Update[0].Val.GetJsonIetfVal()) + config.fromBody(ctx, getResp) } config.Id = types.StringValue(config.getPath()) diff --git a/internal/provider/data_source_iosxr_router_static_vrf_ipv4_unicast.go b/internal/provider/data_source_iosxr_router_static_vrf_ipv4_unicast.go index c92f3066..6ed42df2 100644 --- a/internal/provider/data_source_iosxr_router_static_vrf_ipv4_unicast.go +++ b/internal/provider/data_source_iosxr_router_static_vrf_ipv4_unicast.go @@ -128,14 +128,6 @@ func (d *RouterStaticVRFIPv4UnicastDataSource) Schema(ctx context.Context, req d MarkdownDescription: "Forwarding router's address", Computed: true, }, - "bfd_fast_detect_minimum_interval": schema.Int64Attribute{ - MarkdownDescription: "Hello interval", - Computed: true, - }, - "bfd_fast_detect_multiplier": schema.Int64Attribute{ - MarkdownDescription: "Detect multiplier", - Computed: true, - }, "description": schema.StringAttribute{ MarkdownDescription: "description of the static route", Computed: true, @@ -160,6 +152,14 @@ func (d *RouterStaticVRFIPv4UnicastDataSource) Schema(ctx context.Context, req d MarkdownDescription: "Set metric for this route", Computed: true, }, + "bfd_fast_detect_minimum_interval": schema.Int64Attribute{ + MarkdownDescription: "Hello interval", + Computed: true, + }, + "bfd_fast_detect_multiplier": schema.Int64Attribute{ + MarkdownDescription: "Detect multiplier", + Computed: true, + }, }, }, }, @@ -172,14 +172,6 @@ func (d *RouterStaticVRFIPv4UnicastDataSource) Schema(ctx context.Context, req d MarkdownDescription: "Forwarding router's address", Computed: true, }, - "bfd_fast_detect_minimum_interval": schema.Int64Attribute{ - MarkdownDescription: "Hello interval", - Computed: true, - }, - "bfd_fast_detect_multiplier": schema.Int64Attribute{ - MarkdownDescription: "Detect multiplier", - Computed: true, - }, "description": schema.StringAttribute{ MarkdownDescription: "description of the static route", Computed: true, @@ -265,14 +257,6 @@ func (d *RouterStaticVRFIPv4UnicastDataSource) Schema(ctx context.Context, req d MarkdownDescription: "Forwarding router's address", Computed: true, }, - "bfd_fast_detect_minimum_interval": schema.Int64Attribute{ - MarkdownDescription: "Hello interval", - Computed: true, - }, - "bfd_fast_detect_multiplier": schema.Int64Attribute{ - MarkdownDescription: "Detect multiplier", - Computed: true, - }, "description": schema.StringAttribute{ MarkdownDescription: "description of the static route", Computed: true, @@ -309,14 +293,6 @@ func (d *RouterStaticVRFIPv4UnicastDataSource) Schema(ctx context.Context, req d MarkdownDescription: "Forwarding router's address", Computed: true, }, - "bfd_fast_detect_minimum_interval": schema.Int64Attribute{ - MarkdownDescription: "Hello interval", - Computed: true, - }, - "bfd_fast_detect_multiplier": schema.Int64Attribute{ - MarkdownDescription: "Detect multiplier", - Computed: true, - }, "description": schema.StringAttribute{ MarkdownDescription: "description of the static route", Computed: true, @@ -384,11 +360,11 @@ func (d *RouterStaticVRFIPv4UnicastDataSource) Read(ctx context.Context, req dat if device.Managed { getResp, err := d.data.Client.Get(ctx, config.Device.ValueString(), config.getPath()) if err != nil { - resp.Diagnostics.AddError("Unable to apply gNMI Get operation", err.Error()) + resp.Diagnostics.AddError("Unable to apply Get operation", err.Error()) return } - config.fromBody(ctx, getResp.Notification[0].Update[0].Val.GetJsonIetfVal()) + config.fromBody(ctx, getResp) } config.Id = types.StringValue(config.getPath()) diff --git a/internal/provider/data_source_iosxr_router_static_vrf_ipv6_multicast.go b/internal/provider/data_source_iosxr_router_static_vrf_ipv6_multicast.go index 950a0352..4aade916 100644 --- a/internal/provider/data_source_iosxr_router_static_vrf_ipv6_multicast.go +++ b/internal/provider/data_source_iosxr_router_static_vrf_ipv6_multicast.go @@ -249,14 +249,6 @@ func (d *RouterStaticVRFIPv6MulticastDataSource) Schema(ctx context.Context, req MarkdownDescription: "Forwarding router's address", Computed: true, }, - "bfd_fast_detect_minimum_interval": schema.Int64Attribute{ - MarkdownDescription: "Hello interval", - Computed: true, - }, - "bfd_fast_detect_multiplier": schema.Int64Attribute{ - MarkdownDescription: "Detect multiplier", - Computed: true, - }, "description": schema.StringAttribute{ MarkdownDescription: "description of the static route", Computed: true, @@ -281,6 +273,14 @@ func (d *RouterStaticVRFIPv6MulticastDataSource) Schema(ctx context.Context, req MarkdownDescription: "Set metric for this route", Computed: true, }, + "bfd_fast_detect_minimum_interval": schema.Int64Attribute{ + MarkdownDescription: "Hello interval", + Computed: true, + }, + "bfd_fast_detect_multiplier": schema.Int64Attribute{ + MarkdownDescription: "Detect multiplier", + Computed: true, + }, }, }, }, @@ -360,11 +360,11 @@ func (d *RouterStaticVRFIPv6MulticastDataSource) Read(ctx context.Context, req d if device.Managed { getResp, err := d.data.Client.Get(ctx, config.Device.ValueString(), config.getPath()) if err != nil { - resp.Diagnostics.AddError("Unable to apply gNMI Get operation", err.Error()) + resp.Diagnostics.AddError("Unable to apply Get operation", err.Error()) return } - config.fromBody(ctx, getResp.Notification[0].Update[0].Val.GetJsonIetfVal()) + config.fromBody(ctx, getResp) } config.Id = types.StringValue(config.getPath()) diff --git a/internal/provider/data_source_iosxr_router_static_vrf_ipv6_unicast.go b/internal/provider/data_source_iosxr_router_static_vrf_ipv6_unicast.go index 91ca182c..1efbc058 100644 --- a/internal/provider/data_source_iosxr_router_static_vrf_ipv6_unicast.go +++ b/internal/provider/data_source_iosxr_router_static_vrf_ipv6_unicast.go @@ -360,11 +360,11 @@ func (d *RouterStaticVRFIPv6UnicastDataSource) Read(ctx context.Context, req dat if device.Managed { getResp, err := d.data.Client.Get(ctx, config.Device.ValueString(), config.getPath()) if err != nil { - resp.Diagnostics.AddError("Unable to apply gNMI Get operation", err.Error()) + resp.Diagnostics.AddError("Unable to apply Get operation", err.Error()) return } - config.fromBody(ctx, getResp.Notification[0].Update[0].Val.GetJsonIetfVal()) + config.fromBody(ctx, getResp) } config.Id = types.StringValue(config.getPath()) diff --git a/internal/provider/data_source_iosxr_router_vrrp_interface.go b/internal/provider/data_source_iosxr_router_vrrp_interface.go index 23de8613..d7cd244e 100644 --- a/internal/provider/data_source_iosxr_router_vrrp_interface.go +++ b/internal/provider/data_source_iosxr_router_vrrp_interface.go @@ -128,11 +128,11 @@ func (d *RouterVRRPInterfaceDataSource) Read(ctx context.Context, req datasource if device.Managed { getResp, err := d.data.Client.Get(ctx, config.Device.ValueString(), config.getPath()) if err != nil { - resp.Diagnostics.AddError("Unable to apply gNMI Get operation", err.Error()) + resp.Diagnostics.AddError("Unable to apply Get operation", err.Error()) return } - config.fromBody(ctx, getResp.Notification[0].Update[0].Val.GetJsonIetfVal()) + config.fromBody(ctx, getResp) } config.Id = types.StringValue(config.getPath()) diff --git a/internal/provider/data_source_iosxr_router_vrrp_interface_ipv4.go b/internal/provider/data_source_iosxr_router_vrrp_interface_ipv4.go index c63b4141..ba1095b9 100644 --- a/internal/provider/data_source_iosxr_router_vrrp_interface_ipv4.go +++ b/internal/provider/data_source_iosxr_router_vrrp_interface_ipv4.go @@ -204,11 +204,11 @@ func (d *RouterVRRPInterfaceIPv4DataSource) Read(ctx context.Context, req dataso if device.Managed { getResp, err := d.data.Client.Get(ctx, config.Device.ValueString(), config.getPath()) if err != nil { - resp.Diagnostics.AddError("Unable to apply gNMI Get operation", err.Error()) + resp.Diagnostics.AddError("Unable to apply Get operation", err.Error()) return } - config.fromBody(ctx, getResp.Notification[0].Update[0].Val.GetJsonIetfVal()) + config.fromBody(ctx, getResp) } config.Id = types.StringValue(config.getPath()) diff --git a/internal/provider/data_source_iosxr_router_vrrp_interface_ipv6.go b/internal/provider/data_source_iosxr_router_vrrp_interface_ipv6.go index 766c9ea2..920c2242 100644 --- a/internal/provider/data_source_iosxr_router_vrrp_interface_ipv6.go +++ b/internal/provider/data_source_iosxr_router_vrrp_interface_ipv6.go @@ -75,17 +75,9 @@ func (d *RouterVRRPInterfaceIPv6DataSource) Schema(ctx context.Context, req data MarkdownDescription: "VRRP configuration", Required: true, }, - "global_addresses": schema.ListNestedAttribute{ - MarkdownDescription: "Global VRRP IPv6 address", + "global_addresses": schema.StringAttribute{ + MarkdownDescription: "Set Global VRRP IPv6 address", Computed: true, - NestedObject: schema.NestedAttributeObject{ - Attributes: map[string]schema.Attribute{ - "address": schema.StringAttribute{ - MarkdownDescription: "Set Global VRRP IPv6 address", - Computed: true, - }, - }, - }, }, "address_linklocal": schema.StringAttribute{ MarkdownDescription: "VRRP IPv6 linklocal address", @@ -200,11 +192,11 @@ func (d *RouterVRRPInterfaceIPv6DataSource) Read(ctx context.Context, req dataso if device.Managed { getResp, err := d.data.Client.Get(ctx, config.Device.ValueString(), config.getPath()) if err != nil { - resp.Diagnostics.AddError("Unable to apply gNMI Get operation", err.Error()) + resp.Diagnostics.AddError("Unable to apply Get operation", err.Error()) return } - config.fromBody(ctx, getResp.Notification[0].Update[0].Val.GetJsonIetfVal()) + config.fromBody(ctx, getResp) } config.Id = types.StringValue(config.getPath()) diff --git a/internal/provider/data_source_iosxr_segment_routing.go b/internal/provider/data_source_iosxr_segment_routing.go index fb05de42..dc1ff871 100644 --- a/internal/provider/data_source_iosxr_segment_routing.go +++ b/internal/provider/data_source_iosxr_segment_routing.go @@ -124,11 +124,11 @@ func (d *SegmentRoutingDataSource) Read(ctx context.Context, req datasource.Read if device.Managed { getResp, err := d.data.Client.Get(ctx, config.Device.ValueString(), config.getPath()) if err != nil { - resp.Diagnostics.AddError("Unable to apply gNMI Get operation", err.Error()) + resp.Diagnostics.AddError("Unable to apply Get operation", err.Error()) return } - config.fromBody(ctx, getResp.Notification[0].Update[0].Val.GetJsonIetfVal()) + config.fromBody(ctx, getResp) } config.Id = types.StringValue(config.getPath()) diff --git a/internal/provider/data_source_iosxr_segment_routing_te.go b/internal/provider/data_source_iosxr_segment_routing_te.go index 687ffa69..d8999da2 100644 --- a/internal/provider/data_source_iosxr_segment_routing_te.go +++ b/internal/provider/data_source_iosxr_segment_routing_te.go @@ -264,11 +264,11 @@ func (d *SegmentRoutingTEDataSource) Read(ctx context.Context, req datasource.Re if device.Managed { getResp, err := d.data.Client.Get(ctx, config.Device.ValueString(), config.getPath()) if err != nil { - resp.Diagnostics.AddError("Unable to apply gNMI Get operation", err.Error()) + resp.Diagnostics.AddError("Unable to apply Get operation", err.Error()) return } - config.fromBody(ctx, getResp.Notification[0].Update[0].Val.GetJsonIetfVal()) + config.fromBody(ctx, getResp) } config.Id = types.StringValue(config.getPath()) diff --git a/internal/provider/data_source_iosxr_segment_routing_te_policy_candidate_path.go b/internal/provider/data_source_iosxr_segment_routing_te_policy_candidate_path.go index 3cec73bf..40fbd667 100644 --- a/internal/provider/data_source_iosxr_segment_routing_te_policy_candidate_path.go +++ b/internal/provider/data_source_iosxr_segment_routing_te_policy_candidate_path.go @@ -140,11 +140,11 @@ func (d *SegmentRoutingTEPolicyCandidatePathDataSource) Read(ctx context.Context if device.Managed { getResp, err := d.data.Client.Get(ctx, config.Device.ValueString(), config.getPath()) if err != nil { - resp.Diagnostics.AddError("Unable to apply gNMI Get operation", err.Error()) + resp.Diagnostics.AddError("Unable to apply Get operation", err.Error()) return } - config.fromBody(ctx, getResp.Notification[0].Update[0].Val.GetJsonIetfVal()) + config.fromBody(ctx, getResp) } config.Id = types.StringValue(config.getPath()) diff --git a/internal/provider/data_source_iosxr_segment_routing_te_policy_candidate_path_test.go b/internal/provider/data_source_iosxr_segment_routing_te_policy_candidate_path_test.go index 1cf61b18..59659e36 100644 --- a/internal/provider/data_source_iosxr_segment_routing_te_policy_candidate_path_test.go +++ b/internal/provider/data_source_iosxr_segment_routing_te_policy_candidate_path_test.go @@ -64,7 +64,6 @@ resource "iosxr_gnmi" "PreReq1" { attributes = { "policy-name" = "POLICY1" } - depends_on = [iosxr_gnmi.PreReq0, ] } ` diff --git a/internal/provider/data_source_iosxr_segment_routing_v6.go b/internal/provider/data_source_iosxr_segment_routing_v6.go index f3419885..21b80183 100644 --- a/internal/provider/data_source_iosxr_segment_routing_v6.go +++ b/internal/provider/data_source_iosxr_segment_routing_v6.go @@ -168,11 +168,11 @@ func (d *SegmentRoutingV6DataSource) Read(ctx context.Context, req datasource.Re if device.Managed { getResp, err := d.data.Client.Get(ctx, config.Device.ValueString(), config.getPath()) if err != nil { - resp.Diagnostics.AddError("Unable to apply gNMI Get operation", err.Error()) + resp.Diagnostics.AddError("Unable to apply Get operation", err.Error()) return } - config.fromBody(ctx, getResp.Notification[0].Update[0].Val.GetJsonIetfVal()) + config.fromBody(ctx, getResp) } config.Id = types.StringValue(config.getPath()) diff --git a/internal/provider/data_source_iosxr_service_timestamps.go b/internal/provider/data_source_iosxr_service_timestamps.go index 607f014b..dc879708 100644 --- a/internal/provider/data_source_iosxr_service_timestamps.go +++ b/internal/provider/data_source_iosxr_service_timestamps.go @@ -160,11 +160,11 @@ func (d *ServiceTimestampsDataSource) Read(ctx context.Context, req datasource.R if device.Managed { getResp, err := d.data.Client.Get(ctx, config.Device.ValueString(), config.getPath()) if err != nil { - resp.Diagnostics.AddError("Unable to apply gNMI Get operation", err.Error()) + resp.Diagnostics.AddError("Unable to apply Get operation", err.Error()) return } - config.fromBody(ctx, getResp.Notification[0].Update[0].Val.GetJsonIetfVal()) + config.fromBody(ctx, getResp) } config.Id = types.StringValue(config.getPath()) diff --git a/internal/provider/data_source_iosxr_snmp_server.go b/internal/provider/data_source_iosxr_snmp_server.go index d3af84ee..41090f1e 100644 --- a/internal/provider/data_source_iosxr_snmp_server.go +++ b/internal/provider/data_source_iosxr_snmp_server.go @@ -412,11 +412,11 @@ func (d *SNMPServerDataSource) Read(ctx context.Context, req datasource.ReadRequ if device.Managed { getResp, err := d.data.Client.Get(ctx, config.Device.ValueString(), config.getPath()) if err != nil { - resp.Diagnostics.AddError("Unable to apply gNMI Get operation", err.Error()) + resp.Diagnostics.AddError("Unable to apply Get operation", err.Error()) return } - config.fromBody(ctx, getResp.Notification[0].Update[0].Val.GetJsonIetfVal()) + config.fromBody(ctx, getResp) } config.Id = types.StringValue(config.getPath()) diff --git a/internal/provider/data_source_iosxr_snmp_server_mib.go b/internal/provider/data_source_iosxr_snmp_server_mib.go index 284da9ed..bd142d3c 100644 --- a/internal/provider/data_source_iosxr_snmp_server_mib.go +++ b/internal/provider/data_source_iosxr_snmp_server_mib.go @@ -112,11 +112,11 @@ func (d *SNMPServerMIBDataSource) Read(ctx context.Context, req datasource.ReadR if device.Managed { getResp, err := d.data.Client.Get(ctx, config.Device.ValueString(), config.getPath()) if err != nil { - resp.Diagnostics.AddError("Unable to apply gNMI Get operation", err.Error()) + resp.Diagnostics.AddError("Unable to apply Get operation", err.Error()) return } - config.fromBody(ctx, getResp.Notification[0].Update[0].Val.GetJsonIetfVal()) + config.fromBody(ctx, getResp) } config.Id = types.StringValue(config.getPath()) diff --git a/internal/provider/data_source_iosxr_snmp_server_view.go b/internal/provider/data_source_iosxr_snmp_server_view.go index 9c1fd0ba..4e16064a 100644 --- a/internal/provider/data_source_iosxr_snmp_server_view.go +++ b/internal/provider/data_source_iosxr_snmp_server_view.go @@ -128,11 +128,11 @@ func (d *SNMPServerViewDataSource) Read(ctx context.Context, req datasource.Read if device.Managed { getResp, err := d.data.Client.Get(ctx, config.Device.ValueString(), config.getPath()) if err != nil { - resp.Diagnostics.AddError("Unable to apply gNMI Get operation", err.Error()) + resp.Diagnostics.AddError("Unable to apply Get operation", err.Error()) return } - config.fromBody(ctx, getResp.Notification[0].Update[0].Val.GetJsonIetfVal()) + config.fromBody(ctx, getResp) } config.Id = types.StringValue(config.getPath()) diff --git a/internal/provider/data_source_iosxr_snmp_server_vrf_host.go b/internal/provider/data_source_iosxr_snmp_server_vrf_host.go index 0c092127..d34f7d02 100644 --- a/internal/provider/data_source_iosxr_snmp_server_vrf_host.go +++ b/internal/provider/data_source_iosxr_snmp_server_vrf_host.go @@ -132,11 +132,11 @@ func (d *SNMPServerVRFHostDataSource) Read(ctx context.Context, req datasource.R if device.Managed { getResp, err := d.data.Client.Get(ctx, config.Device.ValueString(), config.getPath()) if err != nil { - resp.Diagnostics.AddError("Unable to apply gNMI Get operation", err.Error()) + resp.Diagnostics.AddError("Unable to apply Get operation", err.Error()) return } - config.fromBody(ctx, getResp.Notification[0].Update[0].Val.GetJsonIetfVal()) + config.fromBody(ctx, getResp) } config.Id = types.StringValue(config.getPath()) diff --git a/internal/provider/data_source_iosxr_ssh.go b/internal/provider/data_source_iosxr_ssh.go index f21d8313..dd9afbb4 100644 --- a/internal/provider/data_source_iosxr_ssh.go +++ b/internal/provider/data_source_iosxr_ssh.go @@ -144,11 +144,11 @@ func (d *SSHDataSource) Read(ctx context.Context, req datasource.ReadRequest, re if device.Managed { getResp, err := d.data.Client.Get(ctx, config.Device.ValueString(), config.getPath()) if err != nil { - resp.Diagnostics.AddError("Unable to apply gNMI Get operation", err.Error()) + resp.Diagnostics.AddError("Unable to apply Get operation", err.Error()) return } - config.fromBody(ctx, getResp.Notification[0].Update[0].Val.GetJsonIetfVal()) + config.fromBody(ctx, getResp) } config.Id = types.StringValue(config.getPath()) diff --git a/internal/provider/data_source_iosxr_tag_set.go b/internal/provider/data_source_iosxr_tag_set.go index eeb73e6d..7060c9fc 100644 --- a/internal/provider/data_source_iosxr_tag_set.go +++ b/internal/provider/data_source_iosxr_tag_set.go @@ -112,11 +112,11 @@ func (d *TagSetDataSource) Read(ctx context.Context, req datasource.ReadRequest, if device.Managed { getResp, err := d.data.Client.Get(ctx, config.Device.ValueString(), config.getPath()) if err != nil { - resp.Diagnostics.AddError("Unable to apply gNMI Get operation", err.Error()) + resp.Diagnostics.AddError("Unable to apply Get operation", err.Error()) return } - config.fromBody(ctx, getResp.Notification[0].Update[0].Val.GetJsonIetfVal()) + config.fromBody(ctx, getResp) } config.Id = types.StringValue(config.getPath()) diff --git a/internal/provider/data_source_iosxr_telnet.go b/internal/provider/data_source_iosxr_telnet.go index 118f6980..96cb20a1 100644 --- a/internal/provider/data_source_iosxr_telnet.go +++ b/internal/provider/data_source_iosxr_telnet.go @@ -156,11 +156,11 @@ func (d *TelnetDataSource) Read(ctx context.Context, req datasource.ReadRequest, if device.Managed { getResp, err := d.data.Client.Get(ctx, config.Device.ValueString(), config.getPath()) if err != nil { - resp.Diagnostics.AddError("Unable to apply gNMI Get operation", err.Error()) + resp.Diagnostics.AddError("Unable to apply Get operation", err.Error()) return } - config.fromBody(ctx, getResp.Notification[0].Update[0].Val.GetJsonIetfVal()) + config.fromBody(ctx, getResp) } config.Id = types.StringValue(config.getPath()) diff --git a/internal/provider/data_source_iosxr_vrf.go b/internal/provider/data_source_iosxr_vrf.go index 145c1f7a..031db620 100644 --- a/internal/provider/data_source_iosxr_vrf.go +++ b/internal/provider/data_source_iosxr_vrf.go @@ -420,11 +420,11 @@ func (d *VRFDataSource) Read(ctx context.Context, req datasource.ReadRequest, re if device.Managed { getResp, err := d.data.Client.Get(ctx, config.Device.ValueString(), config.getPath()) if err != nil { - resp.Diagnostics.AddError("Unable to apply gNMI Get operation", err.Error()) + resp.Diagnostics.AddError("Unable to apply Get operation", err.Error()) return } - config.fromBody(ctx, getResp.Notification[0].Update[0].Val.GetJsonIetfVal()) + config.fromBody(ctx, getResp) } config.Id = types.StringValue(config.getPath()) diff --git a/internal/provider/helpers/xml_common.go b/internal/provider/helpers/xml_common.go new file mode 100644 index 00000000..8b093f4d --- /dev/null +++ b/internal/provider/helpers/xml_common.go @@ -0,0 +1,83 @@ +// Copyright © 2023 Cisco Systems, Inc. and its affiliates. +// All rights reserved. +// +// Licensed under the Mozilla Public License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// https://mozilla.org/MPL/2.0/ +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +// SPDX-License-Identifier: MPL-2.0 + +package helpers + +import ( + "encoding/xml" + "fmt" + "regexp" + "strings" +) + +var validXMLName = regexp.MustCompile(`^[a-zA-Z_][\w\.\-]*$`) + +// validateXMLName validates that a name is a valid XML element name +func validateXMLName(name string) error { + if !validXMLName.MatchString(name) { + return fmt.Errorf("invalid XML element name: %s", name) + } + return nil +} + +// extractNamespace extracts the xmlns attribute from XML attributes +func extractNamespace(attrs []xml.Attr) string { + for _, attr := range attrs { + if attr.Name.Local == "xmlns" { + return attr.Value + } + } + return "" +} + +// extractNamespacePrefix extracts the last part of a namespace URL +func extractNamespacePrefix(namespace string) string { + parts := strings.Split(namespace, "/") + if len(parts) > 0 { + return parts[len(parts)-1] + } + return namespace +} + +// removeNamespacePrefix removes Cisco-IOS-XR namespace prefix from element name +func removeNamespacePrefix(elementName string) string { + if idx := strings.Index(elementName, ":"); idx > 0 { + if strings.HasPrefix(elementName[:idx], "Cisco-IOS-XR-") { + return elementName[idx+1:] + } + } + return elementName +} + +// extractNamespaceFromElement extracts the full namespace URL from an element name +func extractNamespaceFromElement(elementName string) string { + if idx := strings.Index(elementName, ":"); idx > 0 { + module := elementName[:idx] + if strings.HasPrefix(module, "Cisco-IOS-XR-") { + return fmt.Sprintf("http://cisco.com/ns/yang/%s", module) + } + } + return "" +} + +// normalizeNamespace converts a short namespace to a full URL if needed +func normalizeNamespace(ns string) string { + if strings.HasPrefix(ns, "http://") || strings.HasPrefix(ns, "https://") { + return ns + } + return fmt.Sprintf("http://cisco.com/ns/yang/%s", ns) +} diff --git a/internal/provider/helpers/xml_to_json.go b/internal/provider/helpers/xml_to_json.go new file mode 100644 index 00000000..b0d674cc --- /dev/null +++ b/internal/provider/helpers/xml_to_json.go @@ -0,0 +1,287 @@ +// Copyright © 2023 Cisco Systems, Inc. and its affiliates. +// All rights reserved. +// +// Licensed under the Mozilla Public License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// https://mozilla.org/MPL/2.0/ +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +// SPDX-License-Identifier: MPL-2.0 + +package helpers + +import ( + "encoding/xml" + "fmt" + "io" + "strings" + + "github.com/tidwall/gjson" + "github.com/tidwall/sjson" +) + +// elementInfo tracks XML element state during parsing +type elementInfo struct { + name string + namespace string + jsonPath string + hasText bool + childCount int + isListItem bool + parentName string + hasLeafChild bool + uniqueChildren map[string]int +} + +func newElementInfo(name, namespace, jsonPath, parentName string, isListItem bool) elementInfo { + return elementInfo{ + name: name, + namespace: namespace, + jsonPath: jsonPath, + parentName: parentName, + isListItem: isListItem, + uniqueChildren: make(map[string]int), + } +} + +// XMLToJSON converts XML input to JSON format with namespace prefixes +// Automatically skips container-only levels (no leaf values) +func XMLToJSON(xmlInput string) (string, error) { + decoder := xml.NewDecoder(strings.NewReader(xmlInput)) + parser := &xmlParser{ + jsonStr: "{}", + decoder: decoder, + } + return parser.parse() +} + +type xmlParser struct { + jsonStr string + decoder *xml.Decoder + stack []elementInfo + inData bool + dataDepth int + currentDepth int +} + +func (p *xmlParser) parse() (string, error) { + for { + token, err := p.decoder.Token() + if err == io.EOF { + break + } + if err != nil { + return "", fmt.Errorf("failed to parse XML: %w", err) + } + + switch t := token.(type) { + case xml.StartElement: + if err := p.handleStartElement(t); err != nil { + return "", err + } + case xml.EndElement: + p.handleEndElement(t) + case xml.CharData: + p.handleCharData(t) + } + } + return p.jsonStr, nil +} + +func (p *xmlParser) handleStartElement(t xml.StartElement) error { + p.currentDepth++ + + if t.Name.Local == "data" { + p.inData = true + p.dataDepth = p.currentDepth + return nil + } + + if !p.inData || p.currentDepth <= p.dataDepth { + return nil + } + + // Skip first element after data (root container) + if p.currentDepth == p.dataDepth+1 { + p.stack = append(p.stack, newElementInfo(t.Name.Local, "", "", "", false)) + return nil + } + + namespace := extractNamespace(t.Attr) + key := buildKey(t.Name.Local, namespace) + + var parentName string + var isListItem bool + if len(p.stack) > 0 { + parentName = p.stack[len(p.stack)-1].name + isListItem = shouldBeListItem(t.Name.Local, parentName) + p.stack[len(p.stack)-1].childCount++ + p.stack[len(p.stack)-1].uniqueChildren[t.Name.Local]++ + } + + jsonPath := p.buildJSONPath(key) + p.stack = append(p.stack, newElementInfo(t.Name.Local, namespace, jsonPath, parentName, isListItem)) + + return nil +} + +func (p *xmlParser) buildJSONPath(key string) string { + if len(p.stack) == 0 { + return key + } + + parent := p.stack[len(p.stack)-1] + if parent.jsonPath == "" || (len(p.stack) == 1 && !parent.hasLeafChild) { + return key + } + + return parent.jsonPath + "." + key +} + +func (p *xmlParser) handleEndElement(t xml.EndElement) { + p.currentDepth-- + + if t.Name.Local == "data" { + p.inData = false + return + } + + if !p.inData || len(p.stack) == 0 { + return + } + + elem := p.stack[len(p.stack)-1] + p.stack = p.stack[:len(p.stack)-1] + + // Skip container-only levels + if p.shouldSkipContainer(elem) { + p.flattenContainer(elem) + return + } + + // Mark parent as having leaf child + if (elem.childCount == 0 || elem.hasText) && len(p.stack) > 0 { + p.stack[len(p.stack)-1].hasLeafChild = true + } + + if elem.jsonPath == "" { + return + } + + p.setJSONValue(elem) +} + +func (p *xmlParser) shouldSkipContainer(elem elementInfo) bool { + return len(p.stack) == 1 && + p.stack[0].jsonPath == "" && + elem.childCount > 0 && + !elem.hasText && + !elem.hasLeafChild && + elem.jsonPath != "" +} + +func (p *xmlParser) flattenContainer(elem elementInfo) { + val := gjson.Get(p.jsonStr, elem.jsonPath) + if !val.Exists() { + return + } + + if m, ok := val.Value().(map[string]interface{}); ok { + p.jsonStr = "{}" + for k, v := range m { + p.jsonStr, _ = sjson.Set(p.jsonStr, k, v) + } + } +} + +func (p *xmlParser) setJSONValue(elem elementInfo) { + if elem.hasText { + if elem.isListItem { + currentValue := gjson.Get(p.jsonStr, elem.jsonPath) + if currentValue.Exists() { + p.jsonStr, _ = sjson.Set(p.jsonStr, elem.jsonPath, []interface{}{currentValue.Value()}) + } + } + } else if elem.childCount == 0 { + // Empty element + value := map[string]interface{}{} + if elem.isListItem { + p.jsonStr, _ = sjson.Set(p.jsonStr, elem.jsonPath, []interface{}{value}) + } else { + p.jsonStr, _ = sjson.Set(p.jsonStr, elem.jsonPath, value) + } + } else { + // Has children + if elem.isListItem { + currentValue := gjson.Get(p.jsonStr, elem.jsonPath) + if currentValue.Exists() && currentValue.IsObject() { + p.jsonStr, _ = sjson.Set(p.jsonStr, elem.jsonPath, []interface{}{currentValue.Value()}) + } + } else { + currentValue := gjson.Get(p.jsonStr, elem.jsonPath) + if !currentValue.Exists() { + p.jsonStr, _ = sjson.Set(p.jsonStr, elem.jsonPath, map[string]interface{}{}) + } + } + } +} + +func (p *xmlParser) handleCharData(t xml.CharData) { + if !p.inData || len(p.stack) == 0 { + return + } + + text := strings.TrimSpace(string(t)) + if text == "" { + return + } + + elem := &p.stack[len(p.stack)-1] + elem.hasText = true + elem.hasLeafChild = true + + // Mark all parents as having leaf children + for i := range p.stack { + p.stack[i].hasLeafChild = true + } + + if elem.jsonPath != "" { + p.jsonStr, _ = sjson.Set(p.jsonStr, elem.jsonPath, text) + } +} + +func buildKey(localName, namespace string) string { + if namespace != "" { + nsPrefix := extractNamespacePrefix(namespace) + return nsPrefix + ":" + localName + } + return localName +} + +func shouldBeListItem(childName, parentName string) bool { + if parentName == "" { + return false + } + + // Check if parent is plural of child + if strings.HasSuffix(parentName, "s") && childName == strings.TrimSuffix(parentName, "s") { + return true + } + + // Check common list suffixes + listSuffixes := []string{"-string", "-list", "-entry", "-item"} + for _, suffix := range listSuffixes { + if childName == parentName+suffix { + return true + } + } + + return false +} diff --git a/internal/provider/helpers/xpath_to_xml.go b/internal/provider/helpers/xpath_to_xml.go new file mode 100644 index 00000000..41ec69e8 --- /dev/null +++ b/internal/provider/helpers/xpath_to_xml.go @@ -0,0 +1,441 @@ +// Copyright © 2023 Cisco Systems, Inc. and its affiliates. +// All rights reserved. +// +// Licensed under the Mozilla Public License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// https://mozilla.org/MPL/2.0/ +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +// SPDX-License-Identifier: MPL-2.0 + +package helpers + +import ( + "encoding/json" + "fmt" + "html" + "strings" +) + +// GetNetconfXml converts XPath to NETCONF XML +func GetNetconfXml(xpath, operation, body string) (string, error) { + if err := validateOperation(operation, body); err != nil { + return "", err + } + + rootNamespace, xpathParts, err := parseXPath(xpath) + if err != nil { + return "", err + } + + var filter string + if operation == "update" { + predicateKeys := extractPredicateKeys(xpathParts) + filter = buildUpdateXML(xpathParts, rootNamespace, body, predicateKeys) + } else { + filter = buildSubtreeXML(xpathParts, rootNamespace, operation, len(xpathParts)) + } + + // Wrap delete/update operations + if operation == "delete" || operation == "update" { + filter = fmt.Sprintf("%s", filter) + } + + return filter, nil +} + +func validateOperation(operation, body string) error { + if operation != "get" && operation != "delete" && operation != "update" { + return fmt.Errorf("operation must be 'get', 'delete', or 'update'") + } + if operation == "update" && body == "" { + return fmt.Errorf("body is required for update operations") + } + return nil +} + +func parseXPath(xpath string) (string, []string, error) { + if xpath == "" { + return "", nil, fmt.Errorf("xpath cannot be empty") + } + + colonIdx := strings.Index(xpath, ":") + if colonIdx <= 0 { + return "", nil, fmt.Errorf("xpath must include Cisco-IOS-XR- namespace prefix") + } + + module := xpath[:colonIdx] + if !strings.HasPrefix(module, "Cisco-IOS-XR-") { + return "", nil, fmt.Errorf("invalid namespace prefix: %s", module) + } + + rootNamespace := fmt.Sprintf("http://cisco.com/ns/yang/%s", module) + xpathWithoutNS := strings.TrimPrefix(xpath[colonIdx+1:], "/") + parts := splitXPath(xpathWithoutNS) + + if len(parts) == 0 { + return "", nil, fmt.Errorf("invalid xpath") + } + + return rootNamespace, parts, nil +} + +// buildUpdateXML builds XML with preserved JSON key order +func buildUpdateXML(parts []string, rootNamespace, body string, excludeKeys map[string]bool) string { + return buildUpdateXMLRecursive(parts, rootNamespace, body, excludeKeys, len(parts), len(parts)) +} + +func buildUpdateXMLRecursive(parts []string, rootNamespace, body string, excludeKeys map[string]bool, totalDepth, currentDepth int) string { + if len(parts) == 0 { + return "" + } + + tagName, predicate := parseElement(parts[0]) + if validateXMLName(tagName) != nil { + return "" + } + + elementNS := extractNamespaceFromElement(parts[0]) + isLeaf := len(parts) == 1 + isRoot := currentDepth == totalDepth + + var elem string + if isLeaf { + bodyXML := jsonToXML(body, excludeKeys) + elem = formatElement(tagName, predicate+bodyXML) + } else { + children := buildUpdateXMLRecursive(parts[1:], "", body, excludeKeys, totalDepth, currentDepth-1) + elem = formatElement(tagName, predicate+children) + } + + return applyNamespace(elem, tagName, elementNS, rootNamespace, isRoot) +} + +func parseElement(part string) (string, string) { + tagName := removeNamespacePrefix(part) + tagNameClean, predicate := parsePartWithPredicate(tagName) + return tagNameClean, predicate +} + +func formatElement(tagName, content string) string { + return fmt.Sprintf("<%s>%s", tagName, content, tagName) +} + +func applyNamespace(elem, tagName, elementNS, rootNS string, isRoot bool) string { + if elementNS != "" { + return addNamespaceToElement(elem, tagName, elementNS) + } + if isRoot && rootNS != "" { + return addNamespaceToElement(elem, tagName, rootNS) + } + return elem +} + +// jsonToXML converts JSON string to XML preserving key order +func jsonToXML(jsonStr string, excludeKeys map[string]bool) string { + var data map[string]interface{} + if err := json.Unmarshal([]byte(jsonStr), &data); err != nil { + return "" + } + + keys := parseJSONKeys(jsonStr) + var sb strings.Builder + + for _, key := range keys { + if value, exists := data[key]; exists && !excludeKeys[key] { + sb.WriteString(jsonValueToXML(key, value, excludeKeys)) + } + } + + return sb.String() +} + +// parseJSONKeys extracts top-level keys from JSON in order +func parseJSONKeys(jsonStr string) []string { + var keys []string + var key strings.Builder + var inString, inKey, escape, afterColon bool + depth := 0 + + for i := 0; i < len(jsonStr); i++ { + ch := jsonStr[i] + + if escape { + escape = false + if inKey { + key.WriteByte(ch) + } + continue + } + + if ch == '\\' { + escape = true + if inKey { + key.WriteByte(ch) + } + continue + } + + if ch == '"' { + if inString { + if inKey && depth == 1 && !afterColon { + keys = append(keys, key.String()) + key.Reset() + inKey = false + } + inString = false + } else { + inString = true + if depth == 1 && !afterColon && isAfterKeyPosition(jsonStr, i) { + inKey = true + } + } + } else if inString && inKey { + key.WriteByte(ch) + } else if !inString { + switch ch { + case '{': + depth++ + afterColon = false + case '}': + depth-- + afterColon = false + case ':': + if depth == 1 { + afterColon = true + } + case ',': + if depth == 1 { + afterColon = false + } + } + } + } + + return keys +} + +func isAfterKeyPosition(jsonStr string, pos int) bool { + for i := pos - 1; i >= 0; i-- { + ch := jsonStr[i] + if ch == ' ' || ch == '\t' || ch == '\n' || ch == '\r' { + continue + } + return ch == '{' || ch == ',' + } + return false +} + +// jsonValueToXML converts a single JSON key-value pair to XML +func jsonValueToXML(key string, value interface{}, excludeKeys map[string]bool) string { + if excludeKeys[key] { + return "" + } + + xmlKey, nsPrefix := splitNamespacedKey(key) + if validateXMLName(xmlKey) != nil { + return "" + } + + switch v := value.(type) { + case map[string]interface{}: + return mapToXML(xmlKey, nsPrefix, v, excludeKeys) + case []interface{}: + return arrayToXML(xmlKey, nsPrefix, v, excludeKeys) + case string: + return scalarToXML(xmlKey, nsPrefix, html.EscapeString(v)) + case nil: + return emptyElementXML(xmlKey, nsPrefix) + default: + return scalarToXML(xmlKey, nsPrefix, html.EscapeString(fmt.Sprintf("%v", v))) + } +} + +func splitNamespacedKey(key string) (string, string) { + if !strings.Contains(key, ":") { + return key, "" + } + parts := strings.SplitN(key, ":", 2) + return parts[1], normalizeNamespace(parts[0]) +} + +func mapToXML(xmlKey, nsPrefix string, m map[string]interface{}, excludeKeys map[string]bool) string { + if len(m) == 0 { + return emptyElementXML(xmlKey, nsPrefix) + } + + childJSON, _ := json.Marshal(m) + childXML := jsonToXML(string(childJSON), excludeKeys) + return wrapWithNamespace(xmlKey, nsPrefix, childXML) +} + +func arrayToXML(xmlKey, nsPrefix string, arr []interface{}, excludeKeys map[string]bool) string { + var sb strings.Builder + for _, item := range arr { + switch v := item.(type) { + case map[string]interface{}: + childJSON, _ := json.Marshal(v) + childXML := jsonToXML(string(childJSON), excludeKeys) + sb.WriteString(wrapWithNamespace(xmlKey, nsPrefix, childXML)) + case nil: + sb.WriteString(emptyElementXML(xmlKey, nsPrefix)) + default: + escapedValue := html.EscapeString(fmt.Sprintf("%v", v)) + sb.WriteString(wrapWithNamespace(xmlKey, nsPrefix, escapedValue)) + } + } + return sb.String() +} + +func scalarToXML(xmlKey, nsPrefix, value string) string { + return wrapWithNamespace(xmlKey, nsPrefix, value) +} + +func emptyElementXML(xmlKey, nsPrefix string) string { + if nsPrefix != "" { + return fmt.Sprintf(`<%s xmlns="%s"/>`, xmlKey, nsPrefix) + } + return fmt.Sprintf("<%s/>", xmlKey) +} + +func wrapWithNamespace(xmlKey, nsPrefix, content string) string { + if nsPrefix != "" { + return fmt.Sprintf(`<%s xmlns="%s">%s`, xmlKey, nsPrefix, content, xmlKey) + } + return fmt.Sprintf("<%s>%s", xmlKey, content, xmlKey) +} + +func splitXPath(xpath string) []string { + var parts []string + var current strings.Builder + inBracket := false + + for _, char := range xpath { + switch char { + case '[': + inBracket = true + current.WriteRune(char) + case ']': + inBracket = false + current.WriteRune(char) + case '/': + if !inBracket && current.Len() > 0 { + parts = append(parts, current.String()) + current.Reset() + } else if inBracket { + current.WriteRune(char) + } + default: + current.WriteRune(char) + } + } + + if current.Len() > 0 { + parts = append(parts, current.String()) + } + + return parts +} + +func extractPredicateKeys(parts []string) map[string]bool { + keys := make(map[string]bool) + for _, part := range parts { + part = removeNamespacePrefix(part) + if idx := strings.Index(part, "["); idx >= 0 { + predicateStr := part[idx+1 : len(part)-1] + if strings.Contains(predicateStr, "=") { + kvParts := strings.SplitN(predicateStr, "=", 2) + keys[strings.TrimSpace(kvParts[0])] = true + } + } + } + return keys +} + +func buildSubtreeXML(parts []string, rootNamespace, operation string, totalDepth int) string { + return buildSubtreeXMLRecursive(parts, rootNamespace, operation, totalDepth, totalDepth) +} + +func buildSubtreeXMLRecursive(parts []string, rootNamespace, operation string, totalDepth, currentDepth int) string { + if len(parts) == 0 { + return "" + } + + tagName, predicate := parseElement(parts[0]) + if validateXMLName(tagName) != nil { + return "" + } + + elementNS := extractNamespaceFromElement(parts[0]) + isLeaf := len(parts) == 1 + isRoot := currentDepth == totalDepth + + var elem string + if isLeaf { + deleteAttr := "" + if operation == "delete" { + deleteAttr = ` xmlns:nc="urn:ietf:params:xml:ns:netconf:base:1.0" nc:operation="delete"` + } + + if predicate != "" { + elem = fmt.Sprintf("<%s%s>%s", tagName, deleteAttr, predicate, tagName) + } else { + elem = fmt.Sprintf("<%s%s/>", tagName, deleteAttr) + } + } else { + children := buildSubtreeXMLRecursive(parts[1:], "", operation, totalDepth, currentDepth-1) + elem = formatElement(tagName, predicate+children) + } + + return applyNamespace(elem, tagName, elementNS, rootNamespace, isRoot) +} + +func addNamespaceToElement(elem, tagName, namespace string) string { + patterns := []struct { + old string + new string + }{ + {fmt.Sprintf("<%s ", tagName), fmt.Sprintf(`<%s xmlns="%s" `, tagName, namespace)}, + {fmt.Sprintf("<%s>", tagName), fmt.Sprintf(`<%s xmlns="%s">`, tagName, namespace)}, + {fmt.Sprintf("<%s/>", tagName), fmt.Sprintf(`<%s xmlns="%s"/>`, tagName, namespace)}, + } + + for _, p := range patterns { + if strings.HasPrefix(elem, p.old) { + return strings.Replace(elem, p.old, p.new, 1) + } + } + return elem +} + +func parsePartWithPredicate(part string) (string, string) { + if !strings.Contains(part, "[") { + return part, "" + } + + idx := strings.Index(part, "[") + tagName := part[:idx] + predicateStr := part[idx+1 : len(part)-1] + + if !strings.Contains(predicateStr, "=") { + return tagName, "" + } + + kvParts := strings.SplitN(predicateStr, "=", 2) + key := strings.TrimSpace(kvParts[0]) + value := strings.Trim(strings.TrimSpace(kvParts[1]), "\"'") + + if validateXMLName(key) != nil { + return tagName, "" + } + + escapedValue := html.EscapeString(value) + return tagName, fmt.Sprintf("<%s>%s", key, escapedValue, key) +} diff --git a/internal/provider/provider.go b/internal/provider/provider.go index 37eee64f..79f06208 100644 --- a/internal/provider/provider.go +++ b/internal/provider/provider.go @@ -21,6 +21,7 @@ package provider import ( "context" + "fmt" "os" "slices" "strconv" @@ -47,29 +48,35 @@ type providerData struct { Username types.String `tfsdk:"username"` Password types.String `tfsdk:"password"` Host types.String `tfsdk:"host"` + Protocol types.String `tfsdk:"protocol"` + Port types.Int64 `tfsdk:"port"` VerifyCertificate types.Bool `tfsdk:"verify_certificate"` Tls types.Bool `tfsdk:"tls"` Certificate types.String `tfsdk:"certificate"` Key types.String `tfsdk:"key"` CaCertificate types.String `tfsdk:"ca_certificate"` ReuseConnection types.Bool `tfsdk:"reuse_connection"` + MaxRetries types.Int64 `tfsdk:"max_retries"` SelectedDevices types.List `tfsdk:"selected_devices"` Devices []providerDataDevice `tfsdk:"devices"` } type providerDataDevice struct { - Name types.String `tfsdk:"name"` - Host types.String `tfsdk:"host"` - Managed types.Bool `tfsdk:"managed"` + Name types.String `tfsdk:"name"` + Host types.String `tfsdk:"host"` + Protocol types.String `tfsdk:"protocol"` + Port types.Int64 `tfsdk:"port"` + Managed types.Bool `tfsdk:"managed"` } type IosxrProviderData struct { - Client *client.Client + Client client.Client Devices map[string]*IosxrProviderDataDevice } type IosxrProviderDataDevice struct { - Managed bool + Managed bool + Protocol string } // Metadata returns the provider type name. @@ -93,6 +100,14 @@ func (p *iosxrProvider) Schema(ctx context.Context, req provider.SchemaRequest, MarkdownDescription: "IP or name of the Cisco IOS-XR device. Optionally a port can be added with `:12345`. The default port is `57400`. This can also be set as the IOSXR_HOST environment variable. If no `host` is provided, the `host` of the first device from the `devices` list is being used.", Optional: true, }, + "protocol": schema.StringAttribute{ + MarkdownDescription: "Protocol to use for device communication. Valid values are `gnmi` and `netconf`. Defaults to `gnmi`. This can also be set as the IOSXR_PROTOCOL environment variable.", + Optional: true, + }, + "port": schema.Int64Attribute{ + MarkdownDescription: "Port to connect to on the Cisco IOS-XR device. Defaults to `57400` for gNMI and `830` for NETCONF. This can also be set as the IOSXR_PORT environment variable.", + Optional: true, + }, "verify_certificate": schema.BoolAttribute{ MarkdownDescription: "Verify target certificate. This can also be set as the IOSXR_VERIFY_CERTIFICATE environment variable. Defaults to `false`.", Optional: true, @@ -117,6 +132,10 @@ func (p *iosxrProvider) Schema(ctx context.Context, req provider.SchemaRequest, MarkdownDescription: "Reuse gNMI connection. This can also be set as the IOSXR_REUSE_CONNECTION environment variable. Defaults to `true`.", Optional: true, }, + "max_retries": schema.Int64Attribute{ + MarkdownDescription: "Maximum number of retries for device operations. This can also be set as the IOSXR_MAX_RETRIES environment variable. Defaults to `3`.", + Optional: true, + }, "selected_devices": schema.ListAttribute{ MarkdownDescription: "This can be used to select a list of devices to manage from the `devices` list. Selected devices will be managed while other devices will be skipped and their state will be frozen. This can be used to deploy changes to a subset of devices. Defaults to all devices.", Optional: true, @@ -135,6 +154,14 @@ func (p *iosxrProvider) Schema(ctx context.Context, req provider.SchemaRequest, MarkdownDescription: "IP of the Cisco IOS-XR device.", Required: true, }, + "protocol": schema.StringAttribute{ + MarkdownDescription: "Protocol to use for this device. Valid values are `gnmi` and `netconf`. If not specified, uses the provider-level protocol setting.", + Optional: true, + }, + "port": schema.Int64Attribute{ + MarkdownDescription: "Port to connect to on this device. If not specified, uses the provider-level port setting or protocol defaults.", + Optional: true, + }, "managed": schema.BoolAttribute{ MarkdownDescription: "Enable or disable device management. This can be used to temporarily skip a device due to maintenance for example. Defaults to `true`.", Optional: true, @@ -236,6 +263,68 @@ func (p *iosxrProvider) Configure(ctx context.Context, req provider.ConfigureReq return } + var protocol string + if config.Protocol.IsUnknown() { + // Cannot connect to client with an unknown value + resp.Diagnostics.AddWarning( + "Unable to create client", + "Cannot use unknown value as protocol", + ) + return + } + + if config.Protocol.IsNull() { + protocol = os.Getenv("IOSXR_PROTOCOL") + if protocol == "" { + protocol = "gnmi" // Default to gNMI + } + } else { + protocol = config.Protocol.ValueString() + } + + // Validate protocol + if protocol != "gnmi" && protocol != "netconf" { + resp.Diagnostics.AddError( + "Invalid protocol", + "Protocol must be either 'gnmi' or 'netconf', got: "+protocol, + ) + return + } + + var port int64 + if config.Port.IsUnknown() { + // Cannot connect to client with an unknown value + resp.Diagnostics.AddWarning( + "Unable to create client", + "Cannot use unknown value as port", + ) + return + } + + if config.Port.IsNull() { + portStr := os.Getenv("IOSXR_PORT") + if portStr == "" { + // Set default port based on protocol + if protocol == "netconf" { + port = 830 + } else { + port = 57400 // gNMI default + } + } else { + var err error + port, err = strconv.ParseInt(portStr, 10, 64) + if err != nil { + resp.Diagnostics.AddError( + "Invalid port value", + "IOSXR_PORT must be a valid integer, got: "+portStr, + ) + return + } + } + } else { + port = config.Port.ValueInt64() + } + var verifyCertificate bool if config.VerifyCertificate.IsUnknown() { // Cannot connect to client with an unknown value @@ -371,6 +460,35 @@ func (p *iosxrProvider) Configure(ctx context.Context, req provider.ConfigureReq reuseConnection = config.ReuseConnection.ValueBool() } + var maxRetries int64 + if config.MaxRetries.IsUnknown() { + // Cannot connect to client with an unknown value + resp.Diagnostics.AddWarning( + "Unable to create client", + "Cannot use unknown value as max_retries", + ) + return + } + + if config.MaxRetries.IsNull() { + maxRetriesStr := os.Getenv("IOSXR_MAX_RETRIES") + if maxRetriesStr == "" { + maxRetries = 3 // Default to 3 retries + } else { + var err error + maxRetries, err = strconv.ParseInt(maxRetriesStr, 10, 64) + if err != nil { + resp.Diagnostics.AddError( + "Invalid max_retries value", + "IOSXR_MAX_RETRIES must be a valid integer, got: "+maxRetriesStr, + ) + return + } + } + } else { + maxRetries = config.MaxRetries.ValueInt64() + } + var selectedDevices []string if config.SelectedDevices.IsUnknown() { // Cannot connect to client with an unknown value @@ -422,21 +540,33 @@ func (p *iosxrProvider) Configure(ctx context.Context, req provider.ConfigureReq } } - client := client.NewClient(reuseConnection) + // Create unified client based on protocol + clientInstance := client.NewClient(client.ProtocolType(protocol), reuseConnection, int(maxRetries)) + + // Add target for default device + var err error + hostWithPort := host + if !strings.Contains(host, ":") { + hostWithPort = fmt.Sprintf("%s:%d", host, port) + } + err = clientInstance.AddTarget(ctx, "", hostWithPort, username, password, int(port), certificate, key, caCertificate, verifyCertificate, tls) - err := client.AddTarget(ctx, "", host, username, password, certificate, key, caCertificate, verifyCertificate, tls) if err != nil { resp.Diagnostics.AddError("Unable to add target", err.Error()) + return } // Build provider data structure with device management information providerData := &IosxrProviderData{ - Client: &client, + Client: clientInstance, Devices: make(map[string]*IosxrProviderDataDevice), } // Add default device (empty string) - providerData.Devices[""] = &IosxrProviderDataDevice{Managed: true} + providerData.Devices[""] = &IosxrProviderDataDevice{ + Managed: true, + Protocol: protocol, + } // Add all devices with their managed status for _, device := range config.Devices { @@ -447,12 +577,54 @@ func (p *iosxrProvider) Configure(ctx context.Context, req provider.ConfigureReq } else { managed = device.Managed.IsNull() || device.Managed.IsUnknown() || device.Managed.ValueBool() } - providerData.Devices[deviceName] = &IosxrProviderDataDevice{Managed: managed} if managed { - err := client.AddTarget(ctx, deviceName, device.Host.ValueString(), username, password, certificate, key, caCertificate, verifyCertificate, tls) + // Get device-specific protocol and port if specified, otherwise use defaults + deviceProtocol := protocol + devicePort := port + + if !device.Protocol.IsNull() && !device.Protocol.IsUnknown() { + deviceProtocol = device.Protocol.ValueString() + // Validate device protocol + if deviceProtocol != "gnmi" && deviceProtocol != "netconf" { + resp.Diagnostics.AddError( + "Invalid device protocol", + fmt.Sprintf("Device '%s' protocol must be either 'gnmi' or 'netconf', got: %s", deviceName, deviceProtocol), + ) + return + } + } + + if !device.Port.IsNull() && !device.Port.IsUnknown() { + devicePort = device.Port.ValueInt64() + } + + // Store device info with protocol + providerData.Devices[deviceName] = &IosxrProviderDataDevice{ + Managed: managed, + Protocol: deviceProtocol, + } + + // Add device target + deviceHostWithPort := device.Host.ValueString() + if !strings.Contains(deviceHostWithPort, ":") { + deviceHostWithPort = fmt.Sprintf("%s:%d", deviceHostWithPort, devicePort) + } + err = clientInstance.AddTarget(ctx, deviceName, deviceHostWithPort, username, password, int(devicePort), certificate, key, caCertificate, verifyCertificate, tls) + if err != nil { - resp.Diagnostics.AddError("Unable to add target", err.Error()) + resp.Diagnostics.AddError("Unable to add device target", fmt.Sprintf("Device '%s': %s", deviceName, err.Error())) + return + } + } else { + // For unmanaged devices, still store the protocol info + deviceProtocol := protocol + if !device.Protocol.IsNull() && !device.Protocol.IsUnknown() { + deviceProtocol = device.Protocol.ValueString() + } + providerData.Devices[deviceName] = &IosxrProviderDataDevice{ + Managed: managed, + Protocol: deviceProtocol, } } } diff --git a/internal/provider/resource_iosxr_as_path_set.go b/internal/provider/resource_iosxr_as_path_set.go index f2fbe948..43935461 100644 --- a/internal/provider/resource_iosxr_as_path_set.go +++ b/internal/provider/resource_iosxr_as_path_set.go @@ -180,7 +180,7 @@ func (r *ASPathSetResource) Read(ctx context.Context, req resource.ReadRequest, resp.State.RemoveResource(ctx) return } else { - resp.Diagnostics.AddError("Unable to apply gNMI Get operation", err.Error()) + resp.Diagnostics.AddError("Unable to apply Get operation", err.Error()) return } } @@ -191,7 +191,7 @@ func (r *ASPathSetResource) Read(ctx context.Context, req resource.ReadRequest, } // After `terraform import` we switch to a full read. - respBody := getResp.Notification[0].Update[0].Val.GetJsonIetfVal() + respBody := getResp if imp { state.fromBody(ctx, respBody) } else { diff --git a/internal/provider/resource_iosxr_banner.go b/internal/provider/resource_iosxr_banner.go index cbaf3203..cfa0dbf7 100644 --- a/internal/provider/resource_iosxr_banner.go +++ b/internal/provider/resource_iosxr_banner.go @@ -179,7 +179,7 @@ func (r *BannerResource) Read(ctx context.Context, req resource.ReadRequest, res resp.State.RemoveResource(ctx) return } else { - resp.Diagnostics.AddError("Unable to apply gNMI Get operation", err.Error()) + resp.Diagnostics.AddError("Unable to apply Get operation", err.Error()) return } } @@ -190,7 +190,8 @@ func (r *BannerResource) Read(ctx context.Context, req resource.ReadRequest, res } // After `terraform import` we switch to a full read. - respBody := getResp.Notification[0].Update[0].Val.GetJsonIetfVal() + respBody := getResp + tflog.Debug(ctx, fmt.Sprintf("%s: respBody", respBody)) if imp { state.fromBody(ctx, respBody) } else { diff --git a/internal/provider/resource_iosxr_bfd.go b/internal/provider/resource_iosxr_bfd.go index 726b8f22..f341e034 100644 --- a/internal/provider/resource_iosxr_bfd.go +++ b/internal/provider/resource_iosxr_bfd.go @@ -376,7 +376,7 @@ func (r *BFDResource) Read(ctx context.Context, req resource.ReadRequest, resp * resp.State.RemoveResource(ctx) return } else { - resp.Diagnostics.AddError("Unable to apply gNMI Get operation", err.Error()) + resp.Diagnostics.AddError("Unable to apply Get operation", err.Error()) return } } @@ -387,7 +387,7 @@ func (r *BFDResource) Read(ctx context.Context, req resource.ReadRequest, resp * } // After `terraform import` we switch to a full read. - respBody := getResp.Notification[0].Update[0].Val.GetJsonIetfVal() + respBody := getResp if imp { state.fromBody(ctx, respBody) } else { diff --git a/internal/provider/resource_iosxr_bgp_as_format.go b/internal/provider/resource_iosxr_bgp_as_format.go index 9691efe6..eeac49dc 100644 --- a/internal/provider/resource_iosxr_bgp_as_format.go +++ b/internal/provider/resource_iosxr_bgp_as_format.go @@ -179,7 +179,7 @@ func (r *BGPASFormatResource) Read(ctx context.Context, req resource.ReadRequest resp.State.RemoveResource(ctx) return } else { - resp.Diagnostics.AddError("Unable to apply gNMI Get operation", err.Error()) + resp.Diagnostics.AddError("Unable to apply Get operation", err.Error()) return } } @@ -190,7 +190,7 @@ func (r *BGPASFormatResource) Read(ctx context.Context, req resource.ReadRequest } // After `terraform import` we switch to a full read. - respBody := getResp.Notification[0].Update[0].Val.GetJsonIetfVal() + respBody := getResp if imp { state.fromBody(ctx, respBody) } else { diff --git a/internal/provider/resource_iosxr_cdp.go b/internal/provider/resource_iosxr_cdp.go index 8bbc7902..c86dce93 100644 --- a/internal/provider/resource_iosxr_cdp.go +++ b/internal/provider/resource_iosxr_cdp.go @@ -199,7 +199,7 @@ func (r *CDPResource) Read(ctx context.Context, req resource.ReadRequest, resp * resp.State.RemoveResource(ctx) return } else { - resp.Diagnostics.AddError("Unable to apply gNMI Get operation", err.Error()) + resp.Diagnostics.AddError("Unable to apply Get operation", err.Error()) return } } @@ -210,7 +210,7 @@ func (r *CDPResource) Read(ctx context.Context, req resource.ReadRequest, resp * } // After `terraform import` we switch to a full read. - respBody := getResp.Notification[0].Update[0].Val.GetJsonIetfVal() + respBody := getResp if imp { state.fromBody(ctx, respBody) } else { diff --git a/internal/provider/resource_iosxr_class_map_qos.go b/internal/provider/resource_iosxr_class_map_qos.go index ebe0fa22..e3ec8692 100644 --- a/internal/provider/resource_iosxr_class_map_qos.go +++ b/internal/provider/resource_iosxr_class_map_qos.go @@ -32,7 +32,6 @@ import ( "github.com/hashicorp/terraform-plugin-framework/path" "github.com/hashicorp/terraform-plugin-framework/resource" "github.com/hashicorp/terraform-plugin-framework/resource/schema" - "github.com/hashicorp/terraform-plugin-framework/resource/schema/booldefault" "github.com/hashicorp/terraform-plugin-framework/resource/schema/planmodifier" "github.com/hashicorp/terraform-plugin-framework/resource/schema/stringplanmodifier" "github.com/hashicorp/terraform-plugin-framework/schema/validator" @@ -84,10 +83,8 @@ func (r *ClassMapQoSResource) Schema(ctx context.Context, req resource.SchemaReq }, }, "match_any": schema.BoolAttribute{ - MarkdownDescription: helpers.NewAttributeDescription("Match any match criteria (default)").AddDefaultValueDescription("true").String, + MarkdownDescription: helpers.NewAttributeDescription("Match any match criteria (default)").String, Optional: true, - Computed: true, - Default: booldefault.StaticBool(true), }, "description": schema.StringAttribute{ MarkdownDescription: helpers.NewAttributeDescription("Set description for this class-map").String, @@ -207,7 +204,7 @@ func (r *ClassMapQoSResource) Read(ctx context.Context, req resource.ReadRequest resp.State.RemoveResource(ctx) return } else { - resp.Diagnostics.AddError("Unable to apply gNMI Get operation", err.Error()) + resp.Diagnostics.AddError("Unable to apply Get operation", err.Error()) return } } @@ -218,7 +215,7 @@ func (r *ClassMapQoSResource) Read(ctx context.Context, req resource.ReadRequest } // After `terraform import` we switch to a full read. - respBody := getResp.Notification[0].Update[0].Val.GetJsonIetfVal() + respBody := getResp if imp { state.fromBody(ctx, respBody) } else { diff --git a/internal/provider/resource_iosxr_class_map_qos_test.go b/internal/provider/resource_iosxr_class_map_qos_test.go index 87dd3863..53e0cba7 100644 --- a/internal/provider/resource_iosxr_class_map_qos_test.go +++ b/internal/provider/resource_iosxr_class_map_qos_test.go @@ -87,7 +87,6 @@ func iosxrClassMapQoSImportStateIdFunc(resourceName string) resource.ImportState func testAccIosxrClassMapQoSConfig_minimum() string { config := `resource "iosxr_class_map_qos" "test" {` + "\n" config += ` class_map_name = "TEST"` + "\n" - config += ` match_dscp = ["46"]` + "\n" config += `}` + "\n" return config } diff --git a/internal/provider/resource_iosxr_community_set.go b/internal/provider/resource_iosxr_community_set.go index 6b62cdbd..cf3b463c 100644 --- a/internal/provider/resource_iosxr_community_set.go +++ b/internal/provider/resource_iosxr_community_set.go @@ -180,7 +180,7 @@ func (r *CommunitySetResource) Read(ctx context.Context, req resource.ReadReques resp.State.RemoveResource(ctx) return } else { - resp.Diagnostics.AddError("Unable to apply gNMI Get operation", err.Error()) + resp.Diagnostics.AddError("Unable to apply Get operation", err.Error()) return } } @@ -191,7 +191,7 @@ func (r *CommunitySetResource) Read(ctx context.Context, req resource.ReadReques } // After `terraform import` we switch to a full read. - respBody := getResp.Notification[0].Update[0].Val.GetJsonIetfVal() + respBody := getResp if imp { state.fromBody(ctx, respBody) } else { diff --git a/internal/provider/resource_iosxr_domain.go b/internal/provider/resource_iosxr_domain.go index ffc98177..de0ff2ff 100644 --- a/internal/provider/resource_iosxr_domain.go +++ b/internal/provider/resource_iosxr_domain.go @@ -287,7 +287,7 @@ func (r *DomainResource) Read(ctx context.Context, req resource.ReadRequest, res resp.State.RemoveResource(ctx) return } else { - resp.Diagnostics.AddError("Unable to apply gNMI Get operation", err.Error()) + resp.Diagnostics.AddError("Unable to apply Get operation", err.Error()) return } } @@ -298,7 +298,7 @@ func (r *DomainResource) Read(ctx context.Context, req resource.ReadRequest, res } // After `terraform import` we switch to a full read. - respBody := getResp.Notification[0].Update[0].Val.GetJsonIetfVal() + respBody := getResp if imp { state.fromBody(ctx, respBody) } else { diff --git a/internal/provider/resource_iosxr_domain_vrf.go b/internal/provider/resource_iosxr_domain_vrf.go index 7e802e29..105cf86d 100644 --- a/internal/provider/resource_iosxr_domain_vrf.go +++ b/internal/provider/resource_iosxr_domain_vrf.go @@ -294,7 +294,7 @@ func (r *DomainVRFResource) Read(ctx context.Context, req resource.ReadRequest, resp.State.RemoveResource(ctx) return } else { - resp.Diagnostics.AddError("Unable to apply gNMI Get operation", err.Error()) + resp.Diagnostics.AddError("Unable to apply Get operation", err.Error()) return } } @@ -305,7 +305,7 @@ func (r *DomainVRFResource) Read(ctx context.Context, req resource.ReadRequest, } // After `terraform import` we switch to a full read. - respBody := getResp.Notification[0].Update[0].Val.GetJsonIetfVal() + respBody := getResp if imp { state.fromBody(ctx, respBody) } else { diff --git a/internal/provider/resource_iosxr_domain_vrf_test.go b/internal/provider/resource_iosxr_domain_vrf_test.go index e334a91a..d0768ada 100644 --- a/internal/provider/resource_iosxr_domain_vrf_test.go +++ b/internal/provider/resource_iosxr_domain_vrf_test.go @@ -36,18 +36,18 @@ import ( func TestAccIosxrDomainVRF(t *testing.T) { var checks []resource.TestCheckFunc checks = append(checks, resource.TestCheckResourceAttr("iosxr_domain_vrf.test", "vrf_name", "TEST-VRF")) - checks = append(checks, resource.TestCheckResourceAttr("iosxr_domain_vrf.test", "domains.0.domain_name", "example.com")) + checks = append(checks, resource.TestCheckResourceAttr("iosxr_domain_vrf.test", "domains.0.domain_name", "DOMAIN11")) checks = append(checks, resource.TestCheckResourceAttr("iosxr_domain_vrf.test", "domains.0.order", "12345")) checks = append(checks, resource.TestCheckResourceAttr("iosxr_domain_vrf.test", "lookup_disable", "true")) checks = append(checks, resource.TestCheckResourceAttr("iosxr_domain_vrf.test", "lookup_source_interface", "Loopback214")) - checks = append(checks, resource.TestCheckResourceAttr("iosxr_domain_vrf.test", "name", "cisco.com")) - checks = append(checks, resource.TestCheckResourceAttr("iosxr_domain_vrf.test", "ipv4_hosts.0.host_name", "HOST_NAME_IPV4")) - checks = append(checks, resource.TestCheckResourceAttr("iosxr_domain_vrf.test", "ipv4_hosts.0.ip_address.0", "10.0.0.10")) + checks = append(checks, resource.TestCheckResourceAttr("iosxr_domain_vrf.test", "name", "DNAME")) + checks = append(checks, resource.TestCheckResourceAttr("iosxr_domain_vrf.test", "ipv4_hosts.0.host_name", "HOST-AGC")) + checks = append(checks, resource.TestCheckResourceAttr("iosxr_domain_vrf.test", "ipv4_hosts.0.ip_address.0", "10.0.0.0")) checks = append(checks, resource.TestCheckResourceAttr("iosxr_domain_vrf.test", "name_servers.0.address", "10.0.0.1")) checks = append(checks, resource.TestCheckResourceAttr("iosxr_domain_vrf.test", "name_servers.0.order", "0")) - checks = append(checks, resource.TestCheckResourceAttr("iosxr_domain_vrf.test", "ipv6_hosts.0.host_name", "HOST_NAME_IPV6")) + checks = append(checks, resource.TestCheckResourceAttr("iosxr_domain_vrf.test", "ipv6_hosts.0.host_name", "HOST-ACC")) checks = append(checks, resource.TestCheckResourceAttr("iosxr_domain_vrf.test", "ipv6_hosts.0.ipv6_address.0", "10::10")) - checks = append(checks, resource.TestCheckResourceAttr("iosxr_domain_vrf.test", "multicast", "multicast.cisco.com")) + checks = append(checks, resource.TestCheckResourceAttr("iosxr_domain_vrf.test", "multicast", "TESTACC")) var steps []resource.TestStep if os.Getenv("SKIP_MINIMUM_TEST") == "" { steps = append(steps, resource.TestStep{ @@ -95,7 +95,6 @@ func iosxrDomainVRFImportStateIdFunc(resourceName string) resource.ImportStateId func testAccIosxrDomainVRFConfig_minimum() string { config := `resource "iosxr_domain_vrf" "test" {` + "\n" config += ` vrf_name = "TEST-VRF"` + "\n" - config += ` lookup_disable = true` + "\n" config += `}` + "\n" return config } @@ -108,25 +107,25 @@ func testAccIosxrDomainVRFConfig_all() string { config := `resource "iosxr_domain_vrf" "test" {` + "\n" config += ` vrf_name = "TEST-VRF"` + "\n" config += ` domains = [{` + "\n" - config += ` domain_name = "example.com"` + "\n" + config += ` domain_name = "DOMAIN11"` + "\n" config += ` order = 12345` + "\n" config += ` }]` + "\n" config += ` lookup_disable = true` + "\n" config += ` lookup_source_interface = "Loopback214"` + "\n" - config += ` name = "cisco.com"` + "\n" + config += ` name = "DNAME"` + "\n" config += ` ipv4_hosts = [{` + "\n" - config += ` host_name = "HOST_NAME_IPV4"` + "\n" - config += ` ip_address = ["10.0.0.10"]` + "\n" + config += ` host_name = "HOST-AGC"` + "\n" + config += ` ip_address = ["10.0.0.0"]` + "\n" config += ` }]` + "\n" config += ` name_servers = [{` + "\n" config += ` address = "10.0.0.1"` + "\n" config += ` order = 0` + "\n" config += ` }]` + "\n" config += ` ipv6_hosts = [{` + "\n" - config += ` host_name = "HOST_NAME_IPV6"` + "\n" + config += ` host_name = "HOST-ACC"` + "\n" config += ` ipv6_address = ["10::10"]` + "\n" config += ` }]` + "\n" - config += ` multicast = "multicast.cisco.com"` + "\n" + config += ` multicast = "TESTACC"` + "\n" config += `}` + "\n" return config } diff --git a/internal/provider/resource_iosxr_error_disable_recovery.go b/internal/provider/resource_iosxr_error_disable_recovery.go index fd04161e..a2150a5f 100644 --- a/internal/provider/resource_iosxr_error_disable_recovery.go +++ b/internal/provider/resource_iosxr_error_disable_recovery.go @@ -313,7 +313,7 @@ func (r *ErrorDisableRecoveryResource) Read(ctx context.Context, req resource.Re resp.State.RemoveResource(ctx) return } else { - resp.Diagnostics.AddError("Unable to apply gNMI Get operation", err.Error()) + resp.Diagnostics.AddError("Unable to apply Get operation", err.Error()) return } } @@ -324,7 +324,7 @@ func (r *ErrorDisableRecoveryResource) Read(ctx context.Context, req resource.Re } // After `terraform import` we switch to a full read. - respBody := getResp.Notification[0].Update[0].Val.GetJsonIetfVal() + respBody := getResp if imp { state.fromBody(ctx, respBody) } else { diff --git a/internal/provider/resource_iosxr_error_disable_recovery_test.go b/internal/provider/resource_iosxr_error_disable_recovery_test.go index a2b9f019..9ea3078a 100644 --- a/internal/provider/resource_iosxr_error_disable_recovery_test.go +++ b/internal/provider/resource_iosxr_error_disable_recovery_test.go @@ -99,7 +99,6 @@ func iosxrErrorDisableRecoveryImportStateIdFunc(resourceName string) resource.Im func testAccIosxrErrorDisableRecoveryConfig_minimum() string { config := `resource "iosxr_error_disable_recovery" "test" {` + "\n" - config += ` link_oam_session_down_interval = 30` + "\n" config += `}` + "\n" return config } diff --git a/internal/provider/resource_iosxr_esi_set.go b/internal/provider/resource_iosxr_esi_set.go index 0061dbad..bc2e328a 100644 --- a/internal/provider/resource_iosxr_esi_set.go +++ b/internal/provider/resource_iosxr_esi_set.go @@ -180,7 +180,7 @@ func (r *ESISetResource) Read(ctx context.Context, req resource.ReadRequest, res resp.State.RemoveResource(ctx) return } else { - resp.Diagnostics.AddError("Unable to apply gNMI Get operation", err.Error()) + resp.Diagnostics.AddError("Unable to apply Get operation", err.Error()) return } } @@ -191,7 +191,7 @@ func (r *ESISetResource) Read(ctx context.Context, req resource.ReadRequest, res } // After `terraform import` we switch to a full read. - respBody := getResp.Notification[0].Update[0].Val.GetJsonIetfVal() + respBody := getResp if imp { state.fromBody(ctx, respBody) } else { diff --git a/internal/provider/resource_iosxr_evpn.go b/internal/provider/resource_iosxr_evpn.go index aaa1b667..89eebb95 100644 --- a/internal/provider/resource_iosxr_evpn.go +++ b/internal/provider/resource_iosxr_evpn.go @@ -235,7 +235,7 @@ func (r *EVPNResource) Read(ctx context.Context, req resource.ReadRequest, resp resp.State.RemoveResource(ctx) return } else { - resp.Diagnostics.AddError("Unable to apply gNMI Get operation", err.Error()) + resp.Diagnostics.AddError("Unable to apply Get operation", err.Error()) return } } @@ -246,7 +246,7 @@ func (r *EVPNResource) Read(ctx context.Context, req resource.ReadRequest, resp } // After `terraform import` we switch to a full read. - respBody := getResp.Notification[0].Update[0].Val.GetJsonIetfVal() + respBody := getResp if imp { state.fromBody(ctx, respBody) } else { diff --git a/internal/provider/resource_iosxr_evpn_evi.go b/internal/provider/resource_iosxr_evpn_evi.go index 89890af7..38158e0e 100644 --- a/internal/provider/resource_iosxr_evpn_evi.go +++ b/internal/provider/resource_iosxr_evpn_evi.go @@ -416,7 +416,7 @@ func (r *EVPNEVIResource) Read(ctx context.Context, req resource.ReadRequest, re resp.State.RemoveResource(ctx) return } else { - resp.Diagnostics.AddError("Unable to apply gNMI Get operation", err.Error()) + resp.Diagnostics.AddError("Unable to apply Get operation", err.Error()) return } } @@ -427,7 +427,7 @@ func (r *EVPNEVIResource) Read(ctx context.Context, req resource.ReadRequest, re } // After `terraform import` we switch to a full read. - respBody := getResp.Notification[0].Update[0].Val.GetJsonIetfVal() + respBody := getResp if imp { state.fromBody(ctx, respBody) } else { diff --git a/internal/provider/resource_iosxr_evpn_group.go b/internal/provider/resource_iosxr_evpn_group.go index ab2439c4..18bb84e5 100644 --- a/internal/provider/resource_iosxr_evpn_group.go +++ b/internal/provider/resource_iosxr_evpn_group.go @@ -201,7 +201,7 @@ func (r *EVPNGroupResource) Read(ctx context.Context, req resource.ReadRequest, resp.State.RemoveResource(ctx) return } else { - resp.Diagnostics.AddError("Unable to apply gNMI Get operation", err.Error()) + resp.Diagnostics.AddError("Unable to apply Get operation", err.Error()) return } } @@ -212,7 +212,7 @@ func (r *EVPNGroupResource) Read(ctx context.Context, req resource.ReadRequest, } // After `terraform import` we switch to a full read. - respBody := getResp.Notification[0].Update[0].Val.GetJsonIetfVal() + respBody := getResp if imp { state.fromBody(ctx, respBody) } else { diff --git a/internal/provider/resource_iosxr_evpn_interface.go b/internal/provider/resource_iosxr_evpn_interface.go index 89a56a51..1ba2bd98 100644 --- a/internal/provider/resource_iosxr_evpn_interface.go +++ b/internal/provider/resource_iosxr_evpn_interface.go @@ -214,7 +214,7 @@ func (r *EVPNInterfaceResource) Read(ctx context.Context, req resource.ReadReque resp.State.RemoveResource(ctx) return } else { - resp.Diagnostics.AddError("Unable to apply gNMI Get operation", err.Error()) + resp.Diagnostics.AddError("Unable to apply Get operation", err.Error()) return } } @@ -225,7 +225,7 @@ func (r *EVPNInterfaceResource) Read(ctx context.Context, req resource.ReadReque } // After `terraform import` we switch to a full read. - respBody := getResp.Notification[0].Update[0].Val.GetJsonIetfVal() + respBody := getResp if imp { state.fromBody(ctx, respBody) } else { diff --git a/internal/provider/resource_iosxr_evpn_segment_routing_srv6_evi.go b/internal/provider/resource_iosxr_evpn_segment_routing_srv6_evi.go index c0fd54a3..733e2ce9 100644 --- a/internal/provider/resource_iosxr_evpn_segment_routing_srv6_evi.go +++ b/internal/provider/resource_iosxr_evpn_segment_routing_srv6_evi.go @@ -345,7 +345,7 @@ func (r *EVPNSegmentRoutingSRv6EVIResource) Read(ctx context.Context, req resour resp.State.RemoveResource(ctx) return } else { - resp.Diagnostics.AddError("Unable to apply gNMI Get operation", err.Error()) + resp.Diagnostics.AddError("Unable to apply Get operation", err.Error()) return } } @@ -356,7 +356,7 @@ func (r *EVPNSegmentRoutingSRv6EVIResource) Read(ctx context.Context, req resour } // After `terraform import` we switch to a full read. - respBody := getResp.Notification[0].Update[0].Val.GetJsonIetfVal() + respBody := getResp if imp { state.fromBody(ctx, respBody) } else { diff --git a/internal/provider/resource_iosxr_extcommunity_cost_set.go b/internal/provider/resource_iosxr_extcommunity_cost_set.go index d7564f60..a8a443d3 100644 --- a/internal/provider/resource_iosxr_extcommunity_cost_set.go +++ b/internal/provider/resource_iosxr_extcommunity_cost_set.go @@ -180,7 +180,7 @@ func (r *ExtcommunityCostSetResource) Read(ctx context.Context, req resource.Rea resp.State.RemoveResource(ctx) return } else { - resp.Diagnostics.AddError("Unable to apply gNMI Get operation", err.Error()) + resp.Diagnostics.AddError("Unable to apply Get operation", err.Error()) return } } @@ -191,7 +191,7 @@ func (r *ExtcommunityCostSetResource) Read(ctx context.Context, req resource.Rea } // After `terraform import` we switch to a full read. - respBody := getResp.Notification[0].Update[0].Val.GetJsonIetfVal() + respBody := getResp if imp { state.fromBody(ctx, respBody) } else { diff --git a/internal/provider/resource_iosxr_extcommunity_opaque_set.go b/internal/provider/resource_iosxr_extcommunity_opaque_set.go index 17bab609..4b49c858 100644 --- a/internal/provider/resource_iosxr_extcommunity_opaque_set.go +++ b/internal/provider/resource_iosxr_extcommunity_opaque_set.go @@ -180,7 +180,7 @@ func (r *ExtcommunityOpaqueSetResource) Read(ctx context.Context, req resource.R resp.State.RemoveResource(ctx) return } else { - resp.Diagnostics.AddError("Unable to apply gNMI Get operation", err.Error()) + resp.Diagnostics.AddError("Unable to apply Get operation", err.Error()) return } } @@ -191,7 +191,7 @@ func (r *ExtcommunityOpaqueSetResource) Read(ctx context.Context, req resource.R } // After `terraform import` we switch to a full read. - respBody := getResp.Notification[0].Update[0].Val.GetJsonIetfVal() + respBody := getResp if imp { state.fromBody(ctx, respBody) } else { diff --git a/internal/provider/resource_iosxr_extcommunity_rt_set.go b/internal/provider/resource_iosxr_extcommunity_rt_set.go index ba7c3041..6f161d40 100644 --- a/internal/provider/resource_iosxr_extcommunity_rt_set.go +++ b/internal/provider/resource_iosxr_extcommunity_rt_set.go @@ -180,7 +180,7 @@ func (r *ExtcommunityRTSetResource) Read(ctx context.Context, req resource.ReadR resp.State.RemoveResource(ctx) return } else { - resp.Diagnostics.AddError("Unable to apply gNMI Get operation", err.Error()) + resp.Diagnostics.AddError("Unable to apply Get operation", err.Error()) return } } @@ -191,7 +191,7 @@ func (r *ExtcommunityRTSetResource) Read(ctx context.Context, req resource.ReadR } // After `terraform import` we switch to a full read. - respBody := getResp.Notification[0].Update[0].Val.GetJsonIetfVal() + respBody := getResp if imp { state.fromBody(ctx, respBody) } else { diff --git a/internal/provider/resource_iosxr_extcommunity_soo_set.go b/internal/provider/resource_iosxr_extcommunity_soo_set.go index a55b6b98..2649030d 100644 --- a/internal/provider/resource_iosxr_extcommunity_soo_set.go +++ b/internal/provider/resource_iosxr_extcommunity_soo_set.go @@ -180,7 +180,7 @@ func (r *ExtcommunitySOOSetResource) Read(ctx context.Context, req resource.Read resp.State.RemoveResource(ctx) return } else { - resp.Diagnostics.AddError("Unable to apply gNMI Get operation", err.Error()) + resp.Diagnostics.AddError("Unable to apply Get operation", err.Error()) return } } @@ -191,7 +191,7 @@ func (r *ExtcommunitySOOSetResource) Read(ctx context.Context, req resource.Read } // After `terraform import` we switch to a full read. - respBody := getResp.Notification[0].Update[0].Val.GetJsonIetfVal() + respBody := getResp if imp { state.fromBody(ctx, respBody) } else { diff --git a/internal/provider/resource_iosxr_flow_exporter_map.go b/internal/provider/resource_iosxr_flow_exporter_map.go index f3d503c6..24d1bea1 100644 --- a/internal/provider/resource_iosxr_flow_exporter_map.go +++ b/internal/provider/resource_iosxr_flow_exporter_map.go @@ -291,7 +291,7 @@ func (r *FlowExporterMapResource) Read(ctx context.Context, req resource.ReadReq resp.State.RemoveResource(ctx) return } else { - resp.Diagnostics.AddError("Unable to apply gNMI Get operation", err.Error()) + resp.Diagnostics.AddError("Unable to apply Get operation", err.Error()) return } } @@ -302,7 +302,7 @@ func (r *FlowExporterMapResource) Read(ctx context.Context, req resource.ReadReq } // After `terraform import` we switch to a full read. - respBody := getResp.Notification[0].Update[0].Val.GetJsonIetfVal() + respBody := getResp if imp { state.fromBody(ctx, respBody) } else { diff --git a/internal/provider/resource_iosxr_flow_exporter_map_test.go b/internal/provider/resource_iosxr_flow_exporter_map_test.go index 8362ae7d..d4e5abbb 100644 --- a/internal/provider/resource_iosxr_flow_exporter_map_test.go +++ b/internal/provider/resource_iosxr_flow_exporter_map_test.go @@ -34,12 +34,13 @@ import ( // Section below is generated&owned by "gen/generator.go". //template:begin testAcc func TestAccIosxrFlowExporterMap(t *testing.T) { - if os.Getenv("NCS") == "" { - t.Skip("skipping test, set environment variable NCS") + if os.Getenv("PHYSICAL") == "" { + t.Skip("skipping test, set environment variable PHYSICAL") } var checks []resource.TestCheckFunc - checks = append(checks, resource.TestCheckResourceAttr("iosxr_flow_exporter_map.test", "name", "exporter_map1")) - checks = append(checks, resource.TestCheckResourceAttr("iosxr_flow_exporter_map.test", "destination_ipv4_address", "192.0.2.1")) + checks = append(checks, resource.TestCheckResourceAttr("iosxr_flow_exporter_map.test", "name", "TEST")) + checks = append(checks, resource.TestCheckResourceAttr("iosxr_flow_exporter_map.test", "destination_ipv4_address", "10.1.1.1")) + checks = append(checks, resource.TestCheckResourceAttr("iosxr_flow_exporter_map.test", "destination_ipv6_address", "1::1")) checks = append(checks, resource.TestCheckResourceAttr("iosxr_flow_exporter_map.test", "destination_vrf", "VRF1")) checks = append(checks, resource.TestCheckResourceAttr("iosxr_flow_exporter_map.test", "source", "GigabitEthernet0/0/0/1")) checks = append(checks, resource.TestCheckResourceAttr("iosxr_flow_exporter_map.test", "dscp", "62")) @@ -57,11 +58,11 @@ func TestAccIosxrFlowExporterMap(t *testing.T) { var steps []resource.TestStep if os.Getenv("SKIP_MINIMUM_TEST") == "" { steps = append(steps, resource.TestStep{ - Config: testAccIosxrFlowExporterMapPrerequisitesConfig + testAccIosxrFlowExporterMapConfig_minimum(), + Config: testAccIosxrFlowExporterMapConfig_minimum(), }) } steps = append(steps, resource.TestStep{ - Config: testAccIosxrFlowExporterMapPrerequisitesConfig + testAccIosxrFlowExporterMapConfig_all(), + Config: testAccIosxrFlowExporterMapConfig_all(), Check: resource.ComposeTestCheckFunc(checks...), }) steps = append(steps, resource.TestStep{ @@ -93,15 +94,6 @@ func iosxrFlowExporterMapImportStateIdFunc(resourceName string) resource.ImportS // End of section. //template:end importStateIdFunc // Section below is generated&owned by "gen/generator.go". //template:begin testPrerequisites -const testAccIosxrFlowExporterMapPrerequisitesConfig = ` -resource "iosxr_gnmi" "PreReq0" { - path = "Cisco-IOS-XR-um-vrf-cfg:/vrfs/vrf[vrf-name=VRF1]" - attributes = { - "vrf-name" = "VRF1" - } -} - -` // End of section. //template:end testPrerequisites @@ -109,9 +101,8 @@ resource "iosxr_gnmi" "PreReq0" { func testAccIosxrFlowExporterMapConfig_minimum() string { config := `resource "iosxr_flow_exporter_map" "test" {` + "\n" - config += ` name = "exporter_map1"` + "\n" + config += ` name = "TEST"` + "\n" config += ` version_export_format = "v9"` + "\n" - config += ` depends_on = [iosxr_gnmi.PreReq0, ]` + "\n" config += `}` + "\n" return config } @@ -122,8 +113,9 @@ func testAccIosxrFlowExporterMapConfig_minimum() string { func testAccIosxrFlowExporterMapConfig_all() string { config := `resource "iosxr_flow_exporter_map" "test" {` + "\n" - config += ` name = "exporter_map1"` + "\n" - config += ` destination_ipv4_address = "192.0.2.1"` + "\n" + config += ` name = "TEST"` + "\n" + config += ` destination_ipv4_address = "10.1.1.1"` + "\n" + config += ` destination_ipv6_address = "1::1"` + "\n" config += ` destination_vrf = "VRF1"` + "\n" config += ` source = "GigabitEthernet0/0/0/1"` + "\n" config += ` dscp = 62` + "\n" @@ -138,7 +130,6 @@ func testAccIosxrFlowExporterMapConfig_all() string { config += ` version_options_sampler_table_timeout = 4096` + "\n" config += ` version_options_class_table_timeout = 255` + "\n" config += ` version_options_vrf_table_timeout = 122` + "\n" - config += ` depends_on = [iosxr_gnmi.PreReq0, ]` + "\n" config += `}` + "\n" return config } diff --git a/internal/provider/resource_iosxr_flow_monitor_map.go b/internal/provider/resource_iosxr_flow_monitor_map.go index 18733086..1210de2d 100644 --- a/internal/provider/resource_iosxr_flow_monitor_map.go +++ b/internal/provider/resource_iosxr_flow_monitor_map.go @@ -184,14 +184,6 @@ func (r *FlowMonitorMapResource) Schema(ctx context.Context, req resource.Schema MarkdownDescription: helpers.NewAttributeDescription("IPV4 gtp record format").String, Optional: true, }, - "record_ipv4_l2_l3": schema.BoolAttribute{ - MarkdownDescription: helpers.NewAttributeDescription("IPv4 record with Layer2 details").String, - Optional: true, - }, - "record_ipv4_extended": schema.BoolAttribute{ - MarkdownDescription: helpers.NewAttributeDescription("IPv4 record with extended details").String, - Optional: true, - }, "record_ipv6": schema.BoolAttribute{ MarkdownDescription: helpers.NewAttributeDescription("IPv6 raw record format").String, Optional: true, @@ -208,18 +200,6 @@ func (r *FlowMonitorMapResource) Schema(ctx context.Context, req resource.Schema MarkdownDescription: helpers.NewAttributeDescription("IPV6 gtp record format").String, Optional: true, }, - "record_ipv6_srv6": schema.BoolAttribute{ - MarkdownDescription: helpers.NewAttributeDescription("SRv6 record format").String, - Optional: true, - }, - "record_ipv6_l2_l3": schema.BoolAttribute{ - MarkdownDescription: helpers.NewAttributeDescription("IPv6 record with Layer2 details").String, - Optional: true, - }, - "record_ipv6_extended": schema.BoolAttribute{ - MarkdownDescription: helpers.NewAttributeDescription("IPv6 record with extended details").String, - Optional: true, - }, "record_mpls": schema.BoolAttribute{ MarkdownDescription: helpers.NewAttributeDescription("MPLS record format").String, Optional: true, @@ -455,7 +435,7 @@ func (r *FlowMonitorMapResource) Read(ctx context.Context, req resource.ReadRequ resp.State.RemoveResource(ctx) return } else { - resp.Diagnostics.AddError("Unable to apply gNMI Get operation", err.Error()) + resp.Diagnostics.AddError("Unable to apply Get operation", err.Error()) return } } @@ -466,7 +446,7 @@ func (r *FlowMonitorMapResource) Read(ctx context.Context, req resource.ReadRequ } // After `terraform import` we switch to a full read. - respBody := getResp.Notification[0].Update[0].Val.GetJsonIetfVal() + respBody := getResp if imp { state.fromBody(ctx, respBody) } else { diff --git a/internal/provider/resource_iosxr_flow_monitor_map_test.go b/internal/provider/resource_iosxr_flow_monitor_map_test.go index 51331dd3..3ab6dd89 100644 --- a/internal/provider/resource_iosxr_flow_monitor_map_test.go +++ b/internal/provider/resource_iosxr_flow_monitor_map_test.go @@ -34,22 +34,53 @@ import ( // Section below is generated&owned by "gen/generator.go". //template:begin testAcc func TestAccIosxrFlowMonitorMap(t *testing.T) { - if os.Getenv("NCS") == "" { - t.Skip("skipping test, set environment variable NCS") + if os.Getenv("PHYSICAL") == "" { + t.Skip("skipping test, set environment variable PHYSICAL") } var checks []resource.TestCheckFunc checks = append(checks, resource.TestCheckResourceAttr("iosxr_flow_monitor_map.test", "name", "monitor_map1")) - checks = append(checks, resource.TestCheckResourceAttr("iosxr_flow_monitor_map.test", "exporters.0.name", "exporter_map1")) + checks = append(checks, resource.TestCheckResourceAttr("iosxr_flow_monitor_map.test", "exporters.0.name", "exporter1")) checks = append(checks, resource.TestCheckResourceAttr("iosxr_flow_monitor_map.test", "option_outphysint", "true")) checks = append(checks, resource.TestCheckResourceAttr("iosxr_flow_monitor_map.test", "option_filtered", "true")) checks = append(checks, resource.TestCheckResourceAttr("iosxr_flow_monitor_map.test", "option_bgpattr", "true")) checks = append(checks, resource.TestCheckResourceAttr("iosxr_flow_monitor_map.test", "option_outbundlemember", "true")) + checks = append(checks, resource.TestCheckResourceAttr("iosxr_flow_monitor_map.test", "record_ipv4", "true")) + checks = append(checks, resource.TestCheckResourceAttr("iosxr_flow_monitor_map.test", "record_ipv4_destination", "true")) + checks = append(checks, resource.TestCheckResourceAttr("iosxr_flow_monitor_map.test", "record_ipv4_destination_tos", "true")) + checks = append(checks, resource.TestCheckResourceAttr("iosxr_flow_monitor_map.test", "record_ipv4_as", "true")) + checks = append(checks, resource.TestCheckResourceAttr("iosxr_flow_monitor_map.test", "record_ipv4_protocol_port", "true")) + checks = append(checks, resource.TestCheckResourceAttr("iosxr_flow_monitor_map.test", "record_ipv4_prefix", "true")) + checks = append(checks, resource.TestCheckResourceAttr("iosxr_flow_monitor_map.test", "record_ipv4_source_prefix", "true")) + checks = append(checks, resource.TestCheckResourceAttr("iosxr_flow_monitor_map.test", "record_ipv4_destination_prefix", "true")) + checks = append(checks, resource.TestCheckResourceAttr("iosxr_flow_monitor_map.test", "record_ipv4_as_tos", "true")) + checks = append(checks, resource.TestCheckResourceAttr("iosxr_flow_monitor_map.test", "record_ipv4_protocol_port_tos", "true")) + checks = append(checks, resource.TestCheckResourceAttr("iosxr_flow_monitor_map.test", "record_ipv4_prefix_tos", "true")) + checks = append(checks, resource.TestCheckResourceAttr("iosxr_flow_monitor_map.test", "record_ipv4_source_prefix_tos", "true")) + checks = append(checks, resource.TestCheckResourceAttr("iosxr_flow_monitor_map.test", "record_ipv4_destination_prefix_tos", "true")) + checks = append(checks, resource.TestCheckResourceAttr("iosxr_flow_monitor_map.test", "record_ipv4_prefix_port", "true")) + checks = append(checks, resource.TestCheckResourceAttr("iosxr_flow_monitor_map.test", "record_ipv4_bgp_nexthop_tos", "true")) + checks = append(checks, resource.TestCheckResourceAttr("iosxr_flow_monitor_map.test", "record_ipv4_peer_as", "true")) + checks = append(checks, resource.TestCheckResourceAttr("iosxr_flow_monitor_map.test", "record_ipv4_gtp", "true")) + checks = append(checks, resource.TestCheckResourceAttr("iosxr_flow_monitor_map.test", "record_ipv6", "true")) + checks = append(checks, resource.TestCheckResourceAttr("iosxr_flow_monitor_map.test", "record_ipv6_destination", "true")) + checks = append(checks, resource.TestCheckResourceAttr("iosxr_flow_monitor_map.test", "record_ipv6_peer_as", "true")) + checks = append(checks, resource.TestCheckResourceAttr("iosxr_flow_monitor_map.test", "record_ipv6_gtp", "true")) + checks = append(checks, resource.TestCheckResourceAttr("iosxr_flow_monitor_map.test", "record_mpls", "true")) + checks = append(checks, resource.TestCheckResourceAttr("iosxr_flow_monitor_map.test", "record_mpls_ipv4_fields", "true")) + checks = append(checks, resource.TestCheckResourceAttr("iosxr_flow_monitor_map.test", "record_mpls_ipv6_fields", "true")) + checks = append(checks, resource.TestCheckResourceAttr("iosxr_flow_monitor_map.test", "record_mpls_ipv4_ipv6_fields", "true")) checks = append(checks, resource.TestCheckResourceAttr("iosxr_flow_monitor_map.test", "record_mpls_labels", "2")) + checks = append(checks, resource.TestCheckResourceAttr("iosxr_flow_monitor_map.test", "record_map_t", "true")) + checks = append(checks, resource.TestCheckResourceAttr("iosxr_flow_monitor_map.test", "record_sflow", "true")) + checks = append(checks, resource.TestCheckResourceAttr("iosxr_flow_monitor_map.test", "record_datalink_record", "true")) + checks = append(checks, resource.TestCheckResourceAttr("iosxr_flow_monitor_map.test", "record_default_rtp", "true")) + checks = append(checks, resource.TestCheckResourceAttr("iosxr_flow_monitor_map.test", "record_default_mdi", "true")) checks = append(checks, resource.TestCheckResourceAttr("iosxr_flow_monitor_map.test", "cache_entries", "5000")) checks = append(checks, resource.TestCheckResourceAttr("iosxr_flow_monitor_map.test", "cache_timeout_active", "1")) checks = append(checks, resource.TestCheckResourceAttr("iosxr_flow_monitor_map.test", "cache_timeout_inactive", "0")) checks = append(checks, resource.TestCheckResourceAttr("iosxr_flow_monitor_map.test", "cache_timeout_update", "1")) checks = append(checks, resource.TestCheckResourceAttr("iosxr_flow_monitor_map.test", "cache_timeout_rate_limit", "5000")) + checks = append(checks, resource.TestCheckResourceAttr("iosxr_flow_monitor_map.test", "cache_permanent", "true")) checks = append(checks, resource.TestCheckResourceAttr("iosxr_flow_monitor_map.test", "cache_immediate", "true")) checks = append(checks, resource.TestCheckResourceAttr("iosxr_flow_monitor_map.test", "hw_cache_timeout_inactive", "50")) checks = append(checks, resource.TestCheckResourceAttr("iosxr_flow_monitor_map.test", "sflow_options", "true")) @@ -64,11 +95,11 @@ func TestAccIosxrFlowMonitorMap(t *testing.T) { var steps []resource.TestStep if os.Getenv("SKIP_MINIMUM_TEST") == "" { steps = append(steps, resource.TestStep{ - Config: testAccIosxrFlowMonitorMapPrerequisitesConfig + testAccIosxrFlowMonitorMapConfig_minimum(), + Config: testAccIosxrFlowMonitorMapConfig_minimum(), }) } steps = append(steps, resource.TestStep{ - Config: testAccIosxrFlowMonitorMapPrerequisitesConfig + testAccIosxrFlowMonitorMapConfig_all(), + Config: testAccIosxrFlowMonitorMapConfig_all(), Check: resource.ComposeTestCheckFunc(checks...), }) steps = append(steps, resource.TestStep{ @@ -100,15 +131,6 @@ func iosxrFlowMonitorMapImportStateIdFunc(resourceName string) resource.ImportSt // End of section. //template:end importStateIdFunc // Section below is generated&owned by "gen/generator.go". //template:begin testPrerequisites -const testAccIosxrFlowMonitorMapPrerequisitesConfig = ` -resource "iosxr_gnmi" "PreReq0" { - path = "Cisco-IOS-XR-um-flow-cfg:/flow/exporter-maps/exporter-map[exporter-map-name=exporter_map1]" - attributes = { - "exporter-map-name" = "exporter_map1" - } -} - -` // End of section. //template:end testPrerequisites @@ -117,7 +139,6 @@ resource "iosxr_gnmi" "PreReq0" { func testAccIosxrFlowMonitorMapConfig_minimum() string { config := `resource "iosxr_flow_monitor_map" "test" {` + "\n" config += ` name = "monitor_map1"` + "\n" - config += ` depends_on = [iosxr_gnmi.PreReq0, ]` + "\n" config += `}` + "\n" return config } @@ -130,18 +151,49 @@ func testAccIosxrFlowMonitorMapConfig_all() string { config := `resource "iosxr_flow_monitor_map" "test" {` + "\n" config += ` name = "monitor_map1"` + "\n" config += ` exporters = [{` + "\n" - config += ` name = "exporter_map1"` + "\n" + config += ` name = "exporter1"` + "\n" config += ` }]` + "\n" config += ` option_outphysint = true` + "\n" config += ` option_filtered = true` + "\n" config += ` option_bgpattr = true` + "\n" config += ` option_outbundlemember = true` + "\n" + config += ` record_ipv4 = true` + "\n" + config += ` record_ipv4_destination = true` + "\n" + config += ` record_ipv4_destination_tos = true` + "\n" + config += ` record_ipv4_as = true` + "\n" + config += ` record_ipv4_protocol_port = true` + "\n" + config += ` record_ipv4_prefix = true` + "\n" + config += ` record_ipv4_source_prefix = true` + "\n" + config += ` record_ipv4_destination_prefix = true` + "\n" + config += ` record_ipv4_as_tos = true` + "\n" + config += ` record_ipv4_protocol_port_tos = true` + "\n" + config += ` record_ipv4_prefix_tos = true` + "\n" + config += ` record_ipv4_source_prefix_tos = true` + "\n" + config += ` record_ipv4_destination_prefix_tos = true` + "\n" + config += ` record_ipv4_prefix_port = true` + "\n" + config += ` record_ipv4_bgp_nexthop_tos = true` + "\n" + config += ` record_ipv4_peer_as = true` + "\n" + config += ` record_ipv4_gtp = true` + "\n" + config += ` record_ipv6 = true` + "\n" + config += ` record_ipv6_destination = true` + "\n" + config += ` record_ipv6_peer_as = true` + "\n" + config += ` record_ipv6_gtp = true` + "\n" + config += ` record_mpls = true` + "\n" + config += ` record_mpls_ipv4_fields = true` + "\n" + config += ` record_mpls_ipv6_fields = true` + "\n" + config += ` record_mpls_ipv4_ipv6_fields = true` + "\n" config += ` record_mpls_labels = 2` + "\n" + config += ` record_map_t = true` + "\n" + config += ` record_sflow = true` + "\n" + config += ` record_datalink_record = true` + "\n" + config += ` record_default_rtp = true` + "\n" + config += ` record_default_mdi = true` + "\n" config += ` cache_entries = 5000` + "\n" config += ` cache_timeout_active = 1` + "\n" config += ` cache_timeout_inactive = 0` + "\n" config += ` cache_timeout_update = 1` + "\n" config += ` cache_timeout_rate_limit = 5000` + "\n" + config += ` cache_permanent = true` + "\n" config += ` cache_immediate = true` + "\n" config += ` hw_cache_timeout_inactive = 50` + "\n" config += ` sflow_options = true` + "\n" @@ -153,7 +205,6 @@ func testAccIosxrFlowMonitorMapConfig_all() string { config += ` sflow_options_sample_header_size = 128` + "\n" config += ` sflow_options_input_ifindex = "physical"` + "\n" config += ` sflow_options_output_ifindex = "physical"` + "\n" - config += ` depends_on = [iosxr_gnmi.PreReq0, ]` + "\n" config += `}` + "\n" return config } diff --git a/internal/provider/resource_iosxr_flow_sampler_map.go b/internal/provider/resource_iosxr_flow_sampler_map.go index 19ed3222..86cf08bc 100644 --- a/internal/provider/resource_iosxr_flow_sampler_map.go +++ b/internal/provider/resource_iosxr_flow_sampler_map.go @@ -192,7 +192,7 @@ func (r *FlowSamplerMapResource) Read(ctx context.Context, req resource.ReadRequ resp.State.RemoveResource(ctx) return } else { - resp.Diagnostics.AddError("Unable to apply gNMI Get operation", err.Error()) + resp.Diagnostics.AddError("Unable to apply Get operation", err.Error()) return } } @@ -203,7 +203,7 @@ func (r *FlowSamplerMapResource) Read(ctx context.Context, req resource.ReadRequ } // After `terraform import` we switch to a full read. - respBody := getResp.Notification[0].Update[0].Val.GetJsonIetfVal() + respBody := getResp if imp { state.fromBody(ctx, respBody) } else { diff --git a/internal/provider/resource_iosxr_flow_sampler_map_test.go b/internal/provider/resource_iosxr_flow_sampler_map_test.go index da361ad1..74a41a24 100644 --- a/internal/provider/resource_iosxr_flow_sampler_map_test.go +++ b/internal/provider/resource_iosxr_flow_sampler_map_test.go @@ -34,8 +34,8 @@ import ( // Section below is generated&owned by "gen/generator.go". //template:begin testAcc func TestAccIosxrFlowSamplerMap(t *testing.T) { - if os.Getenv("NCS") == "" { - t.Skip("skipping test, set environment variable NCS") + if os.Getenv("PHYSICAL") == "" { + t.Skip("skipping test, set environment variable PHYSICAL") } var checks []resource.TestCheckFunc checks = append(checks, resource.TestCheckResourceAttr("iosxr_flow_sampler_map.test", "name", "sampler_map1")) diff --git a/internal/provider/resource_iosxr_fpd.go b/internal/provider/resource_iosxr_fpd.go index ecbebbf1..a33bc000 100644 --- a/internal/provider/resource_iosxr_fpd.go +++ b/internal/provider/resource_iosxr_fpd.go @@ -188,7 +188,7 @@ func (r *FPDResource) Read(ctx context.Context, req resource.ReadRequest, resp * resp.State.RemoveResource(ctx) return } else { - resp.Diagnostics.AddError("Unable to apply gNMI Get operation", err.Error()) + resp.Diagnostics.AddError("Unable to apply Get operation", err.Error()) return } } @@ -199,7 +199,7 @@ func (r *FPDResource) Read(ctx context.Context, req resource.ReadRequest, resp * } // After `terraform import` we switch to a full read. - respBody := getResp.Notification[0].Update[0].Val.GetJsonIetfVal() + respBody := getResp if imp { state.fromBody(ctx, respBody) } else { diff --git a/internal/provider/resource_iosxr_gnmi.go b/internal/provider/resource_iosxr_gnmi.go index 08c3602b..3524789e 100644 --- a/internal/provider/resource_iosxr_gnmi.go +++ b/internal/provider/resource_iosxr_gnmi.go @@ -213,12 +213,12 @@ func (r *GnmiResource) Read(ctx context.Context, req resource.ReadRequest, resp resp.State.RemoveResource(ctx) return } else { - resp.Diagnostics.AddError("Unable to apply gNMI Get operation", err.Error()) + resp.Diagnostics.AddError("Unable to apply Get operation", err.Error()) return } } - diags = state.fromBody(ctx, getResp.Notification[0].Update[0].Val.GetJsonIetfVal()) + diags = state.fromBody(ctx, getResp) resp.Diagnostics.Append(diags...) if resp.Diagnostics.HasError() { return diff --git a/internal/provider/resource_iosxr_hostname.go b/internal/provider/resource_iosxr_hostname.go index 58cb9c9c..a91baa2a 100644 --- a/internal/provider/resource_iosxr_hostname.go +++ b/internal/provider/resource_iosxr_hostname.go @@ -175,7 +175,7 @@ func (r *HostnameResource) Read(ctx context.Context, req resource.ReadRequest, r resp.State.RemoveResource(ctx) return } else { - resp.Diagnostics.AddError("Unable to apply gNMI Get operation", err.Error()) + resp.Diagnostics.AddError("Unable to apply Get operation", err.Error()) return } } @@ -186,7 +186,7 @@ func (r *HostnameResource) Read(ctx context.Context, req resource.ReadRequest, r } // After `terraform import` we switch to a full read. - respBody := getResp.Notification[0].Update[0].Val.GetJsonIetfVal() + respBody := getResp if imp { state.fromBody(ctx, respBody) } else { diff --git a/internal/provider/resource_iosxr_hostname_test.go b/internal/provider/resource_iosxr_hostname_test.go index 11c9392d..afcd88fe 100644 --- a/internal/provider/resource_iosxr_hostname_test.go +++ b/internal/provider/resource_iosxr_hostname_test.go @@ -80,7 +80,6 @@ func iosxrHostnameImportStateIdFunc(resourceName string) resource.ImportStateIdF func testAccIosxrHostnameConfig_minimum() string { config := `resource "iosxr_hostname" "test" {` + "\n" - config += ` system_network_name = "ROUTER-1"` + "\n" config += `}` + "\n" return config } diff --git a/internal/provider/resource_iosxr_interface.go b/internal/provider/resource_iosxr_interface.go index ac24821f..1c1a746e 100644 --- a/internal/provider/resource_iosxr_interface.go +++ b/internal/provider/resource_iosxr_interface.go @@ -695,7 +695,7 @@ func (r *InterfaceResource) Read(ctx context.Context, req resource.ReadRequest, resp.State.RemoveResource(ctx) return } else { - resp.Diagnostics.AddError("Unable to apply gNMI Get operation", err.Error()) + resp.Diagnostics.AddError("Unable to apply Get operation", err.Error()) return } } @@ -706,7 +706,7 @@ func (r *InterfaceResource) Read(ctx context.Context, req resource.ReadRequest, } // After `terraform import` we switch to a full read. - respBody := getResp.Notification[0].Update[0].Val.GetJsonIetfVal() + respBody := getResp if imp { state.fromBody(ctx, respBody) } else { diff --git a/internal/provider/resource_iosxr_interface_test.go b/internal/provider/resource_iosxr_interface_test.go index e1123f8d..4781e83b 100644 --- a/internal/provider/resource_iosxr_interface_test.go +++ b/internal/provider/resource_iosxr_interface_test.go @@ -42,13 +42,9 @@ func TestAccIosxrInterface(t *testing.T) { checks = append(checks, resource.TestCheckResourceAttr("iosxr_interface.test", "dampening", "true")) checks = append(checks, resource.TestCheckResourceAttr("iosxr_interface.test", "dampening_decay_half_life_value", "2")) checks = append(checks, resource.TestCheckResourceAttr("iosxr_interface.test", "ipv4_point_to_point", "true")) - if os.Getenv("XRV9K") != "" { - checks = append(checks, resource.TestCheckResourceAttr("iosxr_interface.test", "service_policy_input.0.name", "PMAP-IN")) - } - if os.Getenv("XRV9K") != "" { - checks = append(checks, resource.TestCheckResourceAttr("iosxr_interface.test", "service_policy_output.0.name", "PMAP-OUT")) - } - checks = append(checks, resource.TestCheckResourceAttr("iosxr_interface.test", "shutdown", "false")) + checks = append(checks, resource.TestCheckResourceAttr("iosxr_interface.test", "service_policy_input.0.name", "PMAP-IN")) + checks = append(checks, resource.TestCheckResourceAttr("iosxr_interface.test", "service_policy_output.0.name", "PMAP-OUT")) + checks = append(checks, resource.TestCheckResourceAttr("iosxr_interface.test", "shutdown", "true")) checks = append(checks, resource.TestCheckResourceAttr("iosxr_interface.test", "mtu", "9000")) checks = append(checks, resource.TestCheckResourceAttr("iosxr_interface.test", "bandwidth", "100000")) checks = append(checks, resource.TestCheckResourceAttr("iosxr_interface.test", "description", "My Interface Description")) @@ -66,48 +62,22 @@ func TestAccIosxrInterface(t *testing.T) { checks = append(checks, resource.TestCheckResourceAttr("iosxr_interface.test", "ipv4_verify_unicast_source_reachable_via_allow_default", "false")) } checks = append(checks, resource.TestCheckResourceAttr("iosxr_interface.test", "ipv4_access_group_ingress_acl1", "ACL1")) - if os.Getenv("XRV9K") != "" { - checks = append(checks, resource.TestCheckResourceAttr("iosxr_interface.test", "ipv4_access_group_ingress_hardware_count", "true")) - } - if os.Getenv("XRV9K") != "" { - checks = append(checks, resource.TestCheckResourceAttr("iosxr_interface.test", "ipv4_access_group_ingress_interface_statistics", "true")) - } - if os.Getenv("NCS") != "" || os.Getenv("XRV9K") != "" { - checks = append(checks, resource.TestCheckResourceAttr("iosxr_interface.test", "ipv4_access_group_ingress_compress", "0")) - } + checks = append(checks, resource.TestCheckResourceAttr("iosxr_interface.test", "ipv4_access_group_ingress_hardware_count", "true")) + checks = append(checks, resource.TestCheckResourceAttr("iosxr_interface.test", "ipv4_access_group_ingress_interface_statistics", "true")) + checks = append(checks, resource.TestCheckResourceAttr("iosxr_interface.test", "ipv4_access_group_ingress_compress", "0")) checks = append(checks, resource.TestCheckResourceAttr("iosxr_interface.test", "ipv4_access_group_egress_acl", "ACL1")) - if os.Getenv("XRV9K") != "" { - checks = append(checks, resource.TestCheckResourceAttr("iosxr_interface.test", "ipv4_access_group_egress_hardware_count", "true")) - } - if os.Getenv("XRV9K") != "" { - checks = append(checks, resource.TestCheckResourceAttr("iosxr_interface.test", "ipv4_access_group_egress_interface_statistics", "true")) - } - if os.Getenv("NCS") != "" || os.Getenv("XRV9K") != "" { - checks = append(checks, resource.TestCheckResourceAttr("iosxr_interface.test", "ipv4_access_group_egress_compress", "0")) - } - if os.Getenv("XRV9K") != "" { - checks = append(checks, resource.TestCheckResourceAttr("iosxr_interface.test", "ipv6_verify_unicast_source_reachable_via_type", "any")) - } - if os.Getenv("XRV9K") != "" { - checks = append(checks, resource.TestCheckResourceAttr("iosxr_interface.test", "ipv6_verify_unicast_source_reachable_via_allow_self_ping", "true")) - } - if os.Getenv("XRV9K") != "" { - checks = append(checks, resource.TestCheckResourceAttr("iosxr_interface.test", "ipv6_verify_unicast_source_reachable_via_allow_default", "false")) - } + checks = append(checks, resource.TestCheckResourceAttr("iosxr_interface.test", "ipv4_access_group_egress_hardware_count", "true")) + checks = append(checks, resource.TestCheckResourceAttr("iosxr_interface.test", "ipv4_access_group_egress_interface_statistics", "true")) + checks = append(checks, resource.TestCheckResourceAttr("iosxr_interface.test", "ipv4_access_group_egress_compress", "0")) + checks = append(checks, resource.TestCheckResourceAttr("iosxr_interface.test", "ipv6_verify_unicast_source_reachable_via_type", "any")) + checks = append(checks, resource.TestCheckResourceAttr("iosxr_interface.test", "ipv6_verify_unicast_source_reachable_via_allow_self_ping", "true")) + checks = append(checks, resource.TestCheckResourceAttr("iosxr_interface.test", "ipv6_verify_unicast_source_reachable_via_allow_default", "false")) checks = append(checks, resource.TestCheckResourceAttr("iosxr_interface.test", "ipv6_access_group_ingress_acl1", "ACL2")) - if os.Getenv("XRV9K") != "" { - checks = append(checks, resource.TestCheckResourceAttr("iosxr_interface.test", "ipv6_access_group_ingress_interface_statistics", "true")) - } - if os.Getenv("NCS") != "" || os.Getenv("XRV9K") != "" { - checks = append(checks, resource.TestCheckResourceAttr("iosxr_interface.test", "ipv6_access_group_ingress_compress", "0")) - } + checks = append(checks, resource.TestCheckResourceAttr("iosxr_interface.test", "ipv6_access_group_ingress_interface_statistics", "true")) + checks = append(checks, resource.TestCheckResourceAttr("iosxr_interface.test", "ipv6_access_group_ingress_compress", "0")) checks = append(checks, resource.TestCheckResourceAttr("iosxr_interface.test", "ipv6_access_group_egress_acl", "ACL2")) - if os.Getenv("XRV9K") != "" { - checks = append(checks, resource.TestCheckResourceAttr("iosxr_interface.test", "ipv6_access_group_egress_interface_statistics", "true")) - } - if os.Getenv("NCS") != "" || os.Getenv("XRV9K") != "" { - checks = append(checks, resource.TestCheckResourceAttr("iosxr_interface.test", "ipv6_access_group_egress_compress", "0")) - } + checks = append(checks, resource.TestCheckResourceAttr("iosxr_interface.test", "ipv6_access_group_egress_interface_statistics", "true")) + checks = append(checks, resource.TestCheckResourceAttr("iosxr_interface.test", "ipv6_access_group_egress_compress", "0")) checks = append(checks, resource.TestCheckResourceAttr("iosxr_interface.test", "ipv6_link_local_address", "fe80::1")) checks = append(checks, resource.TestCheckResourceAttr("iosxr_interface.test", "ipv6_link_local_zone", "0")) checks = append(checks, resource.TestCheckResourceAttr("iosxr_interface.test", "ipv6_autoconfig", "false")) @@ -116,14 +86,34 @@ func TestAccIosxrInterface(t *testing.T) { checks = append(checks, resource.TestCheckResourceAttr("iosxr_interface.test", "ipv6_addresses.0.prefix_length", "64")) checks = append(checks, resource.TestCheckResourceAttr("iosxr_interface.test", "ipv6_addresses.0.zone", "0")) checks = append(checks, resource.TestCheckResourceAttr("iosxr_interface.test", "bundle_port_priority", "100")) - if os.Getenv("FLOW") != "" { + if os.Getenv("PHYSICAL") != "" { + checks = append(checks, resource.TestCheckResourceAttr("iosxr_interface.test", "flow_ipv4_ingress_monitors.0.monitor_map_name", "MMAP1")) + } + if os.Getenv("PHYSICAL") != "" { checks = append(checks, resource.TestCheckResourceAttr("iosxr_interface.test", "flow_ipv4_ingress_monitor_samplers.0.monitor_map_name", "MMAP1")) checks = append(checks, resource.TestCheckResourceAttr("iosxr_interface.test", "flow_ipv4_ingress_monitor_samplers.0.sampler_map_name", "SMAP1")) } - if os.Getenv("FLOW") != "" { - checks = append(checks, resource.TestCheckResourceAttr("iosxr_interface.test", "flow_ipv6_ingress_monitor_samplers.0.monitor_map_name", "MMAP2")) + if os.Getenv("PHYSICAL") != "" { + checks = append(checks, resource.TestCheckResourceAttr("iosxr_interface.test", "flow_ipv4_egress_monitors.0.monitor_map_name", "MMAP1")) + } + if os.Getenv("PHYSICAL") != "" { + checks = append(checks, resource.TestCheckResourceAttr("iosxr_interface.test", "flow_ipv4_egress_monitor_samplers.0.monitor_map_name", "MMAP1")) + checks = append(checks, resource.TestCheckResourceAttr("iosxr_interface.test", "flow_ipv4_egress_monitor_samplers.0.sampler_map_name", "SMAP1")) + } + if os.Getenv("PHYSICAL") != "" { + checks = append(checks, resource.TestCheckResourceAttr("iosxr_interface.test", "flow_ipv6_ingress_monitors.0.monitor_map_name", "MMAP1")) + } + if os.Getenv("PHYSICAL") != "" { + checks = append(checks, resource.TestCheckResourceAttr("iosxr_interface.test", "flow_ipv6_ingress_monitor_samplers.0.monitor_map_name", "MMAP1")) checks = append(checks, resource.TestCheckResourceAttr("iosxr_interface.test", "flow_ipv6_ingress_monitor_samplers.0.sampler_map_name", "SMAP1")) } + if os.Getenv("PHYSICAL") != "" { + checks = append(checks, resource.TestCheckResourceAttr("iosxr_interface.test", "flow_ipv6_egress_monitors.0.monitor_map_name", "MMAP1")) + } + if os.Getenv("PHYSICAL") != "" { + checks = append(checks, resource.TestCheckResourceAttr("iosxr_interface.test", "flow_ipv6_egress_monitor_samplers.0.monitor_map_name", "MMAP1")) + checks = append(checks, resource.TestCheckResourceAttr("iosxr_interface.test", "flow_ipv6_egress_monitor_samplers.0.sampler_map_name", "SMAP1")) + } var steps []resource.TestStep if os.Getenv("SKIP_MINIMUM_TEST") == "" { steps = append(steps, resource.TestStep{ @@ -255,8 +245,6 @@ resource "iosxr_gnmi" "PreReq3" { func testAccIosxrInterfaceConfig_minimum() string { config := `resource "iosxr_interface" "test" {` + "\n" config += ` interface_name = "GigabitEthernet0/0/0/1"` + "\n" - config += ` shutdown = false` + "\n" - config += ` load_interval = 30` + "\n" config += ` depends_on = [iosxr_gnmi.PreReq0, iosxr_gnmi.PreReq1, iosxr_gnmi.PreReq2, iosxr_gnmi.PreReq3, ]` + "\n" config += `}` + "\n" return config @@ -275,17 +263,13 @@ func testAccIosxrInterfaceConfig_all() string { config += ` dampening = true` + "\n" config += ` dampening_decay_half_life_value = 2` + "\n" config += ` ipv4_point_to_point = true` + "\n" - if os.Getenv("XRV9K") != "" { - config += ` service_policy_input = [{` + "\n" - config += ` name = "PMAP-IN"` + "\n" - config += ` }]` + "\n" - } - if os.Getenv("XRV9K") != "" { - config += ` service_policy_output = [{` + "\n" - config += ` name = "PMAP-OUT"` + "\n" - config += ` }]` + "\n" - } - config += ` shutdown = false` + "\n" + config += ` service_policy_input = [{` + "\n" + config += ` name = "PMAP-IN"` + "\n" + config += ` }]` + "\n" + config += ` service_policy_output = [{` + "\n" + config += ` name = "PMAP-OUT"` + "\n" + config += ` }]` + "\n" + config += ` shutdown = true` + "\n" config += ` mtu = 9000` + "\n" config += ` bandwidth = 100000` + "\n" config += ` description = "My Interface Description"` + "\n" @@ -303,48 +287,22 @@ func testAccIosxrInterfaceConfig_all() string { config += ` ipv4_verify_unicast_source_reachable_via_allow_default = false` + "\n" } config += ` ipv4_access_group_ingress_acl1 = "ACL1"` + "\n" - if os.Getenv("XRV9K") != "" { - config += ` ipv4_access_group_ingress_hardware_count = true` + "\n" - } - if os.Getenv("XRV9K") != "" { - config += ` ipv4_access_group_ingress_interface_statistics = true` + "\n" - } - if os.Getenv("NCS") != "" || os.Getenv("XRV9K") != "" { - config += ` ipv4_access_group_ingress_compress = 0` + "\n" - } + config += ` ipv4_access_group_ingress_hardware_count = true` + "\n" + config += ` ipv4_access_group_ingress_interface_statistics = true` + "\n" + config += ` ipv4_access_group_ingress_compress = 0` + "\n" config += ` ipv4_access_group_egress_acl = "ACL1"` + "\n" - if os.Getenv("XRV9K") != "" { - config += ` ipv4_access_group_egress_hardware_count = true` + "\n" - } - if os.Getenv("XRV9K") != "" { - config += ` ipv4_access_group_egress_interface_statistics = true` + "\n" - } - if os.Getenv("NCS") != "" || os.Getenv("XRV9K") != "" { - config += ` ipv4_access_group_egress_compress = 0` + "\n" - } - if os.Getenv("XRV9K") != "" { - config += ` ipv6_verify_unicast_source_reachable_via_type = "any"` + "\n" - } - if os.Getenv("XRV9K") != "" { - config += ` ipv6_verify_unicast_source_reachable_via_allow_self_ping = true` + "\n" - } - if os.Getenv("XRV9K") != "" { - config += ` ipv6_verify_unicast_source_reachable_via_allow_default = false` + "\n" - } + config += ` ipv4_access_group_egress_hardware_count = true` + "\n" + config += ` ipv4_access_group_egress_interface_statistics = true` + "\n" + config += ` ipv4_access_group_egress_compress = 0` + "\n" + config += ` ipv6_verify_unicast_source_reachable_via_type = "any"` + "\n" + config += ` ipv6_verify_unicast_source_reachable_via_allow_self_ping = true` + "\n" + config += ` ipv6_verify_unicast_source_reachable_via_allow_default = false` + "\n" config += ` ipv6_access_group_ingress_acl1 = "ACL2"` + "\n" - if os.Getenv("XRV9K") != "" { - config += ` ipv6_access_group_ingress_interface_statistics = true` + "\n" - } - if os.Getenv("NCS") != "" || os.Getenv("XRV9K") != "" { - config += ` ipv6_access_group_ingress_compress = 0` + "\n" - } + config += ` ipv6_access_group_ingress_interface_statistics = true` + "\n" + config += ` ipv6_access_group_ingress_compress = 0` + "\n" config += ` ipv6_access_group_egress_acl = "ACL2"` + "\n" - if os.Getenv("XRV9K") != "" { - config += ` ipv6_access_group_egress_interface_statistics = true` + "\n" - } - if os.Getenv("NCS") != "" || os.Getenv("XRV9K") != "" { - config += ` ipv6_access_group_egress_compress = 0` + "\n" - } + config += ` ipv6_access_group_egress_interface_statistics = true` + "\n" + config += ` ipv6_access_group_egress_compress = 0` + "\n" config += ` ipv6_link_local_address = "fe80::1"` + "\n" config += ` ipv6_link_local_zone = "0"` + "\n" config += ` ipv6_autoconfig = false` + "\n" @@ -355,15 +313,47 @@ func testAccIosxrInterfaceConfig_all() string { config += ` zone = "0"` + "\n" config += ` }]` + "\n" config += ` bundle_port_priority = 100` + "\n" - if os.Getenv("FLOW") != "" { + if os.Getenv("PHYSICAL") != "" { + config += ` flow_ipv4_ingress_monitors = [{` + "\n" + config += ` monitor_map_name = "MMAP1"` + "\n" + config += ` }]` + "\n" + } + if os.Getenv("PHYSICAL") != "" { config += ` flow_ipv4_ingress_monitor_samplers = [{` + "\n" config += ` monitor_map_name = "MMAP1"` + "\n" config += ` sampler_map_name = "SMAP1"` + "\n" config += ` }]` + "\n" } - if os.Getenv("FLOW") != "" { + if os.Getenv("PHYSICAL") != "" { + config += ` flow_ipv4_egress_monitors = [{` + "\n" + config += ` monitor_map_name = "MMAP1"` + "\n" + config += ` }]` + "\n" + } + if os.Getenv("PHYSICAL") != "" { + config += ` flow_ipv4_egress_monitor_samplers = [{` + "\n" + config += ` monitor_map_name = "MMAP1"` + "\n" + config += ` sampler_map_name = "SMAP1"` + "\n" + config += ` }]` + "\n" + } + if os.Getenv("PHYSICAL") != "" { + config += ` flow_ipv6_ingress_monitors = [{` + "\n" + config += ` monitor_map_name = "MMAP1"` + "\n" + config += ` }]` + "\n" + } + if os.Getenv("PHYSICAL") != "" { config += ` flow_ipv6_ingress_monitor_samplers = [{` + "\n" - config += ` monitor_map_name = "MMAP2"` + "\n" + config += ` monitor_map_name = "MMAP1"` + "\n" + config += ` sampler_map_name = "SMAP1"` + "\n" + config += ` }]` + "\n" + } + if os.Getenv("PHYSICAL") != "" { + config += ` flow_ipv6_egress_monitors = [{` + "\n" + config += ` monitor_map_name = "MMAP1"` + "\n" + config += ` }]` + "\n" + } + if os.Getenv("PHYSICAL") != "" { + config += ` flow_ipv6_egress_monitor_samplers = [{` + "\n" + config += ` monitor_map_name = "MMAP1"` + "\n" config += ` sampler_map_name = "SMAP1"` + "\n" config += ` }]` + "\n" } diff --git a/internal/provider/resource_iosxr_ipv4_access_list.go b/internal/provider/resource_iosxr_ipv4_access_list.go index 7cb74b74..f0c783cc 100644 --- a/internal/provider/resource_iosxr_ipv4_access_list.go +++ b/internal/provider/resource_iosxr_ipv4_access_list.go @@ -1185,7 +1185,7 @@ func (r *IPv4AccessListResource) Read(ctx context.Context, req resource.ReadRequ resp.State.RemoveResource(ctx) return } else { - resp.Diagnostics.AddError("Unable to apply gNMI Get operation", err.Error()) + resp.Diagnostics.AddError("Unable to apply Get operation", err.Error()) return } } @@ -1196,7 +1196,7 @@ func (r *IPv4AccessListResource) Read(ctx context.Context, req resource.ReadRequ } // After `terraform import` we switch to a full read. - respBody := getResp.Notification[0].Update[0].Val.GetJsonIetfVal() + respBody := getResp if imp { state.fromBody(ctx, respBody) } else { diff --git a/internal/provider/resource_iosxr_ipv4_access_list_options.go b/internal/provider/resource_iosxr_ipv4_access_list_options.go index 61d24fea..63c7a704 100644 --- a/internal/provider/resource_iosxr_ipv4_access_list_options.go +++ b/internal/provider/resource_iosxr_ipv4_access_list_options.go @@ -191,7 +191,7 @@ func (r *IPv4AccessListOptionsResource) Read(ctx context.Context, req resource.R resp.State.RemoveResource(ctx) return } else { - resp.Diagnostics.AddError("Unable to apply gNMI Get operation", err.Error()) + resp.Diagnostics.AddError("Unable to apply Get operation", err.Error()) return } } @@ -202,7 +202,7 @@ func (r *IPv4AccessListOptionsResource) Read(ctx context.Context, req resource.R } // After `terraform import` we switch to a full read. - respBody := getResp.Notification[0].Update[0].Val.GetJsonIetfVal() + respBody := getResp if imp { state.fromBody(ctx, respBody) } else { diff --git a/internal/provider/resource_iosxr_ipv4_access_list_options_test.go b/internal/provider/resource_iosxr_ipv4_access_list_options_test.go index ff32b3f5..526bb257 100644 --- a/internal/provider/resource_iosxr_ipv4_access_list_options_test.go +++ b/internal/provider/resource_iosxr_ipv4_access_list_options_test.go @@ -81,7 +81,6 @@ func iosxrIPv4AccessListOptionsImportStateIdFunc(resourceName string) resource.I func testAccIosxrIPv4AccessListOptionsConfig_minimum() string { config := `resource "iosxr_ipv4_access_list_options" "test" {` + "\n" - config += ` log_update_rate = 1000` + "\n" config += `}` + "\n" return config } diff --git a/internal/provider/resource_iosxr_ipv4_access_list_test.go b/internal/provider/resource_iosxr_ipv4_access_list_test.go index ae61951c..2b5459b6 100644 --- a/internal/provider/resource_iosxr_ipv4_access_list_test.go +++ b/internal/provider/resource_iosxr_ipv4_access_list_test.go @@ -96,13 +96,6 @@ func iosxrIPv4AccessListImportStateIdFunc(resourceName string) resource.ImportSt func testAccIosxrIPv4AccessListConfig_minimum() string { config := `resource "iosxr_ipv4_access_list" "test" {` + "\n" config += ` access_list_name = "ACCESS1"` + "\n" - config += ` sequences = [{` + "\n" - config += ` sequence_number = 11` + "\n" - config += ` permit_protocol = "tcp"` + "\n" - config += ` permit_source_address = "18.0.0.0"` + "\n" - config += ` permit_source_wildcard_mask = "0.255.255.255"` + "\n" - config += ` permit_destination_host = "11.1.1.1"` + "\n" - config += ` }]` + "\n" config += `}` + "\n" return config } diff --git a/internal/provider/resource_iosxr_ipv4_prefix_list.go b/internal/provider/resource_iosxr_ipv4_prefix_list.go index 6c5153c1..4322496a 100644 --- a/internal/provider/resource_iosxr_ipv4_prefix_list.go +++ b/internal/provider/resource_iosxr_ipv4_prefix_list.go @@ -244,7 +244,7 @@ func (r *IPv4PrefixListResource) Read(ctx context.Context, req resource.ReadRequ resp.State.RemoveResource(ctx) return } else { - resp.Diagnostics.AddError("Unable to apply gNMI Get operation", err.Error()) + resp.Diagnostics.AddError("Unable to apply Get operation", err.Error()) return } } @@ -255,7 +255,7 @@ func (r *IPv4PrefixListResource) Read(ctx context.Context, req resource.ReadRequ } // After `terraform import` we switch to a full read. - respBody := getResp.Notification[0].Update[0].Val.GetJsonIetfVal() + respBody := getResp if imp { state.fromBody(ctx, respBody) } else { diff --git a/internal/provider/resource_iosxr_ipv4_prefix_list_test.go b/internal/provider/resource_iosxr_ipv4_prefix_list_test.go index a7b0e1f4..1a290afa 100644 --- a/internal/provider/resource_iosxr_ipv4_prefix_list_test.go +++ b/internal/provider/resource_iosxr_ipv4_prefix_list_test.go @@ -40,6 +40,7 @@ func TestAccIosxrIPv4PrefixList(t *testing.T) { checks = append(checks, resource.TestCheckResourceAttr("iosxr_ipv4_prefix_list.test", "sequences.0.permission", "deny")) checks = append(checks, resource.TestCheckResourceAttr("iosxr_ipv4_prefix_list.test", "sequences.0.prefix", "10.1.0.0")) checks = append(checks, resource.TestCheckResourceAttr("iosxr_ipv4_prefix_list.test", "sequences.0.mask", "255.255.0.0")) + checks = append(checks, resource.TestCheckResourceAttr("iosxr_ipv4_prefix_list.test", "sequences.0.match_prefix_length_eq", "12")) checks = append(checks, resource.TestCheckResourceAttr("iosxr_ipv4_prefix_list.test", "sequences.0.match_prefix_length_ge", "22")) checks = append(checks, resource.TestCheckResourceAttr("iosxr_ipv4_prefix_list.test", "sequences.0.match_prefix_length_le", "32")) var steps []resource.TestStep @@ -105,6 +106,7 @@ func testAccIosxrIPv4PrefixListConfig_all() string { config += ` permission = "deny"` + "\n" config += ` prefix = "10.1.0.0"` + "\n" config += ` mask = "255.255.0.0"` + "\n" + config += ` match_prefix_length_eq = 12` + "\n" config += ` match_prefix_length_ge = 22` + "\n" config += ` match_prefix_length_le = 32` + "\n" config += ` }]` + "\n" diff --git a/internal/provider/resource_iosxr_ipv6.go b/internal/provider/resource_iosxr_ipv6.go index 469108b1..4a06807e 100644 --- a/internal/provider/resource_iosxr_ipv6.go +++ b/internal/provider/resource_iosxr_ipv6.go @@ -235,7 +235,7 @@ func (r *IPv6Resource) Read(ctx context.Context, req resource.ReadRequest, resp resp.State.RemoveResource(ctx) return } else { - resp.Diagnostics.AddError("Unable to apply gNMI Get operation", err.Error()) + resp.Diagnostics.AddError("Unable to apply Get operation", err.Error()) return } } @@ -246,7 +246,7 @@ func (r *IPv6Resource) Read(ctx context.Context, req resource.ReadRequest, resp } // After `terraform import` we switch to a full read. - respBody := getResp.Notification[0].Update[0].Val.GetJsonIetfVal() + respBody := getResp if imp { state.fromBody(ctx, respBody) } else { diff --git a/internal/provider/resource_iosxr_ipv6_access_list.go b/internal/provider/resource_iosxr_ipv6_access_list.go index ae161456..1008d6e2 100644 --- a/internal/provider/resource_iosxr_ipv6_access_list.go +++ b/internal/provider/resource_iosxr_ipv6_access_list.go @@ -1025,7 +1025,7 @@ func (r *IPv6AccessListResource) Read(ctx context.Context, req resource.ReadRequ resp.State.RemoveResource(ctx) return } else { - resp.Diagnostics.AddError("Unable to apply gNMI Get operation", err.Error()) + resp.Diagnostics.AddError("Unable to apply Get operation", err.Error()) return } } @@ -1036,7 +1036,7 @@ func (r *IPv6AccessListResource) Read(ctx context.Context, req resource.ReadRequ } // After `terraform import` we switch to a full read. - respBody := getResp.Notification[0].Update[0].Val.GetJsonIetfVal() + respBody := getResp if imp { state.fromBody(ctx, respBody) } else { diff --git a/internal/provider/resource_iosxr_ipv6_access_list_options.go b/internal/provider/resource_iosxr_ipv6_access_list_options.go index e7951fb4..88cda3f4 100644 --- a/internal/provider/resource_iosxr_ipv6_access_list_options.go +++ b/internal/provider/resource_iosxr_ipv6_access_list_options.go @@ -191,7 +191,7 @@ func (r *IPv6AccessListOptionsResource) Read(ctx context.Context, req resource.R resp.State.RemoveResource(ctx) return } else { - resp.Diagnostics.AddError("Unable to apply gNMI Get operation", err.Error()) + resp.Diagnostics.AddError("Unable to apply Get operation", err.Error()) return } } @@ -202,7 +202,7 @@ func (r *IPv6AccessListOptionsResource) Read(ctx context.Context, req resource.R } // After `terraform import` we switch to a full read. - respBody := getResp.Notification[0].Update[0].Val.GetJsonIetfVal() + respBody := getResp if imp { state.fromBody(ctx, respBody) } else { diff --git a/internal/provider/resource_iosxr_ipv6_access_list_options_test.go b/internal/provider/resource_iosxr_ipv6_access_list_options_test.go index 55734df8..cb0b2d38 100644 --- a/internal/provider/resource_iosxr_ipv6_access_list_options_test.go +++ b/internal/provider/resource_iosxr_ipv6_access_list_options_test.go @@ -81,7 +81,6 @@ func iosxrIPv6AccessListOptionsImportStateIdFunc(resourceName string) resource.I func testAccIosxrIPv6AccessListOptionsConfig_minimum() string { config := `resource "iosxr_ipv6_access_list_options" "test" {` + "\n" - config += ` log_update_rate = 1000` + "\n" config += `}` + "\n" return config } diff --git a/internal/provider/resource_iosxr_ipv6_access_list_test.go b/internal/provider/resource_iosxr_ipv6_access_list_test.go index c509ce75..c0470f40 100644 --- a/internal/provider/resource_iosxr_ipv6_access_list_test.go +++ b/internal/provider/resource_iosxr_ipv6_access_list_test.go @@ -94,13 +94,6 @@ func iosxrIPv6AccessListImportStateIdFunc(resourceName string) resource.ImportSt func testAccIosxrIPv6AccessListConfig_minimum() string { config := `resource "iosxr_ipv6_access_list" "test" {` + "\n" config += ` access_list_name = "TEST1"` + "\n" - config += ` sequences = [{` + "\n" - config += ` sequence_number = 22` + "\n" - config += ` permit_protocol = "tcp"` + "\n" - config += ` permit_source_address = "1::1"` + "\n" - config += ` permit_source_prefix_length = 64` + "\n" - config += ` permit_destination_host = "2::1"` + "\n" - config += ` }]` + "\n" config += `}` + "\n" return config } diff --git a/internal/provider/resource_iosxr_ipv6_prefix_list.go b/internal/provider/resource_iosxr_ipv6_prefix_list.go index 24b62984..818d25d0 100644 --- a/internal/provider/resource_iosxr_ipv6_prefix_list.go +++ b/internal/provider/resource_iosxr_ipv6_prefix_list.go @@ -244,7 +244,7 @@ func (r *IPv6PrefixListResource) Read(ctx context.Context, req resource.ReadRequ resp.State.RemoveResource(ctx) return } else { - resp.Diagnostics.AddError("Unable to apply gNMI Get operation", err.Error()) + resp.Diagnostics.AddError("Unable to apply Get operation", err.Error()) return } } @@ -255,7 +255,7 @@ func (r *IPv6PrefixListResource) Read(ctx context.Context, req resource.ReadRequ } // After `terraform import` we switch to a full read. - respBody := getResp.Notification[0].Update[0].Val.GetJsonIetfVal() + respBody := getResp if imp { state.fromBody(ctx, respBody) } else { diff --git a/internal/provider/resource_iosxr_ipv6_prefix_list_test.go b/internal/provider/resource_iosxr_ipv6_prefix_list_test.go index 93a3d4cf..1927470c 100644 --- a/internal/provider/resource_iosxr_ipv6_prefix_list_test.go +++ b/internal/provider/resource_iosxr_ipv6_prefix_list_test.go @@ -41,7 +41,6 @@ func TestAccIosxrIPv6PrefixList(t *testing.T) { checks = append(checks, resource.TestCheckResourceAttr("iosxr_ipv6_prefix_list.test", "sequences.0.prefix", "2001:db8::")) checks = append(checks, resource.TestCheckResourceAttr("iosxr_ipv6_prefix_list.test", "sequences.0.mask", "32")) checks = append(checks, resource.TestCheckResourceAttr("iosxr_ipv6_prefix_list.test", "sequences.0.match_prefix_length_ge", "64")) - checks = append(checks, resource.TestCheckResourceAttr("iosxr_ipv6_prefix_list.test", "sequences.0.match_prefix_length_le", "128")) var steps []resource.TestStep if os.Getenv("SKIP_MINIMUM_TEST") == "" { steps = append(steps, resource.TestStep{ @@ -106,7 +105,6 @@ func testAccIosxrIPv6PrefixListConfig_all() string { config += ` prefix = "2001:db8::"` + "\n" config += ` mask = 32` + "\n" config += ` match_prefix_length_ge = 64` + "\n" - config += ` match_prefix_length_le = 128` + "\n" config += ` }]` + "\n" config += `}` + "\n" return config diff --git a/internal/provider/resource_iosxr_key_chain.go b/internal/provider/resource_iosxr_key_chain.go index 388b4232..28d3becd 100644 --- a/internal/provider/resource_iosxr_key_chain.go +++ b/internal/provider/resource_iosxr_key_chain.go @@ -301,7 +301,7 @@ func (r *KeyChainResource) Read(ctx context.Context, req resource.ReadRequest, r resp.State.RemoveResource(ctx) return } else { - resp.Diagnostics.AddError("Unable to apply gNMI Get operation", err.Error()) + resp.Diagnostics.AddError("Unable to apply Get operation", err.Error()) return } } @@ -312,7 +312,7 @@ func (r *KeyChainResource) Read(ctx context.Context, req resource.ReadRequest, r } // After `terraform import` we switch to a full read. - respBody := getResp.Notification[0].Update[0].Val.GetJsonIetfVal() + respBody := getResp if imp { state.fromBody(ctx, respBody) } else { diff --git a/internal/provider/resource_iosxr_l2vpn.go b/internal/provider/resource_iosxr_l2vpn.go index becf1cae..61ea5692 100644 --- a/internal/provider/resource_iosxr_l2vpn.go +++ b/internal/provider/resource_iosxr_l2vpn.go @@ -212,7 +212,7 @@ func (r *L2VPNResource) Read(ctx context.Context, req resource.ReadRequest, resp resp.State.RemoveResource(ctx) return } else { - resp.Diagnostics.AddError("Unable to apply gNMI Get operation", err.Error()) + resp.Diagnostics.AddError("Unable to apply Get operation", err.Error()) return } } @@ -223,7 +223,7 @@ func (r *L2VPNResource) Read(ctx context.Context, req resource.ReadRequest, resp } // After `terraform import` we switch to a full read. - respBody := getResp.Notification[0].Update[0].Val.GetJsonIetfVal() + respBody := getResp if imp { state.fromBody(ctx, respBody) } else { diff --git a/internal/provider/resource_iosxr_l2vpn_bridge_group.go b/internal/provider/resource_iosxr_l2vpn_bridge_group.go index 280df501..aeafeef7 100644 --- a/internal/provider/resource_iosxr_l2vpn_bridge_group.go +++ b/internal/provider/resource_iosxr_l2vpn_bridge_group.go @@ -184,7 +184,7 @@ func (r *L2VPNBridgeGroupResource) Read(ctx context.Context, req resource.ReadRe resp.State.RemoveResource(ctx) return } else { - resp.Diagnostics.AddError("Unable to apply gNMI Get operation", err.Error()) + resp.Diagnostics.AddError("Unable to apply Get operation", err.Error()) return } } @@ -195,7 +195,7 @@ func (r *L2VPNBridgeGroupResource) Read(ctx context.Context, req resource.ReadRe } // After `terraform import` we switch to a full read. - respBody := getResp.Notification[0].Update[0].Val.GetJsonIetfVal() + respBody := getResp if imp { state.fromBody(ctx, respBody) } else { diff --git a/internal/provider/resource_iosxr_l2vpn_bridge_group_bridge_domain.go b/internal/provider/resource_iosxr_l2vpn_bridge_group_bridge_domain.go index 1530868b..3aa69685 100644 --- a/internal/provider/resource_iosxr_l2vpn_bridge_group_bridge_domain.go +++ b/internal/provider/resource_iosxr_l2vpn_bridge_group_bridge_domain.go @@ -309,7 +309,7 @@ func (r *L2VPNBridgeGroupBridgeDomainResource) Read(ctx context.Context, req res resp.State.RemoveResource(ctx) return } else { - resp.Diagnostics.AddError("Unable to apply gNMI Get operation", err.Error()) + resp.Diagnostics.AddError("Unable to apply Get operation", err.Error()) return } } @@ -320,7 +320,7 @@ func (r *L2VPNBridgeGroupBridgeDomainResource) Read(ctx context.Context, req res } // After `terraform import` we switch to a full read. - respBody := getResp.Notification[0].Update[0].Val.GetJsonIetfVal() + respBody := getResp if imp { state.fromBody(ctx, respBody) } else { diff --git a/internal/provider/resource_iosxr_l2vpn_pw_class.go b/internal/provider/resource_iosxr_l2vpn_pw_class.go index 48d82526..8295d0ff 100644 --- a/internal/provider/resource_iosxr_l2vpn_pw_class.go +++ b/internal/provider/resource_iosxr_l2vpn_pw_class.go @@ -236,7 +236,7 @@ func (r *L2VPNPWClassResource) Read(ctx context.Context, req resource.ReadReques resp.State.RemoveResource(ctx) return } else { - resp.Diagnostics.AddError("Unable to apply gNMI Get operation", err.Error()) + resp.Diagnostics.AddError("Unable to apply Get operation", err.Error()) return } } @@ -247,7 +247,7 @@ func (r *L2VPNPWClassResource) Read(ctx context.Context, req resource.ReadReques } // After `terraform import` we switch to a full read. - respBody := getResp.Notification[0].Update[0].Val.GetJsonIetfVal() + respBody := getResp if imp { state.fromBody(ctx, respBody) } else { diff --git a/internal/provider/resource_iosxr_l2vpn_test.go b/internal/provider/resource_iosxr_l2vpn_test.go index b024902e..6ff8b96b 100644 --- a/internal/provider/resource_iosxr_l2vpn_test.go +++ b/internal/provider/resource_iosxr_l2vpn_test.go @@ -37,12 +37,8 @@ func TestAccIosxrL2VPN(t *testing.T) { var checks []resource.TestCheckFunc checks = append(checks, resource.TestCheckResourceAttr("iosxr_l2vpn.test", "description", "My L2VPN Description")) checks = append(checks, resource.TestCheckResourceAttr("iosxr_l2vpn.test", "router_id", "1.2.3.4")) - if os.Getenv("NCS") != "" || os.Getenv("XRV9K") != "" { - checks = append(checks, resource.TestCheckResourceAttr("iosxr_l2vpn.test", "load_balancing_flow_src_dst_mac", "false")) - } - if os.Getenv("NCS") != "" || os.Getenv("XRV9K") != "" { - checks = append(checks, resource.TestCheckResourceAttr("iosxr_l2vpn.test", "load_balancing_flow_src_dst_ip", "true")) - } + checks = append(checks, resource.TestCheckResourceAttr("iosxr_l2vpn.test", "load_balancing_flow_src_dst_mac", "false")) + checks = append(checks, resource.TestCheckResourceAttr("iosxr_l2vpn.test", "load_balancing_flow_src_dst_ip", "true")) checks = append(checks, resource.TestCheckResourceAttr("iosxr_l2vpn.test", "xconnect_groups.0.group_name", "P2P")) var steps []resource.TestStep if os.Getenv("SKIP_MINIMUM_TEST") == "" { @@ -100,12 +96,8 @@ func testAccIosxrL2VPNConfig_all() string { config := `resource "iosxr_l2vpn" "test" {` + "\n" config += ` description = "My L2VPN Description"` + "\n" config += ` router_id = "1.2.3.4"` + "\n" - if os.Getenv("NCS") != "" || os.Getenv("XRV9K") != "" { - config += ` load_balancing_flow_src_dst_mac = false` + "\n" - } - if os.Getenv("NCS") != "" || os.Getenv("XRV9K") != "" { - config += ` load_balancing_flow_src_dst_ip = true` + "\n" - } + config += ` load_balancing_flow_src_dst_mac = false` + "\n" + config += ` load_balancing_flow_src_dst_ip = true` + "\n" config += ` xconnect_groups = [{` + "\n" config += ` group_name = "P2P"` + "\n" config += ` }]` + "\n" diff --git a/internal/provider/resource_iosxr_l2vpn_xconnect_group_p2p.go b/internal/provider/resource_iosxr_l2vpn_xconnect_group_p2p.go index f4627b20..29f00d1a 100644 --- a/internal/provider/resource_iosxr_l2vpn_xconnect_group_p2p.go +++ b/internal/provider/resource_iosxr_l2vpn_xconnect_group_p2p.go @@ -379,7 +379,7 @@ func (r *L2VPNXconnectGroupP2PResource) Read(ctx context.Context, req resource.R resp.State.RemoveResource(ctx) return } else { - resp.Diagnostics.AddError("Unable to apply gNMI Get operation", err.Error()) + resp.Diagnostics.AddError("Unable to apply Get operation", err.Error()) return } } @@ -390,7 +390,7 @@ func (r *L2VPNXconnectGroupP2PResource) Read(ctx context.Context, req resource.R } // After `terraform import` we switch to a full read. - respBody := getResp.Notification[0].Update[0].Val.GetJsonIetfVal() + respBody := getResp if imp { state.fromBody(ctx, respBody) } else { diff --git a/internal/provider/resource_iosxr_lacp.go b/internal/provider/resource_iosxr_lacp.go index 80faab96..13c00f1a 100644 --- a/internal/provider/resource_iosxr_lacp.go +++ b/internal/provider/resource_iosxr_lacp.go @@ -188,7 +188,7 @@ func (r *LACPResource) Read(ctx context.Context, req resource.ReadRequest, resp resp.State.RemoveResource(ctx) return } else { - resp.Diagnostics.AddError("Unable to apply gNMI Get operation", err.Error()) + resp.Diagnostics.AddError("Unable to apply Get operation", err.Error()) return } } @@ -199,7 +199,7 @@ func (r *LACPResource) Read(ctx context.Context, req resource.ReadRequest, resp } // After `terraform import` we switch to a full read. - respBody := getResp.Notification[0].Update[0].Val.GetJsonIetfVal() + respBody := getResp if imp { state.fromBody(ctx, respBody) } else { diff --git a/internal/provider/resource_iosxr_lldp.go b/internal/provider/resource_iosxr_lldp.go index 2454dcd8..ca9ee0c2 100644 --- a/internal/provider/resource_iosxr_lldp.go +++ b/internal/provider/resource_iosxr_lldp.go @@ -230,7 +230,7 @@ func (r *LLDPResource) Read(ctx context.Context, req resource.ReadRequest, resp resp.State.RemoveResource(ctx) return } else { - resp.Diagnostics.AddError("Unable to apply gNMI Get operation", err.Error()) + resp.Diagnostics.AddError("Unable to apply Get operation", err.Error()) return } } @@ -241,7 +241,7 @@ func (r *LLDPResource) Read(ctx context.Context, req resource.ReadRequest, resp } // After `terraform import` we switch to a full read. - respBody := getResp.Notification[0].Update[0].Val.GetJsonIetfVal() + respBody := getResp if imp { state.fromBody(ctx, respBody) } else { diff --git a/internal/provider/resource_iosxr_logging.go b/internal/provider/resource_iosxr_logging.go index c6eff90c..d3c61c6b 100644 --- a/internal/provider/resource_iosxr_logging.go +++ b/internal/provider/resource_iosxr_logging.go @@ -243,7 +243,7 @@ func (r *LoggingResource) Read(ctx context.Context, req resource.ReadRequest, re resp.State.RemoveResource(ctx) return } else { - resp.Diagnostics.AddError("Unable to apply gNMI Get operation", err.Error()) + resp.Diagnostics.AddError("Unable to apply Get operation", err.Error()) return } } @@ -254,7 +254,7 @@ func (r *LoggingResource) Read(ctx context.Context, req resource.ReadRequest, re } // After `terraform import` we switch to a full read. - respBody := getResp.Notification[0].Update[0].Val.GetJsonIetfVal() + respBody := getResp if imp { state.fromBody(ctx, respBody) } else { diff --git a/internal/provider/resource_iosxr_logging_source_interface.go b/internal/provider/resource_iosxr_logging_source_interface.go index 45b3df0f..a18f9c26 100644 --- a/internal/provider/resource_iosxr_logging_source_interface.go +++ b/internal/provider/resource_iosxr_logging_source_interface.go @@ -188,7 +188,7 @@ func (r *LoggingSourceInterfaceResource) Read(ctx context.Context, req resource. resp.State.RemoveResource(ctx) return } else { - resp.Diagnostics.AddError("Unable to apply gNMI Get operation", err.Error()) + resp.Diagnostics.AddError("Unable to apply Get operation", err.Error()) return } } @@ -199,7 +199,7 @@ func (r *LoggingSourceInterfaceResource) Read(ctx context.Context, req resource. } // After `terraform import` we switch to a full read. - respBody := getResp.Notification[0].Update[0].Val.GetJsonIetfVal() + respBody := getResp if imp { state.fromBody(ctx, respBody) } else { diff --git a/internal/provider/resource_iosxr_logging_source_interface_test.go b/internal/provider/resource_iosxr_logging_source_interface_test.go index de5853b5..53f8ea0a 100644 --- a/internal/provider/resource_iosxr_logging_source_interface_test.go +++ b/internal/provider/resource_iosxr_logging_source_interface_test.go @@ -40,11 +40,11 @@ func TestAccIosxrLoggingSourceInterface(t *testing.T) { var steps []resource.TestStep if os.Getenv("SKIP_MINIMUM_TEST") == "" { steps = append(steps, resource.TestStep{ - Config: testAccIosxrLoggingSourceInterfacePrerequisitesConfig + testAccIosxrLoggingSourceInterfaceConfig_minimum(), + Config: testAccIosxrLoggingSourceInterfaceConfig_minimum(), }) } steps = append(steps, resource.TestStep{ - Config: testAccIosxrLoggingSourceInterfacePrerequisitesConfig + testAccIosxrLoggingSourceInterfaceConfig_all(), + Config: testAccIosxrLoggingSourceInterfaceConfig_all(), Check: resource.ComposeTestCheckFunc(checks...), }) steps = append(steps, resource.TestStep{ @@ -76,22 +76,6 @@ func iosxrLoggingSourceInterfaceImportStateIdFunc(resourceName string) resource. // End of section. //template:end importStateIdFunc // Section below is generated&owned by "gen/generator.go". //template:begin testPrerequisites -const testAccIosxrLoggingSourceInterfacePrerequisitesConfig = ` -resource "iosxr_gnmi" "PreReq0" { - path = "Cisco-IOS-XR-um-interface-cfg:/interfaces/interface[interface-name=Loopback0]" - attributes = { - "interface-name" = "Loopback0" - } -} - -resource "iosxr_gnmi" "PreReq1" { - path = "Cisco-IOS-XR-um-vrf-cfg:/vrfs/vrf[vrf-name=VRF1]" - attributes = { - "vrf-name" = "VRF1" - } -} - -` // End of section. //template:end testPrerequisites @@ -100,10 +84,6 @@ resource "iosxr_gnmi" "PreReq1" { func testAccIosxrLoggingSourceInterfaceConfig_minimum() string { config := `resource "iosxr_logging_source_interface" "test" {` + "\n" config += ` name = "Loopback0"` + "\n" - config += ` vrfs = [{` + "\n" - config += ` name = "VRF1"` + "\n" - config += ` }]` + "\n" - config += ` depends_on = [iosxr_gnmi.PreReq0, iosxr_gnmi.PreReq1, ]` + "\n" config += `}` + "\n" return config } @@ -118,7 +98,6 @@ func testAccIosxrLoggingSourceInterfaceConfig_all() string { config += ` vrfs = [{` + "\n" config += ` name = "VRF1"` + "\n" config += ` }]` + "\n" - config += ` depends_on = [iosxr_gnmi.PreReq0, iosxr_gnmi.PreReq1, ]` + "\n" config += `}` + "\n" return config } diff --git a/internal/provider/resource_iosxr_logging_test.go b/internal/provider/resource_iosxr_logging_test.go index 141fbb87..ba8540e0 100644 --- a/internal/provider/resource_iosxr_logging_test.go +++ b/internal/provider/resource_iosxr_logging_test.go @@ -90,7 +90,6 @@ func iosxrLoggingImportStateIdFunc(resourceName string) resource.ImportStateIdFu func testAccIosxrLoggingConfig_minimum() string { config := `resource "iosxr_logging" "test" {` + "\n" - config += ` trap = "informational"` + "\n" config += `}` + "\n" return config } diff --git a/internal/provider/resource_iosxr_logging_vrf.go b/internal/provider/resource_iosxr_logging_vrf.go index 1776a4fe..b26ce86a 100644 --- a/internal/provider/resource_iosxr_logging_vrf.go +++ b/internal/provider/resource_iosxr_logging_vrf.go @@ -256,7 +256,7 @@ func (r *LoggingVRFResource) Read(ctx context.Context, req resource.ReadRequest, resp.State.RemoveResource(ctx) return } else { - resp.Diagnostics.AddError("Unable to apply gNMI Get operation", err.Error()) + resp.Diagnostics.AddError("Unable to apply Get operation", err.Error()) return } } @@ -267,7 +267,7 @@ func (r *LoggingVRFResource) Read(ctx context.Context, req resource.ReadRequest, } // After `terraform import` we switch to a full read. - respBody := getResp.Notification[0].Update[0].Val.GetJsonIetfVal() + respBody := getResp if imp { state.fromBody(ctx, respBody) } else { diff --git a/internal/provider/resource_iosxr_mpls_ldp.go b/internal/provider/resource_iosxr_mpls_ldp.go index 9465aa3e..bbe1798a 100644 --- a/internal/provider/resource_iosxr_mpls_ldp.go +++ b/internal/provider/resource_iosxr_mpls_ldp.go @@ -129,10 +129,6 @@ func (r *MPLSLDPResource) Schema(ctx context.Context, req resource.SchemaRequest }, }, }, - "capabilities_sac": schema.BoolAttribute{ - MarkdownDescription: helpers.NewAttributeDescription("State Advertisement Control").String, - Optional: true, - }, "capabilities_sac_ipv4_disable": schema.BoolAttribute{ MarkdownDescription: helpers.NewAttributeDescription("Disable exchanging IPv4 prefix label bindings").String, Optional: true, @@ -163,10 +159,6 @@ func (r *MPLSLDPResource) Schema(ctx context.Context, req resource.SchemaRequest int64validator.Between(60, 600), }, }, - "mldp": schema.BoolAttribute{ - MarkdownDescription: helpers.NewAttributeDescription("Configure mLDP parameters").String, - Optional: true, - }, "mldp_logging_notifications": schema.BoolAttribute{ MarkdownDescription: helpers.NewAttributeDescription("MLDP logging notifications").String, Optional: true, @@ -306,7 +298,7 @@ func (r *MPLSLDPResource) Read(ctx context.Context, req resource.ReadRequest, re resp.State.RemoveResource(ctx) return } else { - resp.Diagnostics.AddError("Unable to apply gNMI Get operation", err.Error()) + resp.Diagnostics.AddError("Unable to apply Get operation", err.Error()) return } } @@ -317,7 +309,7 @@ func (r *MPLSLDPResource) Read(ctx context.Context, req resource.ReadRequest, re } // After `terraform import` we switch to a full read. - respBody := getResp.Notification[0].Update[0].Val.GetJsonIetfVal() + respBody := getResp if imp { state.fromBody(ctx, respBody) } else { diff --git a/internal/provider/resource_iosxr_mpls_oam.go b/internal/provider/resource_iosxr_mpls_oam.go index ea914f47..865c65e9 100644 --- a/internal/provider/resource_iosxr_mpls_oam.go +++ b/internal/provider/resource_iosxr_mpls_oam.go @@ -199,7 +199,7 @@ func (r *MPLSOAMResource) Read(ctx context.Context, req resource.ReadRequest, re resp.State.RemoveResource(ctx) return } else { - resp.Diagnostics.AddError("Unable to apply gNMI Get operation", err.Error()) + resp.Diagnostics.AddError("Unable to apply Get operation", err.Error()) return } } @@ -210,7 +210,7 @@ func (r *MPLSOAMResource) Read(ctx context.Context, req resource.ReadRequest, re } // After `terraform import` we switch to a full read. - respBody := getResp.Notification[0].Update[0].Val.GetJsonIetfVal() + respBody := getResp if imp { state.fromBody(ctx, respBody) } else { diff --git a/internal/provider/resource_iosxr_mpls_traffic_eng.go b/internal/provider/resource_iosxr_mpls_traffic_eng.go index 72bd8ef1..135f41b0 100644 --- a/internal/provider/resource_iosxr_mpls_traffic_eng.go +++ b/internal/provider/resource_iosxr_mpls_traffic_eng.go @@ -176,7 +176,7 @@ func (r *MPLSTrafficEngResource) Read(ctx context.Context, req resource.ReadRequ resp.State.RemoveResource(ctx) return } else { - resp.Diagnostics.AddError("Unable to apply gNMI Get operation", err.Error()) + resp.Diagnostics.AddError("Unable to apply Get operation", err.Error()) return } } @@ -187,7 +187,7 @@ func (r *MPLSTrafficEngResource) Read(ctx context.Context, req resource.ReadRequ } // After `terraform import` we switch to a full read. - respBody := getResp.Notification[0].Update[0].Val.GetJsonIetfVal() + respBody := getResp if imp { state.fromBody(ctx, respBody) } else { diff --git a/internal/provider/resource_iosxr_ntp.go b/internal/provider/resource_iosxr_ntp.go index 616bdedc..eff438f9 100644 --- a/internal/provider/resource_iosxr_ntp.go +++ b/internal/provider/resource_iosxr_ntp.go @@ -972,7 +972,7 @@ func (r *NTPResource) Read(ctx context.Context, req resource.ReadRequest, resp * resp.State.RemoveResource(ctx) return } else { - resp.Diagnostics.AddError("Unable to apply gNMI Get operation", err.Error()) + resp.Diagnostics.AddError("Unable to apply Get operation", err.Error()) return } } @@ -983,7 +983,7 @@ func (r *NTPResource) Read(ctx context.Context, req resource.ReadRequest, resp * } // After `terraform import` we switch to a full read. - respBody := getResp.Notification[0].Update[0].Val.GetJsonIetfVal() + respBody := getResp if imp { state.fromBody(ctx, respBody) } else { diff --git a/internal/provider/resource_iosxr_pce.go b/internal/provider/resource_iosxr_pce.go index c2d0bcc9..1caaf054 100644 --- a/internal/provider/resource_iosxr_pce.go +++ b/internal/provider/resource_iosxr_pce.go @@ -249,7 +249,7 @@ func (r *PCEResource) Read(ctx context.Context, req resource.ReadRequest, resp * resp.State.RemoveResource(ctx) return } else { - resp.Diagnostics.AddError("Unable to apply gNMI Get operation", err.Error()) + resp.Diagnostics.AddError("Unable to apply Get operation", err.Error()) return } } @@ -260,7 +260,7 @@ func (r *PCEResource) Read(ctx context.Context, req resource.ReadRequest, resp * } // After `terraform import` we switch to a full read. - respBody := getResp.Notification[0].Update[0].Val.GetJsonIetfVal() + respBody := getResp if imp { state.fromBody(ctx, respBody) } else { diff --git a/internal/provider/resource_iosxr_policy_map_qos.go b/internal/provider/resource_iosxr_policy_map_qos.go index 38de2ec4..3c3ed50d 100644 --- a/internal/provider/resource_iosxr_policy_map_qos.go +++ b/internal/provider/resource_iosxr_policy_map_qos.go @@ -301,7 +301,7 @@ func (r *PolicyMapQoSResource) Read(ctx context.Context, req resource.ReadReques resp.State.RemoveResource(ctx) return } else { - resp.Diagnostics.AddError("Unable to apply gNMI Get operation", err.Error()) + resp.Diagnostics.AddError("Unable to apply Get operation", err.Error()) return } } @@ -312,7 +312,7 @@ func (r *PolicyMapQoSResource) Read(ctx context.Context, req resource.ReadReques } // After `terraform import` we switch to a full read. - respBody := getResp.Notification[0].Update[0].Val.GetJsonIetfVal() + respBody := getResp if imp { state.fromBody(ctx, respBody) } else { diff --git a/internal/provider/resource_iosxr_prefix_set.go b/internal/provider/resource_iosxr_prefix_set.go index 1dd1f4b2..9bb90d66 100644 --- a/internal/provider/resource_iosxr_prefix_set.go +++ b/internal/provider/resource_iosxr_prefix_set.go @@ -180,7 +180,7 @@ func (r *PrefixSetResource) Read(ctx context.Context, req resource.ReadRequest, resp.State.RemoveResource(ctx) return } else { - resp.Diagnostics.AddError("Unable to apply gNMI Get operation", err.Error()) + resp.Diagnostics.AddError("Unable to apply Get operation", err.Error()) return } } @@ -191,7 +191,7 @@ func (r *PrefixSetResource) Read(ctx context.Context, req resource.ReadRequest, } // After `terraform import` we switch to a full read. - respBody := getResp.Notification[0].Update[0].Val.GetJsonIetfVal() + respBody := getResp if imp { state.fromBody(ctx, respBody) } else { diff --git a/internal/provider/resource_iosxr_rd_set.go b/internal/provider/resource_iosxr_rd_set.go index c01b4bf7..6e5786de 100644 --- a/internal/provider/resource_iosxr_rd_set.go +++ b/internal/provider/resource_iosxr_rd_set.go @@ -180,7 +180,7 @@ func (r *RDSetResource) Read(ctx context.Context, req resource.ReadRequest, resp resp.State.RemoveResource(ctx) return } else { - resp.Diagnostics.AddError("Unable to apply gNMI Get operation", err.Error()) + resp.Diagnostics.AddError("Unable to apply Get operation", err.Error()) return } } @@ -191,7 +191,7 @@ func (r *RDSetResource) Read(ctx context.Context, req resource.ReadRequest, resp } // After `terraform import` we switch to a full read. - respBody := getResp.Notification[0].Update[0].Val.GetJsonIetfVal() + respBody := getResp if imp { state.fromBody(ctx, respBody) } else { diff --git a/internal/provider/resource_iosxr_rd_set_test.go b/internal/provider/resource_iosxr_rd_set_test.go index 4bd233e3..f8076faa 100644 --- a/internal/provider/resource_iosxr_rd_set_test.go +++ b/internal/provider/resource_iosxr_rd_set_test.go @@ -36,7 +36,7 @@ import ( func TestAccIosxrRDSet(t *testing.T) { var checks []resource.TestCheckFunc checks = append(checks, resource.TestCheckResourceAttr("iosxr_rd_set.test", "set_name", "set1")) - checks = append(checks, resource.TestCheckResourceAttr("iosxr_rd_set.test", "rpl", "rd-set set1\n 65001:1,\n 123456:1,\n 192.0.2.1:1,\n match any\nend-set\n")) + checks = append(checks, resource.TestCheckResourceAttr("iosxr_rd_set.test", "rpl", "rd-set set1\nend-set\n")) var steps []resource.TestStep if os.Getenv("SKIP_MINIMUM_TEST") == "" { steps = append(steps, resource.TestStep{ @@ -84,7 +84,7 @@ func iosxrRDSetImportStateIdFunc(resourceName string) resource.ImportStateIdFunc func testAccIosxrRDSetConfig_minimum() string { config := `resource "iosxr_rd_set" "test" {` + "\n" config += ` set_name = "set1"` + "\n" - config += ` rpl = "rd-set set1\n 65001:1,\n 123456:1,\n 192.0.2.1:1,\n match any\nend-set\n"` + "\n" + config += ` rpl = "rd-set set1\nend-set\n"` + "\n" config += `}` + "\n" return config } @@ -96,7 +96,7 @@ func testAccIosxrRDSetConfig_minimum() string { func testAccIosxrRDSetConfig_all() string { config := `resource "iosxr_rd_set" "test" {` + "\n" config += ` set_name = "set1"` + "\n" - config += ` rpl = "rd-set set1\n 65001:1,\n 123456:1,\n 192.0.2.1:1,\n match any\nend-set\n"` + "\n" + config += ` rpl = "rd-set set1\nend-set\n"` + "\n" config += `}` + "\n" return config } diff --git a/internal/provider/resource_iosxr_route_policy.go b/internal/provider/resource_iosxr_route_policy.go index 6437ad58..c81f7ab8 100644 --- a/internal/provider/resource_iosxr_route_policy.go +++ b/internal/provider/resource_iosxr_route_policy.go @@ -180,7 +180,7 @@ func (r *RoutePolicyResource) Read(ctx context.Context, req resource.ReadRequest resp.State.RemoveResource(ctx) return } else { - resp.Diagnostics.AddError("Unable to apply gNMI Get operation", err.Error()) + resp.Diagnostics.AddError("Unable to apply Get operation", err.Error()) return } } @@ -191,7 +191,7 @@ func (r *RoutePolicyResource) Read(ctx context.Context, req resource.ReadRequest } // After `terraform import` we switch to a full read. - respBody := getResp.Notification[0].Update[0].Val.GetJsonIetfVal() + respBody := getResp if imp { state.fromBody(ctx, respBody) } else { diff --git a/internal/provider/resource_iosxr_route_policy_test.go b/internal/provider/resource_iosxr_route_policy_test.go index 004e2226..fd8bfbb0 100644 --- a/internal/provider/resource_iosxr_route_policy_test.go +++ b/internal/provider/resource_iosxr_route_policy_test.go @@ -40,11 +40,11 @@ func TestAccIosxrRoutePolicy(t *testing.T) { var steps []resource.TestStep if os.Getenv("SKIP_MINIMUM_TEST") == "" { steps = append(steps, resource.TestStep{ - Config: testAccIosxrRoutePolicyPrerequisitesConfig + testAccIosxrRoutePolicyConfig_minimum(), + Config: testAccIosxrRoutePolicyConfig_minimum(), }) } steps = append(steps, resource.TestStep{ - Config: testAccIosxrRoutePolicyPrerequisitesConfig + testAccIosxrRoutePolicyConfig_all(), + Config: testAccIosxrRoutePolicyConfig_all(), Check: resource.ComposeTestCheckFunc(checks...), }) steps = append(steps, resource.TestStep{ @@ -76,16 +76,6 @@ func iosxrRoutePolicyImportStateIdFunc(resourceName string) resource.ImportState // End of section. //template:end importStateIdFunc // Section below is generated&owned by "gen/generator.go". //template:begin testPrerequisites -const testAccIosxrRoutePolicyPrerequisitesConfig = ` -resource "iosxr_gnmi" "PreReq0" { - path = "Cisco-IOS-XR-um-route-policy-cfg:/routing-policy/sets/prefix-sets/prefix-set[set-name=PREFIX_SET_1]" - attributes = { - "set-name" = "PREFIX_SET_1" - "rpl-prefix-set" = "prefix-set PREFIX_SET_1\n 10.1.1.0/26 ge 26,\n 10.1.2.0/26 ge 26\nend-set\n" - } -} - -` // End of section. //template:end testPrerequisites @@ -95,7 +85,6 @@ func testAccIosxrRoutePolicyConfig_minimum() string { config := `resource "iosxr_route_policy" "test" {` + "\n" config += ` route_policy_name = "ROUTE_POLICY_1"` + "\n" config += ` rpl = "route-policy ROUTE_POLICY_1\n if destination in PREFIX_SET_1 then\n set extcommunity rt (12345:1) additive\n endif\n pass\nend-policy\n"` + "\n" - config += ` depends_on = [iosxr_gnmi.PreReq0, ]` + "\n" config += `}` + "\n" return config } @@ -108,7 +97,6 @@ func testAccIosxrRoutePolicyConfig_all() string { config := `resource "iosxr_route_policy" "test" {` + "\n" config += ` route_policy_name = "ROUTE_POLICY_1"` + "\n" config += ` rpl = "route-policy ROUTE_POLICY_1\n if destination in PREFIX_SET_1 then\n set extcommunity rt (12345:1) additive\n endif\n pass\nend-policy\n"` + "\n" - config += ` depends_on = [iosxr_gnmi.PreReq0, ]` + "\n" config += `}` + "\n" return config } diff --git a/internal/provider/resource_iosxr_router_bgp.go b/internal/provider/resource_iosxr_router_bgp.go index 4fe0be5b..a16cee1b 100644 --- a/internal/provider/resource_iosxr_router_bgp.go +++ b/internal/provider/resource_iosxr_router_bgp.go @@ -98,10 +98,6 @@ func (r *RouterBGPResource) Schema(ctx context.Context, req resource.SchemaReque int64validator.Between(1, 4294967295), }, }, - "nsr": schema.BoolAttribute{ - MarkdownDescription: helpers.NewAttributeDescription("Enable non-stop-routing support for all neighbors").String, - Optional: true, - }, "nsr_disable": schema.BoolAttribute{ MarkdownDescription: helpers.NewAttributeDescription("Disable non-stop-routing support for all neighbors").String, Optional: true, @@ -133,10 +129,6 @@ func (r *RouterBGPResource) Schema(ctx context.Context, req resource.SchemaReque MarkdownDescription: helpers.NewAttributeDescription("Disable keepalives/hold time").String, Optional: true, }, - "timers_bgp_keepalive_zero_holdtime_zero": schema.BoolAttribute{ - MarkdownDescription: helpers.NewAttributeDescription("Disable keepalives/hold time").String, - Optional: true, - }, "timers_bgp_keepalive_zero_minimum_acceptable_holdtime": schema.Int64Attribute{ MarkdownDescription: helpers.NewAttributeDescription("Minimum acceptable holdtime from neighbor").AddIntegerRangeDescription(3, 65535).String, Optional: true, @@ -151,6 +143,10 @@ func (r *RouterBGPResource) Schema(ctx context.Context, req resource.SchemaReque int64validator.Between(3, 65535), }, }, + "timers_bgp_holdtime_zero": schema.BoolAttribute{ + MarkdownDescription: helpers.NewAttributeDescription("Disable keepalives/hold time").String, + Optional: true, + }, "timers_bgp_holdtime_minimum_acceptable_holdtime": schema.Int64Attribute{ MarkdownDescription: helpers.NewAttributeDescription("Minimum acceptable holdtime from neighbor").AddIntegerRangeDescription(3, 65535).String, Optional: true, @@ -353,10 +349,6 @@ func (r *RouterBGPResource) Schema(ctx context.Context, req resource.SchemaReque MarkdownDescription: helpers.NewAttributeDescription("Disable keepalives/hold time").String, Optional: true, }, - "timers_keepalive_zero_holdtime_zero": schema.BoolAttribute{ - MarkdownDescription: helpers.NewAttributeDescription("Disable keepalives/hold time").String, - Optional: true, - }, "timers_keepalive_zero_minimum_acceptable_holdtime": schema.Int64Attribute{ MarkdownDescription: helpers.NewAttributeDescription("Minimum acceptable holdtime from neighbor").AddIntegerRangeDescription(3, 65535).String, Optional: true, @@ -364,13 +356,17 @@ func (r *RouterBGPResource) Schema(ctx context.Context, req resource.SchemaReque int64validator.Between(3, 65535), }, }, - "timers_holdtime": schema.Int64Attribute{ + "timers_holdtime_number": schema.Int64Attribute{ MarkdownDescription: helpers.NewAttributeDescription("Holdtime").AddIntegerRangeDescription(3, 65535).String, Optional: true, Validators: []validator.Int64{ int64validator.Between(3, 65535), }, }, + "timers_holdtime_zero": schema.BoolAttribute{ + MarkdownDescription: helpers.NewAttributeDescription("Disable keepalives/hold time").String, + Optional: true, + }, "timers_holdtime_minimum_acceptable_holdtime": schema.Int64Attribute{ MarkdownDescription: helpers.NewAttributeDescription("Minimum acceptable holdtime from neighbor").AddIntegerRangeDescription(3, 65535).String, Optional: true, @@ -486,7 +482,7 @@ func (r *RouterBGPResource) Read(ctx context.Context, req resource.ReadRequest, resp.State.RemoveResource(ctx) return } else { - resp.Diagnostics.AddError("Unable to apply gNMI Get operation", err.Error()) + resp.Diagnostics.AddError("Unable to apply Get operation", err.Error()) return } } @@ -497,7 +493,7 @@ func (r *RouterBGPResource) Read(ctx context.Context, req resource.ReadRequest, } // After `terraform import` we switch to a full read. - respBody := getResp.Notification[0].Update[0].Val.GetJsonIetfVal() + respBody := getResp if imp { state.fromBody(ctx, respBody) } else { diff --git a/internal/provider/resource_iosxr_router_bgp_address_family.go b/internal/provider/resource_iosxr_router_bgp_address_family.go index 1338b092..9f020b16 100644 --- a/internal/provider/resource_iosxr_router_bgp_address_family.go +++ b/internal/provider/resource_iosxr_router_bgp_address_family.go @@ -164,10 +164,6 @@ func (r *RouterBGPAddressFamilyResource) Schema(ctx context.Context, req resourc int64validator.Between(2, 1024), }, }, - "maximum_paths_ibgp_unequal_cost": schema.BoolAttribute{ - MarkdownDescription: helpers.NewAttributeDescription("Allow multipaths to have different BGP nexthop IGP metrics").String, - Optional: true, - }, "maximum_paths_ibgp_unequal_cost_deterministic": schema.BoolAttribute{ MarkdownDescription: helpers.NewAttributeDescription("Deterministic Multipath selection primarily on IGP metric order").String, Optional: true, @@ -921,7 +917,7 @@ func (r *RouterBGPAddressFamilyResource) Read(ctx context.Context, req resource. resp.State.RemoveResource(ctx) return } else { - resp.Diagnostics.AddError("Unable to apply gNMI Get operation", err.Error()) + resp.Diagnostics.AddError("Unable to apply Get operation", err.Error()) return } } @@ -932,7 +928,7 @@ func (r *RouterBGPAddressFamilyResource) Read(ctx context.Context, req resource. } // After `terraform import` we switch to a full read. - respBody := getResp.Notification[0].Update[0].Val.GetJsonIetfVal() + respBody := getResp if imp { state.fromBody(ctx, respBody) } else { diff --git a/internal/provider/resource_iosxr_router_bgp_neighbor_address_family.go b/internal/provider/resource_iosxr_router_bgp_neighbor_address_family.go index f81bbb2b..b215c797 100644 --- a/internal/provider/resource_iosxr_router_bgp_neighbor_address_family.go +++ b/internal/provider/resource_iosxr_router_bgp_neighbor_address_family.go @@ -127,14 +127,6 @@ func (r *RouterBGPNeighborAddressFamilyResource) Schema(ctx context.Context, req MarkdownDescription: helpers.NewAttributeDescription("Prevent route-reflector-client from being inherited from the parent").String, Optional: true, }, - "advertise_vpnv4_unicast": schema.BoolAttribute{ - MarkdownDescription: helpers.NewAttributeDescription("Enable advertise vpnv4 unicast").String, - Optional: true, - }, - "advertise_vpnv4_unicast_re_originated": schema.BoolAttribute{ - MarkdownDescription: helpers.NewAttributeDescription("Advertise re-orignated and local routes only").String, - Optional: true, - }, "advertise_vpnv4_unicast_re_originated_stitching_rt": schema.BoolAttribute{ MarkdownDescription: helpers.NewAttributeDescription("Advertise re-originated and local routes with stitching Route-Targets").String, Optional: true, @@ -168,10 +160,6 @@ func (r *RouterBGPNeighborAddressFamilyResource) Schema(ctx context.Context, req stringvalidator.LengthBetween(1, 255), }, }, - "soft_reconfiguration_inbound": schema.BoolAttribute{ - MarkdownDescription: helpers.NewAttributeDescription("Allow inbound soft reconfiguration for this neighbor").String, - Optional: true, - }, "soft_reconfiguration_inbound_always": schema.BoolAttribute{ MarkdownDescription: helpers.NewAttributeDescription("Always use soft reconfig, even if route refresh is supported").String, Optional: true, @@ -322,7 +310,7 @@ func (r *RouterBGPNeighborAddressFamilyResource) Read(ctx context.Context, req r resp.State.RemoveResource(ctx) return } else { - resp.Diagnostics.AddError("Unable to apply gNMI Get operation", err.Error()) + resp.Diagnostics.AddError("Unable to apply Get operation", err.Error()) return } } @@ -333,7 +321,7 @@ func (r *RouterBGPNeighborAddressFamilyResource) Read(ctx context.Context, req r } // After `terraform import` we switch to a full read. - respBody := getResp.Notification[0].Update[0].Val.GetJsonIetfVal() + respBody := getResp if imp { state.fromBody(ctx, respBody) } else { diff --git a/internal/provider/resource_iosxr_router_bgp_neighbor_address_family_test.go b/internal/provider/resource_iosxr_router_bgp_neighbor_address_family_test.go index b51f0c55..9d3ea6a4 100644 --- a/internal/provider/resource_iosxr_router_bgp_neighbor_address_family_test.go +++ b/internal/provider/resource_iosxr_router_bgp_neighbor_address_family_test.go @@ -36,23 +36,20 @@ import ( func TestAccIosxrRouterBGPNeighborAddressFamily(t *testing.T) { var checks []resource.TestCheckFunc checks = append(checks, resource.TestCheckResourceAttr("iosxr_router_bgp_neighbor_address_family.test", "af_name", "vpnv4-unicast")) + checks = append(checks, resource.TestCheckResourceAttr("iosxr_router_bgp_neighbor_address_family.test", "import_stitching_rt_re_originate_stitching_rt", "true")) checks = append(checks, resource.TestCheckResourceAttr("iosxr_router_bgp_neighbor_address_family.test", "route_reflector_client", "true")) checks = append(checks, resource.TestCheckResourceAttr("iosxr_router_bgp_neighbor_address_family.test", "route_reflector_client_inheritance_disable", "true")) - checks = append(checks, resource.TestCheckResourceAttr("iosxr_router_bgp_neighbor_address_family.test", "advertise_vpnv4_unicast", "true")) - checks = append(checks, resource.TestCheckResourceAttr("iosxr_router_bgp_neighbor_address_family.test", "advertise_vpnv4_unicast_re_originated", "true")) checks = append(checks, resource.TestCheckResourceAttr("iosxr_router_bgp_neighbor_address_family.test", "advertise_vpnv4_unicast_re_originated_stitching_rt", "true")) checks = append(checks, resource.TestCheckResourceAttr("iosxr_router_bgp_neighbor_address_family.test", "next_hop_self", "true")) checks = append(checks, resource.TestCheckResourceAttr("iosxr_router_bgp_neighbor_address_family.test", "next_hop_self_inheritance_disable", "true")) checks = append(checks, resource.TestCheckResourceAttr("iosxr_router_bgp_neighbor_address_family.test", "encapsulation_type", "srv6")) checks = append(checks, resource.TestCheckResourceAttr("iosxr_router_bgp_neighbor_address_family.test", "route_policy_in", "ROUTE_POLICY_1")) checks = append(checks, resource.TestCheckResourceAttr("iosxr_router_bgp_neighbor_address_family.test", "route_policy_out", "ROUTE_POLICY_1")) - checks = append(checks, resource.TestCheckResourceAttr("iosxr_router_bgp_neighbor_address_family.test", "soft_reconfiguration_inbound", "true")) checks = append(checks, resource.TestCheckResourceAttr("iosxr_router_bgp_neighbor_address_family.test", "soft_reconfiguration_inbound_always", "true")) checks = append(checks, resource.TestCheckResourceAttr("iosxr_router_bgp_neighbor_address_family.test", "maximum_prefix_limit", "1248576")) checks = append(checks, resource.TestCheckResourceAttr("iosxr_router_bgp_neighbor_address_family.test", "maximum_prefix_threshold", "80")) checks = append(checks, resource.TestCheckResourceAttr("iosxr_router_bgp_neighbor_address_family.test", "maximum_prefix_warning_only", "true")) checks = append(checks, resource.TestCheckResourceAttr("iosxr_router_bgp_neighbor_address_family.test", "default_originate", "true")) - checks = append(checks, resource.TestCheckResourceAttr("iosxr_router_bgp_neighbor_address_family.test", "default_originate_route_policy", "ROUTE_POLICY_1")) var steps []resource.TestStep if os.Getenv("SKIP_MINIMUM_TEST") == "" { steps = append(steps, resource.TestStep{ @@ -158,23 +155,20 @@ func testAccIosxrRouterBGPNeighborAddressFamilyConfig_all() string { config += ` as_number = "65001"` + "\n" config += ` address = "10.1.1.2"` + "\n" config += ` af_name = "vpnv4-unicast"` + "\n" + config += ` import_stitching_rt_re_originate_stitching_rt = true` + "\n" config += ` route_reflector_client = true` + "\n" config += ` route_reflector_client_inheritance_disable = true` + "\n" - config += ` advertise_vpnv4_unicast = true` + "\n" - config += ` advertise_vpnv4_unicast_re_originated = true` + "\n" config += ` advertise_vpnv4_unicast_re_originated_stitching_rt = true` + "\n" config += ` next_hop_self = true` + "\n" config += ` next_hop_self_inheritance_disable = true` + "\n" config += ` encapsulation_type = "srv6"` + "\n" config += ` route_policy_in = "ROUTE_POLICY_1"` + "\n" config += ` route_policy_out = "ROUTE_POLICY_1"` + "\n" - config += ` soft_reconfiguration_inbound = true` + "\n" config += ` soft_reconfiguration_inbound_always = true` + "\n" config += ` maximum_prefix_limit = 1248576` + "\n" config += ` maximum_prefix_threshold = 80` + "\n" config += ` maximum_prefix_warning_only = true` + "\n" config += ` default_originate = true` + "\n" - config += ` default_originate_route_policy = "ROUTE_POLICY_1"` + "\n" config += ` depends_on = [iosxr_gnmi.PreReq0, iosxr_gnmi.PreReq1, ]` + "\n" config += `}` + "\n" return config diff --git a/internal/provider/resource_iosxr_router_bgp_neighbor_group.go b/internal/provider/resource_iosxr_router_bgp_neighbor_group.go index 46371c9e..674ca64d 100644 --- a/internal/provider/resource_iosxr_router_bgp_neighbor_group.go +++ b/internal/provider/resource_iosxr_router_bgp_neighbor_group.go @@ -217,10 +217,6 @@ func (r *RouterBGPNeighborGroupResource) Schema(ctx context.Context, req resourc MarkdownDescription: helpers.NewAttributeDescription("Disable keepalives/hold time").String, Optional: true, }, - "timers_keepalive_zero_holdtime_zero": schema.BoolAttribute{ - MarkdownDescription: helpers.NewAttributeDescription("Disable keepalives/hold time").String, - Optional: true, - }, "timers_keepalive_zero_minimum_acceptable_holdtime": schema.Int64Attribute{ MarkdownDescription: helpers.NewAttributeDescription("Minimum acceptable holdtime from neighbor").AddIntegerRangeDescription(3, 65535).String, Optional: true, @@ -235,6 +231,10 @@ func (r *RouterBGPNeighborGroupResource) Schema(ctx context.Context, req resourc int64validator.Between(3, 65535), }, }, + "timers_holdtime_zero": schema.BoolAttribute{ + MarkdownDescription: helpers.NewAttributeDescription("Disable keepalives/hold time").String, + Optional: true, + }, "timers_holdtime_minimum_acceptable_holdtime": schema.Int64Attribute{ MarkdownDescription: helpers.NewAttributeDescription("Minimum acceptable holdtime from neighbor").AddIntegerRangeDescription(3, 65535).String, Optional: true, @@ -392,7 +392,7 @@ func (r *RouterBGPNeighborGroupResource) Read(ctx context.Context, req resource. resp.State.RemoveResource(ctx) return } else { - resp.Diagnostics.AddError("Unable to apply gNMI Get operation", err.Error()) + resp.Diagnostics.AddError("Unable to apply Get operation", err.Error()) return } } @@ -403,7 +403,7 @@ func (r *RouterBGPNeighborGroupResource) Read(ctx context.Context, req resource. } // After `terraform import` we switch to a full read. - respBody := getResp.Notification[0].Update[0].Val.GetJsonIetfVal() + respBody := getResp if imp { state.fromBody(ctx, respBody) } else { diff --git a/internal/provider/resource_iosxr_router_bgp_neighbor_group_test.go b/internal/provider/resource_iosxr_router_bgp_neighbor_group_test.go index 348f0480..860e060b 100644 --- a/internal/provider/resource_iosxr_router_bgp_neighbor_group_test.go +++ b/internal/provider/resource_iosxr_router_bgp_neighbor_group_test.go @@ -44,11 +44,11 @@ func TestAccIosxrRouterBGPNeighborGroup(t *testing.T) { checks = append(checks, resource.TestCheckResourceAttr("iosxr_router_bgp_neighbor_group.test", "bfd_multiplier", "4")) checks = append(checks, resource.TestCheckResourceAttr("iosxr_router_bgp_neighbor_group.test", "bfd_fast_detect", "true")) checks = append(checks, resource.TestCheckResourceAttr("iosxr_router_bgp_neighbor_group.test", "bfd_fast_detect_strict_mode", "false")) + checks = append(checks, resource.TestCheckResourceAttr("iosxr_router_bgp_neighbor_group.test", "bfd_fast_detect_disable", "false")) checks = append(checks, resource.TestCheckResourceAttr("iosxr_router_bgp_neighbor_group.test", "password", "12341C2713181F13253920")) checks = append(checks, resource.TestCheckResourceAttr("iosxr_router_bgp_neighbor_group.test", "password_inheritance_disable", "false")) checks = append(checks, resource.TestCheckResourceAttr("iosxr_router_bgp_neighbor_group.test", "timers_keepalive_interval", "10")) - checks = append(checks, resource.TestCheckResourceAttr("iosxr_router_bgp_neighbor_group.test", "timers_holdtime", "30")) - checks = append(checks, resource.TestCheckResourceAttr("iosxr_router_bgp_neighbor_group.test", "timers_holdtime_minimum_acceptable_holdtime", "30")) + checks = append(checks, resource.TestCheckResourceAttr("iosxr_router_bgp_neighbor_group.test", "timers_holdtime", "20")) checks = append(checks, resource.TestCheckResourceAttr("iosxr_router_bgp_neighbor_group.test", "address_families.0.af_name", "ipv4-labeled-unicast")) checks = append(checks, resource.TestCheckResourceAttr("iosxr_router_bgp_neighbor_group.test", "address_families.0.soft_reconfiguration_inbound_always", "true")) checks = append(checks, resource.TestCheckResourceAttr("iosxr_router_bgp_neighbor_group.test", "address_families.0.next_hop_self", "true")) @@ -144,11 +144,11 @@ func testAccIosxrRouterBGPNeighborGroupConfig_all() string { config += ` bfd_multiplier = 4` + "\n" config += ` bfd_fast_detect = true` + "\n" config += ` bfd_fast_detect_strict_mode = false` + "\n" + config += ` bfd_fast_detect_disable = false` + "\n" config += ` password = "12341C2713181F13253920"` + "\n" config += ` password_inheritance_disable = false` + "\n" config += ` timers_keepalive_interval = 10` + "\n" - config += ` timers_holdtime = 30` + "\n" - config += ` timers_holdtime_minimum_acceptable_holdtime = 30` + "\n" + config += ` timers_holdtime = 20` + "\n" config += ` address_families = [{` + "\n" config += ` af_name = "ipv4-labeled-unicast"` + "\n" config += ` soft_reconfiguration_inbound_always = true` + "\n" diff --git a/internal/provider/resource_iosxr_router_bgp_vrf.go b/internal/provider/resource_iosxr_router_bgp_vrf.go index 8fbb8c01..6b970a5a 100644 --- a/internal/provider/resource_iosxr_router_bgp_vrf.go +++ b/internal/provider/resource_iosxr_router_bgp_vrf.go @@ -161,10 +161,6 @@ func (r *RouterBGPVRFResource) Schema(ctx context.Context, req resource.SchemaRe MarkdownDescription: helpers.NewAttributeDescription("Disable keepalives/hold time").String, Optional: true, }, - "timers_bgp_keepalive_zero_holdtime_zero": schema.BoolAttribute{ - MarkdownDescription: helpers.NewAttributeDescription("Disable keepalives/hold time").String, - Optional: true, - }, "timers_bgp_keepalive_zero_minimum_acceptable_holdtime": schema.Int64Attribute{ MarkdownDescription: helpers.NewAttributeDescription("Minimum acceptable holdtime from neighbor").AddIntegerRangeDescription(3, 65535).String, Optional: true, @@ -179,6 +175,10 @@ func (r *RouterBGPVRFResource) Schema(ctx context.Context, req resource.SchemaRe int64validator.Between(3, 65535), }, }, + "timers_bgp_holdtime_zero": schema.BoolAttribute{ + MarkdownDescription: helpers.NewAttributeDescription("Disable keepalives/hold time").String, + Optional: true, + }, "timers_bgp_holdtime_minimum_acceptable_holdtime": schema.Int64Attribute{ MarkdownDescription: helpers.NewAttributeDescription("Minimum acceptable holdtime from neighbor").AddIntegerRangeDescription(3, 65535).String, Optional: true, @@ -298,11 +298,11 @@ func (r *RouterBGPVRFResource) Schema(ctx context.Context, req resource.SchemaRe MarkdownDescription: helpers.NewAttributeDescription("Do not prepend local AS to announcements from this neighbor").String, Optional: true, }, - "local_as_no_prepend_replace_as": schema.BoolAttribute{ + "local_as_replace_as": schema.BoolAttribute{ MarkdownDescription: helpers.NewAttributeDescription("Prepend only local AS to announcements to this neighbor").String, Optional: true, }, - "local_as_no_prepend_replace_as_dual_as": schema.BoolAttribute{ + "local_as_dual_as": schema.BoolAttribute{ MarkdownDescription: helpers.NewAttributeDescription("Dual-AS mode").String, Optional: true, }, @@ -329,10 +329,6 @@ func (r *RouterBGPVRFResource) Schema(ctx context.Context, req resource.SchemaRe MarkdownDescription: helpers.NewAttributeDescription("Disable keepalives/hold time").String, Optional: true, }, - "timers_keepalive_zero_holdtime_zero": schema.BoolAttribute{ - MarkdownDescription: helpers.NewAttributeDescription("Disable keepalives/hold time").String, - Optional: true, - }, "timers_keepalive_zero_minimum_acceptable_holdtime": schema.Int64Attribute{ MarkdownDescription: helpers.NewAttributeDescription("Minimum acceptable holdtime from neighbor").AddIntegerRangeDescription(3, 65535).String, Optional: true, @@ -347,6 +343,10 @@ func (r *RouterBGPVRFResource) Schema(ctx context.Context, req resource.SchemaRe int64validator.Between(3, 65535), }, }, + "timers_holdtime_zero": schema.BoolAttribute{ + MarkdownDescription: helpers.NewAttributeDescription("Disable keepalives/hold time").String, + Optional: true, + }, "timers_holdtime_minimum_acceptable_holdtime": schema.Int64Attribute{ MarkdownDescription: helpers.NewAttributeDescription("Minimum acceptable holdtime from neighbor").AddIntegerRangeDescription(3, 65535).String, Optional: true, @@ -462,7 +462,7 @@ func (r *RouterBGPVRFResource) Read(ctx context.Context, req resource.ReadReques resp.State.RemoveResource(ctx) return } else { - resp.Diagnostics.AddError("Unable to apply gNMI Get operation", err.Error()) + resp.Diagnostics.AddError("Unable to apply Get operation", err.Error()) return } } @@ -473,7 +473,7 @@ func (r *RouterBGPVRFResource) Read(ctx context.Context, req resource.ReadReques } // After `terraform import` we switch to a full read. - respBody := getResp.Notification[0].Update[0].Val.GetJsonIetfVal() + respBody := getResp if imp { state.fromBody(ctx, respBody) } else { diff --git a/internal/provider/resource_iosxr_router_bgp_vrf_address_family.go b/internal/provider/resource_iosxr_router_bgp_vrf_address_family.go index f1f52fce..101aa855 100644 --- a/internal/provider/resource_iosxr_router_bgp_vrf_address_family.go +++ b/internal/provider/resource_iosxr_router_bgp_vrf_address_family.go @@ -183,10 +183,6 @@ func (r *RouterBGPVRFAddressFamilyResource) Schema(ctx context.Context, req reso int64validator.Between(2, 128), }, }, - "maximum_paths_ibgp_unequal_cost": schema.BoolAttribute{ - MarkdownDescription: helpers.NewAttributeDescription("Allow multipaths to have different BGP nexthop IGP metrics").String, - Optional: true, - }, "maximum_paths_ibgp_unequal_cost_deterministic": schema.BoolAttribute{ MarkdownDescription: helpers.NewAttributeDescription("Deterministic Multipath selection primarily on IGP metric order").String, Optional: true, @@ -957,7 +953,7 @@ func (r *RouterBGPVRFAddressFamilyResource) Read(ctx context.Context, req resour resp.State.RemoveResource(ctx) return } else { - resp.Diagnostics.AddError("Unable to apply gNMI Get operation", err.Error()) + resp.Diagnostics.AddError("Unable to apply Get operation", err.Error()) return } } @@ -968,7 +964,7 @@ func (r *RouterBGPVRFAddressFamilyResource) Read(ctx context.Context, req resour } // After `terraform import` we switch to a full read. - respBody := getResp.Notification[0].Update[0].Val.GetJsonIetfVal() + respBody := getResp if imp { state.fromBody(ctx, respBody) } else { diff --git a/internal/provider/resource_iosxr_router_bgp_vrf_address_family_test.go b/internal/provider/resource_iosxr_router_bgp_vrf_address_family_test.go index d6bf58ab..0292bbf2 100644 --- a/internal/provider/resource_iosxr_router_bgp_vrf_address_family_test.go +++ b/internal/provider/resource_iosxr_router_bgp_vrf_address_family_test.go @@ -44,34 +44,23 @@ func TestAccIosxrRouterBGPVRFAddressFamily(t *testing.T) { checks = append(checks, resource.TestCheckResourceAttr("iosxr_router_bgp_vrf_address_family.test", "allocate_label_all", "true")) checks = append(checks, resource.TestCheckResourceAttr("iosxr_router_bgp_vrf_address_family.test", "allocate_label_all_unlabeled_path", "true")) checks = append(checks, resource.TestCheckResourceAttr("iosxr_router_bgp_vrf_address_family.test", "advertise_best_external", "true")) - checks = append(checks, resource.TestCheckResourceAttr("iosxr_router_bgp_vrf_address_family.test", "maximum_paths_ebgp_multipath", "10")) - checks = append(checks, resource.TestCheckResourceAttr("iosxr_router_bgp_vrf_address_family.test", "maximum_paths_ebgp_selective", "true")) - checks = append(checks, resource.TestCheckResourceAttr("iosxr_router_bgp_vrf_address_family.test", "maximum_paths_ebgp_route_policy", "MULTIPATH_POLICY")) - checks = append(checks, resource.TestCheckResourceAttr("iosxr_router_bgp_vrf_address_family.test", "maximum_paths_ibgp_multipath", "10")) - checks = append(checks, resource.TestCheckResourceAttr("iosxr_router_bgp_vrf_address_family.test", "maximum_paths_ibgp_unequal_cost", "true")) - checks = append(checks, resource.TestCheckResourceAttr("iosxr_router_bgp_vrf_address_family.test", "maximum_paths_ibgp_unequal_cost_deterministic", "true")) - checks = append(checks, resource.TestCheckResourceAttr("iosxr_router_bgp_vrf_address_family.test", "maximum_paths_ibgp_selective", "true")) - checks = append(checks, resource.TestCheckResourceAttr("iosxr_router_bgp_vrf_address_family.test", "maximum_paths_ibgp_route_policy", "MULTIPATH_POLICY")) - checks = append(checks, resource.TestCheckResourceAttr("iosxr_router_bgp_vrf_address_family.test", "label_mode_per_prefix", "true")) checks = append(checks, resource.TestCheckResourceAttr("iosxr_router_bgp_vrf_address_family.test", "segment_routing_srv6_locator", "LocAlgo11")) - checks = append(checks, resource.TestCheckResourceAttr("iosxr_router_bgp_vrf_address_family.test", "segment_routing_srv6_alloc_mode_per_vrf", "true")) checks = append(checks, resource.TestCheckResourceAttr("iosxr_router_bgp_vrf_address_family.test", "aggregate_addresses.0.address", "10.0.0.0")) checks = append(checks, resource.TestCheckResourceAttr("iosxr_router_bgp_vrf_address_family.test", "aggregate_addresses.0.prefix", "8")) checks = append(checks, resource.TestCheckResourceAttr("iosxr_router_bgp_vrf_address_family.test", "aggregate_addresses.0.as_set", "true")) checks = append(checks, resource.TestCheckResourceAttr("iosxr_router_bgp_vrf_address_family.test", "aggregate_addresses.0.as_confed_set", "false")) checks = append(checks, resource.TestCheckResourceAttr("iosxr_router_bgp_vrf_address_family.test", "aggregate_addresses.0.summary_only", "true")) - checks = append(checks, resource.TestCheckResourceAttr("iosxr_router_bgp_vrf_address_family.test", "aggregate_addresses.0.route_policy", "ROUTE_POLICY_1")) checks = append(checks, resource.TestCheckResourceAttr("iosxr_router_bgp_vrf_address_family.test", "aggregate_addresses.0.description", "Aggregate route description")) checks = append(checks, resource.TestCheckResourceAttr("iosxr_router_bgp_vrf_address_family.test", "aggregate_addresses.0.set_tag", "100")) checks = append(checks, resource.TestCheckResourceAttr("iosxr_router_bgp_vrf_address_family.test", "networks.0.address", "10.1.0.0")) checks = append(checks, resource.TestCheckResourceAttr("iosxr_router_bgp_vrf_address_family.test", "networks.0.prefix", "16")) checks = append(checks, resource.TestCheckResourceAttr("iosxr_router_bgp_vrf_address_family.test", "networks.0.route_policy", "ROUTE_POLICY_1")) checks = append(checks, resource.TestCheckResourceAttr("iosxr_router_bgp_vrf_address_family.test", "redistribute_ospf.0.router_tag", "OSPF1")) - checks = append(checks, resource.TestCheckResourceAttr("iosxr_router_bgp_vrf_address_family.test", "redistribute_ospf.0.match_internal_external_nssa_external_2", "true")) checks = append(checks, resource.TestCheckResourceAttr("iosxr_router_bgp_vrf_address_family.test", "redistribute_ospf.0.metric", "100")) checks = append(checks, resource.TestCheckResourceAttr("iosxr_router_bgp_vrf_address_family.test", "redistribute_ospf.0.multipath", "true")) checks = append(checks, resource.TestCheckResourceAttr("iosxr_router_bgp_vrf_address_family.test", "redistribute_ospf.0.route_policy", "REDISTRIBUTE_POLICY")) checks = append(checks, resource.TestCheckResourceAttr("iosxr_router_bgp_vrf_address_family.test", "redistribute_eigrp.0.instance_name", "EIGRP1")) + checks = append(checks, resource.TestCheckResourceAttr("iosxr_router_bgp_vrf_address_family.test", "redistribute_eigrp.0.match_internal", "true")) checks = append(checks, resource.TestCheckResourceAttr("iosxr_router_bgp_vrf_address_family.test", "redistribute_eigrp.0.match_internal_external", "true")) checks = append(checks, resource.TestCheckResourceAttr("iosxr_router_bgp_vrf_address_family.test", "redistribute_eigrp.0.metric", "100")) checks = append(checks, resource.TestCheckResourceAttr("iosxr_router_bgp_vrf_address_family.test", "redistribute_eigrp.0.multipath", "true")) @@ -178,22 +167,14 @@ resource "iosxr_gnmi" "PreReq0" { } resource "iosxr_gnmi" "PreReq1" { - path = "Cisco-IOS-XR-um-vrf-cfg:/vrfs/vrf[vrf-name=VRF3]" + path = "Cisco-IOS-XR-um-vrf-cfg:/vrfs/vrf[vrf-name=VRF1]/Cisco-IOS-XR-um-router-bgp-cfg:rd/Cisco-IOS-XR-um-router-bgp-cfg:two-byte-as" attributes = { - "vrf-name" = "VRF3" + "two-byte-as-number" = "1" + "asn2-index" = "1" } } resource "iosxr_gnmi" "PreReq2" { - path = "Cisco-IOS-XR-um-vrf-cfg:/vrfs/vrf[vrf-name=VRF3]/Cisco-IOS-XR-um-router-bgp-cfg:rd/Cisco-IOS-XR-um-router-bgp-cfg:two-byte-as" - attributes = { - "two-byte-as-number" = "65001" - "asn2-index" = "3" - } - depends_on = [iosxr_gnmi.PreReq1, ] -} - -resource "iosxr_gnmi" "PreReq3" { path = "Cisco-IOS-XR-um-router-bgp-cfg:/router/bgp/as[as-number=65001]" attributes = { "as-number" = "65001" @@ -220,9 +201,9 @@ resource "iosxr_gnmi" "PreReq3" { func testAccIosxrRouterBGPVRFAddressFamilyConfig_minimum() string { config := `resource "iosxr_router_bgp_vrf_address_family" "test" {` + "\n" config += ` as_number = "65001"` + "\n" - config += ` vrf_name = "VRF3"` + "\n" + config += ` vrf_name = "VRF1"` + "\n" config += ` af_name = "ipv4-unicast"` + "\n" - config += ` depends_on = [iosxr_gnmi.PreReq0, iosxr_gnmi.PreReq1, iosxr_gnmi.PreReq2, iosxr_gnmi.PreReq3, ]` + "\n" + config += ` depends_on = [iosxr_gnmi.PreReq0, iosxr_gnmi.PreReq1, iosxr_gnmi.PreReq2, ]` + "\n" config += `}` + "\n" return config } @@ -234,7 +215,7 @@ func testAccIosxrRouterBGPVRFAddressFamilyConfig_minimum() string { func testAccIosxrRouterBGPVRFAddressFamilyConfig_all() string { config := `resource "iosxr_router_bgp_vrf_address_family" "test" {` + "\n" config += ` as_number = "65001"` + "\n" - config += ` vrf_name = "VRF3"` + "\n" + config += ` vrf_name = "VRF1"` + "\n" config += ` af_name = "ipv4-unicast"` + "\n" config += ` additional_paths_send = true` + "\n" config += ` additional_paths_send_disable = true` + "\n" @@ -244,24 +225,13 @@ func testAccIosxrRouterBGPVRFAddressFamilyConfig_all() string { config += ` allocate_label_all = true` + "\n" config += ` allocate_label_all_unlabeled_path = true` + "\n" config += ` advertise_best_external = true` + "\n" - config += ` maximum_paths_ebgp_multipath = 10` + "\n" - config += ` maximum_paths_ebgp_selective = true` + "\n" - config += ` maximum_paths_ebgp_route_policy = "MULTIPATH_POLICY"` + "\n" - config += ` maximum_paths_ibgp_multipath = 10` + "\n" - config += ` maximum_paths_ibgp_unequal_cost = true` + "\n" - config += ` maximum_paths_ibgp_unequal_cost_deterministic = true` + "\n" - config += ` maximum_paths_ibgp_selective = true` + "\n" - config += ` maximum_paths_ibgp_route_policy = "MULTIPATH_POLICY"` + "\n" - config += ` label_mode_per_prefix = true` + "\n" config += ` segment_routing_srv6_locator = "LocAlgo11"` + "\n" - config += ` segment_routing_srv6_alloc_mode_per_vrf = true` + "\n" config += ` aggregate_addresses = [{` + "\n" config += ` address = "10.0.0.0"` + "\n" config += ` prefix = 8` + "\n" config += ` as_set = true` + "\n" config += ` as_confed_set = false` + "\n" config += ` summary_only = true` + "\n" - config += ` route_policy = "ROUTE_POLICY_1"` + "\n" config += ` description = "Aggregate route description"` + "\n" config += ` set_tag = 100` + "\n" config += ` }]` + "\n" @@ -272,13 +242,13 @@ func testAccIosxrRouterBGPVRFAddressFamilyConfig_all() string { config += ` }]` + "\n" config += ` redistribute_ospf = [{` + "\n" config += ` router_tag = "OSPF1"` + "\n" - config += ` match_internal_external_nssa_external_2 = true` + "\n" config += ` metric = 100` + "\n" config += ` multipath = true` + "\n" config += ` route_policy = "REDISTRIBUTE_POLICY"` + "\n" config += ` }]` + "\n" config += ` redistribute_eigrp = [{` + "\n" config += ` instance_name = "EIGRP1"` + "\n" + config += ` match_internal = true` + "\n" config += ` match_internal_external = true` + "\n" config += ` metric = 100` + "\n" config += ` multipath = true` + "\n" @@ -303,7 +273,7 @@ func testAccIosxrRouterBGPVRFAddressFamilyConfig_all() string { config += ` redistribute_rip_metric = 100` + "\n" config += ` redistribute_rip_multipath = true` + "\n" config += ` redistribute_rip_route_policy = "REDISTRIBUTE_POLICY"` + "\n" - config += ` depends_on = [iosxr_gnmi.PreReq0, iosxr_gnmi.PreReq1, iosxr_gnmi.PreReq2, iosxr_gnmi.PreReq3, ]` + "\n" + config += ` depends_on = [iosxr_gnmi.PreReq0, iosxr_gnmi.PreReq1, iosxr_gnmi.PreReq2, ]` + "\n" config += `}` + "\n" return config } diff --git a/internal/provider/resource_iosxr_router_bgp_vrf_neighbor_address_family.go b/internal/provider/resource_iosxr_router_bgp_vrf_neighbor_address_family.go index 791b9a8b..540c8dfb 100644 --- a/internal/provider/resource_iosxr_router_bgp_vrf_neighbor_address_family.go +++ b/internal/provider/resource_iosxr_router_bgp_vrf_neighbor_address_family.go @@ -128,10 +128,6 @@ func (r *RouterBGPVRFNeighborAddressFamilyResource) Schema(ctx context.Context, stringvalidator.LengthBetween(1, 255), }, }, - "default_originate": schema.BoolAttribute{ - MarkdownDescription: helpers.NewAttributeDescription("Originate default route to this neighbor").String, - Optional: true, - }, "default_originate_route_policy": schema.StringAttribute{ MarkdownDescription: helpers.NewAttributeDescription("Route policy to specify criteria to originate default").String, Optional: true, @@ -281,7 +277,7 @@ func (r *RouterBGPVRFNeighborAddressFamilyResource) Read(ctx context.Context, re resp.State.RemoveResource(ctx) return } else { - resp.Diagnostics.AddError("Unable to apply gNMI Get operation", err.Error()) + resp.Diagnostics.AddError("Unable to apply Get operation", err.Error()) return } } @@ -292,7 +288,7 @@ func (r *RouterBGPVRFNeighborAddressFamilyResource) Read(ctx context.Context, re } // After `terraform import` we switch to a full read. - respBody := getResp.Notification[0].Update[0].Val.GetJsonIetfVal() + respBody := getResp if imp { state.fromBody(ctx, respBody) } else { diff --git a/internal/provider/resource_iosxr_router_hsrp_interface.go b/internal/provider/resource_iosxr_router_hsrp_interface.go index fed11713..398bf8c7 100644 --- a/internal/provider/resource_iosxr_router_hsrp_interface.go +++ b/internal/provider/resource_iosxr_router_hsrp_interface.go @@ -227,7 +227,7 @@ func (r *RouterHSRPInterfaceResource) Read(ctx context.Context, req resource.Rea resp.State.RemoveResource(ctx) return } else { - resp.Diagnostics.AddError("Unable to apply gNMI Get operation", err.Error()) + resp.Diagnostics.AddError("Unable to apply Get operation", err.Error()) return } } @@ -238,7 +238,7 @@ func (r *RouterHSRPInterfaceResource) Read(ctx context.Context, req resource.Rea } // After `terraform import` we switch to a full read. - respBody := getResp.Notification[0].Update[0].Val.GetJsonIetfVal() + respBody := getResp if imp { state.fromBody(ctx, respBody) } else { diff --git a/internal/provider/resource_iosxr_router_hsrp_interface_ipv4_group_v1.go b/internal/provider/resource_iosxr_router_hsrp_interface_ipv4_group_v1.go index f8a03396..c148a2bf 100644 --- a/internal/provider/resource_iosxr_router_hsrp_interface_ipv4_group_v1.go +++ b/internal/provider/resource_iosxr_router_hsrp_interface_ipv4_group_v1.go @@ -150,21 +150,21 @@ func (r *RouterHSRPInterfaceIPv4GroupV1Resource) Schema(ctx context.Context, req int64validator.Between(100, 3000), }, }, - "timers_msec_holdtime": schema.Int64Attribute{ + "timers_msec2": schema.Int64Attribute{ MarkdownDescription: helpers.NewAttributeDescription("Specify hold time in milliseconds").AddIntegerRangeDescription(100, 3000).String, Optional: true, Validators: []validator.Int64{ int64validator.Between(100, 3000), }, }, - "timers_seconds": schema.Int64Attribute{ + "timers_hold_time": schema.Int64Attribute{ MarkdownDescription: helpers.NewAttributeDescription("Hold time in seconds").AddIntegerRangeDescription(1, 255).String, Optional: true, Validators: []validator.Int64{ int64validator.Between(1, 255), }, }, - "timers_seconds_holdtime": schema.Int64Attribute{ + "timers_hold_time2": schema.Int64Attribute{ MarkdownDescription: helpers.NewAttributeDescription("Hold time in seconds").AddIntegerRangeDescription(1, 255).String, Optional: true, Validators: []validator.Int64{ @@ -341,7 +341,7 @@ func (r *RouterHSRPInterfaceIPv4GroupV1Resource) Read(ctx context.Context, req r resp.State.RemoveResource(ctx) return } else { - resp.Diagnostics.AddError("Unable to apply gNMI Get operation", err.Error()) + resp.Diagnostics.AddError("Unable to apply Get operation", err.Error()) return } } @@ -352,7 +352,7 @@ func (r *RouterHSRPInterfaceIPv4GroupV1Resource) Read(ctx context.Context, req r } // After `terraform import` we switch to a full read. - respBody := getResp.Notification[0].Update[0].Val.GetJsonIetfVal() + respBody := getResp if imp { state.fromBody(ctx, respBody) } else { diff --git a/internal/provider/resource_iosxr_router_hsrp_interface_ipv4_group_v1_test.go b/internal/provider/resource_iosxr_router_hsrp_interface_ipv4_group_v1_test.go index 54a1d1e8..2c0fe848 100644 --- a/internal/provider/resource_iosxr_router_hsrp_interface_ipv4_group_v1_test.go +++ b/internal/provider/resource_iosxr_router_hsrp_interface_ipv4_group_v1_test.go @@ -39,14 +39,10 @@ func TestAccIosxrRouterHSRPInterfaceIPv4GroupV1(t *testing.T) { checks = append(checks, resource.TestCheckResourceAttr("iosxr_router_hsrp_interface_ipv4_group_v1.test", "address", "22.22.1.1")) checks = append(checks, resource.TestCheckResourceAttr("iosxr_router_hsrp_interface_ipv4_group_v1.test", "address_learn", "false")) checks = append(checks, resource.TestCheckResourceAttr("iosxr_router_hsrp_interface_ipv4_group_v1.test", "priority", "124")) - checks = append(checks, resource.TestCheckResourceAttr("iosxr_router_hsrp_interface_ipv4_group_v1.test", "mac_address", "00:01:00:02:00:02")) checks = append(checks, resource.TestCheckResourceAttr("iosxr_router_hsrp_interface_ipv4_group_v1.test", "name", "NAME11")) checks = append(checks, resource.TestCheckResourceAttr("iosxr_router_hsrp_interface_ipv4_group_v1.test", "preempt_delay", "3200")) - checks = append(checks, resource.TestCheckResourceAttr("iosxr_router_hsrp_interface_ipv4_group_v1.test", "timers_msec", "100")) - checks = append(checks, resource.TestCheckResourceAttr("iosxr_router_hsrp_interface_ipv4_group_v1.test", "timers_msec_holdtime", "300")) checks = append(checks, resource.TestCheckResourceAttr("iosxr_router_hsrp_interface_ipv4_group_v1.test", "bfd_fast_detect_peer_ipv4", "44.44.4.4")) - checks = append(checks, resource.TestCheckResourceAttr("iosxr_router_hsrp_interface_ipv4_group_v1.test", "bfd_fast_detect_peer_interface", "GigabitEthernet0/0/0/1")) - checks = append(checks, resource.TestCheckResourceAttr("iosxr_router_hsrp_interface_ipv4_group_v1.test", "secondary_ipv4_addresses.0.address", "2.2.2.2")) + checks = append(checks, resource.TestCheckResourceAttr("iosxr_router_hsrp_interface_ipv4_group_v1.test", "bfd_fast_detect_peer_interface", "GigabitEthernet0/0/0/7")) checks = append(checks, resource.TestCheckResourceAttr("iosxr_router_hsrp_interface_ipv4_group_v1.test", "track_interfaces.0.track_name", "GigabitEthernet0/0/0/1")) checks = append(checks, resource.TestCheckResourceAttr("iosxr_router_hsrp_interface_ipv4_group_v1.test", "track_interfaces.0.priority_decrement", "166")) checks = append(checks, resource.TestCheckResourceAttr("iosxr_router_hsrp_interface_ipv4_group_v1.test", "track_objects.0.object_name", "OBJECT1")) @@ -125,16 +121,10 @@ func testAccIosxrRouterHSRPInterfaceIPv4GroupV1Config_all() string { config += ` address = "22.22.1.1"` + "\n" config += ` address_learn = false` + "\n" config += ` priority = 124` + "\n" - config += ` mac_address = "00:01:00:02:00:02"` + "\n" config += ` name = "NAME11"` + "\n" config += ` preempt_delay = 3200` + "\n" - config += ` timers_msec = 100` + "\n" - config += ` timers_msec_holdtime = 300` + "\n" config += ` bfd_fast_detect_peer_ipv4 = "44.44.4.4"` + "\n" - config += ` bfd_fast_detect_peer_interface = "GigabitEthernet0/0/0/1"` + "\n" - config += ` secondary_ipv4_addresses = [{` + "\n" - config += ` address = "2.2.2.2"` + "\n" - config += ` }]` + "\n" + config += ` bfd_fast_detect_peer_interface = "GigabitEthernet0/0/0/7"` + "\n" config += ` track_interfaces = [{` + "\n" config += ` track_name = "GigabitEthernet0/0/0/1"` + "\n" config += ` priority_decrement = 166` + "\n" diff --git a/internal/provider/resource_iosxr_router_hsrp_interface_ipv4_group_v2.go b/internal/provider/resource_iosxr_router_hsrp_interface_ipv4_group_v2.go index e21526a5..6e1f085c 100644 --- a/internal/provider/resource_iosxr_router_hsrp_interface_ipv4_group_v2.go +++ b/internal/provider/resource_iosxr_router_hsrp_interface_ipv4_group_v2.go @@ -150,21 +150,21 @@ func (r *RouterHSRPInterfaceIPv4GroupV2Resource) Schema(ctx context.Context, req int64validator.Between(100, 3000), }, }, - "timers_msec_holdtime": schema.Int64Attribute{ + "timers_msec2": schema.Int64Attribute{ MarkdownDescription: helpers.NewAttributeDescription("Specify hold time in milliseconds").AddIntegerRangeDescription(100, 3000).String, Optional: true, Validators: []validator.Int64{ int64validator.Between(100, 3000), }, }, - "timers_seconds": schema.Int64Attribute{ + "timers_hold_time": schema.Int64Attribute{ MarkdownDescription: helpers.NewAttributeDescription("Hold time in seconds").AddIntegerRangeDescription(1, 255).String, Optional: true, Validators: []validator.Int64{ int64validator.Between(1, 255), }, }, - "timers_seconds_holdtime": schema.Int64Attribute{ + "timers_hold_time2": schema.Int64Attribute{ MarkdownDescription: helpers.NewAttributeDescription("Hold time in seconds").AddIntegerRangeDescription(1, 255).String, Optional: true, Validators: []validator.Int64{ @@ -341,7 +341,7 @@ func (r *RouterHSRPInterfaceIPv4GroupV2Resource) Read(ctx context.Context, req r resp.State.RemoveResource(ctx) return } else { - resp.Diagnostics.AddError("Unable to apply gNMI Get operation", err.Error()) + resp.Diagnostics.AddError("Unable to apply Get operation", err.Error()) return } } @@ -352,7 +352,7 @@ func (r *RouterHSRPInterfaceIPv4GroupV2Resource) Read(ctx context.Context, req r } // After `terraform import` we switch to a full read. - respBody := getResp.Notification[0].Update[0].Val.GetJsonIetfVal() + respBody := getResp if imp { state.fromBody(ctx, respBody) } else { diff --git a/internal/provider/resource_iosxr_router_hsrp_interface_ipv4_group_v2_test.go b/internal/provider/resource_iosxr_router_hsrp_interface_ipv4_group_v2_test.go index def10cc1..f3054336 100644 --- a/internal/provider/resource_iosxr_router_hsrp_interface_ipv4_group_v2_test.go +++ b/internal/provider/resource_iosxr_router_hsrp_interface_ipv4_group_v2_test.go @@ -39,14 +39,9 @@ func TestAccIosxrRouterHSRPInterfaceIPv4GroupV2(t *testing.T) { checks = append(checks, resource.TestCheckResourceAttr("iosxr_router_hsrp_interface_ipv4_group_v2.test", "address", "33.33.33.3")) checks = append(checks, resource.TestCheckResourceAttr("iosxr_router_hsrp_interface_ipv4_group_v2.test", "address_learn", "false")) checks = append(checks, resource.TestCheckResourceAttr("iosxr_router_hsrp_interface_ipv4_group_v2.test", "priority", "133")) - checks = append(checks, resource.TestCheckResourceAttr("iosxr_router_hsrp_interface_ipv4_group_v2.test", "mac_address", "00:01:00:02:00:02")) checks = append(checks, resource.TestCheckResourceAttr("iosxr_router_hsrp_interface_ipv4_group_v2.test", "name", "NAME22")) checks = append(checks, resource.TestCheckResourceAttr("iosxr_router_hsrp_interface_ipv4_group_v2.test", "preempt_delay", "3100")) - checks = append(checks, resource.TestCheckResourceAttr("iosxr_router_hsrp_interface_ipv4_group_v2.test", "timers_seconds", "10")) - checks = append(checks, resource.TestCheckResourceAttr("iosxr_router_hsrp_interface_ipv4_group_v2.test", "timers_seconds_holdtime", "30")) checks = append(checks, resource.TestCheckResourceAttr("iosxr_router_hsrp_interface_ipv4_group_v2.test", "bfd_fast_detect_peer_ipv4", "45.45.45.4")) - checks = append(checks, resource.TestCheckResourceAttr("iosxr_router_hsrp_interface_ipv4_group_v2.test", "bfd_fast_detect_peer_interface", "GigabitEthernet0/0/0/1")) - checks = append(checks, resource.TestCheckResourceAttr("iosxr_router_hsrp_interface_ipv4_group_v2.test", "secondary_ipv4_addresses.0.address", "10.10.1.2")) checks = append(checks, resource.TestCheckResourceAttr("iosxr_router_hsrp_interface_ipv4_group_v2.test", "track_interfaces.0.track_name", "GigabitEthernet0/0/0/7")) checks = append(checks, resource.TestCheckResourceAttr("iosxr_router_hsrp_interface_ipv4_group_v2.test", "track_interfaces.0.priority_decrement", "66")) checks = append(checks, resource.TestCheckResourceAttr("iosxr_router_hsrp_interface_ipv4_group_v2.test", "track_objects.0.object_name", "OBJECT2")) @@ -125,16 +120,9 @@ func testAccIosxrRouterHSRPInterfaceIPv4GroupV2Config_all() string { config += ` address = "33.33.33.3"` + "\n" config += ` address_learn = false` + "\n" config += ` priority = 133` + "\n" - config += ` mac_address = "00:01:00:02:00:02"` + "\n" config += ` name = "NAME22"` + "\n" config += ` preempt_delay = 3100` + "\n" - config += ` timers_seconds = 10` + "\n" - config += ` timers_seconds_holdtime = 30` + "\n" config += ` bfd_fast_detect_peer_ipv4 = "45.45.45.4"` + "\n" - config += ` bfd_fast_detect_peer_interface = "GigabitEthernet0/0/0/1"` + "\n" - config += ` secondary_ipv4_addresses = [{` + "\n" - config += ` address = "10.10.1.2"` + "\n" - config += ` }]` + "\n" config += ` track_interfaces = [{` + "\n" config += ` track_name = "GigabitEthernet0/0/0/7"` + "\n" config += ` priority_decrement = 66` + "\n" diff --git a/internal/provider/resource_iosxr_router_hsrp_interface_ipv6_group_v2.go b/internal/provider/resource_iosxr_router_hsrp_interface_ipv6_group_v2.go index e02c7b08..c3a59c94 100644 --- a/internal/provider/resource_iosxr_router_hsrp_interface_ipv6_group_v2.go +++ b/internal/provider/resource_iosxr_router_hsrp_interface_ipv6_group_v2.go @@ -117,14 +117,14 @@ func (r *RouterHSRPInterfaceIPv6GroupV2Resource) Schema(ctx context.Context, req stringvalidator.RegexMatches(regexp.MustCompile(`[0-9a-fA-F]{2}(:[0-9a-fA-F]{2}){5}`), ""), }, }, - "timers_seconds": schema.Int64Attribute{ + "timers_hold_time": schema.Int64Attribute{ MarkdownDescription: helpers.NewAttributeDescription("Hold time in seconds").AddIntegerRangeDescription(1, 255).String, Optional: true, Validators: []validator.Int64{ int64validator.Between(1, 255), }, }, - "timers_seconds_holdtime": schema.Int64Attribute{ + "timers_hold_time2": schema.Int64Attribute{ MarkdownDescription: helpers.NewAttributeDescription("Hold time in seconds").AddIntegerRangeDescription(1, 255).String, Optional: true, Validators: []validator.Int64{ @@ -138,7 +138,7 @@ func (r *RouterHSRPInterfaceIPv6GroupV2Resource) Schema(ctx context.Context, req int64validator.Between(100, 3000), }, }, - "timers_msec_holdtime": schema.Int64Attribute{ + "timers_msec2": schema.Int64Attribute{ MarkdownDescription: helpers.NewAttributeDescription("Specify hold time in milliseconds").AddIntegerRangeDescription(100, 3000).String, Optional: true, Validators: []validator.Int64{ @@ -348,7 +348,7 @@ func (r *RouterHSRPInterfaceIPv6GroupV2Resource) Read(ctx context.Context, req r resp.State.RemoveResource(ctx) return } else { - resp.Diagnostics.AddError("Unable to apply gNMI Get operation", err.Error()) + resp.Diagnostics.AddError("Unable to apply Get operation", err.Error()) return } } @@ -359,7 +359,7 @@ func (r *RouterHSRPInterfaceIPv6GroupV2Resource) Read(ctx context.Context, req r } // After `terraform import` we switch to a full read. - respBody := getResp.Notification[0].Update[0].Val.GetJsonIetfVal() + respBody := getResp if imp { state.fromBody(ctx, respBody) } else { diff --git a/internal/provider/resource_iosxr_router_hsrp_interface_ipv6_group_v2_test.go b/internal/provider/resource_iosxr_router_hsrp_interface_ipv6_group_v2_test.go index 4c75ba12..c1216512 100644 --- a/internal/provider/resource_iosxr_router_hsrp_interface_ipv6_group_v2_test.go +++ b/internal/provider/resource_iosxr_router_hsrp_interface_ipv6_group_v2_test.go @@ -39,7 +39,7 @@ func TestAccIosxrRouterHSRPInterfaceIPv6GroupV2(t *testing.T) { checks = append(checks, resource.TestCheckResourceAttr("iosxr_router_hsrp_interface_ipv6_group_v2.test", "name", "gp2")) checks = append(checks, resource.TestCheckResourceAttr("iosxr_router_hsrp_interface_ipv6_group_v2.test", "mac_address", "00:01:00:02:00:02")) checks = append(checks, resource.TestCheckResourceAttr("iosxr_router_hsrp_interface_ipv6_group_v2.test", "timers_msec", "100")) - checks = append(checks, resource.TestCheckResourceAttr("iosxr_router_hsrp_interface_ipv6_group_v2.test", "timers_msec_holdtime", "300")) + checks = append(checks, resource.TestCheckResourceAttr("iosxr_router_hsrp_interface_ipv6_group_v2.test", "timers_msec2", "300")) checks = append(checks, resource.TestCheckResourceAttr("iosxr_router_hsrp_interface_ipv6_group_v2.test", "preempt_delay", "256")) checks = append(checks, resource.TestCheckResourceAttr("iosxr_router_hsrp_interface_ipv6_group_v2.test", "priority", "244")) checks = append(checks, resource.TestCheckResourceAttr("iosxr_router_hsrp_interface_ipv6_group_v2.test", "bfd_fast_detect_peer_ipv6", "fe80::240:d0ff:fe48:4672")) @@ -125,7 +125,7 @@ func testAccIosxrRouterHSRPInterfaceIPv6GroupV2Config_all() string { config += ` name = "gp2"` + "\n" config += ` mac_address = "00:01:00:02:00:02"` + "\n" config += ` timers_msec = 100` + "\n" - config += ` timers_msec_holdtime = 300` + "\n" + config += ` timers_msec2 = 300` + "\n" config += ` preempt_delay = 256` + "\n" config += ` priority = 244` + "\n" config += ` bfd_fast_detect_peer_ipv6 = "fe80::240:d0ff:fe48:4672"` + "\n" diff --git a/internal/provider/resource_iosxr_router_isis.go b/internal/provider/resource_iosxr_router_isis.go index eff59a76..833ebe2a 100644 --- a/internal/provider/resource_iosxr_router_isis.go +++ b/internal/provider/resource_iosxr_router_isis.go @@ -313,10 +313,6 @@ func (r *RouterISISResource) Schema(ctx context.Context, req resource.SchemaRequ MarkdownDescription: helpers.NewAttributeDescription("Enable purge originator identification").String, Optional: true, }, - "distribute_link_state": schema.BoolAttribute{ - MarkdownDescription: helpers.NewAttributeDescription("Distribute the link-state database to external services").String, - Optional: true, - }, "distribute_link_state_instance_id": schema.Int64Attribute{ MarkdownDescription: helpers.NewAttributeDescription("Set distribution process instance identifier").AddIntegerRangeDescription(32, 4294967295).String, Optional: true, @@ -555,7 +551,7 @@ func (r *RouterISISResource) Read(ctx context.Context, req resource.ReadRequest, resp.State.RemoveResource(ctx) return } else { - resp.Diagnostics.AddError("Unable to apply gNMI Get operation", err.Error()) + resp.Diagnostics.AddError("Unable to apply Get operation", err.Error()) return } } @@ -566,7 +562,7 @@ func (r *RouterISISResource) Read(ctx context.Context, req resource.ReadRequest, } // After `terraform import` we switch to a full read. - respBody := getResp.Notification[0].Update[0].Val.GetJsonIetfVal() + respBody := getResp if imp { state.fromBody(ctx, respBody) } else { diff --git a/internal/provider/resource_iosxr_router_isis_address_family.go b/internal/provider/resource_iosxr_router_isis_address_family.go index 98b93c7a..f93c0088 100644 --- a/internal/provider/resource_iosxr_router_isis_address_family.go +++ b/internal/provider/resource_iosxr_router_isis_address_family.go @@ -955,7 +955,7 @@ func (r *RouterISISAddressFamilyResource) Read(ctx context.Context, req resource resp.State.RemoveResource(ctx) return } else { - resp.Diagnostics.AddError("Unable to apply gNMI Get operation", err.Error()) + resp.Diagnostics.AddError("Unable to apply Get operation", err.Error()) return } } @@ -966,7 +966,7 @@ func (r *RouterISISAddressFamilyResource) Read(ctx context.Context, req resource } // After `terraform import` we switch to a full read. - respBody := getResp.Notification[0].Update[0].Val.GetJsonIetfVal() + respBody := getResp if imp { state.fromBody(ctx, respBody) } else { diff --git a/internal/provider/resource_iosxr_router_isis_address_family_test.go b/internal/provider/resource_iosxr_router_isis_address_family_test.go index 5c3cdb1e..d8f0d18b 100644 --- a/internal/provider/resource_iosxr_router_isis_address_family_test.go +++ b/internal/provider/resource_iosxr_router_isis_address_family_test.go @@ -38,8 +38,6 @@ func TestAccIosxrRouterISISAddressFamily(t *testing.T) { checks = append(checks, resource.TestCheckResourceAttr("iosxr_router_isis_address_family.test", "af_name", "ipv4")) checks = append(checks, resource.TestCheckResourceAttr("iosxr_router_isis_address_family.test", "saf_name", "unicast")) checks = append(checks, resource.TestCheckResourceAttr("iosxr_router_isis_address_family.test", "metric_style_wide_transition", "true")) - checks = append(checks, resource.TestCheckResourceAttr("iosxr_router_isis_address_family.test", "metric_style_levels.0.level_number", "1")) - checks = append(checks, resource.TestCheckResourceAttr("iosxr_router_isis_address_family.test", "metric_style_levels.0.wide_transition", "true")) checks = append(checks, resource.TestCheckResourceAttr("iosxr_router_isis_address_family.test", "router_id_ip_address", "192.168.1.1")) checks = append(checks, resource.TestCheckResourceAttr("iosxr_router_isis_address_family.test", "default_information_originate", "true")) checks = append(checks, resource.TestCheckResourceAttr("iosxr_router_isis_address_family.test", "fast_reroute_delay_interval", "300")) @@ -57,11 +55,9 @@ func TestAccIosxrRouterISISAddressFamily(t *testing.T) { checks = append(checks, resource.TestCheckResourceAttr("iosxr_router_isis_address_family.test", "fast_reroute_per_prefix_tiebreaker_node_protecting_index", "40")) checks = append(checks, resource.TestCheckResourceAttr("iosxr_router_isis_address_family.test", "fast_reroute_per_prefix_tiebreaker_primary_path_index", "50")) checks = append(checks, resource.TestCheckResourceAttr("iosxr_router_isis_address_family.test", "fast_reroute_per_prefix_tiebreaker_srlg_disjoint_index", "70")) - checks = append(checks, resource.TestCheckResourceAttr("iosxr_router_isis_address_family.test", "fast_reroute_per_link_priority_limit", "critical")) checks = append(checks, resource.TestCheckResourceAttr("iosxr_router_isis_address_family.test", "fast_reroute_per_link_priority_limit_levels.0.level_number", "1")) checks = append(checks, resource.TestCheckResourceAttr("iosxr_router_isis_address_family.test", "fast_reroute_per_link_priority_limit_levels.0.priority_limit", "critical")) checks = append(checks, resource.TestCheckResourceAttr("iosxr_router_isis_address_family.test", "fast_reroute_per_link_use_candidate_only", "true")) - checks = append(checks, resource.TestCheckResourceAttr("iosxr_router_isis_address_family.test", "microloop_avoidance", "true")) checks = append(checks, resource.TestCheckResourceAttr("iosxr_router_isis_address_family.test", "microloop_avoidance_protected", "true")) checks = append(checks, resource.TestCheckResourceAttr("iosxr_router_isis_address_family.test", "microloop_avoidance_rib_update_delay", "5000")) checks = append(checks, resource.TestCheckResourceAttr("iosxr_router_isis_address_family.test", "advertise_passive_only", "true")) @@ -178,10 +174,6 @@ func testAccIosxrRouterISISAddressFamilyConfig_all() string { config += ` af_name = "ipv4"` + "\n" config += ` saf_name = "unicast"` + "\n" config += ` metric_style_wide_transition = true` + "\n" - config += ` metric_style_levels = [{` + "\n" - config += ` level_number = 1` + "\n" - config += ` wide_transition = true` + "\n" - config += ` }]` + "\n" config += ` router_id_ip_address = "192.168.1.1"` + "\n" config += ` default_information_originate = true` + "\n" config += ` fast_reroute_delay_interval = 300` + "\n" @@ -205,13 +197,11 @@ func testAccIosxrRouterISISAddressFamilyConfig_all() string { config += ` fast_reroute_per_prefix_tiebreaker_node_protecting_index = 40` + "\n" config += ` fast_reroute_per_prefix_tiebreaker_primary_path_index = 50` + "\n" config += ` fast_reroute_per_prefix_tiebreaker_srlg_disjoint_index = 70` + "\n" - config += ` fast_reroute_per_link_priority_limit = "critical"` + "\n" config += ` fast_reroute_per_link_priority_limit_levels = [{` + "\n" config += ` level_number = 1` + "\n" config += ` priority_limit = "critical"` + "\n" config += ` }]` + "\n" config += ` fast_reroute_per_link_use_candidate_only = true` + "\n" - config += ` microloop_avoidance = true` + "\n" config += ` microloop_avoidance_protected = true` + "\n" config += ` microloop_avoidance_rib_update_delay = 5000` + "\n" config += ` advertise_passive_only = true` + "\n" diff --git a/internal/provider/resource_iosxr_router_isis_interface.go b/internal/provider/resource_iosxr_router_isis_interface.go index 0c2e06b2..43d71fdc 100644 --- a/internal/provider/resource_iosxr_router_isis_interface.go +++ b/internal/provider/resource_iosxr_router_isis_interface.go @@ -228,7 +228,7 @@ func (r *RouterISISInterfaceResource) Schema(ctx context.Context, req resource.S MarkdownDescription: helpers.NewAttributeDescription("Do not require authentication of incoming IIHs").String, Optional: true, }, - "hello_password_keychain_name": schema.StringAttribute{ + "hello_password_keychain": schema.StringAttribute{ MarkdownDescription: helpers.NewAttributeDescription("Specifies a Key Chain name will follow").String, Optional: true, Validators: []validator.String{ @@ -251,36 +251,36 @@ func (r *RouterISISInterfaceResource) Schema(ctx context.Context, req resource.S int64validator.Between(1, 2), }, }, - "hello_password_text_encrypted": schema.StringAttribute{ + "text_encrypted": schema.StringAttribute{ MarkdownDescription: helpers.NewAttributeDescription("Specifies a password will follow").String, Optional: true, Validators: []validator.String{ stringvalidator.RegexMatches(regexp.MustCompile(`(!.+)|([^!].+)`), ""), }, }, - "hello_password_text_send_only": schema.BoolAttribute{ + "text_send_only": schema.BoolAttribute{ MarkdownDescription: helpers.NewAttributeDescription("Do not require authentication of incoming IIHs").String, Optional: true, }, - "hello_password_hmac_md5_encrypted": schema.StringAttribute{ + "hmac_md5_encrypted": schema.StringAttribute{ MarkdownDescription: helpers.NewAttributeDescription("Specifies a password will follow").String, Optional: true, Validators: []validator.String{ stringvalidator.RegexMatches(regexp.MustCompile(`(!.+)|([^!].+)`), ""), }, }, - "hello_password_hmac_md5_send_only": schema.BoolAttribute{ + "hmac_md5_send_only": schema.BoolAttribute{ MarkdownDescription: helpers.NewAttributeDescription("Do not require authentication of incoming IIHs").String, Optional: true, }, - "hello_keychain_name": schema.StringAttribute{ + "keychain_name": schema.StringAttribute{ MarkdownDescription: helpers.NewAttributeDescription("Specifies a Key Chain name will follow").String, Optional: true, Validators: []validator.String{ stringvalidator.LengthBetween(1, 1024), }, }, - "hello_keychain_send_only": schema.BoolAttribute{ + "keychain_send_only": schema.BoolAttribute{ MarkdownDescription: helpers.NewAttributeDescription("Do not require authentication of incoming IIHs").String, Optional: true, }, @@ -403,7 +403,7 @@ func (r *RouterISISInterfaceResource) Read(ctx context.Context, req resource.Rea resp.State.RemoveResource(ctx) return } else { - resp.Diagnostics.AddError("Unable to apply gNMI Get operation", err.Error()) + resp.Diagnostics.AddError("Unable to apply Get operation", err.Error()) return } } @@ -414,7 +414,7 @@ func (r *RouterISISInterfaceResource) Read(ctx context.Context, req resource.Rea } // After `terraform import` we switch to a full read. - respBody := getResp.Notification[0].Update[0].Val.GetJsonIetfVal() + respBody := getResp if imp { state.fromBody(ctx, respBody) } else { diff --git a/internal/provider/resource_iosxr_router_isis_interface_address_family.go b/internal/provider/resource_iosxr_router_isis_interface_address_family.go index 428b029a..caaf3315 100644 --- a/internal/provider/resource_iosxr_router_isis_interface_address_family.go +++ b/internal/provider/resource_iosxr_router_isis_interface_address_family.go @@ -357,7 +357,7 @@ func (r *RouterISISInterfaceAddressFamilyResource) Read(ctx context.Context, req resp.State.RemoveResource(ctx) return } else { - resp.Diagnostics.AddError("Unable to apply gNMI Get operation", err.Error()) + resp.Diagnostics.AddError("Unable to apply Get operation", err.Error()) return } } @@ -368,7 +368,7 @@ func (r *RouterISISInterfaceAddressFamilyResource) Read(ctx context.Context, req } // After `terraform import` we switch to a full read. - respBody := getResp.Notification[0].Update[0].Val.GetJsonIetfVal() + respBody := getResp if imp { state.fromBody(ctx, respBody) } else { diff --git a/internal/provider/resource_iosxr_router_isis_interface_address_family_test.go b/internal/provider/resource_iosxr_router_isis_interface_address_family_test.go index 65eb8b82..891e13de 100644 --- a/internal/provider/resource_iosxr_router_isis_interface_address_family_test.go +++ b/internal/provider/resource_iosxr_router_isis_interface_address_family_test.go @@ -116,7 +116,6 @@ resource "iosxr_gnmi" "PreReq3" { attributes = { "interface-name" = "GigabitEthernet0/0/0/1" } - depends_on = [iosxr_gnmi.PreReq2, ] } ` diff --git a/internal/provider/resource_iosxr_router_isis_test.go b/internal/provider/resource_iosxr_router_isis_test.go index 52ab55c3..e7ed9700 100644 --- a/internal/provider/resource_iosxr_router_isis_test.go +++ b/internal/provider/resource_iosxr_router_isis_test.go @@ -46,7 +46,6 @@ func TestAccIosxrRouterISIS(t *testing.T) { checks = append(checks, resource.TestCheckResourceAttr("iosxr_router_isis.test", "set_overload_bit_levels.0.advertise_external", "true")) checks = append(checks, resource.TestCheckResourceAttr("iosxr_router_isis.test", "set_overload_bit_levels.0.advertise_interlevel", "true")) checks = append(checks, resource.TestCheckResourceAttr("iosxr_router_isis.test", "nsr", "true")) - checks = append(checks, resource.TestCheckResourceAttr("iosxr_router_isis.test", "nsf_ietf", "true")) checks = append(checks, resource.TestCheckResourceAttr("iosxr_router_isis.test", "nsf_lifetime", "10")) checks = append(checks, resource.TestCheckResourceAttr("iosxr_router_isis.test", "nsf_interface_timer", "5")) checks = append(checks, resource.TestCheckResourceAttr("iosxr_router_isis.test", "nsf_interface_expires", "2")) @@ -56,14 +55,8 @@ func TestAccIosxrRouterISIS(t *testing.T) { checks = append(checks, resource.TestCheckResourceAttr("iosxr_router_isis.test", "lsp_gen_interval_secondary_wait", "200")) checks = append(checks, resource.TestCheckResourceAttr("iosxr_router_isis.test", "lsp_refresh_interval", "65000")) checks = append(checks, resource.TestCheckResourceAttr("iosxr_router_isis.test", "max_lsp_lifetime", "65535")) - checks = append(checks, resource.TestCheckResourceAttr("iosxr_router_isis.test", "lsp_password_hmac_md5_encrypted", "060506324F41584B564B0F49584B")) - checks = append(checks, resource.TestCheckResourceAttr("iosxr_router_isis.test", "lsp_password_hmac_md5_send_only", "true")) - checks = append(checks, resource.TestCheckResourceAttr("iosxr_router_isis.test", "lsp_password_hmac_md5_snp_send_only", "true")) - checks = append(checks, resource.TestCheckResourceAttr("iosxr_router_isis.test", "lsp_password_hmac_md5_enable_poi", "true")) - checks = append(checks, resource.TestCheckResourceAttr("iosxr_router_isis.test", "distribute_link_state", "true")) + checks = append(checks, resource.TestCheckResourceAttr("iosxr_router_isis.test", "lsp_password_text_encrypted", "060506324F41584B564B0F49584B")) checks = append(checks, resource.TestCheckResourceAttr("iosxr_router_isis.test", "distribute_link_state_instance_id", "32")) - checks = append(checks, resource.TestCheckResourceAttr("iosxr_router_isis.test", "distribute_link_state_throttle", "1")) - checks = append(checks, resource.TestCheckResourceAttr("iosxr_router_isis.test", "distribute_link_state_level", "2")) checks = append(checks, resource.TestCheckResourceAttr("iosxr_router_isis.test", "affinity_maps.0.name", "22")) checks = append(checks, resource.TestCheckResourceAttr("iosxr_router_isis.test", "affinity_maps.0.bit_position", "4")) checks = append(checks, resource.TestCheckResourceAttr("iosxr_router_isis.test", "flex_algos.0.number", "128")) @@ -147,7 +140,6 @@ func testAccIosxrRouterISISConfig_all() string { config += ` advertise_interlevel = true` + "\n" config += ` }]` + "\n" config += ` nsr = true` + "\n" - config += ` nsf_ietf = true` + "\n" config += ` nsf_lifetime = 10` + "\n" config += ` nsf_interface_timer = 5` + "\n" config += ` nsf_interface_expires = 2` + "\n" @@ -157,14 +149,8 @@ func testAccIosxrRouterISISConfig_all() string { config += ` lsp_gen_interval_secondary_wait = 200` + "\n" config += ` lsp_refresh_interval = 65000` + "\n" config += ` max_lsp_lifetime = 65535` + "\n" - config += ` lsp_password_hmac_md5_encrypted = "060506324F41584B564B0F49584B"` + "\n" - config += ` lsp_password_hmac_md5_send_only = true` + "\n" - config += ` lsp_password_hmac_md5_snp_send_only = true` + "\n" - config += ` lsp_password_hmac_md5_enable_poi = true` + "\n" - config += ` distribute_link_state = true` + "\n" + config += ` lsp_password_text_encrypted = "060506324F41584B564B0F49584B"` + "\n" config += ` distribute_link_state_instance_id = 32` + "\n" - config += ` distribute_link_state_throttle = 1` + "\n" - config += ` distribute_link_state_level = 2` + "\n" config += ` affinity_maps = [{` + "\n" config += ` name = "22"` + "\n" config += ` bit_position = 4` + "\n" diff --git a/internal/provider/resource_iosxr_router_ospf.go b/internal/provider/resource_iosxr_router_ospf.go index 3e9274d6..0f544ae3 100644 --- a/internal/provider/resource_iosxr_router_ospf.go +++ b/internal/provider/resource_iosxr_router_ospf.go @@ -442,7 +442,7 @@ func (r *RouterOSPFResource) Read(ctx context.Context, req resource.ReadRequest, resp.State.RemoveResource(ctx) return } else { - resp.Diagnostics.AddError("Unable to apply gNMI Get operation", err.Error()) + resp.Diagnostics.AddError("Unable to apply Get operation", err.Error()) return } } @@ -453,7 +453,7 @@ func (r *RouterOSPFResource) Read(ctx context.Context, req resource.ReadRequest, } // After `terraform import` we switch to a full read. - respBody := getResp.Notification[0].Update[0].Val.GetJsonIetfVal() + respBody := getResp if imp { state.fromBody(ctx, respBody) } else { diff --git a/internal/provider/resource_iosxr_router_ospf_area_interface.go b/internal/provider/resource_iosxr_router_ospf_area_interface.go index c889f2d2..992a269e 100644 --- a/internal/provider/resource_iosxr_router_ospf_area_interface.go +++ b/internal/provider/resource_iosxr_router_ospf_area_interface.go @@ -310,7 +310,7 @@ func (r *RouterOSPFAreaInterfaceResource) Read(ctx context.Context, req resource resp.State.RemoveResource(ctx) return } else { - resp.Diagnostics.AddError("Unable to apply gNMI Get operation", err.Error()) + resp.Diagnostics.AddError("Unable to apply Get operation", err.Error()) return } } @@ -321,7 +321,7 @@ func (r *RouterOSPFAreaInterfaceResource) Read(ctx context.Context, req resource } // After `terraform import` we switch to a full read. - respBody := getResp.Notification[0].Update[0].Val.GetJsonIetfVal() + respBody := getResp if imp { state.fromBody(ctx, respBody) } else { diff --git a/internal/provider/resource_iosxr_router_ospf_vrf.go b/internal/provider/resource_iosxr_router_ospf_vrf.go index 1a808734..8abc4788 100644 --- a/internal/provider/resource_iosxr_router_ospf_vrf.go +++ b/internal/provider/resource_iosxr_router_ospf_vrf.go @@ -445,7 +445,7 @@ func (r *RouterOSPFVRFResource) Read(ctx context.Context, req resource.ReadReque resp.State.RemoveResource(ctx) return } else { - resp.Diagnostics.AddError("Unable to apply gNMI Get operation", err.Error()) + resp.Diagnostics.AddError("Unable to apply Get operation", err.Error()) return } } @@ -456,7 +456,7 @@ func (r *RouterOSPFVRFResource) Read(ctx context.Context, req resource.ReadReque } // After `terraform import` we switch to a full read. - respBody := getResp.Notification[0].Update[0].Val.GetJsonIetfVal() + respBody := getResp if imp { state.fromBody(ctx, respBody) } else { diff --git a/internal/provider/resource_iosxr_router_ospf_vrf_area_interface.go b/internal/provider/resource_iosxr_router_ospf_vrf_area_interface.go index 3c4856d3..8e1e1c8b 100644 --- a/internal/provider/resource_iosxr_router_ospf_vrf_area_interface.go +++ b/internal/provider/resource_iosxr_router_ospf_vrf_area_interface.go @@ -251,7 +251,7 @@ func (r *RouterOSPFVRFAreaInterfaceResource) Read(ctx context.Context, req resou resp.State.RemoveResource(ctx) return } else { - resp.Diagnostics.AddError("Unable to apply gNMI Get operation", err.Error()) + resp.Diagnostics.AddError("Unable to apply Get operation", err.Error()) return } } @@ -262,7 +262,7 @@ func (r *RouterOSPFVRFAreaInterfaceResource) Read(ctx context.Context, req resou } // After `terraform import` we switch to a full read. - respBody := getResp.Notification[0].Update[0].Val.GetJsonIetfVal() + respBody := getResp if imp { state.fromBody(ctx, respBody) } else { diff --git a/internal/provider/resource_iosxr_router_static_ipv4_multicast.go b/internal/provider/resource_iosxr_router_static_ipv4_multicast.go index 6c483c8d..18fe4d03 100644 --- a/internal/provider/resource_iosxr_router_static_ipv4_multicast.go +++ b/internal/provider/resource_iosxr_router_static_ipv4_multicast.go @@ -561,7 +561,7 @@ func (r *RouterStaticIPv4MulticastResource) Read(ctx context.Context, req resour resp.State.RemoveResource(ctx) return } else { - resp.Diagnostics.AddError("Unable to apply gNMI Get operation", err.Error()) + resp.Diagnostics.AddError("Unable to apply Get operation", err.Error()) return } } @@ -572,7 +572,7 @@ func (r *RouterStaticIPv4MulticastResource) Read(ctx context.Context, req resour } // After `terraform import` we switch to a full read. - respBody := getResp.Notification[0].Update[0].Val.GetJsonIetfVal() + respBody := getResp if imp { state.fromBody(ctx, respBody) } else { diff --git a/internal/provider/resource_iosxr_router_static_ipv4_unicast.go b/internal/provider/resource_iosxr_router_static_ipv4_unicast.go index ca6c97e0..20ea2b9a 100644 --- a/internal/provider/resource_iosxr_router_static_ipv4_unicast.go +++ b/internal/provider/resource_iosxr_router_static_ipv4_unicast.go @@ -178,20 +178,6 @@ func (r *RouterStaticIPv4UnicastResource) Schema(ctx context.Context, req resour stringvalidator.RegexMatches(regexp.MustCompile(`[0-9\.]*`), ""), }, }, - "bfd_fast_detect_minimum_interval": schema.Int64Attribute{ - MarkdownDescription: helpers.NewAttributeDescription("Hello interval").AddIntegerRangeDescription(3, 30000).String, - Optional: true, - Validators: []validator.Int64{ - int64validator.Between(3, 30000), - }, - }, - "bfd_fast_detect_multiplier": schema.Int64Attribute{ - MarkdownDescription: helpers.NewAttributeDescription("Detect multiplier").AddIntegerRangeDescription(1, 10).String, - Optional: true, - Validators: []validator.Int64{ - int64validator.Between(1, 10), - }, - }, "description": schema.StringAttribute{ MarkdownDescription: helpers.NewAttributeDescription("description of the static route").String, Optional: true, @@ -248,20 +234,6 @@ func (r *RouterStaticIPv4UnicastResource) Schema(ctx context.Context, req resour stringvalidator.RegexMatches(regexp.MustCompile(`[0-9\.]*`), ""), }, }, - "bfd_fast_detect_minimum_interval": schema.Int64Attribute{ - MarkdownDescription: helpers.NewAttributeDescription("Hello interval").AddIntegerRangeDescription(3, 30000).String, - Optional: true, - Validators: []validator.Int64{ - int64validator.Between(3, 30000), - }, - }, - "bfd_fast_detect_multiplier": schema.Int64Attribute{ - MarkdownDescription: helpers.NewAttributeDescription("Detect multiplier").AddIntegerRangeDescription(1, 10).String, - Optional: true, - Validators: []validator.Int64{ - int64validator.Between(1, 10), - }, - }, "description": schema.StringAttribute{ MarkdownDescription: helpers.NewAttributeDescription("description of the static route").String, Optional: true, @@ -393,20 +365,6 @@ func (r *RouterStaticIPv4UnicastResource) Schema(ctx context.Context, req resour stringvalidator.RegexMatches(regexp.MustCompile(`[0-9\.]*`), ""), }, }, - "bfd_fast_detect_minimum_interval": schema.Int64Attribute{ - MarkdownDescription: helpers.NewAttributeDescription("Hello interval").AddIntegerRangeDescription(3, 30000).String, - Optional: true, - Validators: []validator.Int64{ - int64validator.Between(3, 30000), - }, - }, - "bfd_fast_detect_multiplier": schema.Int64Attribute{ - MarkdownDescription: helpers.NewAttributeDescription("Detect multiplier").AddIntegerRangeDescription(1, 10).String, - Optional: true, - Validators: []validator.Int64{ - int64validator.Between(1, 10), - }, - }, "description": schema.StringAttribute{ MarkdownDescription: helpers.NewAttributeDescription("description of the static route").String, Optional: true, @@ -463,20 +421,6 @@ func (r *RouterStaticIPv4UnicastResource) Schema(ctx context.Context, req resour stringvalidator.RegexMatches(regexp.MustCompile(`[0-9\.]*`), ""), }, }, - "bfd_fast_detect_minimum_interval": schema.Int64Attribute{ - MarkdownDescription: helpers.NewAttributeDescription("Hello interval").AddIntegerRangeDescription(3, 30000).String, - Optional: true, - Validators: []validator.Int64{ - int64validator.Between(3, 30000), - }, - }, - "bfd_fast_detect_multiplier": schema.Int64Attribute{ - MarkdownDescription: helpers.NewAttributeDescription("Detect multiplier").AddIntegerRangeDescription(1, 10).String, - Optional: true, - Validators: []validator.Int64{ - int64validator.Between(1, 10), - }, - }, "description": schema.StringAttribute{ MarkdownDescription: helpers.NewAttributeDescription("description of the static route").String, Optional: true, @@ -617,7 +561,7 @@ func (r *RouterStaticIPv4UnicastResource) Read(ctx context.Context, req resource resp.State.RemoveResource(ctx) return } else { - resp.Diagnostics.AddError("Unable to apply gNMI Get operation", err.Error()) + resp.Diagnostics.AddError("Unable to apply Get operation", err.Error()) return } } @@ -628,7 +572,7 @@ func (r *RouterStaticIPv4UnicastResource) Read(ctx context.Context, req resource } // After `terraform import` we switch to a full read. - respBody := getResp.Notification[0].Update[0].Val.GetJsonIetfVal() + respBody := getResp if imp { state.fromBody(ctx, respBody) } else { diff --git a/internal/provider/resource_iosxr_router_static_ipv6_multicast.go b/internal/provider/resource_iosxr_router_static_ipv6_multicast.go index e58fd9b5..aa98a99a 100644 --- a/internal/provider/resource_iosxr_router_static_ipv6_multicast.go +++ b/internal/provider/resource_iosxr_router_static_ipv6_multicast.go @@ -566,7 +566,7 @@ func (r *RouterStaticIPv6MulticastResource) Read(ctx context.Context, req resour resp.State.RemoveResource(ctx) return } else { - resp.Diagnostics.AddError("Unable to apply gNMI Get operation", err.Error()) + resp.Diagnostics.AddError("Unable to apply Get operation", err.Error()) return } } @@ -577,7 +577,7 @@ func (r *RouterStaticIPv6MulticastResource) Read(ctx context.Context, req resour } // After `terraform import` we switch to a full read. - respBody := getResp.Notification[0].Update[0].Val.GetJsonIetfVal() + respBody := getResp if imp { state.fromBody(ctx, respBody) } else { diff --git a/internal/provider/resource_iosxr_router_static_ipv6_unicast.go b/internal/provider/resource_iosxr_router_static_ipv6_unicast.go index c19a8b12..4efe7f24 100644 --- a/internal/provider/resource_iosxr_router_static_ipv6_unicast.go +++ b/internal/provider/resource_iosxr_router_static_ipv6_unicast.go @@ -566,7 +566,7 @@ func (r *RouterStaticIPv6UnicastResource) Read(ctx context.Context, req resource resp.State.RemoveResource(ctx) return } else { - resp.Diagnostics.AddError("Unable to apply gNMI Get operation", err.Error()) + resp.Diagnostics.AddError("Unable to apply Get operation", err.Error()) return } } @@ -577,7 +577,7 @@ func (r *RouterStaticIPv6UnicastResource) Read(ctx context.Context, req resource } // After `terraform import` we switch to a full read. - respBody := getResp.Notification[0].Update[0].Val.GetJsonIetfVal() + respBody := getResp if imp { state.fromBody(ctx, respBody) } else { diff --git a/internal/provider/resource_iosxr_router_static_vrf_ipv4_multicast.go b/internal/provider/resource_iosxr_router_static_vrf_ipv4_multicast.go index e8b67f35..de83ce07 100644 --- a/internal/provider/resource_iosxr_router_static_vrf_ipv4_multicast.go +++ b/internal/provider/resource_iosxr_router_static_vrf_ipv4_multicast.go @@ -189,20 +189,6 @@ func (r *RouterStaticVRFIPv4MulticastResource) Schema(ctx context.Context, req r stringvalidator.RegexMatches(regexp.MustCompile(`[0-9\.]*`), ""), }, }, - "bfd_fast_detect_minimum_interval": schema.Int64Attribute{ - MarkdownDescription: helpers.NewAttributeDescription("Hello interval").AddIntegerRangeDescription(3, 30000).String, - Optional: true, - Validators: []validator.Int64{ - int64validator.Between(3, 30000), - }, - }, - "bfd_fast_detect_multiplier": schema.Int64Attribute{ - MarkdownDescription: helpers.NewAttributeDescription("Detect multiplier").AddIntegerRangeDescription(1, 10).String, - Optional: true, - Validators: []validator.Int64{ - int64validator.Between(1, 10), - }, - }, "description": schema.StringAttribute{ MarkdownDescription: helpers.NewAttributeDescription("description of the static route").String, Optional: true, @@ -243,6 +229,20 @@ func (r *RouterStaticVRFIPv4MulticastResource) Schema(ctx context.Context, req r int64validator.Between(1, 16777214), }, }, + "bfd_fast_detect_minimum_interval": schema.Int64Attribute{ + MarkdownDescription: helpers.NewAttributeDescription("Hello interval").AddIntegerRangeDescription(3, 30000).String, + Optional: true, + Validators: []validator.Int64{ + int64validator.Between(3, 30000), + }, + }, + "bfd_fast_detect_multiplier": schema.Int64Attribute{ + MarkdownDescription: helpers.NewAttributeDescription("Detect multiplier").AddIntegerRangeDescription(1, 10).String, + Optional: true, + Validators: []validator.Int64{ + int64validator.Between(1, 10), + }, + }, }, }, }, @@ -259,20 +259,6 @@ func (r *RouterStaticVRFIPv4MulticastResource) Schema(ctx context.Context, req r stringvalidator.RegexMatches(regexp.MustCompile(`[0-9\.]*`), ""), }, }, - "bfd_fast_detect_minimum_interval": schema.Int64Attribute{ - MarkdownDescription: helpers.NewAttributeDescription("Hello interval").AddIntegerRangeDescription(3, 30000).String, - Optional: true, - Validators: []validator.Int64{ - int64validator.Between(3, 30000), - }, - }, - "bfd_fast_detect_multiplier": schema.Int64Attribute{ - MarkdownDescription: helpers.NewAttributeDescription("Detect multiplier").AddIntegerRangeDescription(1, 10).String, - Optional: true, - Validators: []validator.Int64{ - int64validator.Between(1, 10), - }, - }, "description": schema.StringAttribute{ MarkdownDescription: helpers.NewAttributeDescription("description of the static route").String, Optional: true, @@ -404,20 +390,6 @@ func (r *RouterStaticVRFIPv4MulticastResource) Schema(ctx context.Context, req r stringvalidator.RegexMatches(regexp.MustCompile(`[0-9\.]*`), ""), }, }, - "bfd_fast_detect_minimum_interval": schema.Int64Attribute{ - MarkdownDescription: helpers.NewAttributeDescription("Hello interval").AddIntegerRangeDescription(3, 30000).String, - Optional: true, - Validators: []validator.Int64{ - int64validator.Between(3, 30000), - }, - }, - "bfd_fast_detect_multiplier": schema.Int64Attribute{ - MarkdownDescription: helpers.NewAttributeDescription("Detect multiplier").AddIntegerRangeDescription(1, 10).String, - Optional: true, - Validators: []validator.Int64{ - int64validator.Between(1, 10), - }, - }, "description": schema.StringAttribute{ MarkdownDescription: helpers.NewAttributeDescription("description of the static route").String, Optional: true, @@ -474,20 +446,6 @@ func (r *RouterStaticVRFIPv4MulticastResource) Schema(ctx context.Context, req r stringvalidator.RegexMatches(regexp.MustCompile(`[0-9\.]*`), ""), }, }, - "bfd_fast_detect_minimum_interval": schema.Int64Attribute{ - MarkdownDescription: helpers.NewAttributeDescription("Hello interval").AddIntegerRangeDescription(3, 30000).String, - Optional: true, - Validators: []validator.Int64{ - int64validator.Between(3, 30000), - }, - }, - "bfd_fast_detect_multiplier": schema.Int64Attribute{ - MarkdownDescription: helpers.NewAttributeDescription("Detect multiplier").AddIntegerRangeDescription(1, 10).String, - Optional: true, - Validators: []validator.Int64{ - int64validator.Between(1, 10), - }, - }, "description": schema.StringAttribute{ MarkdownDescription: helpers.NewAttributeDescription("description of the static route").String, Optional: true, @@ -628,7 +586,7 @@ func (r *RouterStaticVRFIPv4MulticastResource) Read(ctx context.Context, req res resp.State.RemoveResource(ctx) return } else { - resp.Diagnostics.AddError("Unable to apply gNMI Get operation", err.Error()) + resp.Diagnostics.AddError("Unable to apply Get operation", err.Error()) return } } @@ -639,7 +597,7 @@ func (r *RouterStaticVRFIPv4MulticastResource) Read(ctx context.Context, req res } // After `terraform import` we switch to a full read. - respBody := getResp.Notification[0].Update[0].Val.GetJsonIetfVal() + respBody := getResp if imp { state.fromBody(ctx, respBody) } else { diff --git a/internal/provider/resource_iosxr_router_static_vrf_ipv4_unicast.go b/internal/provider/resource_iosxr_router_static_vrf_ipv4_unicast.go index 813f277e..ce31bfc0 100644 --- a/internal/provider/resource_iosxr_router_static_vrf_ipv4_unicast.go +++ b/internal/provider/resource_iosxr_router_static_vrf_ipv4_unicast.go @@ -189,20 +189,6 @@ func (r *RouterStaticVRFIPv4UnicastResource) Schema(ctx context.Context, req res stringvalidator.RegexMatches(regexp.MustCompile(`[0-9\.]*`), ""), }, }, - "bfd_fast_detect_minimum_interval": schema.Int64Attribute{ - MarkdownDescription: helpers.NewAttributeDescription("Hello interval").AddIntegerRangeDescription(3, 30000).String, - Optional: true, - Validators: []validator.Int64{ - int64validator.Between(3, 30000), - }, - }, - "bfd_fast_detect_multiplier": schema.Int64Attribute{ - MarkdownDescription: helpers.NewAttributeDescription("Detect multiplier").AddIntegerRangeDescription(1, 10).String, - Optional: true, - Validators: []validator.Int64{ - int64validator.Between(1, 10), - }, - }, "description": schema.StringAttribute{ MarkdownDescription: helpers.NewAttributeDescription("description of the static route").String, Optional: true, @@ -243,6 +229,20 @@ func (r *RouterStaticVRFIPv4UnicastResource) Schema(ctx context.Context, req res int64validator.Between(1, 16777214), }, }, + "bfd_fast_detect_minimum_interval": schema.Int64Attribute{ + MarkdownDescription: helpers.NewAttributeDescription("Hello interval").AddIntegerRangeDescription(3, 30000).String, + Optional: true, + Validators: []validator.Int64{ + int64validator.Between(3, 30000), + }, + }, + "bfd_fast_detect_multiplier": schema.Int64Attribute{ + MarkdownDescription: helpers.NewAttributeDescription("Detect multiplier").AddIntegerRangeDescription(1, 10).String, + Optional: true, + Validators: []validator.Int64{ + int64validator.Between(1, 10), + }, + }, }, }, }, @@ -259,20 +259,6 @@ func (r *RouterStaticVRFIPv4UnicastResource) Schema(ctx context.Context, req res stringvalidator.RegexMatches(regexp.MustCompile(`[0-9\.]*`), ""), }, }, - "bfd_fast_detect_minimum_interval": schema.Int64Attribute{ - MarkdownDescription: helpers.NewAttributeDescription("Hello interval").AddIntegerRangeDescription(3, 30000).String, - Optional: true, - Validators: []validator.Int64{ - int64validator.Between(3, 30000), - }, - }, - "bfd_fast_detect_multiplier": schema.Int64Attribute{ - MarkdownDescription: helpers.NewAttributeDescription("Detect multiplier").AddIntegerRangeDescription(1, 10).String, - Optional: true, - Validators: []validator.Int64{ - int64validator.Between(1, 10), - }, - }, "description": schema.StringAttribute{ MarkdownDescription: helpers.NewAttributeDescription("description of the static route").String, Optional: true, @@ -404,20 +390,6 @@ func (r *RouterStaticVRFIPv4UnicastResource) Schema(ctx context.Context, req res stringvalidator.RegexMatches(regexp.MustCompile(`[0-9\.]*`), ""), }, }, - "bfd_fast_detect_minimum_interval": schema.Int64Attribute{ - MarkdownDescription: helpers.NewAttributeDescription("Hello interval").AddIntegerRangeDescription(3, 30000).String, - Optional: true, - Validators: []validator.Int64{ - int64validator.Between(3, 30000), - }, - }, - "bfd_fast_detect_multiplier": schema.Int64Attribute{ - MarkdownDescription: helpers.NewAttributeDescription("Detect multiplier").AddIntegerRangeDescription(1, 10).String, - Optional: true, - Validators: []validator.Int64{ - int64validator.Between(1, 10), - }, - }, "description": schema.StringAttribute{ MarkdownDescription: helpers.NewAttributeDescription("description of the static route").String, Optional: true, @@ -474,20 +446,6 @@ func (r *RouterStaticVRFIPv4UnicastResource) Schema(ctx context.Context, req res stringvalidator.RegexMatches(regexp.MustCompile(`[0-9\.]*`), ""), }, }, - "bfd_fast_detect_minimum_interval": schema.Int64Attribute{ - MarkdownDescription: helpers.NewAttributeDescription("Hello interval").AddIntegerRangeDescription(3, 30000).String, - Optional: true, - Validators: []validator.Int64{ - int64validator.Between(3, 30000), - }, - }, - "bfd_fast_detect_multiplier": schema.Int64Attribute{ - MarkdownDescription: helpers.NewAttributeDescription("Detect multiplier").AddIntegerRangeDescription(1, 10).String, - Optional: true, - Validators: []validator.Int64{ - int64validator.Between(1, 10), - }, - }, "description": schema.StringAttribute{ MarkdownDescription: helpers.NewAttributeDescription("description of the static route").String, Optional: true, @@ -628,7 +586,7 @@ func (r *RouterStaticVRFIPv4UnicastResource) Read(ctx context.Context, req resou resp.State.RemoveResource(ctx) return } else { - resp.Diagnostics.AddError("Unable to apply gNMI Get operation", err.Error()) + resp.Diagnostics.AddError("Unable to apply Get operation", err.Error()) return } } @@ -639,7 +597,7 @@ func (r *RouterStaticVRFIPv4UnicastResource) Read(ctx context.Context, req resou } // After `terraform import` we switch to a full read. - respBody := getResp.Notification[0].Update[0].Val.GetJsonIetfVal() + respBody := getResp if imp { state.fromBody(ctx, respBody) } else { diff --git a/internal/provider/resource_iosxr_router_static_vrf_ipv6_multicast.go b/internal/provider/resource_iosxr_router_static_vrf_ipv6_multicast.go index d78c3220..deb39a8e 100644 --- a/internal/provider/resource_iosxr_router_static_vrf_ipv6_multicast.go +++ b/internal/provider/resource_iosxr_router_static_vrf_ipv6_multicast.go @@ -380,20 +380,6 @@ func (r *RouterStaticVRFIPv6MulticastResource) Schema(ctx context.Context, req r stringvalidator.RegexMatches(regexp.MustCompile(`[0-9a-fA-F:\.]*`), ""), }, }, - "bfd_fast_detect_minimum_interval": schema.Int64Attribute{ - MarkdownDescription: helpers.NewAttributeDescription("Hello interval").AddIntegerRangeDescription(3, 30000).String, - Optional: true, - Validators: []validator.Int64{ - int64validator.Between(3, 30000), - }, - }, - "bfd_fast_detect_multiplier": schema.Int64Attribute{ - MarkdownDescription: helpers.NewAttributeDescription("Detect multiplier").AddIntegerRangeDescription(1, 10).String, - Optional: true, - Validators: []validator.Int64{ - int64validator.Between(1, 10), - }, - }, "description": schema.StringAttribute{ MarkdownDescription: helpers.NewAttributeDescription("description of the static route").String, Optional: true, @@ -434,6 +420,20 @@ func (r *RouterStaticVRFIPv6MulticastResource) Schema(ctx context.Context, req r int64validator.Between(1, 16777214), }, }, + "bfd_fast_detect_minimum_interval": schema.Int64Attribute{ + MarkdownDescription: helpers.NewAttributeDescription("Hello interval").AddIntegerRangeDescription(3, 30000).String, + Optional: true, + Validators: []validator.Int64{ + int64validator.Between(3, 30000), + }, + }, + "bfd_fast_detect_multiplier": schema.Int64Attribute{ + MarkdownDescription: helpers.NewAttributeDescription("Detect multiplier").AddIntegerRangeDescription(1, 10).String, + Optional: true, + Validators: []validator.Int64{ + int64validator.Between(1, 10), + }, + }, }, }, }, @@ -591,7 +591,7 @@ func (r *RouterStaticVRFIPv6MulticastResource) Read(ctx context.Context, req res resp.State.RemoveResource(ctx) return } else { - resp.Diagnostics.AddError("Unable to apply gNMI Get operation", err.Error()) + resp.Diagnostics.AddError("Unable to apply Get operation", err.Error()) return } } @@ -602,7 +602,7 @@ func (r *RouterStaticVRFIPv6MulticastResource) Read(ctx context.Context, req res } // After `terraform import` we switch to a full read. - respBody := getResp.Notification[0].Update[0].Val.GetJsonIetfVal() + respBody := getResp if imp { state.fromBody(ctx, respBody) } else { diff --git a/internal/provider/resource_iosxr_router_static_vrf_ipv6_multicast_test.go b/internal/provider/resource_iosxr_router_static_vrf_ipv6_multicast_test.go index b4037807..c0841df6 100644 --- a/internal/provider/resource_iosxr_router_static_vrf_ipv6_multicast_test.go +++ b/internal/provider/resource_iosxr_router_static_vrf_ipv6_multicast_test.go @@ -37,19 +37,6 @@ func TestAccIosxrRouterStaticVRFIPv6Multicast(t *testing.T) { var checks []resource.TestCheckFunc checks = append(checks, resource.TestCheckResourceAttr("iosxr_router_static_vrf_ipv6_multicast.test", "prefix_address", "1::")) checks = append(checks, resource.TestCheckResourceAttr("iosxr_router_static_vrf_ipv6_multicast.test", "prefix_length", "64")) - checks = append(checks, resource.TestCheckResourceAttr("iosxr_router_static_vrf_ipv6_multicast.test", "nexthop_interfaces.0.interface_name", "GigabitEthernet0/0/0/1")) - checks = append(checks, resource.TestCheckResourceAttr("iosxr_router_static_vrf_ipv6_multicast.test", "nexthop_interfaces.0.description", "interface-description")) - checks = append(checks, resource.TestCheckResourceAttr("iosxr_router_static_vrf_ipv6_multicast.test", "nexthop_interfaces.0.tag", "100")) - checks = append(checks, resource.TestCheckResourceAttr("iosxr_router_static_vrf_ipv6_multicast.test", "nexthop_interfaces.0.distance_metric", "122")) - checks = append(checks, resource.TestCheckResourceAttr("iosxr_router_static_vrf_ipv6_multicast.test", "nexthop_interfaces.0.permanent", "true")) - checks = append(checks, resource.TestCheckResourceAttr("iosxr_router_static_vrf_ipv6_multicast.test", "nexthop_interfaces.0.metric", "10")) - checks = append(checks, resource.TestCheckResourceAttr("iosxr_router_static_vrf_ipv6_multicast.test", "nexthop_interface_addresses.0.interface_name", "GigabitEthernet0/0/0/2")) - checks = append(checks, resource.TestCheckResourceAttr("iosxr_router_static_vrf_ipv6_multicast.test", "nexthop_interface_addresses.0.address", "2::2")) - checks = append(checks, resource.TestCheckResourceAttr("iosxr_router_static_vrf_ipv6_multicast.test", "nexthop_interface_addresses.0.description", "interface-description")) - checks = append(checks, resource.TestCheckResourceAttr("iosxr_router_static_vrf_ipv6_multicast.test", "nexthop_interface_addresses.0.tag", "103")) - checks = append(checks, resource.TestCheckResourceAttr("iosxr_router_static_vrf_ipv6_multicast.test", "nexthop_interface_addresses.0.distance_metric", "144")) - checks = append(checks, resource.TestCheckResourceAttr("iosxr_router_static_vrf_ipv6_multicast.test", "nexthop_interface_addresses.0.track", "TRACK1")) - checks = append(checks, resource.TestCheckResourceAttr("iosxr_router_static_vrf_ipv6_multicast.test", "nexthop_interface_addresses.0.metric", "10")) checks = append(checks, resource.TestCheckResourceAttr("iosxr_router_static_vrf_ipv6_multicast.test", "nexthop_addresses.0.address", "3::3")) checks = append(checks, resource.TestCheckResourceAttr("iosxr_router_static_vrf_ipv6_multicast.test", "nexthop_addresses.0.description", "ip-description")) checks = append(checks, resource.TestCheckResourceAttr("iosxr_router_static_vrf_ipv6_multicast.test", "nexthop_addresses.0.tag", "104")) @@ -57,21 +44,6 @@ func TestAccIosxrRouterStaticVRFIPv6Multicast(t *testing.T) { checks = append(checks, resource.TestCheckResourceAttr("iosxr_router_static_vrf_ipv6_multicast.test", "nexthop_addresses.0.track", "TRACK1")) checks = append(checks, resource.TestCheckResourceAttr("iosxr_router_static_vrf_ipv6_multicast.test", "nexthop_addresses.0.metric", "10")) checks = append(checks, resource.TestCheckResourceAttr("iosxr_router_static_vrf_ipv6_multicast.test", "vrfs.0.vrf_name", "VRF1")) - checks = append(checks, resource.TestCheckResourceAttr("iosxr_router_static_vrf_ipv6_multicast.test", "vrfs.0.nexthop_interfaces.0.interface_name", "GigabitEthernet0/0/0/3")) - checks = append(checks, resource.TestCheckResourceAttr("iosxr_router_static_vrf_ipv6_multicast.test", "vrfs.0.nexthop_interfaces.0.description", "interface-description")) - checks = append(checks, resource.TestCheckResourceAttr("iosxr_router_static_vrf_ipv6_multicast.test", "vrfs.0.nexthop_interfaces.0.tag", "100")) - checks = append(checks, resource.TestCheckResourceAttr("iosxr_router_static_vrf_ipv6_multicast.test", "vrfs.0.nexthop_interfaces.0.distance_metric", "122")) - checks = append(checks, resource.TestCheckResourceAttr("iosxr_router_static_vrf_ipv6_multicast.test", "vrfs.0.nexthop_interfaces.0.permanent", "true")) - checks = append(checks, resource.TestCheckResourceAttr("iosxr_router_static_vrf_ipv6_multicast.test", "vrfs.0.nexthop_interfaces.0.metric", "10")) - checks = append(checks, resource.TestCheckResourceAttr("iosxr_router_static_vrf_ipv6_multicast.test", "vrfs.0.nexthop_interface_addresses.0.interface_name", "GigabitEthernet0/0/0/4")) - checks = append(checks, resource.TestCheckResourceAttr("iosxr_router_static_vrf_ipv6_multicast.test", "vrfs.0.nexthop_interface_addresses.0.address", "2::2")) - checks = append(checks, resource.TestCheckResourceAttr("iosxr_router_static_vrf_ipv6_multicast.test", "vrfs.0.nexthop_interface_addresses.0.bfd_fast_detect_minimum_interval", "100")) - checks = append(checks, resource.TestCheckResourceAttr("iosxr_router_static_vrf_ipv6_multicast.test", "vrfs.0.nexthop_interface_addresses.0.bfd_fast_detect_multiplier", "3")) - checks = append(checks, resource.TestCheckResourceAttr("iosxr_router_static_vrf_ipv6_multicast.test", "vrfs.0.nexthop_interface_addresses.0.description", "interface-description")) - checks = append(checks, resource.TestCheckResourceAttr("iosxr_router_static_vrf_ipv6_multicast.test", "vrfs.0.nexthop_interface_addresses.0.tag", "103")) - checks = append(checks, resource.TestCheckResourceAttr("iosxr_router_static_vrf_ipv6_multicast.test", "vrfs.0.nexthop_interface_addresses.0.distance_metric", "144")) - checks = append(checks, resource.TestCheckResourceAttr("iosxr_router_static_vrf_ipv6_multicast.test", "vrfs.0.nexthop_interface_addresses.0.track", "TRACK1")) - checks = append(checks, resource.TestCheckResourceAttr("iosxr_router_static_vrf_ipv6_multicast.test", "vrfs.0.nexthop_interface_addresses.0.metric", "10")) checks = append(checks, resource.TestCheckResourceAttr("iosxr_router_static_vrf_ipv6_multicast.test", "vrfs.0.nexthop_addresses.0.address", "3::3")) checks = append(checks, resource.TestCheckResourceAttr("iosxr_router_static_vrf_ipv6_multicast.test", "vrfs.0.nexthop_addresses.0.description", "ip-description")) checks = append(checks, resource.TestCheckResourceAttr("iosxr_router_static_vrf_ipv6_multicast.test", "vrfs.0.nexthop_addresses.0.tag", "104")) @@ -138,9 +110,6 @@ func testAccIosxrRouterStaticVRFIPv6MulticastConfig_minimum() string { config += ` vrf_name = "VRF2"` + "\n" config += ` prefix_address = "1::"` + "\n" config += ` prefix_length = 64` + "\n" - config += ` nexthop_interfaces = [{` + "\n" - config += ` interface_name = "GigabitEthernet0/0/0/1"` + "\n" - config += ` }]` + "\n" config += ` depends_on = [iosxr_gnmi.PreReq0, ]` + "\n" config += `}` + "\n" return config @@ -155,23 +124,6 @@ func testAccIosxrRouterStaticVRFIPv6MulticastConfig_all() string { config += ` vrf_name = "VRF2"` + "\n" config += ` prefix_address = "1::"` + "\n" config += ` prefix_length = 64` + "\n" - config += ` nexthop_interfaces = [{` + "\n" - config += ` interface_name = "GigabitEthernet0/0/0/1"` + "\n" - config += ` description = "interface-description"` + "\n" - config += ` tag = 100` + "\n" - config += ` distance_metric = 122` + "\n" - config += ` permanent = true` + "\n" - config += ` metric = 10` + "\n" - config += ` }]` + "\n" - config += ` nexthop_interface_addresses = [{` + "\n" - config += ` interface_name = "GigabitEthernet0/0/0/2"` + "\n" - config += ` address = "2::2"` + "\n" - config += ` description = "interface-description"` + "\n" - config += ` tag = 103` + "\n" - config += ` distance_metric = 144` + "\n" - config += ` track = "TRACK1"` + "\n" - config += ` metric = 10` + "\n" - config += ` }]` + "\n" config += ` nexthop_addresses = [{` + "\n" config += ` address = "3::3"` + "\n" config += ` description = "ip-description"` + "\n" @@ -182,25 +134,6 @@ func testAccIosxrRouterStaticVRFIPv6MulticastConfig_all() string { config += ` }]` + "\n" config += ` vrfs = [{` + "\n" config += ` vrf_name = "VRF1"` + "\n" - config += ` nexthop_interfaces = [{` + "\n" - config += ` interface_name = "GigabitEthernet0/0/0/3"` + "\n" - config += ` description = "interface-description"` + "\n" - config += ` tag = 100` + "\n" - config += ` distance_metric = 122` + "\n" - config += ` permanent = true` + "\n" - config += ` metric = 10` + "\n" - config += ` }]` + "\n" - config += ` nexthop_interface_addresses = [{` + "\n" - config += ` interface_name = "GigabitEthernet0/0/0/4"` + "\n" - config += ` address = "2::2"` + "\n" - config += ` bfd_fast_detect_minimum_interval = 100` + "\n" - config += ` bfd_fast_detect_multiplier = 3` + "\n" - config += ` description = "interface-description"` + "\n" - config += ` tag = 103` + "\n" - config += ` distance_metric = 144` + "\n" - config += ` track = "TRACK1"` + "\n" - config += ` metric = 10` + "\n" - config += ` }]` + "\n" config += ` nexthop_addresses = [{` + "\n" config += ` address = "3::3"` + "\n" config += ` description = "ip-description"` + "\n" diff --git a/internal/provider/resource_iosxr_router_static_vrf_ipv6_unicast.go b/internal/provider/resource_iosxr_router_static_vrf_ipv6_unicast.go index 07c18a7e..18d76149 100644 --- a/internal/provider/resource_iosxr_router_static_vrf_ipv6_unicast.go +++ b/internal/provider/resource_iosxr_router_static_vrf_ipv6_unicast.go @@ -591,7 +591,7 @@ func (r *RouterStaticVRFIPv6UnicastResource) Read(ctx context.Context, req resou resp.State.RemoveResource(ctx) return } else { - resp.Diagnostics.AddError("Unable to apply gNMI Get operation", err.Error()) + resp.Diagnostics.AddError("Unable to apply Get operation", err.Error()) return } } @@ -602,7 +602,7 @@ func (r *RouterStaticVRFIPv6UnicastResource) Read(ctx context.Context, req resou } // After `terraform import` we switch to a full read. - respBody := getResp.Notification[0].Update[0].Val.GetJsonIetfVal() + respBody := getResp if imp { state.fromBody(ctx, respBody) } else { diff --git a/internal/provider/resource_iosxr_router_vrrp_interface.go b/internal/provider/resource_iosxr_router_vrrp_interface.go index bf7240aa..24f24339 100644 --- a/internal/provider/resource_iosxr_router_vrrp_interface.go +++ b/internal/provider/resource_iosxr_router_vrrp_interface.go @@ -219,7 +219,7 @@ func (r *RouterVRRPInterfaceResource) Read(ctx context.Context, req resource.Rea resp.State.RemoveResource(ctx) return } else { - resp.Diagnostics.AddError("Unable to apply gNMI Get operation", err.Error()) + resp.Diagnostics.AddError("Unable to apply Get operation", err.Error()) return } } @@ -230,7 +230,7 @@ func (r *RouterVRRPInterfaceResource) Read(ctx context.Context, req resource.Rea } // After `terraform import` we switch to a full read. - respBody := getResp.Notification[0].Update[0].Val.GetJsonIetfVal() + respBody := getResp if imp { state.fromBody(ctx, respBody) } else { diff --git a/internal/provider/resource_iosxr_router_vrrp_interface_ipv4.go b/internal/provider/resource_iosxr_router_vrrp_interface_ipv4.go index 248a825d..10fb0baf 100644 --- a/internal/provider/resource_iosxr_router_vrrp_interface_ipv4.go +++ b/internal/provider/resource_iosxr_router_vrrp_interface_ipv4.go @@ -339,7 +339,7 @@ func (r *RouterVRRPInterfaceIPv4Resource) Read(ctx context.Context, req resource resp.State.RemoveResource(ctx) return } else { - resp.Diagnostics.AddError("Unable to apply gNMI Get operation", err.Error()) + resp.Diagnostics.AddError("Unable to apply Get operation", err.Error()) return } } @@ -350,7 +350,7 @@ func (r *RouterVRRPInterfaceIPv4Resource) Read(ctx context.Context, req resource } // After `terraform import` we switch to a full read. - respBody := getResp.Notification[0].Update[0].Val.GetJsonIetfVal() + respBody := getResp if imp { state.fromBody(ctx, respBody) } else { diff --git a/internal/provider/resource_iosxr_router_vrrp_interface_ipv6.go b/internal/provider/resource_iosxr_router_vrrp_interface_ipv6.go index 174753df..52e22a0c 100644 --- a/internal/provider/resource_iosxr_router_vrrp_interface_ipv6.go +++ b/internal/provider/resource_iosxr_router_vrrp_interface_ipv6.go @@ -102,21 +102,13 @@ func (r *RouterVRRPInterfaceIPv6Resource) Schema(ctx context.Context, req resour int64planmodifier.RequiresReplace(), }, }, - "global_addresses": schema.ListNestedAttribute{ - MarkdownDescription: helpers.NewAttributeDescription("Global VRRP IPv6 address").String, + "global_addresses": schema.StringAttribute{ + MarkdownDescription: helpers.NewAttributeDescription("Set Global VRRP IPv6 address").String, Optional: true, - NestedObject: schema.NestedAttributeObject{ - Attributes: map[string]schema.Attribute{ - "address": schema.StringAttribute{ - MarkdownDescription: helpers.NewAttributeDescription("Set Global VRRP IPv6 address").String, - Required: true, - Validators: []validator.String{ - stringvalidator.RegexMatches(regexp.MustCompile(`((:|[0-9a-fA-F]{0,4}):)([0-9a-fA-F]{0,4}:){0,5}((([0-9a-fA-F]{0,4}:)?(:|[0-9a-fA-F]{0,4}))|(((25[0-5]|2[0-4][0-9]|[01]?[0-9]?[0-9])\.){3}(25[0-5]|2[0-4][0-9]|[01]?[0-9]?[0-9])))(%[\p{N}\p{L}]+)?`), ""), - stringvalidator.RegexMatches(regexp.MustCompile(`(([^:]+:){6}(([^:]+:[^:]+)|(.*\..*)))|((([^:]+:)*[^:]+)?::(([^:]+:)*[^:]+)?)(%.+)?`), ""), - stringvalidator.RegexMatches(regexp.MustCompile(`[0-9a-fA-F:\.]*`), ""), - }, - }, - }, + Validators: []validator.String{ + stringvalidator.RegexMatches(regexp.MustCompile(`((:|[0-9a-fA-F]{0,4}):)([0-9a-fA-F]{0,4}:){0,5}((([0-9a-fA-F]{0,4}:)?(:|[0-9a-fA-F]{0,4}))|(((25[0-5]|2[0-4][0-9]|[01]?[0-9]?[0-9])\.){3}(25[0-5]|2[0-4][0-9]|[01]?[0-9]?[0-9])))(%[\p{N}\p{L}]+)?`), ""), + stringvalidator.RegexMatches(regexp.MustCompile(`(([^:]+:){6}(([^:]+:[^:]+)|(.*\..*)))|((([^:]+:)*[^:]+)?::(([^:]+:)*[^:]+)?)(%.+)?`), ""), + stringvalidator.RegexMatches(regexp.MustCompile(`[0-9a-fA-F:\.]*`), ""), }, }, "address_linklocal": schema.StringAttribute{ @@ -328,7 +320,7 @@ func (r *RouterVRRPInterfaceIPv6Resource) Read(ctx context.Context, req resource resp.State.RemoveResource(ctx) return } else { - resp.Diagnostics.AddError("Unable to apply gNMI Get operation", err.Error()) + resp.Diagnostics.AddError("Unable to apply Get operation", err.Error()) return } } @@ -339,7 +331,7 @@ func (r *RouterVRRPInterfaceIPv6Resource) Read(ctx context.Context, req resource } // After `terraform import` we switch to a full read. - respBody := getResp.Notification[0].Update[0].Val.GetJsonIetfVal() + respBody := getResp if imp { state.fromBody(ctx, respBody) } else { diff --git a/internal/provider/resource_iosxr_router_vrrp_interface_ipv6_test.go b/internal/provider/resource_iosxr_router_vrrp_interface_ipv6_test.go index 610d84c4..d6528dc9 100644 --- a/internal/provider/resource_iosxr_router_vrrp_interface_ipv6_test.go +++ b/internal/provider/resource_iosxr_router_vrrp_interface_ipv6_test.go @@ -36,7 +36,6 @@ import ( func TestAccIosxrRouterVRRPInterfaceIPv6(t *testing.T) { var checks []resource.TestCheckFunc checks = append(checks, resource.TestCheckResourceAttr("iosxr_router_vrrp_interface_ipv6.test", "vrrp_id", "124")) - checks = append(checks, resource.TestCheckResourceAttr("iosxr_router_vrrp_interface_ipv6.test", "global_addresses.0.address", "2001:db8::1")) checks = append(checks, resource.TestCheckResourceAttr("iosxr_router_vrrp_interface_ipv6.test", "address_linklocal_autoconfig", "true")) checks = append(checks, resource.TestCheckResourceAttr("iosxr_router_vrrp_interface_ipv6.test", "priority", "250")) checks = append(checks, resource.TestCheckResourceAttr("iosxr_router_vrrp_interface_ipv6.test", "name", "TEST2")) @@ -45,7 +44,7 @@ func TestAccIosxrRouterVRRPInterfaceIPv6(t *testing.T) { checks = append(checks, resource.TestCheckResourceAttr("iosxr_router_vrrp_interface_ipv6.test", "preempt_disable", "false")) checks = append(checks, resource.TestCheckResourceAttr("iosxr_router_vrrp_interface_ipv6.test", "preempt_delay", "255")) checks = append(checks, resource.TestCheckResourceAttr("iosxr_router_vrrp_interface_ipv6.test", "accept_mode_disable", "true")) - checks = append(checks, resource.TestCheckResourceAttr("iosxr_router_vrrp_interface_ipv6.test", "track_interfaces.0.interface_name", "GigabitEthernet0/0/0/4")) + checks = append(checks, resource.TestCheckResourceAttr("iosxr_router_vrrp_interface_ipv6.test", "track_interfaces.0.interface_name", "GigabitEthernet0/0/0/5")) checks = append(checks, resource.TestCheckResourceAttr("iosxr_router_vrrp_interface_ipv6.test", "track_interfaces.0.priority_decrement", "12")) checks = append(checks, resource.TestCheckResourceAttr("iosxr_router_vrrp_interface_ipv6.test", "track_objects.0.object_name", "OBJECT")) checks = append(checks, resource.TestCheckResourceAttr("iosxr_router_vrrp_interface_ipv6.test", "track_objects.0.priority_decrement", "22")) @@ -115,10 +114,6 @@ func testAccIosxrRouterVRRPInterfaceIPv6Config_minimum() string { config := `resource "iosxr_router_vrrp_interface_ipv6" "test" {` + "\n" config += ` interface_name = "GigabitEthernet0/0/0/2"` + "\n" config += ` vrrp_id = 124` + "\n" - config += ` global_addresses = [{` + "\n" - config += ` address = "2001:db8::1"` + "\n" - config += ` }]` + "\n" - config += ` address_linklocal_autoconfig = true` + "\n" config += ` depends_on = [iosxr_gnmi.PreReq0, iosxr_gnmi.PreReq1, ]` + "\n" config += `}` + "\n" return config @@ -132,9 +127,6 @@ func testAccIosxrRouterVRRPInterfaceIPv6Config_all() string { config := `resource "iosxr_router_vrrp_interface_ipv6" "test" {` + "\n" config += ` interface_name = "GigabitEthernet0/0/0/2"` + "\n" config += ` vrrp_id = 124` + "\n" - config += ` global_addresses = [{` + "\n" - config += ` address = "2001:db8::1"` + "\n" - config += ` }]` + "\n" config += ` address_linklocal_autoconfig = true` + "\n" config += ` priority = 250` + "\n" config += ` name = "TEST2"` + "\n" @@ -144,7 +136,7 @@ func testAccIosxrRouterVRRPInterfaceIPv6Config_all() string { config += ` preempt_delay = 255` + "\n" config += ` accept_mode_disable = true` + "\n" config += ` track_interfaces = [{` + "\n" - config += ` interface_name = "GigabitEthernet0/0/0/4"` + "\n" + config += ` interface_name = "GigabitEthernet0/0/0/5"` + "\n" config += ` priority_decrement = 12` + "\n" config += ` }]` + "\n" config += ` track_objects = [{` + "\n" diff --git a/internal/provider/resource_iosxr_segment_routing.go b/internal/provider/resource_iosxr_segment_routing.go index 3d51d985..a1b1f21b 100644 --- a/internal/provider/resource_iosxr_segment_routing.go +++ b/internal/provider/resource_iosxr_segment_routing.go @@ -81,28 +81,28 @@ func (r *SegmentRoutingResource) Schema(ctx context.Context, req resource.Schema }, "global_block_lower_bound": schema.Int64Attribute{ MarkdownDescription: helpers.NewAttributeDescription("SRGB Lower Bound").AddIntegerRangeDescription(16000, 1048574).String, - Optional: true, + Required: true, Validators: []validator.Int64{ int64validator.Between(16000, 1048574), }, }, "global_block_upper_bound": schema.Int64Attribute{ MarkdownDescription: helpers.NewAttributeDescription("SRGB Upper Bound").AddIntegerRangeDescription(16001, 1048575).String, - Optional: true, + Required: true, Validators: []validator.Int64{ int64validator.Between(16001, 1048575), }, }, "local_block_lower_bound": schema.Int64Attribute{ MarkdownDescription: helpers.NewAttributeDescription("SRLB Lower Bound").AddIntegerRangeDescription(15000, 1048574).String, - Optional: true, + Required: true, Validators: []validator.Int64{ int64validator.Between(15000, 1048574), }, }, "local_block_upper_bound": schema.Int64Attribute{ MarkdownDescription: helpers.NewAttributeDescription("SRLB Upper Bound").AddIntegerRangeDescription(15001, 1048575).String, - Optional: true, + Required: true, Validators: []validator.Int64{ int64validator.Between(15001, 1048575), }, @@ -205,7 +205,7 @@ func (r *SegmentRoutingResource) Read(ctx context.Context, req resource.ReadRequ resp.State.RemoveResource(ctx) return } else { - resp.Diagnostics.AddError("Unable to apply gNMI Get operation", err.Error()) + resp.Diagnostics.AddError("Unable to apply Get operation", err.Error()) return } } @@ -216,7 +216,7 @@ func (r *SegmentRoutingResource) Read(ctx context.Context, req resource.ReadRequ } // After `terraform import` we switch to a full read. - respBody := getResp.Notification[0].Update[0].Val.GetJsonIetfVal() + respBody := getResp if imp { state.fromBody(ctx, respBody) } else { diff --git a/internal/provider/resource_iosxr_segment_routing_te.go b/internal/provider/resource_iosxr_segment_routing_te.go index 67380a57..1cdb0737 100644 --- a/internal/provider/resource_iosxr_segment_routing_te.go +++ b/internal/provider/resource_iosxr_segment_routing_te.go @@ -403,7 +403,7 @@ func (r *SegmentRoutingTEResource) Read(ctx context.Context, req resource.ReadRe resp.State.RemoveResource(ctx) return } else { - resp.Diagnostics.AddError("Unable to apply gNMI Get operation", err.Error()) + resp.Diagnostics.AddError("Unable to apply Get operation", err.Error()) return } } @@ -414,7 +414,7 @@ func (r *SegmentRoutingTEResource) Read(ctx context.Context, req resource.ReadRe } // After `terraform import` we switch to a full read. - respBody := getResp.Notification[0].Update[0].Val.GetJsonIetfVal() + respBody := getResp if imp { state.fromBody(ctx, respBody) } else { diff --git a/internal/provider/resource_iosxr_segment_routing_te_policy_candidate_path.go b/internal/provider/resource_iosxr_segment_routing_te_policy_candidate_path.go index b25dce24..a50a8a69 100644 --- a/internal/provider/resource_iosxr_segment_routing_te_policy_candidate_path.go +++ b/internal/provider/resource_iosxr_segment_routing_te_policy_candidate_path.go @@ -238,7 +238,7 @@ func (r *SegmentRoutingTEPolicyCandidatePathResource) Read(ctx context.Context, resp.State.RemoveResource(ctx) return } else { - resp.Diagnostics.AddError("Unable to apply gNMI Get operation", err.Error()) + resp.Diagnostics.AddError("Unable to apply Get operation", err.Error()) return } } @@ -249,7 +249,7 @@ func (r *SegmentRoutingTEPolicyCandidatePathResource) Read(ctx context.Context, } // After `terraform import` we switch to a full read. - respBody := getResp.Notification[0].Update[0].Val.GetJsonIetfVal() + respBody := getResp if imp { state.fromBody(ctx, respBody) } else { diff --git a/internal/provider/resource_iosxr_segment_routing_v6.go b/internal/provider/resource_iosxr_segment_routing_v6.go index 2a41f9b6..aa8035a2 100644 --- a/internal/provider/resource_iosxr_segment_routing_v6.go +++ b/internal/provider/resource_iosxr_segment_routing_v6.go @@ -260,7 +260,7 @@ func (r *SegmentRoutingV6Resource) Read(ctx context.Context, req resource.ReadRe resp.State.RemoveResource(ctx) return } else { - resp.Diagnostics.AddError("Unable to apply gNMI Get operation", err.Error()) + resp.Diagnostics.AddError("Unable to apply Get operation", err.Error()) return } } @@ -271,7 +271,7 @@ func (r *SegmentRoutingV6Resource) Read(ctx context.Context, req resource.ReadRe } // After `terraform import` we switch to a full read. - respBody := getResp.Notification[0].Update[0].Val.GetJsonIetfVal() + respBody := getResp if imp { state.fromBody(ctx, respBody) } else { diff --git a/internal/provider/resource_iosxr_service_timestamps.go b/internal/provider/resource_iosxr_service_timestamps.go index bc84954f..c5a95260 100644 --- a/internal/provider/resource_iosxr_service_timestamps.go +++ b/internal/provider/resource_iosxr_service_timestamps.go @@ -219,7 +219,7 @@ func (r *ServiceTimestampsResource) Read(ctx context.Context, req resource.ReadR resp.State.RemoveResource(ctx) return } else { - resp.Diagnostics.AddError("Unable to apply gNMI Get operation", err.Error()) + resp.Diagnostics.AddError("Unable to apply Get operation", err.Error()) return } } @@ -230,7 +230,7 @@ func (r *ServiceTimestampsResource) Read(ctx context.Context, req resource.ReadR } // After `terraform import` we switch to a full read. - respBody := getResp.Notification[0].Update[0].Val.GetJsonIetfVal() + respBody := getResp if imp { state.fromBody(ctx, respBody) } else { diff --git a/internal/provider/resource_iosxr_service_timestamps_test.go b/internal/provider/resource_iosxr_service_timestamps_test.go index e46b6092..992a3689 100644 --- a/internal/provider/resource_iosxr_service_timestamps_test.go +++ b/internal/provider/resource_iosxr_service_timestamps_test.go @@ -40,13 +40,13 @@ func TestAccIosxrServiceTimestamps(t *testing.T) { checks = append(checks, resource.TestCheckResourceAttr("iosxr_service_timestamps.test", "debug_datetime_show_timezone", "true")) checks = append(checks, resource.TestCheckResourceAttr("iosxr_service_timestamps.test", "debug_datetime_year", "true")) checks = append(checks, resource.TestCheckResourceAttr("iosxr_service_timestamps.test", "debug_uptime", "true")) - checks = append(checks, resource.TestCheckResourceAttr("iosxr_service_timestamps.test", "debug_disable", "false")) + checks = append(checks, resource.TestCheckResourceAttr("iosxr_service_timestamps.test", "debug_disable", "true")) checks = append(checks, resource.TestCheckResourceAttr("iosxr_service_timestamps.test", "log_datetime_localtime", "true")) checks = append(checks, resource.TestCheckResourceAttr("iosxr_service_timestamps.test", "log_datetime_msec", "true")) checks = append(checks, resource.TestCheckResourceAttr("iosxr_service_timestamps.test", "log_datetime_show_timezone", "true")) checks = append(checks, resource.TestCheckResourceAttr("iosxr_service_timestamps.test", "log_datetime_year", "true")) checks = append(checks, resource.TestCheckResourceAttr("iosxr_service_timestamps.test", "log_uptime", "true")) - checks = append(checks, resource.TestCheckResourceAttr("iosxr_service_timestamps.test", "log_disable", "false")) + checks = append(checks, resource.TestCheckResourceAttr("iosxr_service_timestamps.test", "log_disable", "true")) var steps []resource.TestStep if os.Getenv("SKIP_MINIMUM_TEST") == "" { steps = append(steps, resource.TestStep{ @@ -91,7 +91,6 @@ func iosxrServiceTimestampsImportStateIdFunc(resourceName string) resource.Impor func testAccIosxrServiceTimestampsConfig_minimum() string { config := `resource "iosxr_service_timestamps" "test" {` + "\n" - config += ` debug_datetime_localtime = true` + "\n" config += `}` + "\n" return config } @@ -107,13 +106,13 @@ func testAccIosxrServiceTimestampsConfig_all() string { config += ` debug_datetime_show_timezone = true` + "\n" config += ` debug_datetime_year = true` + "\n" config += ` debug_uptime = true` + "\n" - config += ` debug_disable = false` + "\n" + config += ` debug_disable = true` + "\n" config += ` log_datetime_localtime = true` + "\n" config += ` log_datetime_msec = true` + "\n" config += ` log_datetime_show_timezone = true` + "\n" config += ` log_datetime_year = true` + "\n" config += ` log_uptime = true` + "\n" - config += ` log_disable = false` + "\n" + config += ` log_disable = true` + "\n" config += `}` + "\n" return config } diff --git a/internal/provider/resource_iosxr_snmp_server.go b/internal/provider/resource_iosxr_snmp_server.go index b226d9cb..38225899 100644 --- a/internal/provider/resource_iosxr_snmp_server.go +++ b/internal/provider/resource_iosxr_snmp_server.go @@ -565,7 +565,7 @@ func (r *SNMPServerResource) Read(ctx context.Context, req resource.ReadRequest, resp.State.RemoveResource(ctx) return } else { - resp.Diagnostics.AddError("Unable to apply gNMI Get operation", err.Error()) + resp.Diagnostics.AddError("Unable to apply Get operation", err.Error()) return } } @@ -576,7 +576,7 @@ func (r *SNMPServerResource) Read(ctx context.Context, req resource.ReadRequest, } // After `terraform import` we switch to a full read. - respBody := getResp.Notification[0].Update[0].Val.GetJsonIetfVal() + respBody := getResp if imp { state.fromBody(ctx, respBody) } else { diff --git a/internal/provider/resource_iosxr_snmp_server_mib.go b/internal/provider/resource_iosxr_snmp_server_mib.go index a5d734f0..a10d4391 100644 --- a/internal/provider/resource_iosxr_snmp_server_mib.go +++ b/internal/provider/resource_iosxr_snmp_server_mib.go @@ -180,7 +180,7 @@ func (r *SNMPServerMIBResource) Read(ctx context.Context, req resource.ReadReque resp.State.RemoveResource(ctx) return } else { - resp.Diagnostics.AddError("Unable to apply gNMI Get operation", err.Error()) + resp.Diagnostics.AddError("Unable to apply Get operation", err.Error()) return } } @@ -191,7 +191,7 @@ func (r *SNMPServerMIBResource) Read(ctx context.Context, req resource.ReadReque } // After `terraform import` we switch to a full read. - respBody := getResp.Notification[0].Update[0].Val.GetJsonIetfVal() + respBody := getResp if imp { state.fromBody(ctx, respBody) } else { diff --git a/internal/provider/resource_iosxr_snmp_server_view.go b/internal/provider/resource_iosxr_snmp_server_view.go index 6d187128..c4fc915f 100644 --- a/internal/provider/resource_iosxr_snmp_server_view.go +++ b/internal/provider/resource_iosxr_snmp_server_view.go @@ -207,7 +207,7 @@ func (r *SNMPServerViewResource) Read(ctx context.Context, req resource.ReadRequ resp.State.RemoveResource(ctx) return } else { - resp.Diagnostics.AddError("Unable to apply gNMI Get operation", err.Error()) + resp.Diagnostics.AddError("Unable to apply Get operation", err.Error()) return } } @@ -218,7 +218,7 @@ func (r *SNMPServerViewResource) Read(ctx context.Context, req resource.ReadRequ } // After `terraform import` we switch to a full read. - respBody := getResp.Notification[0].Update[0].Val.GetJsonIetfVal() + respBody := getResp if imp { state.fromBody(ctx, respBody) } else { diff --git a/internal/provider/resource_iosxr_snmp_server_vrf_host.go b/internal/provider/resource_iosxr_snmp_server_vrf_host.go index faf2c923..39853497 100644 --- a/internal/provider/resource_iosxr_snmp_server_vrf_host.go +++ b/internal/provider/resource_iosxr_snmp_server_vrf_host.go @@ -220,7 +220,7 @@ func (r *SNMPServerVRFHostResource) Read(ctx context.Context, req resource.ReadR resp.State.RemoveResource(ctx) return } else { - resp.Diagnostics.AddError("Unable to apply gNMI Get operation", err.Error()) + resp.Diagnostics.AddError("Unable to apply Get operation", err.Error()) return } } @@ -231,7 +231,7 @@ func (r *SNMPServerVRFHostResource) Read(ctx context.Context, req resource.ReadR } // After `terraform import` we switch to a full read. - respBody := getResp.Notification[0].Update[0].Val.GetJsonIetfVal() + respBody := getResp if imp { state.fromBody(ctx, respBody) } else { diff --git a/internal/provider/resource_iosxr_ssh.go b/internal/provider/resource_iosxr_ssh.go index 0283dbec..f5deb38b 100644 --- a/internal/provider/resource_iosxr_ssh.go +++ b/internal/provider/resource_iosxr_ssh.go @@ -233,7 +233,7 @@ func (r *SSHResource) Read(ctx context.Context, req resource.ReadRequest, resp * resp.State.RemoveResource(ctx) return } else { - resp.Diagnostics.AddError("Unable to apply gNMI Get operation", err.Error()) + resp.Diagnostics.AddError("Unable to apply Get operation", err.Error()) return } } @@ -244,7 +244,7 @@ func (r *SSHResource) Read(ctx context.Context, req resource.ReadRequest, resp * } // After `terraform import` we switch to a full read. - respBody := getResp.Notification[0].Update[0].Val.GetJsonIetfVal() + respBody := getResp if imp { state.fromBody(ctx, respBody) } else { diff --git a/internal/provider/resource_iosxr_tag_set.go b/internal/provider/resource_iosxr_tag_set.go index e8580411..51b475ca 100644 --- a/internal/provider/resource_iosxr_tag_set.go +++ b/internal/provider/resource_iosxr_tag_set.go @@ -180,7 +180,7 @@ func (r *TagSetResource) Read(ctx context.Context, req resource.ReadRequest, res resp.State.RemoveResource(ctx) return } else { - resp.Diagnostics.AddError("Unable to apply gNMI Get operation", err.Error()) + resp.Diagnostics.AddError("Unable to apply Get operation", err.Error()) return } } @@ -191,7 +191,7 @@ func (r *TagSetResource) Read(ctx context.Context, req resource.ReadRequest, res } // After `terraform import` we switch to a full read. - respBody := getResp.Notification[0].Update[0].Val.GetJsonIetfVal() + respBody := getResp if imp { state.fromBody(ctx, respBody) } else { diff --git a/internal/provider/resource_iosxr_telnet.go b/internal/provider/resource_iosxr_telnet.go index f84e5b65..b7678774 100644 --- a/internal/provider/resource_iosxr_telnet.go +++ b/internal/provider/resource_iosxr_telnet.go @@ -249,7 +249,7 @@ func (r *TelnetResource) Read(ctx context.Context, req resource.ReadRequest, res resp.State.RemoveResource(ctx) return } else { - resp.Diagnostics.AddError("Unable to apply gNMI Get operation", err.Error()) + resp.Diagnostics.AddError("Unable to apply Get operation", err.Error()) return } } @@ -260,7 +260,7 @@ func (r *TelnetResource) Read(ctx context.Context, req resource.ReadRequest, res } // After `terraform import` we switch to a full read. - respBody := getResp.Notification[0].Update[0].Val.GetJsonIetfVal() + respBody := getResp if imp { state.fromBody(ctx, respBody) } else { diff --git a/internal/provider/resource_iosxr_vrf.go b/internal/provider/resource_iosxr_vrf.go index 936d889f..a1a9b1fa 100644 --- a/internal/provider/resource_iosxr_vrf.go +++ b/internal/provider/resource_iosxr_vrf.go @@ -640,7 +640,7 @@ func (r *VRFResource) Read(ctx context.Context, req resource.ReadRequest, resp * resp.State.RemoveResource(ctx) return } else { - resp.Diagnostics.AddError("Unable to apply gNMI Get operation", err.Error()) + resp.Diagnostics.AddError("Unable to apply Get operation", err.Error()) return } } @@ -651,7 +651,7 @@ func (r *VRFResource) Read(ctx context.Context, req resource.ReadRequest, resp * } // After `terraform import` we switch to a full read. - respBody := getResp.Notification[0].Update[0].Val.GetJsonIetfVal() + respBody := getResp if imp { state.fromBody(ctx, respBody) } else {