AGPL Entitlements API (#3523)

* AGPL Entitlements API

Signed-off-by: Spike Curtis <spike@coder.com>

* Generate typesGenerated.ts

Signed-off-by: Spike Curtis <spike@coder.com>

* AllFeatures -> FeatureNames

Signed-off-by: Spike Curtis <spike@coder.com>

Signed-off-by: Spike Curtis <spike@coder.com>
This commit is contained in:
Spike Curtis
2022-08-17 09:02:36 -07:00
committed by GitHub
parent 5817c6ac7f
commit b1b2d1b2b2
6 changed files with 111 additions and 0 deletions
+4
View File
@@ -391,6 +391,10 @@ func New(options *Options) *API {
r.Get("/resources", api.workspaceBuildResources)
r.Get("/state", api.workspaceBuildState)
})
r.Route("/entitlements", func(r chi.Router) {
r.Use(apiKeyMiddleware)
r.Get("/", entitlements)
})
})
r.NotFound(compressHandler(http.HandlerFunc(api.siteHandler.ServeHTTP)).ServeHTTP)
+1
View File
@@ -242,6 +242,7 @@ func TestAuthorizeAllEndpoints(t *testing.T) {
"POST:/api/v2/users/login": {NoAuthorize: true},
"GET:/api/v2/users/authmethods": {NoAuthorize: true},
"POST:/api/v2/csp/reports": {NoAuthorize: true},
"GET:/api/v2/entitlements": {NoAuthorize: true},
"GET:/%40{user}/{workspacename}/apps/{application}/*": {
AssertAction: rbac.ActionRead,
+23
View File
@@ -0,0 +1,23 @@
package coderd
import (
"net/http"
"github.com/coder/coder/coderd/httpapi"
"github.com/coder/coder/codersdk"
)
func entitlements(rw http.ResponseWriter, _ *http.Request) {
features := make(map[string]codersdk.Feature)
for _, f := range codersdk.FeatureNames {
features[f] = codersdk.Feature{
Entitlement: codersdk.EntitlementNotEntitled,
Enabled: false,
}
}
httpapi.Write(rw, http.StatusOK, codersdk.Entitlements{
Features: features,
Warnings: nil,
HasLicense: false,
})
}
+36
View File
@@ -0,0 +1,36 @@
package coderd
import (
"encoding/json"
"net/http"
"net/http/httptest"
"testing"
"github.com/coder/coder/codersdk"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)
func TestEntitlements(t *testing.T) {
t.Parallel()
t.Run("GET", func(t *testing.T) {
t.Parallel()
r := httptest.NewRequest("GET", "https://example.com/api/v2/entitlements", nil)
rw := httptest.NewRecorder()
entitlements(rw, r)
resp := rw.Result()
assert.Equal(t, http.StatusOK, resp.StatusCode)
dec := json.NewDecoder(resp.Body)
var result codersdk.Entitlements
err := dec.Decode(&result)
require.NoError(t, err)
assert.False(t, result.HasLicense)
assert.Empty(t, result.Warnings)
for _, f := range codersdk.FeatureNames {
require.Contains(t, result.Features, f)
fe := result.Features[f]
assert.False(t, fe.Enabled)
assert.Equal(t, codersdk.EntitlementNotEntitled, fe.Entitlement)
}
})
}
+29
View File
@@ -0,0 +1,29 @@
package codersdk
type Entitlement string
const (
EntitlementEntitled Entitlement = "entitled"
EntitlementGracePeriod Entitlement = "grace_period"
EntitlementNotEntitled Entitlement = "not_entitled"
)
const (
FeatureUserLimit = "user_limit"
FeatureAuditLog = "audit_log"
)
var FeatureNames = []string{FeatureUserLimit, FeatureAuditLog}
type Feature struct {
Entitlement Entitlement `json:"entitlement"`
Enabled bool `json:"enabled"`
Limit *int64 `json:"limit"`
Actual *int64 `json:"actual"`
}
type Entitlements struct {
Features map[string]Feature `json:"features"`
Warnings []string `json:"warnings"`
HasLicense bool `json:"has_license"`
}
+18
View File
@@ -134,6 +134,21 @@ export interface CreateWorkspaceRequest {
readonly parameter_values?: CreateParameterRequest[]
}
// From codersdk/features.go
export interface Entitlements {
readonly features: Record<string, Feature>
readonly warnings: string[]
readonly has_license: boolean
}
// From codersdk/features.go
export interface Feature {
readonly entitlement: Entitlement
readonly enabled: boolean
readonly limit?: number
readonly actual?: number
}
// From codersdk/users.go
export interface GenerateAPIKeyResponse {
readonly key: string
@@ -535,6 +550,9 @@ export interface WorkspaceResourceMetadata {
// From codersdk/workspacebuilds.go
export type BuildReason = "autostart" | "autostop" | "initiator"
// From codersdk/features.go
export type Entitlement = "entitled" | "grace_period" | "not_entitled"
// From codersdk/provisionerdaemons.go
export type LogLevel = "debug" | "error" | "info" | "trace" | "warn"