@@ -3,6 +3,7 @@ package client
33import (
44 "bytes"
55 "encoding/json"
6+ "errors"
67 "fmt"
78 "io"
89 "io/ioutil"
@@ -12,7 +13,7 @@ import (
1213)
1314
1415const (
15- // APIVersion is a version of NGINX Plus API.
16+ // APIVersion is the default version of NGINX Plus API supported by the client .
1617 APIVersion = 5
1718
1819 pathNotFoundCode = "PathNotFound"
@@ -21,8 +22,10 @@ const (
2122 defaultServerPort = "80"
2223)
2324
24- // Default values for servers in Upstreams.
2525var (
26+ supportedAPIVersions = versions {4 , 5 }
27+
28+ // Default values for servers in Upstreams.
2629 defaultMaxConns = 0
2730 defaultMaxFails = 1
2831 defaultFailTimeout = "10s"
3235 defaultWeight = 1
3336)
3437
38+ // ErrUnsupportedVer means that client's API version is not supported by NGINX plus API
39+ var ErrUnsupportedVer = errors .New ("API version of the client is not supported by running NGINX Plus" )
40+
3541// NginxClient lets you access NGINX Plus API.
3642type NginxClient struct {
43+ version int
3744 apiEndpoint string
3845 httpClient * http.Client
3946}
@@ -378,31 +385,46 @@ type Processes struct {
378385 Respawned int64
379386}
380387
381- // NewNginxClient creates an NginxClient.
388+ // NewNginxClient creates an NginxClient with the latest supported version .
382389func NewNginxClient (httpClient * http.Client , apiEndpoint string ) (* NginxClient , error ) {
390+ return NewNginxClientWithVersion (httpClient , apiEndpoint , APIVersion )
391+ }
392+
393+ //NewNginxClientWithVersion creates an NginxClient with the given version of NGINX Plus API.
394+ func NewNginxClientWithVersion (httpClient * http.Client , apiEndpoint string , version int ) (* NginxClient , error ) {
395+ if ! versionSupported (version ) {
396+ return nil , fmt .Errorf ("API version %v is not supported by the client" , version )
397+ }
383398 versions , err := getAPIVersions (httpClient , apiEndpoint )
384399 if err != nil {
385400 return nil , fmt .Errorf ("error accessing the API: %v" , err )
386401 }
387-
388402 found := false
389403 for _ , v := range * versions {
390- if v == APIVersion {
404+ if v == version {
391405 found = true
392406 break
393407 }
394408 }
395-
396409 if ! found {
397- return nil , fmt . Errorf ( "API version %v of the client is not supported by API versions of NGINX Plus: %v" , APIVersion , * versions )
410+ return nil , ErrUnsupportedVer
398411 }
399-
400412 return & NginxClient {
401413 apiEndpoint : apiEndpoint ,
402414 httpClient : httpClient ,
415+ version : version ,
403416 }, nil
404417}
405418
419+ func versionSupported (n int ) bool {
420+ for _ , version := range supportedAPIVersions {
421+ if n == version {
422+ return true
423+ }
424+ }
425+ return false
426+ }
427+
406428func getAPIVersions (httpClient * http.Client , endpoint string ) (* versions , error ) {
407429 resp , err := httpClient .Get (endpoint )
408430 if err != nil {
@@ -652,7 +674,7 @@ func (client *NginxClient) getIDOfHTTPServer(upstream string, name string) (int,
652674}
653675
654676func (client * NginxClient ) get (path string , data interface {}) error {
655- url := fmt .Sprintf ("%v/%v/%v" , client .apiEndpoint , APIVersion , path )
677+ url := fmt .Sprintf ("%v/%v/%v" , client .apiEndpoint , client . version , path )
656678 resp , err := client .httpClient .Get (url )
657679 if err != nil {
658680 return fmt .Errorf ("failed to get %v: %v" , path , err )
@@ -677,7 +699,7 @@ func (client *NginxClient) get(path string, data interface{}) error {
677699}
678700
679701func (client * NginxClient ) post (path string , input interface {}) error {
680- url := fmt .Sprintf ("%v/%v/%v" , client .apiEndpoint , APIVersion , path )
702+ url := fmt .Sprintf ("%v/%v/%v" , client .apiEndpoint , client . version , path )
681703
682704 jsonInput , err := json .Marshal (input )
683705 if err != nil {
@@ -699,7 +721,7 @@ func (client *NginxClient) post(path string, input interface{}) error {
699721}
700722
701723func (client * NginxClient ) delete (path string , expectedStatusCode int ) error {
702- path = fmt .Sprintf ("%v/%v/%v/" , client .apiEndpoint , APIVersion , path )
724+ path = fmt .Sprintf ("%v/%v/%v/" , client .apiEndpoint , client . version , path )
703725
704726 req , err := http .NewRequest (http .MethodDelete , path , nil )
705727 if err != nil {
@@ -721,7 +743,7 @@ func (client *NginxClient) delete(path string, expectedStatusCode int) error {
721743}
722744
723745func (client * NginxClient ) patch (path string , input interface {}, expectedStatusCode int ) error {
724- path = fmt .Sprintf ("%v/%v/%v/" , client .apiEndpoint , APIVersion , path )
746+ path = fmt .Sprintf ("%v/%v/%v/" , client .apiEndpoint , client . version , path )
725747
726748 jsonInput , err := json .Marshal (input )
727749 if err != nil {
@@ -1139,6 +1161,9 @@ func (client *NginxClient) GetStreamZoneSync() (*StreamZoneSync, error) {
11391161// GetLocationZones returns http/location_zones stats.
11401162func (client * NginxClient ) GetLocationZones () (* LocationZones , error ) {
11411163 var locationZones LocationZones
1164+ if client .version < 5 {
1165+ return & locationZones , nil
1166+ }
11421167 err := client .get ("http/location_zones" , & locationZones )
11431168 if err != nil {
11441169 return nil , fmt .Errorf ("failed to get location zones: %v" , err )
@@ -1150,6 +1175,9 @@ func (client *NginxClient) GetLocationZones() (*LocationZones, error) {
11501175// GetResolvers returns Resolvers stats.
11511176func (client * NginxClient ) GetResolvers () (* Resolvers , error ) {
11521177 var resolvers Resolvers
1178+ if client .version < 5 {
1179+ return & resolvers , nil
1180+ }
11531181 err := client .get ("resolvers" , & resolvers )
11541182 if err != nil {
11551183 return nil , fmt .Errorf ("failed to get resolvers: %v" , err )
@@ -1368,6 +1396,11 @@ func (client *NginxClient) UpdateStreamServer(upstream string, server StreamUpst
13681396 return nil
13691397}
13701398
1399+ // Version returns client's current N+ API version.
1400+ func (client * NginxClient ) Version () int {
1401+ return client .version
1402+ }
1403+
13711404func addPortToServer (server string ) string {
13721405 if len (strings .Split (server , ":" )) == 2 {
13731406 return server
0 commit comments