Skip to content

Commit b1b2d1b

Browse files
authored
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>
1 parent 5817c6a commit b1b2d1b

File tree

6 files changed

+111
-0
lines changed

6 files changed

+111
-0
lines changed

coderd/coderd.go

+4
Original file line numberDiff line numberDiff line change
@@ -391,6 +391,10 @@ func New(options *Options) *API {
391391
r.Get("/resources", api.workspaceBuildResources)
392392
r.Get("/state", api.workspaceBuildState)
393393
})
394+
r.Route("/entitlements", func(r chi.Router) {
395+
r.Use(apiKeyMiddleware)
396+
r.Get("/", entitlements)
397+
})
394398
})
395399

396400
r.NotFound(compressHandler(http.HandlerFunc(api.siteHandler.ServeHTTP)).ServeHTTP)

coderd/coderd_test.go

+1
Original file line numberDiff line numberDiff line change
@@ -242,6 +242,7 @@ func TestAuthorizeAllEndpoints(t *testing.T) {
242242
"POST:/api/v2/users/login": {NoAuthorize: true},
243243
"GET:/api/v2/users/authmethods": {NoAuthorize: true},
244244
"POST:/api/v2/csp/reports": {NoAuthorize: true},
245+
"GET:/api/v2/entitlements": {NoAuthorize: true},
245246

246247
"GET:/%40{user}/{workspacename}/apps/{application}/*": {
247248
AssertAction: rbac.ActionRead,

coderd/features.go

+23
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
package coderd
2+
3+
import (
4+
"net/http"
5+
6+
"github.com/coder/coder/coderd/httpapi"
7+
"github.com/coder/coder/codersdk"
8+
)
9+
10+
func entitlements(rw http.ResponseWriter, _ *http.Request) {
11+
features := make(map[string]codersdk.Feature)
12+
for _, f := range codersdk.FeatureNames {
13+
features[f] = codersdk.Feature{
14+
Entitlement: codersdk.EntitlementNotEntitled,
15+
Enabled: false,
16+
}
17+
}
18+
httpapi.Write(rw, http.StatusOK, codersdk.Entitlements{
19+
Features: features,
20+
Warnings: nil,
21+
HasLicense: false,
22+
})
23+
}

coderd/features_internal_test.go

+36
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
package coderd
2+
3+
import (
4+
"encoding/json"
5+
"net/http"
6+
"net/http/httptest"
7+
"testing"
8+
9+
"github.com/coder/coder/codersdk"
10+
"github.com/stretchr/testify/assert"
11+
"github.com/stretchr/testify/require"
12+
)
13+
14+
func TestEntitlements(t *testing.T) {
15+
t.Parallel()
16+
t.Run("GET", func(t *testing.T) {
17+
t.Parallel()
18+
r := httptest.NewRequest("GET", "https://example.com/api/v2/entitlements", nil)
19+
rw := httptest.NewRecorder()
20+
entitlements(rw, r)
21+
resp := rw.Result()
22+
assert.Equal(t, http.StatusOK, resp.StatusCode)
23+
dec := json.NewDecoder(resp.Body)
24+
var result codersdk.Entitlements
25+
err := dec.Decode(&result)
26+
require.NoError(t, err)
27+
assert.False(t, result.HasLicense)
28+
assert.Empty(t, result.Warnings)
29+
for _, f := range codersdk.FeatureNames {
30+
require.Contains(t, result.Features, f)
31+
fe := result.Features[f]
32+
assert.False(t, fe.Enabled)
33+
assert.Equal(t, codersdk.EntitlementNotEntitled, fe.Entitlement)
34+
}
35+
})
36+
}

codersdk/features.go

+29
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
package codersdk
2+
3+
type Entitlement string
4+
5+
const (
6+
EntitlementEntitled Entitlement = "entitled"
7+
EntitlementGracePeriod Entitlement = "grace_period"
8+
EntitlementNotEntitled Entitlement = "not_entitled"
9+
)
10+
11+
const (
12+
FeatureUserLimit = "user_limit"
13+
FeatureAuditLog = "audit_log"
14+
)
15+
16+
var FeatureNames = []string{FeatureUserLimit, FeatureAuditLog}
17+
18+
type Feature struct {
19+
Entitlement Entitlement `json:"entitlement"`
20+
Enabled bool `json:"enabled"`
21+
Limit *int64 `json:"limit"`
22+
Actual *int64 `json:"actual"`
23+
}
24+
25+
type Entitlements struct {
26+
Features map[string]Feature `json:"features"`
27+
Warnings []string `json:"warnings"`
28+
HasLicense bool `json:"has_license"`
29+
}

site/src/api/typesGenerated.ts

+18
Original file line numberDiff line numberDiff line change
@@ -134,6 +134,21 @@ export interface CreateWorkspaceRequest {
134134
readonly parameter_values?: CreateParameterRequest[]
135135
}
136136

137+
// From codersdk/features.go
138+
export interface Entitlements {
139+
readonly features: Record<string, Feature>
140+
readonly warnings: string[]
141+
readonly has_license: boolean
142+
}
143+
144+
// From codersdk/features.go
145+
export interface Feature {
146+
readonly entitlement: Entitlement
147+
readonly enabled: boolean
148+
readonly limit?: number
149+
readonly actual?: number
150+
}
151+
137152
// From codersdk/users.go
138153
export interface GenerateAPIKeyResponse {
139154
readonly key: string
@@ -535,6 +550,9 @@ export interface WorkspaceResourceMetadata {
535550
// From codersdk/workspacebuilds.go
536551
export type BuildReason = "autostart" | "autostop" | "initiator"
537552

553+
// From codersdk/features.go
554+
export type Entitlement = "entitled" | "grace_period" | "not_entitled"
555+
538556
// From codersdk/provisionerdaemons.go
539557
export type LogLevel = "debug" | "error" | "info" | "trace" | "warn"
540558

0 commit comments

Comments
 (0)