diff --git a/CHANGELOG.md b/CHANGELOG.md index 25738bcf8..d86d14bae 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,15 @@ # Change Log ## [Releases](https://github.com/NetApp/harvest/releases) +## 25.08.1 / 2025-08-18 Release +:pushpin: This release is the same as version 25.08.0, with a fix for an issue where the ONTAP REST collector fails to start if ZAPIs are disabled on the cluster. + +**Upgrade Recommendation:** Only upgrade if you are monitoring clusters with ZAPIs disabled. If ZAPIs are enabled, you can continue using the 25.08.0. + +**Full Changelog**: https://github.com/NetApp/harvest/compare/v25.08.0...v25.08.1 + +--- + ## 25.08.0 / 2025-08-13 Release :pushpin: Highlights of this major release include: ## :star: New Features diff --git a/cmd/collectors/discovery.go b/cmd/collectors/discovery.go index 5673254f4..d088ec2aa 100644 --- a/cmd/collectors/discovery.go +++ b/cmd/collectors/discovery.go @@ -2,6 +2,8 @@ package collectors import ( "errors" + "time" + ciscorest "github.com/netapp/harvest/v2/cmd/collectors/cisco/rest" sgrest "github.com/netapp/harvest/v2/cmd/collectors/storagegrid/rest" "github.com/netapp/harvest/v2/cmd/tools/rest" @@ -9,8 +11,6 @@ import ( "github.com/netapp/harvest/v2/pkg/auth" "github.com/netapp/harvest/v2/pkg/conf" "github.com/netapp/harvest/v2/pkg/errs" - "net/http" - "time" ) func GatherClusterInfo(pollerName string, cred *auth.Credentials) (conf.Remote, error) { @@ -29,19 +29,21 @@ func GatherStorageGridInfo(pollerName string, cred *auth.Credentials) (conf.Remo } func MergeRemotes(remoteZapi conf.Remote, remoteRest conf.Remote, errZapi error, errRest error) (conf.Remote, error) { - err := errors.Join(errZapi, errRest) - remoteRest.ZAPIsExist = remoteZapi.ZAPIsExist - if errZapi != nil { - return remoteRest, err + // If both failed, return the combined error + if errZapi != nil && errRest != nil { + return remoteRest, errors.Join(errZapi, errRest) } - if errRest != nil { - return remoteZapi, err + // If at least one succeeded, return no error + // Prefer REST remote if available, otherwise use ZAPI remote + if errRest == nil { + return remoteRest, nil } - return remoteRest, err + // errRest != nil but errZapi == nil (only ZAPI succeeded) + return remoteZapi, nil } func checkRest(pollerName string, cred *auth.Credentials) (conf.Remote, error) { @@ -97,7 +99,8 @@ func checkZapi(pollerName string, cred *auth.Credentials) (conf.Remote, error) { var he errs.HarvestError if errors.As(err, &he) { switch { - case he.ErrNum == errs.ErrNumZAPISuspended, he.StatusCode == http.StatusBadRequest: + case he.ErrNum == errs.ErrNumZAPISuspended, he.StatusCode >= 400 && he.StatusCode < 500: + // ZAPI is suspended, or we got a 4xx error, so we assume that ZAPI is not available zapisExist = false returnErr = false } diff --git a/cmd/poller/poller_test.go b/cmd/poller/poller_test.go index 371328a30..ba41cadec 100644 --- a/cmd/poller/poller_test.go +++ b/cmd/poller/poller_test.go @@ -2,13 +2,14 @@ package main import ( "errors" + "strings" + "testing" + "github.com/google/go-cmp/cmp" "github.com/google/go-cmp/cmp/cmpopts" "github.com/netapp/harvest/v2/cmd/collectors" "github.com/netapp/harvest/v2/pkg/conf" "github.com/netapp/harvest/v2/pkg/tree/node" - "strings" - "testing" ) func TestUnion2(t *testing.T) { @@ -268,7 +269,7 @@ func TestMergeRemotes(t *testing.T) { errZapi: nil, errRest: errors.New("no REST"), want: conf.Remote{UUID: "abc", Version: "9.11.1", ZAPIsExist: true}, - wantErr: true, + wantErr: false, }, { name: "No ZAPIs", @@ -277,7 +278,7 @@ func TestMergeRemotes(t *testing.T) { errZapi: errors.New("no ZAPI"), errRest: nil, want: conf.Remote{UUID: "abc", Version: "9.17.1", HasREST: true}, - wantErr: true, + wantErr: false, }, { name: "Both", diff --git a/docs/prepare-cdot-clusters.md b/docs/prepare-cdot-clusters.md index 53b8e2fca..4c268732b 100644 --- a/docs/prepare-cdot-clusters.md +++ b/docs/prepare-cdot-clusters.md @@ -55,7 +55,6 @@ security login rest-role create -role harvest-rest-role -access readonly -api /a security login rest-role create -role harvest-rest-role -access readonly -api /api/network/ethernet/switch/ports security login rest-role create -role harvest-rest-role -access readonly -api /api/network/fc/ports security login rest-role create -role harvest-rest-role -access readonly -api /api/network/ip/interfaces -security login rest-role create -role harvest-rest-role -access readonly -api /api/network/ip/ports security login rest-role create -role harvest-rest-role -access readonly -api /api/network/ip/routes security login rest-role create -role harvest-rest-role -access readonly -api /api/protocols/cifs/services security login rest-role create -role harvest-rest-role -access readonly -api /api/protocols/cifs/sessions