MCPcopy Index your code
hub / github.com/coder/coder / postLicense

Method postLicense

enterprise/coderd/licenses.go:66–154  ·  view source on GitHub ↗

postLicense adds a new Enterprise license to the cluster. We allow multiple different licenses in the cluster at one time for several reasons: 1. Upgrades --- if the license format changes from one version of Coder to the next, during a rolling update you will have different Coder servers that nee

(rw http.ResponseWriter, r *http.Request)

Source from the content-addressed store, hash-verified

64// @Success 201 {object} codersdk.License
65// @Router /api/v2/licenses [post]
66func (api *API) postLicense(rw http.ResponseWriter, r *http.Request) {
67 var (
68 ctx = r.Context()
69 auditor = api.AGPL.Auditor.Load()
70 aReq, commitAudit = audit.InitRequest[database.License](rw, &audit.RequestParams{
71 Audit: *auditor,
72 Log: api.Logger,
73 Request: r,
74 Action: database.AuditActionCreate,
75 })
76 )
77 defer commitAudit()
78
79 if !api.AGPL.Authorize(r, policy.ActionCreate, rbac.ResourceLicense) {
80 httpapi.Forbidden(rw)
81 return
82 }
83
84 var addLicense codersdk.AddLicenseRequest
85 if !httpapi.Read(ctx, rw, r, &addLicense) {
86 return
87 }
88
89 claims, err := license.ParseClaimsIgnoreNbf(addLicense.License, api.LicenseKeys)
90 if err != nil {
91 httpapi.Write(ctx, rw, http.StatusBadRequest, codersdk.Response{
92 Message: "Invalid license",
93 Detail: err.Error(),
94 })
95 return
96 }
97
98 id, err := uuid.Parse(claims.ID)
99 if err != nil {
100 // If no uuid is in the license, we generate a random uuid.
101 // This is not ideal, and this should be fixed to require a uuid
102 // for all licenses. We require this patch to support older licenses.
103 // TODO: In the future (April 2023?) we should remove this and reissue
104 // old licenses with a uuid.
105 id = uuid.New()
106 }
107 if len(claims.DeploymentIDs) > 0 && !slices.Contains(claims.DeploymentIDs, api.AGPL.DeploymentID) {
108 httpapi.Write(ctx, rw, http.StatusBadRequest, codersdk.Response{
109 Message: "License cannot be used on this deployment!",
110 Detail: fmt.Sprintf("The provided license is locked to the following deployments: %q. "+
111 "Your deployment identifier is %q. Please contact sales.", claims.DeploymentIDs, api.AGPL.DeploymentID),
112 })
113 return
114 }
115
116 dl, err := api.Database.InsertLicense(ctx, database.InsertLicenseParams{
117 UploadedAt: dbtime.Now(),
118 JWT: addLicense.License,
119 Exp: claims.ExpiresAt.Time,
120 UUID: id,
121 })
122 if err != nil {
123 httpapi.Write(ctx, rw, http.StatusInternalServerError, codersdk.Response{

Callers

nothing calls this directly

Calls 15

updateEntitlementsMethod · 0.95
InitRequestFunction · 0.92
ForbiddenFunction · 0.92
ReadFunction · 0.92
ParseClaimsIgnoreNbfFunction · 0.92
WriteFunction · 0.92
NowFunction · 0.92
decodeClaimsFunction · 0.85
convertLicenseFunction · 0.85
ContextMethod · 0.65
AuthorizeMethod · 0.65
ParseMethod · 0.65

Tested by

no test coverage detected