Skip to content

AGPL Entitlements API #3523

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 3 commits into from
Aug 17, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions coderd/coderd.go
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
1 change: 1 addition & 0 deletions coderd/coderd_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down
23 changes: 23 additions & 0 deletions coderd/features.go
Original file line number Diff line number Diff line change
@@ -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 changes: 36 additions & 0 deletions coderd/features_internal_test.go
Original file line number Diff line number Diff line change
@@ -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 changes: 29 additions & 0 deletions codersdk/features.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
package codersdk

type Entitlement string

const (
EntitlementEntitled Entitlement = "entitled"
EntitlementGracePeriod Entitlement = "grace_period"
EntitlementNotEntitled Entitlement = "not_entitled"
Comment on lines +6 to +8
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Instead of EntitlementEntitled would Entitled suffice? Seems like these are implicit Entitlement based on the name.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I like the consistency of either always or never including the prefix. It'd be nice if Go would support enums natively one day.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I copied

type UserStatus string

const (
	UserStatusActive    UserStatus = "active"
	UserStatusSuspended UserStatus = "suspended"
)

for the sake of consistency. But, if I were writing the package myself for the first time I'd have dropped the prefix. I don't really mind either way.

)

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 changes: 18 additions & 0 deletions site/src/api/typesGenerated.ts
Original file line number Diff line number Diff line change
Expand Up @@ -129,6 +129,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
Expand Down Expand Up @@ -530,6 +545,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"

Expand Down