Serves the provisioner daemon protobuf API over a WebSocket. @Summary Serve provisioner daemon @ID serve-provisioner-daemon @Security CoderSessionToken @Tags Enterprise @Param organization path string true "Organization ID" format(uuid) @Success 101 @Router /api/v2/organizations/{organization}/prov
(rw http.ResponseWriter, r *http.Request)
| 155 | // @Success 101 |
| 156 | // @Router /api/v2/organizations/{organization}/provisionerdaemons/serve [get] |
| 157 | func (api *API) provisionerDaemonServe(rw http.ResponseWriter, r *http.Request) { |
| 158 | ctx := r.Context() |
| 159 | |
| 160 | tags := map[string]string{} |
| 161 | if r.URL.Query().Has("tag") { |
| 162 | for _, tag := range r.URL.Query()["tag"] { |
| 163 | parts := strings.SplitN(tag, "=", 2) |
| 164 | if len(parts) < 2 { |
| 165 | httpapi.Write(ctx, rw, http.StatusBadRequest, codersdk.Response{ |
| 166 | Message: fmt.Sprintf("Invalid format for tag %q. Key and value must be separated with =.", tag), |
| 167 | }) |
| 168 | return |
| 169 | } |
| 170 | tags[parts[0]] = parts[1] |
| 171 | } |
| 172 | } |
| 173 | if !r.URL.Query().Has("provisioner") { |
| 174 | httpapi.Write(ctx, rw, http.StatusBadRequest, codersdk.Response{ |
| 175 | Message: "The provisioner query parameter must be specified.", |
| 176 | }) |
| 177 | return |
| 178 | } |
| 179 | |
| 180 | provisionersMap := map[codersdk.ProvisionerType]struct{}{} |
| 181 | for _, provisioner := range r.URL.Query()["provisioner"] { |
| 182 | switch provisioner { |
| 183 | case string(codersdk.ProvisionerTypeEcho): |
| 184 | provisionersMap[codersdk.ProvisionerTypeEcho] = struct{}{} |
| 185 | case string(codersdk.ProvisionerTypeTerraform): |
| 186 | provisionersMap[codersdk.ProvisionerTypeTerraform] = struct{}{} |
| 187 | default: |
| 188 | httpapi.Write(ctx, rw, http.StatusBadRequest, codersdk.Response{ |
| 189 | Message: fmt.Sprintf("Unknown provisioner type %q", provisioner), |
| 190 | }) |
| 191 | return |
| 192 | } |
| 193 | } |
| 194 | |
| 195 | name := namesgenerator.NameDigitWith("_") |
| 196 | if vals, ok := r.URL.Query()["name"]; ok && len(vals) > 0 { |
| 197 | name = vals[0] |
| 198 | } else { |
| 199 | api.Logger.Warn(ctx, "unnamed provisioner daemon") |
| 200 | } |
| 201 | |
| 202 | authRes, err := api.provisionerDaemonAuth.authorize(r, httpmw.OrganizationParam(r), tags) |
| 203 | if err != nil { |
| 204 | api.Logger.Warn(ctx, "unauthorized provisioner daemon serve request", slog.F("tags", tags), slog.Error(err)) |
| 205 | httpapi.Write(ctx, rw, http.StatusForbidden, |
| 206 | codersdk.Response{ |
| 207 | Message: fmt.Sprintf("You aren't allowed to create provisioner daemons with scope %q", tags[provisionersdk.TagScope]), |
| 208 | Detail: err.Error(), |
| 209 | }, |
| 210 | ) |
| 211 | return |
| 212 | } |
| 213 | tags = authRes.tags |
| 214 |
nothing calls this directly
no test coverage detected