Skip to content

Commit

Permalink
add license support (#414)
Browse files Browse the repository at this point in the history
  • Loading branch information
pdabelf5 authored Nov 21, 2024
1 parent 09a47e4 commit 2dcffdd
Show file tree
Hide file tree
Showing 2 changed files with 135 additions and 5 deletions.
70 changes: 65 additions & 5 deletions client/nginx.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,9 @@ import (
"io"
"net/http"
"reflect"
"regexp"
"slices"
"strconv"
"strings"
"sync"
"time"
Expand Down Expand Up @@ -41,11 +43,12 @@ var (
)

var (
ErrParameterRequired = errors.New("parameter is required")
ErrServerNotFound = errors.New("server not found")
ErrServerExists = errors.New("server already exists")
ErrNotSupported = errors.New("not supported")
ErrInvalidTimeout = errors.New("invalid timeout")
ErrParameterRequired = errors.New("parameter is required")
ErrServerNotFound = errors.New("server not found")
ErrServerExists = errors.New("server already exists")
ErrNotSupported = errors.New("not supported")
ErrInvalidTimeout = errors.New("invalid timeout")
ErrPlusVersionNotFound = errors.New("plus version not found in the input string")
)

// NginxClient lets you access NGINX Plus API.
Expand Down Expand Up @@ -193,6 +196,20 @@ type NginxInfo struct {
ParentProcessID uint64 `json:"ppid"`
}

// LicenseReporting contains information about license status for NGINX Plus.
type LicenseReporting struct {
Healthy bool
Fails uint64
Grace uint64
}

// NginxLicense contains licensing information about NGINX Plus.
type NginxLicense struct {
ActiveTill uint64 `json:"active_till"`
Eval bool
Reporting LicenseReporting
}

// Caches is a map of cache stats by cache zone.
type Caches = map[string]HTTPCache

Expand Down Expand Up @@ -1553,6 +1570,30 @@ func (client *NginxClient) GetNginxInfo(ctx context.Context) (*NginxInfo, error)
return &info, nil
}

// GetNginxLicense returns Nginx License data with a context.
func (client *NginxClient) GetNginxLicense(ctx context.Context) (*NginxLicense, error) {
var data NginxLicense

info, err := client.GetNginxInfo(ctx)
if err != nil {
return nil, fmt.Errorf("failed to get nginx info: %w", err)
}
release, err := extractPlusVersionValues(info.Build)
if err != nil {
return nil, fmt.Errorf("failed to get nginx plus release: %w", err)
}

if (client.apiVersion < 9) || (release < 33) {
return &data, nil
}

err = client.get(ctx, "license", &data)
if err != nil {
return nil, fmt.Errorf("failed to get license: %w", err)
}
return &data, nil
}

// GetCaches returns Cache stats with a context.
func (client *NginxClient) GetCaches(ctx context.Context) (*Caches, error) {
var caches Caches
Expand Down Expand Up @@ -1988,3 +2029,22 @@ func (client *NginxClient) GetWorkers(ctx context.Context) ([]*Workers, error) {
}
return workers, nil
}

var rePlus = regexp.MustCompile(`-r(\d+)`)

// extractPlusVersionValues.
func extractPlusVersionValues(input string) (int, error) {
var rValue int
matches := rePlus.FindStringSubmatch(input)

if len(matches) < 1 {
return 0, fmt.Errorf("%w [%s]", ErrPlusVersionNotFound, input)
}

rValue, err := strconv.Atoi(matches[1])
if err != nil {
return 0, fmt.Errorf("failed to convert NGINX Plus release to integer: %w", err)
}

return rValue, nil
}
70 changes: 70 additions & 0 deletions client/nginx_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -910,3 +910,73 @@ func TestGetMaxAPIVersionClient(t *testing.T) {
t.Fatalf("expected %v, got %v", c.apiVersion, maxVer)
}
}

func TestExtractPlusVersion(t *testing.T) {
t.Parallel()
tests := []struct {
name string
version string
expected int
}{
{
name: "r32",
version: "nginx-plus-r32",
expected: 32,
},
{
name: "r32p1",
version: "nginx-plus-r32-p1",
expected: 32,
},
{
name: "r32p2",
version: "nginx-plus-r32-p2",
expected: 32,
},
{
name: "r33",
version: "nginx-plus-r33",
expected: 33,
},
}

for _, test := range tests {
t.Run(test.name, func(t *testing.T) {
t.Parallel()
version, err := extractPlusVersionValues(test.version)
if err != nil {
t.Error(err)
}
if version != test.expected {
t.Errorf("values do not match, got: %d, expected %d)", version, test.expected)
}
})
}
}

func TestExtractPlusVersionNegativeCase(t *testing.T) {
t.Parallel()
tests := []struct {
name string
version string
}{
{
name: "no-number",
version: "nginx-plus-rxx",
},
{
name: "extra-chars",
version: "nginx-plus-rxx4343",
},
}

for _, test := range tests {
t.Run(test.name, func(t *testing.T) {
t.Parallel()
_, err := extractPlusVersionValues(test.version)
if err == nil {
t.Errorf("Expected error but got %v", err)
}
})
}
}

0 comments on commit 2dcffdd

Please sign in to comment.